Merge #321
authorAlpar Juttner <alpar@cs.elte.hu>
Thu, 05 Nov 2009 15:50:01 +0100
changeset 7841a7fe3bef514
parent 505 c6acc34f98dc
parent 783 ef88c0a30f85
child 787 c2230649a493
child 789 8ddb7deabab9
Merge #321
lemon/bits/base_extender.h
lemon/path.h
     1.1 --- a/.hgignore	Fri Oct 16 10:21:37 2009 +0200
     1.2 +++ b/.hgignore	Thu Nov 05 15:50:01 2009 +0100
     1.3 @@ -22,11 +22,16 @@
     1.4  lemon/libemon.la
     1.5  lemon/stamp-h2
     1.6  doc/Doxyfile
     1.7 -cmake/cmake.version
     1.8 +cmake/version.cmake
     1.9  .dirstamp
    1.10  .libs/*
    1.11  .deps/*
    1.12  demo/*.eps
    1.13 +m4/libtool.m4
    1.14 +m4/ltoptions.m4
    1.15 +m4/ltsugar.m4
    1.16 +m4/ltversion.m4
    1.17 +m4/lt~obsolete.m4
    1.18  
    1.19  syntax: regexp
    1.20  (.*/)?\#[^/]*\#$
    1.21 @@ -35,10 +40,11 @@
    1.22  ^doc/.*\.tag
    1.23  ^autom4te.cache/.*
    1.24  ^build-aux/.*
    1.25 -^objs.*/.*
    1.26 +^.*objs.*/.*
    1.27  ^test/[a-z_]*$
    1.28 +^tools/[a-z-_]*$
    1.29  ^demo/.*_demo$
    1.30 -^build/.*
    1.31 +^.*build.*/.*
    1.32  ^doc/gen-images/.*
    1.33  CMakeFiles
    1.34  DartTestfile.txt
     2.1 --- a/CMakeLists.txt	Fri Oct 16 10:21:37 2009 +0200
     2.2 +++ b/CMakeLists.txt	Thu Nov 05 15:50:01 2009 +0100
     2.3 @@ -1,37 +1,75 @@
     2.4  CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
     2.5  
     2.6 -IF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
     2.7 -  INCLUDE(${CMAKE_SOURCE_DIR}/cmake/version.cmake)
     2.8 -ELSE(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
     2.9 -  SET(PROJECT_NAME "LEMON")
    2.10 -  SET(PROJECT_VERSION "hg-tip" CACHE STRING "LEMON version string.")
    2.11 -ENDIF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
    2.12 -
    2.13 +SET(PROJECT_NAME "LEMON")
    2.14  PROJECT(${PROJECT_NAME})
    2.15  
    2.16 -SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
    2.17 +IF(EXISTS ${PROJECT_SOURCE_DIR}/cmake/version.cmake)
    2.18 +  INCLUDE(${PROJECT_SOURCE_DIR}/cmake/version.cmake)
    2.19 +ELSEIF(DEFINED ENV{LEMON_VERSION})
    2.20 +  SET(LEMON_VERSION $ENV{LEMON_VERSION} CACHE STRING "LEMON version string.")
    2.21 +ELSE()
    2.22 +  EXECUTE_PROCESS(
    2.23 +    COMMAND hg id -i
    2.24 +    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
    2.25 +    OUTPUT_VARIABLE HG_REVISION
    2.26 +    ERROR_QUIET
    2.27 +    OUTPUT_STRIP_TRAILING_WHITESPACE
    2.28 +  )
    2.29 +  IF(HG_REVISION STREQUAL "")
    2.30 +    SET(HG_REVISION "hg-tip")
    2.31 +  ENDIF()
    2.32 +  SET(LEMON_VERSION ${HG_REVISION} CACHE STRING "LEMON version string.")
    2.33 +ENDIF()
    2.34  
    2.35 -INCLUDE(FindDoxygen)
    2.36 -INCLUDE(FindGhostscript)
    2.37 +SET(PROJECT_VERSION ${LEMON_VERSION})
    2.38  
    2.39 -ADD_DEFINITIONS(-DHAVE_CONFIG_H)
    2.40 +SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
    2.41 +
    2.42 +FIND_PACKAGE(Doxygen)
    2.43 +FIND_PACKAGE(Ghostscript)
    2.44 +FIND_PACKAGE(GLPK 4.33)
    2.45 +FIND_PACKAGE(CPLEX)
    2.46 +FIND_PACKAGE(COIN)
    2.47  
    2.48  INCLUDE(CheckTypeSize)
    2.49 -CHECK_TYPE_SIZE("long long" LEMON_LONG_LONG)
    2.50 +CHECK_TYPE_SIZE("long long" LONG_LONG)
    2.51 +SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
    2.52 +
    2.53 +INCLUDE(FindPythonInterp)
    2.54  
    2.55  ENABLE_TESTING()
    2.56  
    2.57  ADD_SUBDIRECTORY(lemon)
    2.58 -ADD_SUBDIRECTORY(demo)
    2.59 -ADD_SUBDIRECTORY(doc)
    2.60 -ADD_SUBDIRECTORY(test)
    2.61 +IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
    2.62 +  ADD_SUBDIRECTORY(demo)
    2.63 +  ADD_SUBDIRECTORY(tools)
    2.64 +  ADD_SUBDIRECTORY(doc)
    2.65 +  ADD_SUBDIRECTORY(test)
    2.66 +ENDIF()
    2.67  
    2.68 -IF(WIN32)
    2.69 +CONFIGURE_FILE(
    2.70 +  ${PROJECT_SOURCE_DIR}/cmake/LEMONConfig.cmake.in
    2.71 +  ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
    2.72 +  @ONLY
    2.73 +)
    2.74 +IF(UNIX)
    2.75 +  INSTALL(
    2.76 +    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
    2.77 +    DESTINATION share/lemon/cmake
    2.78 +  )
    2.79 +ELSEIF(WIN32)
    2.80 +  INSTALL(
    2.81 +    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
    2.82 +    DESTINATION cmake
    2.83 +  )
    2.84 +ENDIF()
    2.85 +
    2.86 +IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR} AND WIN32)
    2.87    SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
    2.88    SET(CPACK_PACKAGE_VENDOR "EGRES")
    2.89    SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
    2.90 -    "LEMON - Library of Efficient Models and Optimization in Networks")
    2.91 -  SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
    2.92 +    "LEMON - Library for Efficient Modeling and Optimization in Networks")
    2.93 +  SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
    2.94  
    2.95    SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
    2.96  
    2.97 @@ -40,16 +78,19 @@
    2.98    SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
    2.99      "${PROJECT_NAME} ${PROJECT_VERSION}")
   2.100  
   2.101 -  SET(CPACK_COMPONENTS_ALL headers library html_documentation)
   2.102 +  SET(CPACK_COMPONENTS_ALL headers library html_documentation bin)
   2.103  
   2.104    SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
   2.105    SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
   2.106 +  SET(CPACK_COMPONENT_BIN_DISPLAY_NAME "Command line utilities")
   2.107    SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
   2.108  
   2.109    SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
   2.110      "C++ header files")
   2.111    SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
   2.112      "DLL and import library")
   2.113 +  SET(CPACK_COMPONENT_BIN_DESCRIPTION
   2.114 +    "Command line utilities")
   2.115    SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
   2.116      "Doxygen generated documentation")
   2.117  
   2.118 @@ -71,9 +112,9 @@
   2.119    SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
   2.120  
   2.121    SET(CPACK_GENERATOR "NSIS")
   2.122 -  SET(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/lemon.ico")
   2.123 -  SET(CPACK_NSIS_MUI_UNIICON "${CMAKE_SOURCE_DIR}/cmake/nsis/uninstall.ico")
   2.124 -  #SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
   2.125 +  SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis/lemon.ico")
   2.126 +  SET(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/cmake/nsis/uninstall.ico")
   2.127 +  #SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
   2.128    SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico")
   2.129    SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
   2.130    SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu")
   2.131 @@ -88,4 +129,4 @@
   2.132      ")
   2.133  
   2.134    INCLUDE(CPack)
   2.135 -ENDIF(WIN32)
   2.136 +ENDIF()
     3.1 --- a/INSTALL	Fri Oct 16 10:21:37 2009 +0200
     3.2 +++ b/INSTALL	Thu Nov 05 15:50:01 2009 +0100
     3.3 @@ -27,8 +27,8 @@
     3.4     3. `make'
     3.5  
     3.6        This command compiles the non-template part of LEMON into libemon.a
     3.7 -      file. It also compiles the programs in the tools and demo subdirectories
     3.8 -      when enabled.
     3.9 +      file. It also compiles the programs in the tools subdirectory by
    3.10 +      default.
    3.11  
    3.12     4. `make check'
    3.13  
    3.14 @@ -75,14 +75,6 @@
    3.15  
    3.16    Set the installation prefix to PREFIX. By default it is /usr/local.
    3.17  
    3.18 ---enable-demo
    3.19 -
    3.20 -   Build the examples in the demo subdirectory.
    3.21 -
    3.22 ---disable-demo
    3.23 -
    3.24 -   Do not build the examples in the demo subdirectory (default).
    3.25 -
    3.26  --enable-tools
    3.27  
    3.28     Build the programs in the tools subdirectory (default).
    3.29 @@ -158,3 +150,26 @@
    3.30  --without-soplex
    3.31  
    3.32     Disable SoPlex support.
    3.33 +
    3.34 +--with-coin[=PREFIX]
    3.35 +
    3.36 +   Enable support for COIN-OR solvers (CLP and CBC). You should
    3.37 +   specify the prefix too. (by default, COIN-OR tools install
    3.38 +   themselves to the source code directory). This command enables the
    3.39 +   solvers that are actually found.
    3.40 +
    3.41 +--with-coin-includedir=DIR
    3.42 +
    3.43 +   The directory where the COIN-OR header files are located. This is
    3.44 +   only useful when the COIN-OR headers and libraries are not under
    3.45 +   the same prefix (which is unlikely).
    3.46 +
    3.47 +--with-coin-libdir=DIR
    3.48 +
    3.49 +   The directory where the COIN-OR libraries are located. This is only
    3.50 +   useful when the COIN-OR headers and libraries are not under the
    3.51 +   same prefix (which is unlikely).
    3.52 +
    3.53 +--without-coin
    3.54 +
    3.55 +   Disable COIN-OR support.
     4.1 --- a/LICENSE	Fri Oct 16 10:21:37 2009 +0200
     4.2 +++ b/LICENSE	Thu Nov 05 15:50:01 2009 +0100
     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-2008 Egervary Jeno Kombinatorikus Optimalizalasi
     4.8 +Copyright (C) 2003-2009 Egervary Jeno Kombinatorikus Optimalizalasi
     4.9  Kutatocsoport (Egervary Combinatorial Optimization Research Group,
    4.10  EGRES).
    4.11  
     5.1 --- a/Makefile.am	Fri Oct 16 10:21:37 2009 +0200
     5.2 +++ b/Makefile.am	Thu Nov 05 15:50:01 2009 +0100
     5.3 @@ -1,5 +1,7 @@
     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 @@ -9,8 +11,13 @@
    5.12  	m4/lx_check_cplex.m4 \
    5.13  	m4/lx_check_glpk.m4 \
    5.14  	m4/lx_check_soplex.m4 \
    5.15 +	m4/lx_check_coin.m4 \
    5.16  	CMakeLists.txt \
    5.17  	cmake/FindGhostscript.cmake \
    5.18 +	cmake/FindCPLEX.cmake \
    5.19 +	cmake/FindGLPK.cmake \
    5.20 +	cmake/FindCOIN.cmake \
    5.21 +	cmake/LEMONConfig.cmake.in \
    5.22  	cmake/version.cmake.in \
    5.23  	cmake/version.cmake \
    5.24  	cmake/nsis/lemon.ico \
    5.25 @@ -36,9 +43,13 @@
    5.26  include lemon/Makefile.am
    5.27  include test/Makefile.am
    5.28  include doc/Makefile.am
    5.29 -include demo/Makefile.am
    5.30  include tools/Makefile.am
    5.31  
    5.32 +DIST_SUBDIRS = demo
    5.33 +
    5.34 +demo:
    5.35 +	$(MAKE) $(AM_MAKEFLAGS) -C demo
    5.36 +
    5.37  MRPROPERFILES = \
    5.38  	aclocal.m4 \
    5.39  	config.h.in \
    5.40 @@ -65,4 +76,4 @@
    5.41  	zcat $(PACKAGE)-$(VERSION).tar.gz | \
    5.42  	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
    5.43  
    5.44 -.PHONY: mrproper dist-bz2 distcheck-bz2
    5.45 +.PHONY: demo mrproper dist-bz2 distcheck-bz2
     6.1 --- a/NEWS	Fri Oct 16 10:21:37 2009 +0200
     6.2 +++ b/NEWS	Thu Nov 05 15:50:01 2009 +0100
     6.3 @@ -1,3 +1,90 @@
     6.4 +2009-05-13 Version 1.1 released
     6.5 +
     6.6 +        This is the second stable release of the 1.x series. It
     6.7 +        features a better coverage of the tools available in the 0.x
     6.8 +        series, a thoroughly reworked LP/MIP interface plus various
     6.9 +        improvements in the existing tools.
    6.10 +
    6.11 +        * Much improved M$ Windows support
    6.12 +          * Various improvements in the CMAKE build system
    6.13 +          * Compilation warnings are fixed/suppressed
    6.14 +        * Support IBM xlC compiler
    6.15 +        * New algorithms
    6.16 +          * Connectivity related algorithms (#61)
    6.17 +          * Euler walks (#65)
    6.18 +          * Preflow push-relabel max. flow algorithm (#176)
    6.19 +          * Circulation algorithm (push-relabel based) (#175)
    6.20 +          * Suurballe algorithm (#47)
    6.21 +          * Gomory-Hu algorithm (#66)
    6.22 +          * Hao-Orlin algorithm (#58)
    6.23 +          * Edmond's maximum cardinality and weighted matching algorithms
    6.24 +            in general graphs (#48,#265)
    6.25 +          * Minimum cost arborescence/branching (#60)
    6.26 +          * Network Simplex min. cost flow algorithm (#234)
    6.27 +        * New data structures
    6.28 +          * Full graph structure (#57)
    6.29 +          * Grid graph structure (#57)
    6.30 +          * Hypercube graph structure (#57)
    6.31 +          * Graph adaptors (#67)
    6.32 +          * ArcSet and EdgeSet classes (#67)
    6.33 +          * Elevator class (#174)
    6.34 +        * Other new tools
    6.35 +          * LP/MIP interface (#44)
    6.36 +            * Support for GLPK, CPLEX, Soplex, COIN-OR CLP and CBC
    6.37 +          * Reader for the Nauty file format (#55)
    6.38 +          * DIMACS readers (#167)
    6.39 +          * Radix sort algorithms (#72)
    6.40 +          * RangeIdMap and CrossRefMap (#160)
    6.41 +        * New command line tools
    6.42 +          * DIMACS to LGF converter (#182)
    6.43 +          * lgf-gen - a graph generator (#45)
    6.44 +          * DIMACS solver utility (#226)
    6.45 +        * Other code improvements
    6.46 +          * Lognormal distribution added to Random (#102)
    6.47 +          * Better (i.e. O(1) time) item counting in SmartGraph (#3)
    6.48 +          * The standard maps of graphs are guaranteed to be
    6.49 +            reference maps (#190)
    6.50 +        * Miscellaneous
    6.51 +          * Various doc improvements
    6.52 +          * Improved 0.x -> 1.x converter script
    6.53 +
    6.54 +        * Several bugfixes (compared to release 1.0):
    6.55 +          #170: Bugfix SmartDigraph::split()
    6.56 +          #171: Bugfix in SmartGraph::restoreSnapshot()
    6.57 +          #172: Extended test cases for graphs and digraphs
    6.58 +          #173: Bugfix in Random
    6.59 +                * operator()s always return a double now
    6.60 +                * the faulty real<Num>(Num) and real<Num>(Num,Num)
    6.61 +                  have been removed
    6.62 +          #187: Remove DijkstraWidestPathOperationTraits
    6.63 +          #61:  Bugfix in DfsVisit
    6.64 +          #193: Bugfix in GraphReader::skipSection()
    6.65 +          #195: Bugfix in ConEdgeIt()
    6.66 +          #197: Bugfix in heap unionfind
    6.67 +                * This bug affects Edmond's general matching algorithms
    6.68 +          #207: Fix 'make install' without 'make html' using CMAKE
    6.69 +          #208: Suppress or fix VS2008 compilation warnings
    6.70 +          ----: Update the LEMON icon
    6.71 +          ----: Enable the component-based installer
    6.72 +                (in installers made by CPACK)
    6.73 +          ----: Set the proper version for CMAKE in the tarballs
    6.74 +                (made by autotools)
    6.75 +          ----: Minor clarification in the LICENSE file
    6.76 +          ----: Add missing unistd.h include to time_measure.h
    6.77 +          #204: Compilation bug fixed in graph_to_eps.h with VS2005
    6.78 +          #214,#215: windows.h should never be included by lemon headers
    6.79 +          #230: Build systems check the availability of 'long long' type
    6.80 +          #229: Default implementation of Tolerance<> is used for integer types
    6.81 +          #211,#212: Various fixes for compiling on AIX
    6.82 +          ----: Improvements in CMAKE config
    6.83 +                - docs is installed in share/doc/
    6.84 +                - detects newer versions of Ghostscript
    6.85 +          #239: Fix missing 'inline' specifier in time_measure.h
    6.86 +          #274,#280: Install lemon/config.h
    6.87 +          #275: Prefix macro names with LEMON_ in lemon/config.h
    6.88 +          ----: Small script for making the release tarballs added
    6.89 +          ----: Minor improvement in unify-sources.sh (a76f55d7d397)
    6.90 +
    6.91  2009-03-27 LEMON joins to the COIN-OR initiative
    6.92  
    6.93          COIN-OR (Computational Infrastructure for Operations Research,
     7.1 --- a/README	Fri Oct 16 10:21:37 2009 +0200
     7.2 +++ b/README	Thu Nov 05 15:50:01 2009 +0100
     7.3 @@ -1,6 +1,6 @@
     7.4 -==================================================================
     7.5 -LEMON - a Library of Efficient Models and Optimization in Networks
     7.6 -==================================================================
     7.7 +=====================================================================
     7.8 +LEMON - a Library for Efficient Modeling and Optimization in Networks
     7.9 +=====================================================================
    7.10  
    7.11  LEMON is an open source library written in C++. It provides
    7.12  easy-to-use implementations of common data structures and algorithms
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/cmake/FindCOIN.cmake	Thu Nov 05 15:50:01 2009 +0100
     8.3 @@ -0,0 +1,88 @@
     8.4 +SET(COIN_ROOT_DIR "" CACHE PATH "COIN root directory")
     8.5 +
     8.6 +FIND_PATH(COIN_INCLUDE_DIR coin/CoinUtilsConfig.h
     8.7 +  HINTS ${COIN_ROOT_DIR}/include
     8.8 +)
     8.9 +FIND_LIBRARY(COIN_CBC_LIBRARY
    8.10 +  NAMES Cbc libCbc
    8.11 +  HINTS ${COIN_ROOT_DIR}/lib
    8.12 +)
    8.13 +FIND_LIBRARY(COIN_CBC_SOLVER_LIBRARY
    8.14 +  NAMES CbcSolver libCbcSolver
    8.15 +  HINTS ${COIN_ROOT_DIR}/lib
    8.16 +)
    8.17 +FIND_LIBRARY(COIN_CGL_LIBRARY
    8.18 +  NAMES Cgl libCgl
    8.19 +  HINTS ${COIN_ROOT_DIR}/lib
    8.20 +)
    8.21 +FIND_LIBRARY(COIN_CLP_LIBRARY
    8.22 +  NAMES Clp libClp
    8.23 +  HINTS ${COIN_ROOT_DIR}/lib
    8.24 +)
    8.25 +FIND_LIBRARY(COIN_COIN_UTILS_LIBRARY
    8.26 +  NAMES CoinUtils libCoinUtils
    8.27 +  HINTS ${COIN_ROOT_DIR}/lib
    8.28 +)
    8.29 +FIND_LIBRARY(COIN_OSI_LIBRARY
    8.30 +  NAMES Osi libOsi
    8.31 +  HINTS ${COIN_ROOT_DIR}/lib
    8.32 +)
    8.33 +FIND_LIBRARY(COIN_OSI_CBC_LIBRARY
    8.34 +  NAMES OsiCbc libOsiCbc
    8.35 +  HINTS ${COIN_ROOT_DIR}/lib
    8.36 +)
    8.37 +FIND_LIBRARY(COIN_OSI_CLP_LIBRARY
    8.38 +  NAMES OsiClp libOsiClp
    8.39 +  HINTS ${COIN_ROOT_DIR}/lib
    8.40 +)
    8.41 +FIND_LIBRARY(COIN_OSI_VOL_LIBRARY
    8.42 +  NAMES OsiVol libOsiVol
    8.43 +  HINTS ${COIN_ROOT_DIR}/lib
    8.44 +)
    8.45 +FIND_LIBRARY(COIN_VOL_LIBRARY
    8.46 +  NAMES Vol libVol
    8.47 +  HINTS ${COIN_ROOT_DIR}/lib
    8.48 +)
    8.49 +
    8.50 +INCLUDE(FindPackageHandleStandardArgs)
    8.51 +FIND_PACKAGE_HANDLE_STANDARD_ARGS(COIN DEFAULT_MSG
    8.52 +  COIN_INCLUDE_DIR
    8.53 +  COIN_CBC_LIBRARY
    8.54 +  COIN_CBC_SOLVER_LIBRARY
    8.55 +  COIN_CGL_LIBRARY
    8.56 +  COIN_CLP_LIBRARY
    8.57 +  COIN_COIN_UTILS_LIBRARY
    8.58 +  COIN_OSI_LIBRARY
    8.59 +  COIN_OSI_CBC_LIBRARY
    8.60 +  COIN_OSI_CLP_LIBRARY
    8.61 +  COIN_OSI_VOL_LIBRARY
    8.62 +  COIN_VOL_LIBRARY
    8.63 +)
    8.64 +
    8.65 +IF(COIN_FOUND)
    8.66 +  SET(COIN_INCLUDE_DIRS ${COIN_INCLUDE_DIR})
    8.67 +  SET(COIN_LIBRARIES "${COIN_CBC_LIBRARY};${COIN_CBC_SOLVER_LIBRARY};${COIN_CGL_LIBRARY};${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY};${COIN_OSI_LIBRARY};${COIN_OSI_CBC_LIBRARY};${COIN_OSI_CLP_LIBRARY};${COIN_OSI_VOL_LIBRARY};${COIN_VOL_LIBRARY}")
    8.68 +  SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY}")
    8.69 +  SET(COIN_CBC_LIBRARIES ${COIN_LIBRARIES})
    8.70 +ENDIF(COIN_FOUND)
    8.71 +
    8.72 +MARK_AS_ADVANCED(
    8.73 +  COIN_INCLUDE_DIR
    8.74 +  COIN_CBC_LIBRARY
    8.75 +  COIN_CBC_SOLVER_LIBRARY
    8.76 +  COIN_CGL_LIBRARY
    8.77 +  COIN_CLP_LIBRARY
    8.78 +  COIN_COIN_UTILS_LIBRARY
    8.79 +  COIN_OSI_LIBRARY
    8.80 +  COIN_OSI_CBC_LIBRARY
    8.81 +  COIN_OSI_CLP_LIBRARY
    8.82 +  COIN_OSI_VOL_LIBRARY
    8.83 +  COIN_VOL_LIBRARY
    8.84 +)
    8.85 +
    8.86 +IF(COIN_FOUND)
    8.87 +  SET(LEMON_HAVE_LP TRUE)
    8.88 +  SET(LEMON_HAVE_MIP TRUE)
    8.89 +  SET(LEMON_HAVE_CLP TRUE)
    8.90 +  SET(LEMON_HAVE_CBC TRUE)
    8.91 +ENDIF(COIN_FOUND)
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/cmake/FindCPLEX.cmake	Thu Nov 05 15:50:01 2009 +0100
     9.3 @@ -0,0 +1,38 @@
     9.4 +SET(CPLEX_ROOT_DIR "" CACHE PATH "CPLEX root directory")
     9.5 +
     9.6 +FIND_PATH(CPLEX_INCLUDE_DIR
     9.7 +  ilcplex/cplex.h
     9.8 +  PATHS "C:/ILOG/CPLEX91/include"
     9.9 +  PATHS "/opt/ilog/cplex91/include"
    9.10 +  HINTS ${CPLEX_ROOT_DIR}/include
    9.11 +)
    9.12 +FIND_LIBRARY(CPLEX_LIBRARY
    9.13 +  cplex91
    9.14 +  PATHS "C:/ILOG/CPLEX91/lib/msvc7/stat_mda"
    9.15 +  PATHS "/opt/ilog/cplex91/bin"
    9.16 +  HINTS ${CPLEX_ROOT_DIR}/bin
    9.17 +)
    9.18 +
    9.19 +INCLUDE(FindPackageHandleStandardArgs)
    9.20 +FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPLEX DEFAULT_MSG CPLEX_LIBRARY CPLEX_INCLUDE_DIR)
    9.21 +
    9.22 +FIND_PATH(CPLEX_BIN_DIR
    9.23 +  cplex91.dll
    9.24 +  PATHS "C:/ILOG/CPLEX91/bin/x86_win32"
    9.25 +)
    9.26 +
    9.27 +IF(CPLEX_FOUND)
    9.28 +  SET(CPLEX_INCLUDE_DIRS ${CPLEX_INCLUDE_DIR})
    9.29 +  SET(CPLEX_LIBRARIES ${CPLEX_LIBRARY})
    9.30 +  IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    9.31 +    SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread")
    9.32 +  ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    9.33 +ENDIF(CPLEX_FOUND)
    9.34 +
    9.35 +MARK_AS_ADVANCED(CPLEX_LIBRARY CPLEX_INCLUDE_DIR CPLEX_BIN_DIR)
    9.36 +
    9.37 +IF(CPLEX_FOUND)
    9.38 +  SET(LEMON_HAVE_LP TRUE)
    9.39 +  SET(LEMON_HAVE_MIP TRUE)
    9.40 +  SET(LEMON_HAVE_CPLEX TRUE)
    9.41 +ENDIF(CPLEX_FOUND)
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/cmake/FindGLPK.cmake	Thu Nov 05 15:50:01 2009 +0100
    10.3 @@ -0,0 +1,61 @@
    10.4 +SET(GLPK_ROOT_DIR "" CACHE PATH "GLPK root directory")
    10.5 +
    10.6 +SET(GLPK_REGKEY "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Glpk;InstallPath]")
    10.7 +GET_FILENAME_COMPONENT(GLPK_ROOT_PATH ${GLPK_REGKEY} ABSOLUTE)
    10.8 +
    10.9 +FIND_PATH(GLPK_INCLUDE_DIR
   10.10 +  glpk.h
   10.11 +  PATHS ${GLPK_REGKEY}/include
   10.12 +  HINTS ${GLPK_ROOT_DIR}/include
   10.13 +)
   10.14 +FIND_LIBRARY(GLPK_LIBRARY
   10.15 +  glpk
   10.16 +  PATHS ${GLPK_REGKEY}/lib
   10.17 +  HINTS ${GLPK_ROOT_DIR}/lib
   10.18 +)
   10.19 +
   10.20 +IF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY)
   10.21 +  FILE(READ ${GLPK_INCLUDE_DIR}/glpk.h GLPK_GLPK_H)
   10.22 +
   10.23 +  STRING(REGEX MATCH "define[ ]+GLP_MAJOR_VERSION[ ]+[0-9]+" GLPK_MAJOR_VERSION_LINE "${GLPK_GLPK_H}")
   10.24 +  STRING(REGEX REPLACE "define[ ]+GLP_MAJOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MAJOR "${GLPK_MAJOR_VERSION_LINE}")
   10.25 +
   10.26 +  STRING(REGEX MATCH "define[ ]+GLP_MINOR_VERSION[ ]+[0-9]+" GLPK_MINOR_VERSION_LINE "${GLPK_GLPK_H}")
   10.27 +  STRING(REGEX REPLACE "define[ ]+GLP_MINOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MINOR "${GLPK_MINOR_VERSION_LINE}")
   10.28 +
   10.29 +  SET(GLPK_VERSION_STRING "${GLPK_VERSION_MAJOR}.${GLPK_VERSION_MINOR}")
   10.30 +
   10.31 +  IF(GLPK_FIND_VERSION)
   10.32 +    IF(GLPK_FIND_VERSION_COUNT GREATER 2)
   10.33 +      MESSAGE(SEND_ERROR "unexpected version string")
   10.34 +    ENDIF(GLPK_FIND_VERSION_COUNT GREATER 2)
   10.35 +
   10.36 +    MATH(EXPR GLPK_REQUESTED_VERSION "${GLPK_FIND_VERSION_MAJOR}*100 + ${GLPK_FIND_VERSION_MINOR}")
   10.37 +    MATH(EXPR GLPK_FOUND_VERSION "${GLPK_VERSION_MAJOR}*100 + ${GLPK_VERSION_MINOR}")
   10.38 +
   10.39 +    IF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
   10.40 +      SET(GLPK_PROPER_VERSION_FOUND FALSE)
   10.41 +    ELSE(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
   10.42 +      SET(GLPK_PROPER_VERSION_FOUND TRUE)
   10.43 +    ENDIF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
   10.44 +  ELSE(GLPK_FIND_VERSION)
   10.45 +    SET(GLPK_PROPER_VERSION_FOUND TRUE)
   10.46 +  ENDIF(GLPK_FIND_VERSION)
   10.47 +ENDIF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY)
   10.48 +
   10.49 +INCLUDE(FindPackageHandleStandardArgs)
   10.50 +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLPK DEFAULT_MSG GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_PROPER_VERSION_FOUND)
   10.51 +
   10.52 +IF(GLPK_FOUND)
   10.53 +  SET(GLPK_INCLUDE_DIRS ${GLPK_INCLUDE_DIR})
   10.54 +  SET(GLPK_LIBRARIES ${GLPK_LIBRARY})
   10.55 +  SET(GLPK_BIN_DIR ${GLPK_ROOT_PATH}/bin)
   10.56 +ENDIF(GLPK_FOUND)
   10.57 +
   10.58 +MARK_AS_ADVANCED(GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_BIN_DIR)
   10.59 +
   10.60 +IF(GLPK_FOUND)
   10.61 +  SET(LEMON_HAVE_LP TRUE)
   10.62 +  SET(LEMON_HAVE_MIP TRUE)
   10.63 +  SET(LEMON_HAVE_GLPK TRUE)
   10.64 +ENDIF(GLPK_FOUND)
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/cmake/LEMONConfig.cmake.in	Thu Nov 05 15:50:01 2009 +0100
    11.3 @@ -0,0 +1,13 @@
    11.4 +SET(LEMON_INCLUDE_DIR "@CMAKE_INSTALL_PREFIX@/include" CACHE PATH "LEMON include directory")
    11.5 +SET(LEMON_INCLUDE_DIRS "${LEMON_INCLUDE_DIR}")
    11.6 +
    11.7 +IF(UNIX)
    11.8 +  SET(LEMON_LIB_NAME "libemon.a")
    11.9 +ELSEIF(WIN32)
   11.10 +  SET(LEMON_LIB_NAME "lemon.lib")
   11.11 +ENDIF(UNIX)
   11.12 +
   11.13 +SET(LEMON_LIBRARY "@CMAKE_INSTALL_PREFIX@/lib/${LEMON_LIB_NAME}" CACHE FILEPATH "LEMON library")
   11.14 +SET(LEMON_LIBRARIES "${LEMON_LIBRARY}")
   11.15 +
   11.16 +MARK_AS_ADVANCED(LEMON_LIBRARY LEMON_INCLUDE_DIR)
    12.1 --- a/cmake/version.cmake.in	Fri Oct 16 10:21:37 2009 +0200
    12.2 +++ b/cmake/version.cmake.in	Thu Nov 05 15:50:01 2009 +0100
    12.3 @@ -1,2 +1,1 @@
    12.4 -SET(PROJECT_NAME "@PACKAGE_NAME@")
    12.5 -SET(PROJECT_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.")
    12.6 +SET(LEMON_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.")
    13.1 --- a/configure.ac	Fri Oct 16 10:21:37 2009 +0200
    13.2 +++ b/configure.ac	Thu Nov 05 15:50:01 2009 +0100
    13.3 @@ -2,14 +2,17 @@
    13.4  
    13.5  dnl Version information.
    13.6  m4_define([lemon_version_number],
    13.7 -	[m4_normalize(esyscmd([echo ${LEMON_VERSION}]))])
    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]))])
   13.12 +m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i 2> /dev/null]))])
   13.13  m4_define([lemon_version], [ifelse(lemon_version_number(),
   13.14 -			   [],
   13.15 -			   [lemon_hg_path().lemon_hg_revision()],
   13.16 -			   [lemon_version_number()])])
   13.17 +                           [],
   13.18 +                           [ifelse(lemon_hg_revision(),
   13.19 +                           [],
   13.20 +                           [hg-tip],
   13.21 +                           [lemon_hg_path().lemon_hg_revision()])],
   13.22 +                           [lemon_version_number()])])
   13.23  
   13.24  AC_PREREQ([2.59])
   13.25  AC_INIT([LEMON], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon])
   13.26 @@ -19,7 +22,7 @@
   13.27  AC_CONFIG_SRCDIR([lemon/list_graph.h])
   13.28  AC_CONFIG_HEADERS([config.h lemon/config.h])
   13.29  
   13.30 -lx_cmdline_cxxflags_set=${CXXFLAGS+set}
   13.31 +AC_DEFINE([LEMON_VERSION], [lemon_version()], [The version string])
   13.32  
   13.33  dnl Do compilation tests using the C++ compiler.
   13.34  AC_LANG([C++])
   13.35 @@ -38,6 +41,7 @@
   13.36  AC_PROG_LIBTOOL
   13.37  
   13.38  AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
   13.39 +AC_CHECK_PROG([python_found],[python],[yes],[no])
   13.40  AC_CHECK_PROG([gs_found],[gs],[yes],[no])
   13.41  
   13.42  dnl Detect Intel compiler.
   13.43 @@ -52,27 +56,19 @@
   13.44  fi
   13.45  
   13.46  dnl Set custom compiler flags when using g++.
   13.47 -if test x"$lx_cmdline_cxxflags_set" != x"set" -a "$GXX" = yes -a "$ICC" = no; then
   13.48 -  CXXFLAGS="$CXXFLAGS -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 -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
   13.49 +if test "$GXX" = yes -a "$ICC" = no; then
   13.50 +  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.51  fi
   13.52 +AC_SUBST([WARNINGCXXFLAGS])
   13.53  
   13.54  dnl Checks for libraries.
   13.55 -#LX_CHECK_GLPK
   13.56 -#LX_CHECK_CPLEX
   13.57 -#LX_CHECK_SOPLEX
   13.58 +LX_CHECK_GLPK
   13.59 +LX_CHECK_CPLEX
   13.60 +LX_CHECK_SOPLEX
   13.61 +LX_CHECK_COIN
   13.62  
   13.63 -dnl Disable/enable building the demo programs.
   13.64 -AC_ARG_ENABLE([demo],
   13.65 -AS_HELP_STRING([--enable-demo], [build the demo programs])
   13.66 -AS_HELP_STRING([--disable-demo], [do not build the demo programs @<:@default@:>@]),
   13.67 -              [], [enable_demo=no])
   13.68 -AC_MSG_CHECKING([whether to build the demo programs])
   13.69 -if test x"$enable_demo" != x"no"; then
   13.70 -  AC_MSG_RESULT([yes])
   13.71 -else
   13.72 -  AC_MSG_RESULT([no])
   13.73 -fi
   13.74 -AM_CONDITIONAL([WANT_DEMO], [test x"$enable_demo" != x"no"])
   13.75 +AM_CONDITIONAL([HAVE_LP], [test x"$lx_lp_found" = x"yes"])
   13.76 +AM_CONDITIONAL([HAVE_MIP], [test x"$lx_mip_found" = x"yes"])
   13.77  
   13.78  dnl Disable/enable building the binary tools.
   13.79  AC_ARG_ENABLE([tools],
   13.80 @@ -107,6 +103,7 @@
   13.81  
   13.82  AC_CONFIG_FILES([
   13.83  Makefile
   13.84 +demo/Makefile
   13.85  cmake/version.cmake
   13.86  doc/Doxyfile
   13.87  lemon/lemon.pc
   13.88 @@ -120,15 +117,16 @@
   13.89  echo Package version............... : $PACKAGE-$VERSION
   13.90  echo
   13.91  echo C++ compiler.................. : $CXX
   13.92 -echo C++ compiles flags............ : $CXXFLAGS
   13.93 +echo C++ compiles flags............ : $WARNINGCXXFLAGS $CXXFLAGS
   13.94  echo
   13.95  echo Compiler supports long long... : $long_long_found
   13.96  echo
   13.97 -#echo GLPK support.................. : $lx_glpk_found
   13.98 -#echo CPLEX support................. : $lx_cplex_found
   13.99 -#echo SOPLEX support................ : $lx_soplex_found
  13.100 -#echo
  13.101 -echo Build demo programs........... : $enable_demo
  13.102 +echo GLPK support.................. : $lx_glpk_found
  13.103 +echo CPLEX support................. : $lx_cplex_found
  13.104 +echo SOPLEX support................ : $lx_soplex_found
  13.105 +echo CLP support................... : $lx_clp_found
  13.106 +echo CBC support................... : $lx_cbc_found
  13.107 +echo
  13.108  echo Build additional tools........ : $enable_tools
  13.109  echo
  13.110  echo The packace will be installed in
    14.1 --- a/demo/CMakeLists.txt	Fri Oct 16 10:21:37 2009 +0200
    14.2 +++ b/demo/CMakeLists.txt	Thu Nov 05 15:50:01 2009 +0100
    14.3 @@ -1,16 +1,19 @@
    14.4  INCLUDE_DIRECTORIES(
    14.5 -  ${CMAKE_SOURCE_DIR}
    14.6 +  ${PROJECT_SOURCE_DIR}
    14.7    ${PROJECT_BINARY_DIR}
    14.8  )
    14.9  
   14.10 -LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
   14.11 +LINK_DIRECTORIES(
   14.12 +  ${PROJECT_BINARY_DIR}/lemon
   14.13 +)
   14.14  
   14.15  SET(DEMOS
   14.16    arg_parser_demo
   14.17    graph_to_eps_demo
   14.18 -  lgf_demo)
   14.19 +  lgf_demo
   14.20 +)
   14.21  
   14.22  FOREACH(DEMO_NAME ${DEMOS})
   14.23    ADD_EXECUTABLE(${DEMO_NAME} ${DEMO_NAME}.cc)
   14.24    TARGET_LINK_LIBRARIES(${DEMO_NAME} lemon)
   14.25 -ENDFOREACH(DEMO_NAME)
   14.26 +ENDFOREACH()
    15.1 --- a/demo/Makefile.am	Fri Oct 16 10:21:37 2009 +0200
    15.2 +++ b/demo/Makefile.am	Thu Nov 05 15:50:01 2009 +0100
    15.3 @@ -1,16 +1,17 @@
    15.4 -EXTRA_DIST += \
    15.5 -	demo/CMakeLists.txt \
    15.6 -	demo/digraph.lgf
    15.7 +AM_CXXFLAGS = $(WARNINGCXXFLAGS)
    15.8  
    15.9 -if WANT_DEMO
   15.10 +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
   15.11 +LDADD = $(top_builddir)/lemon/libemon.la
   15.12  
   15.13 -noinst_PROGRAMS += \
   15.14 -	demo/arg_parser_demo \
   15.15 -	demo/graph_to_eps_demo \
   15.16 -	demo/lgf_demo
   15.17 +EXTRA_DIST = \
   15.18 +	CMakeLists.txt \
   15.19 +	digraph.lgf
   15.20  
   15.21 -endif WANT_DEMO
   15.22 +noinst_PROGRAMS = \
   15.23 +	arg_parser_demo \
   15.24 +	graph_to_eps_demo \
   15.25 +	lgf_demo
   15.26  
   15.27 -demo_arg_parser_demo_SOURCES = demo/arg_parser_demo.cc
   15.28 -demo_graph_to_eps_demo_SOURCES = demo/graph_to_eps_demo.cc
   15.29 -demo_lgf_demo_SOURCES = demo/lgf_demo.cc
   15.30 +arg_parser_demo_SOURCES = arg_parser_demo.cc
   15.31 +graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc
   15.32 +lgf_demo_SOURCES = lgf_demo.cc
    16.1 --- a/demo/arg_parser_demo.cc	Fri Oct 16 10:21:37 2009 +0200
    16.2 +++ b/demo/arg_parser_demo.cc	Thu Nov 05 15:50:01 2009 +0100
    16.3 @@ -2,7 +2,7 @@
    16.4   *
    16.5   * This file is a part of LEMON, a generic C++ optimization library.
    16.6   *
    16.7 - * Copyright (C) 2003-2008
    16.8 + * Copyright (C) 2003-2009
    16.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   16.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   16.11   *
    17.1 --- a/demo/graph_to_eps_demo.cc	Fri Oct 16 10:21:37 2009 +0200
    17.2 +++ b/demo/graph_to_eps_demo.cc	Thu Nov 05 15:50:01 2009 +0100
    17.3 @@ -2,7 +2,7 @@
    17.4   *
    17.5   * This file is a part of LEMON, a generic C++ optimization library.
    17.6   *
    17.7 - * Copyright (C) 2003-2008
    17.8 + * Copyright (C) 2003-2009
    17.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   17.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   17.11   *
   17.12 @@ -85,14 +85,14 @@
   17.13    graphToEps(g,"graph_to_eps_demo_out_1_pure.eps").
   17.14      coords(coords).
   17.15      title("Sample .eps figure").
   17.16 -    copyright("(C) 2003-2008 LEMON Project").
   17.17 +    copyright("(C) 2003-2009 LEMON Project").
   17.18      run();
   17.19  
   17.20    cout << "Create 'graph_to_eps_demo_out_2.eps'" << endl;
   17.21    graphToEps(g,"graph_to_eps_demo_out_2.eps").
   17.22      coords(coords).
   17.23      title("Sample .eps figure").
   17.24 -    copyright("(C) 2003-2008 LEMON Project").
   17.25 +    copyright("(C) 2003-2009 LEMON Project").
   17.26      absoluteNodeSizes().absoluteArcWidths().
   17.27      nodeScale(2).nodeSizes(sizes).
   17.28      nodeShapes(shapes).
   17.29 @@ -105,7 +105,7 @@
   17.30    cout << "Create 'graph_to_eps_demo_out_3_arr.eps'" << endl;
   17.31    graphToEps(g,"graph_to_eps_demo_out_3_arr.eps").
   17.32      title("Sample .eps figure (with arrowheads)").
   17.33 -    copyright("(C) 2003-2008 LEMON Project").
   17.34 +    copyright("(C) 2003-2009 LEMON Project").
   17.35      absoluteNodeSizes().absoluteArcWidths().
   17.36      nodeColors(composeMap(palette,colors)).
   17.37      coords(coords).
   17.38 @@ -132,7 +132,7 @@
   17.39    cout << "Create 'graph_to_eps_demo_out_4_par.eps'" << endl;
   17.40    graphToEps(g,"graph_to_eps_demo_out_4_par.eps").
   17.41      title("Sample .eps figure (parallel arcs)").
   17.42 -    copyright("(C) 2003-2008 LEMON Project").
   17.43 +    copyright("(C) 2003-2009 LEMON Project").
   17.44      absoluteNodeSizes().absoluteArcWidths().
   17.45      nodeShapes(shapes).
   17.46      coords(coords).
   17.47 @@ -147,7 +147,7 @@
   17.48    cout << "Create 'graph_to_eps_demo_out_5_par_arr.eps'" << endl;
   17.49    graphToEps(g,"graph_to_eps_demo_out_5_par_arr.eps").
   17.50      title("Sample .eps figure (parallel arcs and arrowheads)").
   17.51 -    copyright("(C) 2003-2008 LEMON Project").
   17.52 +    copyright("(C) 2003-2009 LEMON Project").
   17.53      absoluteNodeSizes().absoluteArcWidths().
   17.54      nodeScale(2).nodeSizes(sizes).
   17.55      coords(coords).
   17.56 @@ -163,7 +163,7 @@
   17.57    cout << "Create 'graph_to_eps_demo_out_6_par_arr_a4.eps'" << endl;
   17.58    graphToEps(g,"graph_to_eps_demo_out_6_par_arr_a4.eps").
   17.59      title("Sample .eps figure (fits to A4)").
   17.60 -    copyright("(C) 2003-2008 LEMON Project").
   17.61 +    copyright("(C) 2003-2009 LEMON Project").
   17.62      scaleToA4().
   17.63      absoluteNodeSizes().absoluteArcWidths().
   17.64      nodeScale(2).nodeSizes(sizes).
   17.65 @@ -182,7 +182,7 @@
   17.66    ListDigraph::NodeMap<int> hcolors(h);
   17.67    ListDigraph::NodeMap<Point> hcoords(h);
   17.68  
   17.69 -  int cols=int(sqrt(double(palette.size())));
   17.70 +  int cols=int(std::sqrt(double(palette.size())));
   17.71    for(int i=0;i<int(paletteW.size());i++) {
   17.72      Node n=h.addNode();
   17.73      hcoords[n]=Point(1+i%cols,1+i/cols);
   17.74 @@ -193,7 +193,7 @@
   17.75    graphToEps(h,"graph_to_eps_demo_out_7_colors.eps").
   17.76      scale(60).
   17.77      title("Sample .eps figure (Palette demo)").
   17.78 -    copyright("(C) 2003-2008 LEMON Project").
   17.79 +    copyright("(C) 2003-2009 LEMON Project").
   17.80      coords(hcoords).
   17.81      absoluteNodeSizes().absoluteArcWidths().
   17.82      nodeScale(.45).
    18.1 --- a/demo/lgf_demo.cc	Fri Oct 16 10:21:37 2009 +0200
    18.2 +++ b/demo/lgf_demo.cc	Thu Nov 05 15:50:01 2009 +0100
    18.3 @@ -2,7 +2,7 @@
    18.4   *
    18.5   * This file is a part of LEMON, a generic C++ optimization library.
    18.6   *
    18.7 - * Copyright (C) 2003-2008
    18.8 + * Copyright (C) 2003-2009
    18.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   18.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   18.11   *
    19.1 --- a/doc/CMakeLists.txt	Fri Oct 16 10:21:37 2009 +0200
    19.2 +++ b/doc/CMakeLists.txt	Thu Nov 05 15:50:01 2009 +0100
    19.3 @@ -1,42 +1,52 @@
    19.4  SET(PACKAGE_NAME ${PROJECT_NAME})
    19.5  SET(PACKAGE_VERSION ${PROJECT_VERSION})
    19.6 -SET(abs_top_srcdir ${CMAKE_SOURCE_DIR})
    19.7 -SET(abs_top_builddir ${CMAKE_BINARY_DIR})
    19.8 +SET(abs_top_srcdir ${PROJECT_SOURCE_DIR})
    19.9 +SET(abs_top_builddir ${PROJECT_BINARY_DIR})
   19.10  
   19.11  CONFIGURE_FILE(
   19.12 -  ${CMAKE_SOURCE_DIR}/doc/Doxyfile.in
   19.13 -  ${CMAKE_BINARY_DIR}/doc/Doxyfile
   19.14 -  @ONLY)
   19.15 +  ${PROJECT_SOURCE_DIR}/doc/Doxyfile.in
   19.16 +  ${PROJECT_BINARY_DIR}/doc/Doxyfile
   19.17 +  @ONLY
   19.18 +)
   19.19  
   19.20 -IF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
   19.21 +IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE)
   19.22    FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
   19.23 +  SET(GHOSTSCRIPT_OPTIONS -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha)
   19.24 +  ADD_CUSTOM_TARGET(html
   19.25 +    COMMAND ${CMAKE_COMMAND} -E remove_directory gen-images
   19.26 +    COMMAND ${CMAKE_COMMAND} -E make_directory gen-images
   19.27 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps
   19.28 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps
   19.29 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps
   19.30 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
   19.31 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
   19.32 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
   19.33 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
   19.34 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
   19.35 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
   19.36 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
   19.37 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
   19.38 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
   19.39 +    COMMAND ${CMAKE_COMMAND} -E remove_directory html
   19.40 +    COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox
   19.41 +    COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
   19.42 +    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
   19.43 +  )
   19.44 +
   19.45 +  SET_TARGET_PROPERTIES(html PROPERTIES PROJECT_LABEL BUILD_DOC)
   19.46 +
   19.47    IF(UNIX)
   19.48 -    ADD_CUSTOM_TARGET(html
   19.49 -      COMMAND rm -rf gen-images
   19.50 -      COMMAND mkdir gen-images
   19.51 -      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
   19.52 -      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
   19.53 -      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
   19.54 -      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
   19.55 -      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
   19.56 -      COMMAND rm -rf html
   19.57 -      COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
   19.58 -      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
   19.59 +    INSTALL(
   19.60 +      DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
   19.61 +      DESTINATION share/doc/lemon/html
   19.62 +      COMPONENT html_documentation
   19.63 +    )
   19.64    ELSEIF(WIN32)
   19.65 -    ADD_CUSTOM_TARGET(html
   19.66 -      COMMAND if exist gen-images rmdir /s /q gen-images
   19.67 -      COMMAND mkdir gen-images
   19.68 -      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
   19.69 -      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
   19.70 -      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
   19.71 -      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
   19.72 -      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
   19.73 -      COMMAND if exist html rmdir /s /q html
   19.74 -      COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
   19.75 -      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
   19.76 -  ENDIF(UNIX)
   19.77 -  INSTALL(
   19.78 -    DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
   19.79 -    DESTINATION share/doc
   19.80 -    COMPONENT html_documentation)
   19.81 -ENDIF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
   19.82 +    INSTALL(
   19.83 +      DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
   19.84 +      DESTINATION doc
   19.85 +      COMPONENT html_documentation
   19.86 +    )
   19.87 +  ENDIF()
   19.88 +
   19.89 +ENDIF()
    20.1 --- a/doc/Doxyfile.in	Fri Oct 16 10:21:37 2009 +0200
    20.2 +++ b/doc/Doxyfile.in	Thu Nov 05 15:50:01 2009 +0100
    20.3 @@ -1,4 +1,4 @@
    20.4 -# Doxyfile 1.5.7.1
    20.5 +# Doxyfile 1.5.9
    20.6  
    20.7  #---------------------------------------------------------------------------
    20.8  # Project related configuration options
    20.9 @@ -21,7 +21,6 @@
   20.10  JAVADOC_AUTOBRIEF      = NO
   20.11  QT_AUTOBRIEF           = NO
   20.12  MULTILINE_CPP_IS_BRIEF = NO
   20.13 -DETAILS_AT_TOP         = YES
   20.14  INHERIT_DOCS           = NO
   20.15  SEPARATE_MEMBER_PAGES  = NO
   20.16  TAB_SIZE               = 8
   20.17 @@ -66,7 +65,7 @@
   20.18  GENERATE_DEPRECATEDLIST= YES
   20.19  ENABLED_SECTIONS       = 
   20.20  MAX_INITIALIZER_LINES  = 5
   20.21 -SHOW_USED_FILES        = YES
   20.22 +SHOW_USED_FILES        = NO
   20.23  SHOW_DIRECTORIES       = YES
   20.24  SHOW_FILES             = YES
   20.25  SHOW_NAMESPACES        = YES
   20.26 @@ -91,7 +90,8 @@
   20.27                           "@abs_top_srcdir@/lemon/concepts" \
   20.28                           "@abs_top_srcdir@/demo" \
   20.29                           "@abs_top_srcdir@/tools" \
   20.30 -                         "@abs_top_srcdir@/test/test_tools.h"
   20.31 +                         "@abs_top_srcdir@/test/test_tools.h" \
   20.32 +                         "@abs_top_builddir@/doc/references.dox"
   20.33  INPUT_ENCODING         = UTF-8
   20.34  FILE_PATTERNS          = *.h \
   20.35                           *.cc \
   20.36 @@ -223,7 +223,7 @@
   20.37  EXPAND_AS_DEFINED      = 
   20.38  SKIP_FUNCTION_MACROS   = YES
   20.39  #---------------------------------------------------------------------------
   20.40 -# Configuration::additions related to external references   
   20.41 +# Options related to the search engine   
   20.42  #---------------------------------------------------------------------------
   20.43  TAGFILES               = "@abs_top_srcdir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/  "
   20.44  GENERATE_TAGFILE       = html/lemon.tag
    21.1 --- a/doc/Makefile.am	Fri Oct 16 10:21:37 2009 +0200
    21.2 +++ b/doc/Makefile.am	Thu Nov 05 15:50:01 2009 +0100
    21.3 @@ -8,20 +8,31 @@
    21.4  	doc/license.dox \
    21.5  	doc/mainpage.dox \
    21.6  	doc/migration.dox \
    21.7 +	doc/min_cost_flow.dox \
    21.8  	doc/named-param.dox \
    21.9  	doc/namespaces.dox \
   21.10  	doc/html \
   21.11  	doc/CMakeLists.txt
   21.12  
   21.13  DOC_EPS_IMAGES18 = \
   21.14 +	grid_graph.eps \
   21.15  	nodeshape_0.eps \
   21.16  	nodeshape_1.eps \
   21.17  	nodeshape_2.eps \
   21.18  	nodeshape_3.eps \
   21.19  	nodeshape_4.eps
   21.20  
   21.21 +DOC_EPS_IMAGES27 = \
   21.22 +	bipartite_matching.eps \
   21.23 +	bipartite_partitions.eps \
   21.24 +	connected_components.eps \
   21.25 +	edge_biconnected_components.eps \
   21.26 +	node_biconnected_components.eps \
   21.27 +	strongly_connected_components.eps
   21.28 +
   21.29  DOC_EPS_IMAGES = \
   21.30 -	$(DOC_EPS_IMAGES18)
   21.31 +	$(DOC_EPS_IMAGES18) \
   21.32 +	$(DOC_EPS_IMAGES27)
   21.33  
   21.34  DOC_PNG_IMAGES = \
   21.35  	$(DOC_EPS_IMAGES:%.eps=doc/gen-images/%.png)
   21.36 @@ -44,7 +55,30 @@
   21.37  	  exit 1; \
   21.38  	fi
   21.39  
   21.40 -html-local: $(DOC_PNG_IMAGES)
   21.41 +$(DOC_EPS_IMAGES27:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
   21.42 +	-mkdir doc/gen-images
   21.43 +	if test ${gs_found} = yes; then \
   21.44 +	  $(GS_COMMAND) -sDEVICE=pngalpha -r27 -sOutputFile=$@ $<; \
   21.45 +	else \
   21.46 +	  echo; \
   21.47 +	  echo "Ghostscript not found."; \
   21.48 +	  echo; \
   21.49 +	  exit 1; \
   21.50 +	fi
   21.51 +
   21.52 +references.dox: doc/references.bib
   21.53 +	if test ${python_found} = yes; then \
   21.54 +	  cd doc; \
   21.55 +	  python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \
   21.56 +	  cd ..; \
   21.57 +	else \
   21.58 +	  echo; \
   21.59 +	  echo "Python not found."; \
   21.60 +	  echo; \
   21.61 +	  exit 1; \
   21.62 +	fi
   21.63 +
   21.64 +html-local: $(DOC_PNG_IMAGES) references.dox
   21.65  	if test ${doxygen_found} = yes; then \
   21.66  	  cd doc; \
   21.67  	  doxygen Doxyfile; \
   21.68 @@ -69,19 +103,19 @@
   21.69  
   21.70  install-html-local: doc/html
   21.71  	@$(NORMAL_INSTALL)
   21.72 -	$(mkinstalldirs) $(DESTDIR)$(htmldir)/docs
   21.73 +	$(mkinstalldirs) $(DESTDIR)$(htmldir)/html
   21.74  	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
   21.75  	  f="`echo $$p | sed -e 's|^.*/||'`"; \
   21.76 -	  echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/docs/$$f"; \
   21.77 -	  $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/docs/$$f; \
   21.78 +	  echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f"; \
   21.79 +	  $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f; \
   21.80  	done
   21.81  
   21.82  uninstall-local:
   21.83  	@$(NORMAL_UNINSTALL)
   21.84  	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
   21.85  	  f="`echo $$p | sed -e 's|^.*/||'`"; \
   21.86 -	  echo " rm -f $(DESTDIR)$(htmldir)/docs/$$f"; \
   21.87 -	  rm -f $(DESTDIR)$(htmldir)/docs/$$f; \
   21.88 +	  echo " rm -f $(DESTDIR)$(htmldir)/html/$$f"; \
   21.89 +	  rm -f $(DESTDIR)$(htmldir)/html/$$f; \
   21.90  	done
   21.91  
   21.92  .PHONY: update-external-tags
    22.1 --- a/doc/coding_style.dox	Fri Oct 16 10:21:37 2009 +0200
    22.2 +++ b/doc/coding_style.dox	Thu Nov 05 15:50:01 2009 +0100
    22.3 @@ -2,7 +2,7 @@
    22.4   *
    22.5   * This file is a part of LEMON, a generic C++ optimization library.
    22.6   *
    22.7 - * Copyright (C) 2003-2008
    22.8 + * Copyright (C) 2003-2009
    22.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   22.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   22.11   *
    23.1 --- a/doc/dirs.dox	Fri Oct 16 10:21:37 2009 +0200
    23.2 +++ b/doc/dirs.dox	Thu Nov 05 15:50:01 2009 +0100
    23.3 @@ -2,7 +2,7 @@
    23.4   *
    23.5   * This file is a part of LEMON, a generic C++ optimization library.
    23.6   *
    23.7 - * Copyright (C) 2003-2008
    23.8 + * Copyright (C) 2003-2009
    23.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   23.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   23.11   *
   23.12 @@ -71,7 +71,7 @@
   23.13  \dir bits
   23.14  \brief Auxiliary tools for implementation.
   23.15  
   23.16 -This directory contains some auxiliary classes for implementing graphs, 
   23.17 +This directory contains some auxiliary classes for implementing graphs,
   23.18  maps and some other classes.
   23.19  As a user you typically don't have to deal with these files.
   23.20  */
    24.1 --- a/doc/groups.dox	Fri Oct 16 10:21:37 2009 +0200
    24.2 +++ b/doc/groups.dox	Thu Nov 05 15:50:01 2009 +0100
    24.3 @@ -2,7 +2,7 @@
    24.4   *
    24.5   * This file is a part of LEMON, a generic C++ optimization library.
    24.6   *
    24.7 - * Copyright (C) 2003-2008
    24.8 + * Copyright (C) 2003-2009
    24.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   24.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   24.11   *
   24.12 @@ -16,9 +16,11 @@
   24.13   *
   24.14   */
   24.15  
   24.16 +namespace lemon {
   24.17 +
   24.18  /**
   24.19  @defgroup datas Data Structures
   24.20 -This group describes the several data structures implemented in LEMON.
   24.21 +This group contains the several data structures implemented in LEMON.
   24.22  */
   24.23  
   24.24  /**
   24.25 @@ -60,13 +62,79 @@
   24.26  */
   24.27  
   24.28  /**
   24.29 -@defgroup semi_adaptors Semi-Adaptor Classes for Graphs
   24.30 +@defgroup graph_adaptors Adaptor Classes for Graphs
   24.31  @ingroup graphs
   24.32 -\brief Graph types between real graphs and graph adaptors.
   24.33 +\brief Adaptor classes for digraphs and graphs
   24.34  
   24.35 -This group describes some graph types between real graphs and graph adaptors.
   24.36 -These classes wrap graphs to give new functionality as the adaptors do it.
   24.37 -On the other hand they are not light-weight structures as the adaptors.
   24.38 +This group contains several useful adaptor classes for digraphs and graphs.
   24.39 +
   24.40 +The main parts of LEMON are the different graph structures, generic
   24.41 +graph algorithms, graph concepts, which couple them, and graph
   24.42 +adaptors. While the previous notions are more or less clear, the
   24.43 +latter one needs further explanation. Graph adaptors are graph classes
   24.44 +which serve for considering graph structures in different ways.
   24.45 +
   24.46 +A short example makes this much clearer.  Suppose that we have an
   24.47 +instance \c g of a directed graph type, say ListDigraph and an algorithm
   24.48 +\code
   24.49 +template <typename Digraph>
   24.50 +int algorithm(const Digraph&);
   24.51 +\endcode
   24.52 +is needed to run on the reverse oriented graph.  It may be expensive
   24.53 +(in time or in memory usage) to copy \c g with the reversed
   24.54 +arcs.  In this case, an adaptor class is used, which (according
   24.55 +to LEMON \ref concepts::Digraph "digraph concepts") works as a digraph.
   24.56 +The adaptor uses the original digraph structure and digraph operations when
   24.57 +methods of the reversed oriented graph are called.  This means that the adaptor
   24.58 +have minor memory usage, and do not perform sophisticated algorithmic
   24.59 +actions.  The purpose of it is to give a tool for the cases when a
   24.60 +graph have to be used in a specific alteration.  If this alteration is
   24.61 +obtained by a usual construction like filtering the node or the arc set or
   24.62 +considering a new orientation, then an adaptor is worthwhile to use.
   24.63 +To come back to the reverse oriented graph, in this situation
   24.64 +\code
   24.65 +template<typename Digraph> class ReverseDigraph;
   24.66 +\endcode
   24.67 +template class can be used. The code looks as follows
   24.68 +\code
   24.69 +ListDigraph g;
   24.70 +ReverseDigraph<ListDigraph> rg(g);
   24.71 +int result = algorithm(rg);
   24.72 +\endcode
   24.73 +During running the algorithm, the original digraph \c g is untouched.
   24.74 +This techniques give rise to an elegant code, and based on stable
   24.75 +graph adaptors, complex algorithms can be implemented easily.
   24.76 +
   24.77 +In flow, circulation and matching problems, the residual
   24.78 +graph is of particular importance. Combining an adaptor implementing
   24.79 +this with shortest path algorithms or minimum mean cycle algorithms,
   24.80 +a range of weighted and cardinality optimization algorithms can be
   24.81 +obtained. For other examples, the interested user is referred to the
   24.82 +detailed documentation of particular adaptors.
   24.83 +
   24.84 +The behavior of graph adaptors can be very different. Some of them keep
   24.85 +capabilities of the original graph while in other cases this would be
   24.86 +meaningless. This means that the concepts that they meet depend
   24.87 +on the graph adaptor, and the wrapped graph.
   24.88 +For example, if an arc of a reversed digraph is deleted, this is carried
   24.89 +out by deleting the corresponding arc of the original digraph, thus the
   24.90 +adaptor modifies the original digraph.
   24.91 +However in case of a residual digraph, this operation has no sense.
   24.92 +
   24.93 +Let us stand one more example here to simplify your work.
   24.94 +ReverseDigraph has constructor
   24.95 +\code
   24.96 +ReverseDigraph(Digraph& digraph);
   24.97 +\endcode
   24.98 +This means that in a situation, when a <tt>const %ListDigraph&</tt>
   24.99 +reference to a graph is given, then it have to be instantiated with
  24.100 +<tt>Digraph=const %ListDigraph</tt>.
  24.101 +\code
  24.102 +int algorithm1(const ListDigraph& g) {
  24.103 +  ReverseDigraph<const ListDigraph> rg(g);
  24.104 +  return algorithm2(rg);
  24.105 +}
  24.106 +\endcode
  24.107  */
  24.108  
  24.109  /**
  24.110 @@ -74,7 +142,7 @@
  24.111  @ingroup datas
  24.112  \brief Map structures implemented in LEMON.
  24.113  
  24.114 -This group describes the map structures implemented in LEMON.
  24.115 +This group contains the map structures implemented in LEMON.
  24.116  
  24.117  LEMON provides several special purpose maps and map adaptors that e.g. combine
  24.118  new maps from existing ones.
  24.119 @@ -87,8 +155,11 @@
  24.120  @ingroup maps
  24.121  \brief Special graph-related maps.
  24.122  
  24.123 -This group describes maps that are specifically designed to assign
  24.124 -values to the nodes and arcs of graphs.
  24.125 +This group contains maps that are specifically designed to assign
  24.126 +values to the nodes and arcs/edges of graphs.
  24.127 +
  24.128 +If you are looking for the standard graph maps (\c NodeMap, \c ArcMap,
  24.129 +\c EdgeMap), see the \ref graph_concepts "Graph Structure Concepts".
  24.130  */
  24.131  
  24.132  /**
  24.133 @@ -96,10 +167,10 @@
  24.134  \ingroup maps
  24.135  \brief Tools to create new maps from existing ones
  24.136  
  24.137 -This group describes map adaptors that are used to create "implicit"
  24.138 +This group contains map adaptors that are used to create "implicit"
  24.139  maps from other maps.
  24.140  
  24.141 -Most of them are \ref lemon::concepts::ReadMap "read-only maps".
  24.142 +Most of them are \ref concepts::ReadMap "read-only maps".
  24.143  They can make arithmetic and logical operations between one or two maps
  24.144  (negation, shifting, addition, multiplication, logical 'and', 'or',
  24.145  'not' etc.) or e.g. convert a map to another one of different Value type.
  24.146 @@ -155,19 +226,11 @@
  24.147  */
  24.148  
  24.149  /**
  24.150 -@defgroup matrices Matrices
  24.151 -@ingroup datas
  24.152 -\brief Two dimensional data storages implemented in LEMON.
  24.153 -
  24.154 -This group describes two dimensional data storages implemented in LEMON.
  24.155 -*/
  24.156 -
  24.157 -/**
  24.158  @defgroup paths Path Structures
  24.159  @ingroup datas
  24.160  \brief %Path structures implemented in LEMON.
  24.161  
  24.162 -This group describes the path structures implemented in LEMON.
  24.163 +This group contains the path structures implemented in LEMON.
  24.164  
  24.165  LEMON provides flexible data structures to work with paths.
  24.166  All of them have similar interfaces and they can be copied easily with
  24.167 @@ -175,7 +238,36 @@
  24.168  efficient to have e.g. the Dijkstra algorithm to store its result in
  24.169  any kind of path structure.
  24.170  
  24.171 -\sa lemon::concepts::Path
  24.172 +\sa \ref concepts::Path "Path concept"
  24.173 +*/
  24.174 +
  24.175 +/**
  24.176 +@defgroup heaps Heap Structures
  24.177 +@ingroup datas
  24.178 +\brief %Heap structures implemented in LEMON.
  24.179 +
  24.180 +This group contains the heap structures implemented in LEMON.
  24.181 +
  24.182 +LEMON provides several heap classes. They are efficient implementations
  24.183 +of the abstract data type \e priority \e queue. They store items with
  24.184 +specified values called \e priorities in such a way that finding and
  24.185 +removing the item with minimum priority are efficient.
  24.186 +The basic operations are adding and erasing items, changing the priority
  24.187 +of an item, etc.
  24.188 +
  24.189 +Heaps are crucial in several algorithms, such as Dijkstra and Prim.
  24.190 +The heap implementations have the same interface, thus any of them can be
  24.191 +used easily in such algorithms.
  24.192 +
  24.193 +\sa \ref concepts::Heap "Heap concept"
  24.194 +*/
  24.195 +
  24.196 +/**
  24.197 +@defgroup matrices Matrices
  24.198 +@ingroup datas
  24.199 +\brief Two dimensional data storages implemented in LEMON.
  24.200 +
  24.201 +This group contains two dimensional data storages implemented in LEMON.
  24.202  */
  24.203  
  24.204  /**
  24.205 @@ -183,16 +275,38 @@
  24.206  @ingroup datas
  24.207  \brief Auxiliary data structures implemented in LEMON.
  24.208  
  24.209 -This group describes some data structures implemented in LEMON in
  24.210 +This group contains some data structures implemented in LEMON in
  24.211  order to make it easier to implement combinatorial algorithms.
  24.212  */
  24.213  
  24.214  /**
  24.215 +@defgroup geomdat Geometric Data Structures
  24.216 +@ingroup auxdat
  24.217 +\brief Geometric data structures implemented in LEMON.
  24.218 +
  24.219 +This group contains geometric data structures implemented in LEMON.
  24.220 +
  24.221 + - \ref lemon::dim2::Point "dim2::Point" implements a two dimensional
  24.222 +   vector with the usual operations.
  24.223 + - \ref lemon::dim2::Box "dim2::Box" can be used to determine the
  24.224 +   rectangular bounding box of a set of \ref lemon::dim2::Point
  24.225 +   "dim2::Point"'s.
  24.226 +*/
  24.227 +
  24.228 +/**
  24.229 +@defgroup matrices Matrices
  24.230 +@ingroup auxdat
  24.231 +\brief Two dimensional data storages implemented in LEMON.
  24.232 +
  24.233 +This group contains two dimensional data storages implemented in LEMON.
  24.234 +*/
  24.235 +
  24.236 +/**
  24.237  @defgroup algs Algorithms
  24.238 -\brief This group describes the several algorithms
  24.239 +\brief This group contains the several algorithms
  24.240  implemented in LEMON.
  24.241  
  24.242 -This group describes the several algorithms
  24.243 +This group contains the several algorithms
  24.244  implemented in LEMON.
  24.245  */
  24.246  
  24.247 @@ -201,8 +315,9 @@
  24.248  @ingroup algs
  24.249  \brief Common graph search algorithms.
  24.250  
  24.251 -This group describes the common graph search algorithms like
  24.252 -Breadth-First Search (BFS) and Depth-First Search (DFS).
  24.253 +This group contains the common graph search algorithms, namely
  24.254 +\e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
  24.255 +\ref clrs01algorithms.
  24.256  */
  24.257  
  24.258  /**
  24.259 @@ -210,7 +325,30 @@
  24.260  @ingroup algs
  24.261  \brief Algorithms for finding shortest paths.
  24.262  
  24.263 -This group describes the algorithms for finding shortest paths in graphs.
  24.264 +This group contains the algorithms for finding shortest paths in digraphs
  24.265 +\ref clrs01algorithms.
  24.266 +
  24.267 + - \ref Dijkstra algorithm for finding shortest paths from a source node
  24.268 +   when all arc lengths are non-negative.
  24.269 + - \ref BellmanFord "Bellman-Ford" algorithm for finding shortest paths
  24.270 +   from a source node when arc lenghts can be either positive or negative,
  24.271 +   but the digraph should not contain directed cycles with negative total
  24.272 +   length.
  24.273 + - \ref FloydWarshall "Floyd-Warshall" and \ref Johnson "Johnson" algorithms
  24.274 +   for solving the \e all-pairs \e shortest \e paths \e problem when arc
  24.275 +   lenghts can be either positive or negative, but the digraph should
  24.276 +   not contain directed cycles with negative total length.
  24.277 + - \ref Suurballe A successive shortest path algorithm for finding
  24.278 +   arc-disjoint paths between two nodes having minimum total length.
  24.279 +*/
  24.280 +
  24.281 +/**
  24.282 +@defgroup spantree Minimum Spanning Tree Algorithms
  24.283 +@ingroup algs
  24.284 +\brief Algorithms for finding minimum cost spanning trees and arborescences.
  24.285 +
  24.286 +This group contains the algorithms for finding minimum cost spanning
  24.287 +trees and arborescences \ref clrs01algorithms.
  24.288  */
  24.289  
  24.290  /**
  24.291 @@ -218,40 +356,70 @@
  24.292  @ingroup algs
  24.293  \brief Algorithms for finding maximum flows.
  24.294  
  24.295 -This group describes the algorithms for finding maximum flows and
  24.296 -feasible circulations.
  24.297 +This group contains the algorithms for finding maximum flows and
  24.298 +feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
  24.299  
  24.300 -The maximum flow problem is to find a flow between a single source and
  24.301 -a single target that is maximum. Formally, there is a \f$G=(V,A)\f$
  24.302 -directed graph, an \f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity
  24.303 -function and given \f$s, t \in V\f$ source and target node. The
  24.304 -maximum flow is the \f$f_a\f$ solution of the next optimization problem:
  24.305 +The \e maximum \e flow \e problem is to find a flow of maximum value between
  24.306 +a single source and a single target. Formally, there is a \f$G=(V,A)\f$
  24.307 +digraph, a \f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function and
  24.308 +\f$s, t \in V\f$ source and target nodes.
  24.309 +A maximum flow is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ solution of the
  24.310 +following optimization problem.
  24.311  
  24.312 -\f[ 0 \le f_a \le c_a \f]
  24.313 -\f[ \sum_{v\in\delta^{-}(u)}f_{vu}=\sum_{v\in\delta^{+}(u)}f_{uv}
  24.314 -\qquad \forall u \in V \setminus \{s,t\}\f]
  24.315 -\f[ \max \sum_{v\in\delta^{+}(s)}f_{uv} - \sum_{v\in\delta^{-}(s)}f_{vu}\f]
  24.316 +\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f]
  24.317 +\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu)
  24.318 +    \quad \forall u\in V\setminus\{s,t\} \f]
  24.319 +\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
  24.320  
  24.321  LEMON contains several algorithms for solving maximum flow problems:
  24.322 -- \ref lemon::EdmondsKarp "Edmonds-Karp"
  24.323 -- \ref lemon::Preflow "Goldberg's Preflow algorithm"
  24.324 -- \ref lemon::DinitzSleatorTarjan "Dinitz's blocking flow algorithm with dynamic trees"
  24.325 -- \ref lemon::GoldbergTarjan "Preflow algorithm with dynamic trees"
  24.326 +- \ref EdmondsKarp Edmonds-Karp algorithm
  24.327 +  \ref edmondskarp72theoretical.
  24.328 +- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
  24.329 +  \ref goldberg88newapproach.
  24.330 +- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
  24.331 +  \ref dinic70algorithm, \ref sleator83dynamic.
  24.332 +- \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
  24.333 +  \ref goldberg88newapproach, \ref sleator83dynamic.
  24.334  
  24.335 -In most cases the \ref lemon::Preflow "Preflow" algorithm provides the
  24.336 -fastest method to compute the maximum flow. All impelementations
  24.337 -provides functions to query the minimum cut, which is the dual linear
  24.338 -programming problem of the maximum flow.
  24.339 +In most cases the \ref Preflow algorithm provides the
  24.340 +fastest method for computing a maximum flow. All implementations
  24.341 +also provide functions to query the minimum cut, which is the dual
  24.342 +problem of maximum flow.
  24.343 +
  24.344 +\ref Circulation is a preflow push-relabel algorithm implemented directly 
  24.345 +for finding feasible circulations, which is a somewhat different problem,
  24.346 +but it is strongly related to maximum flow.
  24.347 +For more information, see \ref Circulation.
  24.348  */
  24.349  
  24.350  /**
  24.351 -@defgroup min_cost_flow Minimum Cost Flow Algorithms
  24.352 +@defgroup min_cost_flow_algs Minimum Cost Flow Algorithms
  24.353  @ingroup algs
  24.354  
  24.355  \brief Algorithms for finding minimum cost flows and circulations.
  24.356  
  24.357 -This group describes the algorithms for finding minimum cost flows and
  24.358 -circulations.
  24.359 +This group contains the algorithms for finding minimum cost flows and
  24.360 +circulations \ref amo93networkflows. For more information about this
  24.361 +problem and its dual solution, see \ref min_cost_flow
  24.362 +"Minimum Cost Flow Problem".
  24.363 +
  24.364 +LEMON contains several algorithms for this problem.
  24.365 + - \ref NetworkSimplex Primal Network Simplex algorithm with various
  24.366 +   pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
  24.367 + - \ref CostScaling Push-Relabel and Augment-Relabel algorithms based on
  24.368 +   cost scaling \ref goldberg90approximation, \ref goldberg97efficient,
  24.369 +   \ref bunnagel98efficient.
  24.370 + - \ref CapacityScaling Successive Shortest %Path algorithm with optional
  24.371 +   capacity scaling \ref edmondskarp72theoretical.
  24.372 + - \ref CancelAndTighten The Cancel and Tighten algorithm
  24.373 +   \ref goldberg89cyclecanceling.
  24.374 + - \ref CycleCanceling Cycle-Canceling algorithms
  24.375 +   \ref klein67primal, \ref goldberg89cyclecanceling.
  24.376 +
  24.377 +In general NetworkSimplex is the most efficient implementation,
  24.378 +but in special cases other algorithms could be faster.
  24.379 +For example, if the total supply and/or capacities are rather small,
  24.380 +CapacityScaling is usually the fastest algorithm (without effective scaling).
  24.381  */
  24.382  
  24.383  /**
  24.384 @@ -260,40 +428,117 @@
  24.385  
  24.386  \brief Algorithms for finding minimum cut in graphs.
  24.387  
  24.388 -This group describes the algorithms for finding minimum cut in graphs.
  24.389 +This group contains the algorithms for finding minimum cut in graphs.
  24.390  
  24.391 -The minimum cut problem is to find a non-empty and non-complete
  24.392 -\f$X\f$ subset of the vertices with minimum overall capacity on
  24.393 -outgoing arcs. Formally, there is \f$G=(V,A)\f$ directed graph, an
  24.394 -\f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
  24.395 +The \e minimum \e cut \e problem is to find a non-empty and non-complete
  24.396 +\f$X\f$ subset of the nodes with minimum overall capacity on
  24.397 +outgoing arcs. Formally, there is a \f$G=(V,A)\f$ digraph, a
  24.398 +\f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
  24.399  cut is the \f$X\f$ solution of the next optimization problem:
  24.400  
  24.401  \f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
  24.402 -\sum_{uv\in A, u\in X, v\not\in X}c_{uv}\f]
  24.403 +    \sum_{uv\in A: u\in X, v\not\in X}cap(uv) \f]
  24.404  
  24.405  LEMON contains several algorithms related to minimum cut problems:
  24.406  
  24.407 -- \ref lemon::HaoOrlin "Hao-Orlin algorithm" to calculate minimum cut
  24.408 -  in directed graphs
  24.409 -- \ref lemon::NagamochiIbaraki "Nagamochi-Ibaraki algorithm" to
  24.410 -  calculate minimum cut in undirected graphs
  24.411 -- \ref lemon::GomoryHuTree "Gomory-Hu tree computation" to calculate all
  24.412 -  pairs minimum cut in undirected graphs
  24.413 +- \ref HaoOrlin "Hao-Orlin algorithm" for calculating minimum cut
  24.414 +  in directed graphs.
  24.415 +- \ref NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
  24.416 +  calculating minimum cut in undirected graphs.
  24.417 +- \ref GomoryHu "Gomory-Hu tree computation" for calculating
  24.418 +  all-pairs minimum cut in undirected graphs.
  24.419  
  24.420  If you want to find minimum cut just between two distinict nodes,
  24.421 -please see the \ref max_flow "Maximum Flow page".
  24.422 +see the \ref max_flow "maximum flow problem".
  24.423  */
  24.424  
  24.425  /**
  24.426 -@defgroup graph_prop Connectivity and Other Graph Properties
  24.427 +@defgroup min_mean_cycle Minimum Mean Cycle Algorithms
  24.428 +@ingroup algs
  24.429 +\brief Algorithms for finding minimum mean cycles.
  24.430 +
  24.431 +This group contains the algorithms for finding minimum mean cycles
  24.432 +\ref clrs01algorithms, \ref amo93networkflows.
  24.433 +
  24.434 +The \e minimum \e mean \e cycle \e problem is to find a directed cycle
  24.435 +of minimum mean length (cost) in a digraph.
  24.436 +The mean length of a cycle is the average length of its arcs, i.e. the
  24.437 +ratio between the total length of the cycle and the number of arcs on it.
  24.438 +
  24.439 +This problem has an important connection to \e conservative \e length
  24.440 +\e functions, too. A length function on the arcs of a digraph is called
  24.441 +conservative if and only if there is no directed cycle of negative total
  24.442 +length. For an arbitrary length function, the negative of the minimum
  24.443 +cycle mean is the smallest \f$\epsilon\f$ value so that increasing the
  24.444 +arc lengths uniformly by \f$\epsilon\f$ results in a conservative length
  24.445 +function.
  24.446 +
  24.447 +LEMON contains three algorithms for solving the minimum mean cycle problem:
  24.448 +- \ref Karp "Karp"'s original algorithm \ref amo93networkflows,
  24.449 +  \ref dasdan98minmeancycle.
  24.450 +- \ref HartmannOrlin "Hartmann-Orlin"'s algorithm, which is an improved
  24.451 +  version of Karp's algorithm \ref dasdan98minmeancycle.
  24.452 +- \ref Howard "Howard"'s policy iteration algorithm
  24.453 +  \ref dasdan98minmeancycle.
  24.454 +
  24.455 +In practice, the Howard algorithm proved to be by far the most efficient
  24.456 +one, though the best known theoretical bound on its running time is
  24.457 +exponential.
  24.458 +Both Karp and HartmannOrlin algorithms run in time O(ne) and use space
  24.459 +O(n<sup>2</sup>+e), but the latter one is typically faster due to the
  24.460 +applied early termination scheme.
  24.461 +*/
  24.462 +
  24.463 +/**
  24.464 +@defgroup matching Matching Algorithms
  24.465 +@ingroup algs
  24.466 +\brief Algorithms for finding matchings in graphs and bipartite graphs.
  24.467 +
  24.468 +This group contains the algorithms for calculating
  24.469 +matchings in graphs and bipartite graphs. The general matching problem is
  24.470 +finding a subset of the edges for which each node has at most one incident
  24.471 +edge.
  24.472 +
  24.473 +There are several different algorithms for calculate matchings in
  24.474 +graphs.  The matching problems in bipartite graphs are generally
  24.475 +easier than in general graphs. The goal of the matching optimization
  24.476 +can be finding maximum cardinality, maximum weight or minimum cost
  24.477 +matching. The search can be constrained to find perfect or
  24.478 +maximum cardinality matching.
  24.479 +
  24.480 +The matching algorithms implemented in LEMON:
  24.481 +- \ref MaxBipartiteMatching Hopcroft-Karp augmenting path algorithm
  24.482 +  for calculating maximum cardinality matching in bipartite graphs.
  24.483 +- \ref PrBipartiteMatching Push-relabel algorithm
  24.484 +  for calculating maximum cardinality matching in bipartite graphs.
  24.485 +- \ref MaxWeightedBipartiteMatching
  24.486 +  Successive shortest path algorithm for calculating maximum weighted
  24.487 +  matching and maximum weighted bipartite matching in bipartite graphs.
  24.488 +- \ref MinCostMaxBipartiteMatching
  24.489 +  Successive shortest path algorithm for calculating minimum cost maximum
  24.490 +  matching in bipartite graphs.
  24.491 +- \ref MaxMatching Edmond's blossom shrinking algorithm for calculating
  24.492 +  maximum cardinality matching in general graphs.
  24.493 +- \ref MaxWeightedMatching Edmond's blossom shrinking algorithm for calculating
  24.494 +  maximum weighted matching in general graphs.
  24.495 +- \ref MaxWeightedPerfectMatching
  24.496 +  Edmond's blossom shrinking algorithm for calculating maximum weighted
  24.497 +  perfect matching in general graphs.
  24.498 +
  24.499 +\image html bipartite_matching.png
  24.500 +\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
  24.501 +*/
  24.502 +
  24.503 +/**
  24.504 +@defgroup graph_properties Connectivity and Other Graph Properties
  24.505  @ingroup algs
  24.506  \brief Algorithms for discovering the graph properties
  24.507  
  24.508 -This group describes the algorithms for discovering the graph properties
  24.509 +This group contains the algorithms for discovering the graph properties
  24.510  like connectivity, bipartiteness, euler property, simplicity etc.
  24.511  
  24.512 -\image html edge_biconnected_components.png
  24.513 -\image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
  24.514 +\image html connected_components.png
  24.515 +\image latex connected_components.eps "Connected components" width=\textwidth
  24.516  */
  24.517  
  24.518  /**
  24.519 @@ -301,7 +546,7 @@
  24.520  @ingroup algs
  24.521  \brief Algorithms for planarity checking, embedding and drawing
  24.522  
  24.523 -This group describes the algorithms for planarity checking,
  24.524 +This group contains the algorithms for planarity checking,
  24.525  embedding and drawing.
  24.526  
  24.527  \image html planar.png
  24.528 @@ -309,53 +554,12 @@
  24.529  */
  24.530  
  24.531  /**
  24.532 -@defgroup matching Matching Algorithms
  24.533 +@defgroup approx Approximation Algorithms
  24.534  @ingroup algs
  24.535 -\brief Algorithms for finding matchings in graphs and bipartite graphs.
  24.536 +\brief Approximation algorithms.
  24.537  
  24.538 -This group contains algorithm objects and functions to calculate
  24.539 -matchings in graphs and bipartite graphs. The general matching problem is
  24.540 -finding a subset of the arcs which does not shares common endpoints.
  24.541 -
  24.542 -There are several different algorithms for calculate matchings in
  24.543 -graphs.  The matching problems in bipartite graphs are generally
  24.544 -easier than in general graphs. The goal of the matching optimization
  24.545 -can be the finding maximum cardinality, maximum weight or minimum cost
  24.546 -matching. The search can be constrained to find perfect or
  24.547 -maximum cardinality matching.
  24.548 -
  24.549 -LEMON contains the next algorithms:
  24.550 -- \ref lemon::MaxBipartiteMatching "MaxBipartiteMatching" Hopcroft-Karp
  24.551 -  augmenting path algorithm for calculate maximum cardinality matching in
  24.552 -  bipartite graphs
  24.553 -- \ref lemon::PrBipartiteMatching "PrBipartiteMatching" Push-Relabel
  24.554 -  algorithm for calculate maximum cardinality matching in bipartite graphs
  24.555 -- \ref lemon::MaxWeightedBipartiteMatching "MaxWeightedBipartiteMatching"
  24.556 -  Successive shortest path algorithm for calculate maximum weighted matching
  24.557 -  and maximum weighted bipartite matching in bipartite graph
  24.558 -- \ref lemon::MinCostMaxBipartiteMatching "MinCostMaxBipartiteMatching"
  24.559 -  Successive shortest path algorithm for calculate minimum cost maximum
  24.560 -  matching in bipartite graph
  24.561 -- \ref lemon::MaxMatching "MaxMatching" Edmond's blossom shrinking algorithm
  24.562 -  for calculate maximum cardinality matching in general graph
  24.563 -- \ref lemon::MaxWeightedMatching "MaxWeightedMatching" Edmond's blossom
  24.564 -  shrinking algorithm for calculate maximum weighted matching in general
  24.565 -  graph
  24.566 -- \ref lemon::MaxWeightedPerfectMatching "MaxWeightedPerfectMatching"
  24.567 -  Edmond's blossom shrinking algorithm for calculate maximum weighted
  24.568 -  perfect matching in general graph
  24.569 -
  24.570 -\image html bipartite_matching.png
  24.571 -\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
  24.572 -*/
  24.573 -
  24.574 -/**
  24.575 -@defgroup spantree Minimum Spanning Tree Algorithms
  24.576 -@ingroup algs
  24.577 -\brief Algorithms for finding a minimum cost spanning tree in a graph.
  24.578 -
  24.579 -This group describes the algorithms for finding a minimum cost spanning
  24.580 -tree in a graph
  24.581 +This group contains the approximation and heuristic algorithms
  24.582 +implemented in LEMON.
  24.583  */
  24.584  
  24.585  /**
  24.586 @@ -363,36 +567,30 @@
  24.587  @ingroup algs
  24.588  \brief Auxiliary algorithms implemented in LEMON.
  24.589  
  24.590 -This group describes some algorithms implemented in LEMON
  24.591 +This group contains some algorithms implemented in LEMON
  24.592  in order to make it easier to implement complex algorithms.
  24.593  */
  24.594  
  24.595  /**
  24.596 -@defgroup approx Approximation Algorithms
  24.597 -@ingroup algs
  24.598 -\brief Approximation algorithms.
  24.599 +@defgroup gen_opt_group General Optimization Tools
  24.600 +\brief This group contains some general optimization frameworks
  24.601 +implemented in LEMON.
  24.602  
  24.603 -This group describes the approximation and heuristic algorithms
  24.604 +This group contains some general optimization frameworks
  24.605  implemented in LEMON.
  24.606  */
  24.607  
  24.608  /**
  24.609 -@defgroup gen_opt_group General Optimization Tools
  24.610 -\brief This group describes some general optimization frameworks
  24.611 -implemented in LEMON.
  24.612 +@defgroup lp_group LP and MIP Solvers
  24.613 +@ingroup gen_opt_group
  24.614 +\brief LP and MIP solver interfaces for LEMON.
  24.615  
  24.616 -This group describes some general optimization frameworks
  24.617 -implemented in LEMON.
  24.618 -*/
  24.619 +This group contains LP and MIP solver interfaces for LEMON.
  24.620 +Various LP solvers could be used in the same manner with this
  24.621 +high-level interface.
  24.622  
  24.623 -/**
  24.624 -@defgroup lp_group Lp and Mip Solvers
  24.625 -@ingroup gen_opt_group
  24.626 -\brief Lp and Mip solver interfaces for LEMON.
  24.627 -
  24.628 -This group describes Lp and Mip solver interfaces for LEMON. The
  24.629 -various LP solvers could be used in the same manner with this
  24.630 -interface.
  24.631 +The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
  24.632 +\ref cplex, \ref soplex.
  24.633  */
  24.634  
  24.635  /**
  24.636 @@ -409,7 +607,7 @@
  24.637  @ingroup gen_opt_group
  24.638  \brief Metaheuristics for LEMON library.
  24.639  
  24.640 -This group describes some metaheuristic optimization tools.
  24.641 +This group contains some metaheuristic optimization tools.
  24.642  */
  24.643  
  24.644  /**
  24.645 @@ -424,7 +622,7 @@
  24.646  @ingroup utils
  24.647  \brief Simple basic graph utilities.
  24.648  
  24.649 -This group describes some simple basic graph utilities.
  24.650 +This group contains some simple basic graph utilities.
  24.651  */
  24.652  
  24.653  /**
  24.654 @@ -432,7 +630,7 @@
  24.655  @ingroup utils
  24.656  \brief Tools for development, debugging and testing.
  24.657  
  24.658 -This group describes several useful tools for development,
  24.659 +This group contains several useful tools for development,
  24.660  debugging and testing.
  24.661  */
  24.662  
  24.663 @@ -441,7 +639,7 @@
  24.664  @ingroup misc
  24.665  \brief Simple tools for measuring the performance of algorithms.
  24.666  
  24.667 -This group describes simple tools for measuring the performance
  24.668 +This group contains simple tools for measuring the performance
  24.669  of algorithms.
  24.670  */
  24.671  
  24.672 @@ -450,25 +648,25 @@
  24.673  @ingroup utils
  24.674  \brief Exceptions defined in LEMON.
  24.675  
  24.676 -This group describes the exceptions defined in LEMON.
  24.677 +This group contains the exceptions defined in LEMON.
  24.678  */
  24.679  
  24.680  /**
  24.681  @defgroup io_group Input-Output
  24.682  \brief Graph Input-Output methods
  24.683  
  24.684 -This group describes the tools for importing and exporting graphs
  24.685 +This group contains the tools for importing and exporting graphs
  24.686  and graph related data. Now it supports the \ref lgf-format
  24.687  "LEMON Graph Format", the \c DIMACS format and the encapsulated
  24.688  postscript (EPS) format.
  24.689  */
  24.690  
  24.691  /**
  24.692 -@defgroup lemon_io LEMON Input-Output
  24.693 +@defgroup lemon_io LEMON Graph Format
  24.694  @ingroup io_group
  24.695  \brief Reading and writing LEMON Graph Format.
  24.696  
  24.697 -This group describes methods for reading and writing
  24.698 +This group contains methods for reading and writing
  24.699  \ref lgf-format "LEMON Graph Format".
  24.700  */
  24.701  
  24.702 @@ -477,15 +675,31 @@
  24.703  @ingroup io_group
  24.704  \brief General \c EPS drawer and graph exporter
  24.705  
  24.706 -This group describes general \c EPS drawing methods and special
  24.707 +This group contains general \c EPS drawing methods and special
  24.708  graph exporting tools.
  24.709  */
  24.710  
  24.711  /**
  24.712 +@defgroup dimacs_group DIMACS Format
  24.713 +@ingroup io_group
  24.714 +\brief Read and write files in DIMACS format
  24.715 +
  24.716 +Tools to read a digraph from or write it to a file in DIMACS format data.
  24.717 +*/
  24.718 +
  24.719 +/**
  24.720 +@defgroup nauty_group NAUTY Format
  24.721 +@ingroup io_group
  24.722 +\brief Read \e Nauty format
  24.723 +
  24.724 +Tool to read graphs from \e Nauty format data.
  24.725 +*/
  24.726 +
  24.727 +/**
  24.728  @defgroup concept Concepts
  24.729  \brief Skeleton classes and concept checking classes
  24.730  
  24.731 -This group describes the data/algorithm skeletons and concept checking
  24.732 +This group contains the data/algorithm skeletons and concept checking
  24.733  classes implemented in LEMON.
  24.734  
  24.735  The purpose of the classes in this group is fourfold.
  24.736 @@ -515,8 +729,8 @@
  24.737  @ingroup concept
  24.738  \brief Skeleton and concept checking classes for graph structures
  24.739  
  24.740 -This group describes the skeletons and concept checking classes of LEMON's
  24.741 -graph structures and helper classes used to implement these.
  24.742 +This group contains the skeletons and concept checking classes of
  24.743 +graph structures.
  24.744  */
  24.745  
  24.746  /**
  24.747 @@ -524,23 +738,11 @@
  24.748  @ingroup concept
  24.749  \brief Skeleton and concept checking classes for maps
  24.750  
  24.751 -This group describes the skeletons and concept checking classes of maps.
  24.752 +This group contains the skeletons and concept checking classes of maps.
  24.753  */
  24.754  
  24.755  /**
  24.756 -\anchor demoprograms
  24.757 -
  24.758 -@defgroup demos Demo programs
  24.759 -
  24.760 -Some demo programs are listed here. Their full source codes can be found in
  24.761 -the \c demo subdirectory of the source tree.
  24.762 -
  24.763 -It order to compile them, use <tt>--enable-demo</tt> configure option when
  24.764 -build the library.
  24.765 -*/
  24.766 -
  24.767 -/**
  24.768 -@defgroup tools Standalone utility applications
  24.769 +@defgroup tools Standalone Utility Applications
  24.770  
  24.771  Some utility applications are listed here.
  24.772  
  24.773 @@ -548,3 +750,16 @@
  24.774  them, as well.
  24.775  */
  24.776  
  24.777 +/**
  24.778 +\anchor demoprograms
  24.779 +
  24.780 +@defgroup demos Demo Programs
  24.781 +
  24.782 +Some demo programs are listed here. Their full source codes can be found in
  24.783 +the \c demo subdirectory of the source tree.
  24.784 +
  24.785 +In order to compile them, use the <tt>make demo</tt> or the
  24.786 +<tt>make check</tt> commands.
  24.787 +*/
  24.788 +
  24.789 +}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/doc/images/bipartite_matching.eps	Thu Nov 05 15:50:01 2009 +0100
    25.3 @@ -0,0 +1,586 @@
    25.4 +%!PS-Adobe-3.0 EPSF-3.0
    25.5 +%%BoundingBox: 15 18 829 570
    25.6 +%%HiResBoundingBox: 15.1913 18.4493 828.078 569.438
    25.7 +%%Creator: Karbon14 EPS Exportfilter 0.5
    25.8 +%%CreationDate: (04/15/06 15:20:26)
    25.9 +%%For: (Balazs Dezso) ()
   25.10 +%%Title: ()
   25.11 +
   25.12 +/N {newpath} def
   25.13 +/C {closepath} def
   25.14 +/m {moveto} def
   25.15 +/c {curveto} def
   25.16 +/l {lineto} def
   25.17 +/s {stroke} def
   25.18 +/f {fill} def
   25.19 +/w {setlinewidth} def
   25.20 +/d {setdash} def
   25.21 +/r {setrgbcolor} def
   25.22 +/S {gsave} def
   25.23 +/R {grestore} def
   25.24 +
   25.25 +N
   25.26 +251.402 32.047 m
   25.27 +532.945 293.946 814.484 555.844 814.484 555.844 c
   25.28 +[] 0 d 1 0 0 r 3.92814 w s
   25.29 +
   25.30 +N
   25.31 +749.012 32.047 m
   25.32 +742.465 293.946 735.918 555.844 735.918 555.844 c
   25.33 +[] 0 d 0 0 0 r 1.96407 w s
   25.34 +
   25.35 +N
   25.36 +539.492 32.047 m
   25.37 +637.703 293.946 735.918 555.844 735.918 555.844 c
   25.38 +[] 0 d 0 0 0 r 1.96407 w s
   25.39 +
   25.40 +N
   25.41 +172.832 32.047 m
   25.42 +454.375 293.946 735.918 555.844 735.918 555.844 c
   25.43 +[] 0 d 0 0 0 r 1.96407 w s
   25.44 +
   25.45 +N
   25.46 +107.355 32.047 m
   25.47 +421.637 293.946 735.918 555.844 735.918 555.844 c
   25.48 +[] 0 d 1 0 0 r 3.92814 w s
   25.49 +
   25.50 +N
   25.51 +644.25 555.844 m
   25.52 +696.633 293.946 749.012 32.047 749.012 32.047 c
   25.53 +[] 0 d 0 0 0 r 1.96407 w s
   25.54 +
   25.55 +N
   25.56 +474.016 555.844 m
   25.57 +611.516 293.946 749.012 32.047 749.012 32.047 c
   25.58 +[] 0 d 1 0 0 r 3.92814 w s
   25.59 +
   25.60 +N
   25.61 +683.535 32.047 m
   25.62 +663.894 293.946 644.25 555.844 644.25 555.844 c
   25.63 +[] 0 d 0 0 0 r 1.96407 w s
   25.64 +
   25.65 +N
   25.66 +120.453 555.844 m
   25.67 +401.992 293.946 683.535 32.047 683.535 32.047 c
   25.68 +[] 0 d 0 0 0 r 1.96407 w s
   25.69 +
   25.70 +N
   25.71 +28.7853 555.844 m
   25.72 +356.16 293.946 683.535 32.047 683.535 32.047 c
   25.73 +[] 0 d 1 0 0 r 3.92814 w s
   25.74 +
   25.75 +N
   25.76 +539.492 32.047 m
   25.77 +546.039 293.946 552.586 555.844 552.586 555.844 c
   25.78 +[] 0 d 1 0 0 r 3.92814 w s
   25.79 +
   25.80 +N
   25.81 +316.875 32.047 m
   25.82 +349.613 293.946 382.351 555.844 382.351 555.844 c
   25.83 +[] 0 d 1 0 0 r 3.92814 w s
   25.84 +
   25.85 +N
   25.86 +107.355 32.047 m
   25.87 +244.855 293.946 382.351 555.844 382.351 555.844 c
   25.88 +[] 0 d 0 0 0 r 1.96407 w s
   25.89 +
   25.90 +N
   25.91 +290.687 555.844 m
   25.92 +375.805 293.946 460.922 32.047 460.922 32.047 c
   25.93 +[] 0 d 1 0 0 r 3.92814 w s
   25.94 +
   25.95 +N
   25.96 +120.453 555.844 m
   25.97 +290.687 293.946 460.922 32.047 460.922 32.047 c
   25.98 +[] 0 d 0 0 0 r 1.96407 w s
   25.99 +
  25.100 +N
  25.101 +172.832 32.047 m
  25.102 +146.64 293.946 120.453 555.844 120.453 555.844 c
  25.103 +[] 0 d 1 0 0 r 3.92814 w s
  25.104 +
  25.105 +N
  25.106 +15.6913 555.844 m
  25.107 +15.6913 555.844 l
  25.108 +15.6913 548.614 21.5553 542.75 28.7853 542.75 c
  25.109 +36.0163 542.75 41.8833 548.614 41.8833 555.844 c
  25.110 +41.8833 563.075 36.0163 568.938 28.7853 568.938 c
  25.111 +21.5553 568.938 15.6913 563.075 15.6913 555.844 c
  25.112 +15.6913 555.844 l
  25.113 +C
  25.114 +S 0 0 0 r f R
  25.115 +
  25.116 +N
  25.117 +16.8833 555.844 m
  25.118 +16.8833 555.844 l
  25.119 +16.8833 549.27 22.2113 543.942 28.7853 543.942 c
  25.120 +35.3593 543.942 40.6913 549.27 40.6913 555.844 c
  25.121 +40.6913 562.418 35.3593 567.747 28.7853 567.747 c
  25.122 +22.2113 567.747 16.8833 562.418 16.8833 555.844 c
  25.123 +16.8833 555.844 l
  25.124 +C
  25.125 +S 1 0.5 1 r f R
  25.126 +
  25.127 +N
  25.128 +107.355 555.844 m
  25.129 +107.355 555.844 l
  25.130 +107.355 548.614 113.223 542.75 120.453 542.75 c
  25.131 +127.683 542.75 133.547 548.614 133.547 555.844 c
  25.132 +133.547 563.075 127.683 568.938 120.453 568.938 c
  25.133 +113.223 568.938 107.355 563.075 107.355 555.844 c
  25.134 +107.355 555.844 l
  25.135 +C
  25.136 +S 0 0 0 r f R
  25.137 +
  25.138 +N
  25.139 +108.547 555.844 m
  25.140 +108.547 555.844 l
  25.141 +108.547 549.27 113.879 543.942 120.453 543.942 c
  25.142 +127.027 543.942 132.355 549.27 132.355 555.844 c
  25.143 +132.355 562.418 127.027 567.747 120.453 567.747 c
  25.144 +113.879 567.747 108.547 562.418 108.547 555.844 c
  25.145 +108.547 555.844 l
  25.146 +C
  25.147 +S 1 0 1 r f R
  25.148 +
  25.149 +N
  25.150 +199.019 555.844 m
  25.151 +199.019 555.844 l
  25.152 +199.019 548.614 204.887 542.75 212.117 542.75 c
  25.153 +219.348 542.75 225.211 548.614 225.211 555.844 c
  25.154 +225.211 563.075 219.348 568.938 212.117 568.938 c
  25.155 +204.887 568.938 199.019 563.075 199.019 555.844 c
  25.156 +199.019 555.844 l
  25.157 +C
  25.158 +S 0 0 0 r f R
  25.159 +
  25.160 +N
  25.161 +200.211 555.844 m
  25.162 +200.211 555.844 l
  25.163 +200.211 549.27 205.543 543.942 212.117 543.942 c
  25.164 +218.691 543.942 224.019 549.27 224.019 555.844 c
  25.165 +224.019 562.418 218.691 567.747 212.117 567.747 c
  25.166 +205.543 567.747 200.211 562.418 200.211 555.844 c
  25.167 +200.211 555.844 l
  25.168 +C
  25.169 +S 1 0.5 1 r f R
  25.170 +
  25.171 +N
  25.172 +277.59 555.844 m
  25.173 +277.59 555.844 l
  25.174 +277.59 548.614 283.457 542.75 290.687 542.75 c
  25.175 +297.918 542.75 303.781 548.614 303.781 555.844 c
  25.176 +303.781 563.075 297.918 568.938 290.687 568.938 c
  25.177 +283.457 568.938 277.59 563.075 277.59 555.844 c
  25.178 +277.59 555.844 l
  25.179 +C
  25.180 +S 0 0 0 r f R
  25.181 +
  25.182 +N
  25.183 +278.781 555.844 m
  25.184 +278.781 555.844 l
  25.185 +278.781 549.27 284.113 543.942 290.687 543.942 c
  25.186 +297.262 543.942 302.59 549.27 302.59 555.844 c
  25.187 +302.59 562.418 297.262 567.747 290.687 567.747 c
  25.188 +284.113 567.747 278.781 562.418 278.781 555.844 c
  25.189 +278.781 555.844 l
  25.190 +C
  25.191 +S 1 0 1 r f R
  25.192 +
  25.193 +N
  25.194 +369.258 555.844 m
  25.195 +369.258 555.844 l
  25.196 +369.258 548.614 375.121 542.75 382.351 542.75 c
  25.197 +389.582 542.75 395.445 548.614 395.445 555.844 c
  25.198 +395.445 563.075 389.582 568.938 382.351 568.938 c
  25.199 +375.121 568.938 369.258 563.075 369.258 555.844 c
  25.200 +369.258 555.844 l
  25.201 +C
  25.202 +S 0 0 0 r f R
  25.203 +
  25.204 +N
  25.205 +370.445 555.844 m
  25.206 +370.445 555.844 l
  25.207 +370.445 549.27 375.777 543.942 382.351 543.942 c
  25.208 +388.926 543.942 394.258 549.27 394.258 555.844 c
  25.209 +394.258 562.418 388.926 567.747 382.351 567.747 c
  25.210 +375.777 567.747 370.445 562.418 370.445 555.844 c
  25.211 +370.445 555.844 l
  25.212 +C
  25.213 +S 1 0 1 r f R
  25.214 +
  25.215 +N
  25.216 +460.922 555.844 m
  25.217 +460.922 555.844 l
  25.218 +460.922 548.614 466.785 542.75 474.016 542.75 c
  25.219 +481.246 542.75 487.109 548.614 487.109 555.844 c
  25.220 +487.109 563.075 481.246 568.938 474.016 568.938 c
  25.221 +466.785 568.938 460.922 563.075 460.922 555.844 c
  25.222 +460.922 555.844 l
  25.223 +C
  25.224 +S 0 0 0 r f R
  25.225 +
  25.226 +N
  25.227 +462.113 555.844 m
  25.228 +462.113 555.844 l
  25.229 +462.113 549.27 467.441 543.942 474.016 543.942 c
  25.230 +480.59 543.942 485.922 549.27 485.922 555.844 c
  25.231 +485.922 562.418 480.59 567.747 474.016 567.747 c
  25.232 +467.441 567.747 462.113 562.418 462.113 555.844 c
  25.233 +462.113 555.844 l
  25.234 +C
  25.235 +S 1 0.5 1 r f R
  25.236 +
  25.237 +N
  25.238 +539.492 555.844 m
  25.239 +539.492 555.844 l
  25.240 +539.492 548.614 545.355 542.75 552.586 542.75 c
  25.241 +559.816 542.75 565.68 548.614 565.68 555.844 c
  25.242 +565.68 563.075 559.816 568.938 552.586 568.938 c
  25.243 +545.355 568.938 539.492 563.075 539.492 555.844 c
  25.244 +539.492 555.844 l
  25.245 +C
  25.246 +S 0 0 0 r f R
  25.247 +
  25.248 +N
  25.249 +540.683 555.844 m
  25.250 +540.683 555.844 l
  25.251 +540.683 549.27 546.012 543.942 552.586 543.942 c
  25.252 +559.16 543.942 564.492 549.27 564.492 555.844 c
  25.253 +564.492 562.418 559.16 567.747 552.586 567.747 c
  25.254 +546.012 567.747 540.683 562.418 540.683 555.844 c
  25.255 +540.683 555.844 l
  25.256 +C
  25.257 +S 1 0 1 r f R
  25.258 +
  25.259 +N
  25.260 +631.156 555.844 m
  25.261 +631.156 555.844 l
  25.262 +631.156 548.614 637.019 542.75 644.25 542.75 c
  25.263 +651.48 542.75 657.348 548.614 657.348 555.844 c
  25.264 +657.348 563.075 651.48 568.938 644.25 568.938 c
  25.265 +637.019 568.938 631.156 563.075 631.156 555.844 c
  25.266 +631.156 555.844 l
  25.267 +C
  25.268 +S 0 0 0 r f R
  25.269 +
  25.270 +N
  25.271 +632.348 555.844 m
  25.272 +632.348 555.844 l
  25.273 +632.348 549.27 637.676 543.942 644.25 543.942 c
  25.274 +650.824 543.942 656.156 549.27 656.156 555.844 c
  25.275 +656.156 562.418 650.824 567.747 644.25 567.747 c
  25.276 +637.676 567.747 632.348 562.418 632.348 555.844 c
  25.277 +632.348 555.844 l
  25.278 +C
  25.279 +S 1 0.5 1 r f R
  25.280 +
  25.281 +N
  25.282 +722.82 555.844 m
  25.283 +722.82 555.844 l
  25.284 +722.82 548.614 728.687 542.75 735.918 542.75 c
  25.285 +743.149 542.75 749.012 548.614 749.012 555.844 c
  25.286 +749.012 563.075 743.149 568.938 735.918 568.938 c
  25.287 +728.687 568.938 722.82 563.075 722.82 555.844 c
  25.288 +722.82 555.844 l
  25.289 +C
  25.290 +S 0 0 0 r f R
  25.291 +
  25.292 +N
  25.293 +724.012 555.844 m
  25.294 +724.012 555.844 l
  25.295 +724.012 549.27 729.344 543.942 735.918 543.942 c
  25.296 +742.492 543.942 747.82 549.27 747.82 555.844 c
  25.297 +747.82 562.418 742.492 567.747 735.918 567.747 c
  25.298 +729.344 567.747 724.012 562.418 724.012 555.844 c
  25.299 +724.012 555.844 l
  25.300 +C
  25.301 +S 1 0 1 r f R
  25.302 +
  25.303 +N
  25.304 +801.391 555.844 m
  25.305 +801.391 555.844 l
  25.306 +801.391 548.614 807.254 542.75 814.484 542.75 c
  25.307 +821.715 542.75 827.578 548.614 827.578 555.844 c
  25.308 +827.578 563.075 821.715 568.938 814.484 568.938 c
  25.309 +807.254 568.938 801.391 563.075 801.391 555.844 c
  25.310 +801.391 555.844 l
  25.311 +C
  25.312 +S 0 0 0 r f R
  25.313 +
  25.314 +N
  25.315 +802.582 555.844 m
  25.316 +802.582 555.844 l
  25.317 +802.582 549.27 807.91 543.942 814.484 543.942 c
  25.318 +821.059 543.942 826.387 549.27 826.387 555.844 c
  25.319 +826.387 562.418 821.059 567.747 814.484 567.747 c
  25.320 +807.91 567.747 802.582 562.418 802.582 555.844 c
  25.321 +802.582 555.844 l
  25.322 +C
  25.323 +S 1 0 1 r f R
  25.324 +
  25.325 +N
  25.326 +15.6913 32.047 m
  25.327 +15.6913 32.047 l
  25.328 +15.6913 24.8165 21.5553 18.9493 28.7853 18.9493 c
  25.329 +36.0163 18.9493 41.8833 24.8165 41.8833 32.047 c
  25.330 +41.8833 39.2775 36.0163 45.1407 28.7853 45.1407 c
  25.331 +21.5553 45.1407 15.6913 39.2775 15.6913 32.047 c
  25.332 +15.6913 32.047 l
  25.333 +C
  25.334 +S 0 0 0 r f R
  25.335 +
  25.336 +N
  25.337 +16.8833 32.047 m
  25.338 +16.8833 32.047 l
  25.339 +16.8833 25.4728 22.2113 20.1407 28.7853 20.1407 c
  25.340 +35.3593 20.1407 40.6913 25.4728 40.6913 32.047 c
  25.341 +40.6913 38.6212 35.3593 43.9493 28.7853 43.9493 c
  25.342 +22.2113 43.9493 16.8833 38.6212 16.8833 32.047 c
  25.343 +16.8833 32.047 l
  25.344 +C
  25.345 +S 0.5 0.5 1 r f R
  25.346 +
  25.347 +N
  25.348 +94.2623 32.047 m
  25.349 +94.2623 32.047 l
  25.350 +94.2623 24.8165 100.125 18.9493 107.355 18.9493 c
  25.351 +114.586 18.9493 120.453 24.8165 120.453 32.047 c
  25.352 +120.453 39.2775 114.586 45.1407 107.355 45.1407 c
  25.353 +100.125 45.1407 94.2623 39.2775 94.2623 32.047 c
  25.354 +94.2623 32.047 l
  25.355 +C
  25.356 +S 0 0 0 r f R
  25.357 +
  25.358 +N
  25.359 +95.4533 32.047 m
  25.360 +95.4533 32.047 l
  25.361 +95.4533 25.4728 100.781 20.1407 107.355 20.1407 c
  25.362 +113.93 20.1407 119.262 25.4728 119.262 32.047 c
  25.363 +119.262 38.6212 113.93 43.9493 107.355 43.9493 c
  25.364 +100.781 43.9493 95.4533 38.6212 95.4533 32.047 c
  25.365 +95.4533 32.047 l
  25.366 +C
  25.367 +S 0.5 0.5 1 r f R
  25.368 +
  25.369 +N
  25.370 +159.734 32.047 m
  25.371 +159.734 32.047 l
  25.372 +159.734 24.8165 165.601 18.9493 172.832 18.9493 c
  25.373 +180.062 18.9493 185.926 24.8165 185.926 32.047 c
  25.374 +185.926 39.2775 180.062 45.1407 172.832 45.1407 c
  25.375 +165.601 45.1407 159.734 39.2775 159.734 32.047 c
  25.376 +159.734 32.047 l
  25.377 +C
  25.378 +S 0 0 0 r f R
  25.379 +
  25.380 +N
  25.381 +160.926 32.047 m
  25.382 +160.926 32.047 l
  25.383 +160.926 25.4728 166.258 20.1407 172.832 20.1407 c
  25.384 +179.406 20.1407 184.734 25.4728 184.734 32.047 c
  25.385 +184.734 38.6212 179.406 43.9493 172.832 43.9493 c
  25.386 +166.258 43.9493 160.926 38.6212 160.926 32.047 c
  25.387 +160.926 32.047 l
  25.388 +C
  25.389 +S 0.5 0.5 1 r f R
  25.390 +
  25.391 +N
  25.392 +238.305 32.047 m
  25.393 +238.305 32.047 l
  25.394 +238.305 24.8165 244.172 18.9493 251.402 18.9493 c
  25.395 +258.633 18.9493 264.496 24.8165 264.496 32.047 c
  25.396 +264.496 39.2775 258.633 45.1407 251.402 45.1407 c
  25.397 +244.172 45.1407 238.305 39.2775 238.305 32.047 c
  25.398 +238.305 32.047 l
  25.399 +C
  25.400 +S 0 0 0 r f R
  25.401 +
  25.402 +N
  25.403 +239.496 32.047 m
  25.404 +239.496 32.047 l
  25.405 +239.496 25.4728 244.828 20.1407 251.402 20.1407 c
  25.406 +257.976 20.1407 263.305 25.4728 263.305 32.047 c
  25.407 +263.305 38.6212 257.976 43.9493 251.402 43.9493 c
  25.408 +244.828 43.9493 239.496 38.6212 239.496 32.047 c
  25.409 +239.496 32.047 l
  25.410 +C
  25.411 +S 0.5 0.5 1 r f R
  25.412 +
  25.413 +N
  25.414 +303.781 32.047 m
  25.415 +303.781 32.047 l
  25.416 +303.781 24.8165 309.644 18.9493 316.875 18.9493 c
  25.417 +324.105 18.9493 329.973 24.8165 329.973 32.047 c
  25.418 +329.973 39.2775 324.105 45.1407 316.875 45.1407 c
  25.419 +309.644 45.1407 303.781 39.2775 303.781 32.047 c
  25.420 +303.781 32.047 l
  25.421 +C
  25.422 +S 0 0 0 r f R
  25.423 +
  25.424 +N
  25.425 +304.973 32.047 m
  25.426 +304.973 32.047 l
  25.427 +304.973 25.4728 310.301 20.1407 316.875 20.1407 c
  25.428 +323.449 20.1407 328.781 25.4728 328.781 32.047 c
  25.429 +328.781 38.6212 323.449 43.9493 316.875 43.9493 c
  25.430 +310.301 43.9493 304.973 38.6212 304.973 32.047 c
  25.431 +304.973 32.047 l
  25.432 +C
  25.433 +S 0.5 0.5 1 r f R
  25.434 +
  25.435 +N
  25.436 +382.351 32.047 m
  25.437 +382.351 32.047 l
  25.438 +382.351 24.8165 388.215 18.9493 395.445 18.9493 c
  25.439 +402.676 18.9493 408.543 24.8165 408.543 32.047 c
  25.440 +408.543 39.2775 402.676 45.1407 395.445 45.1407 c
  25.441 +388.215 45.1407 382.351 39.2775 382.351 32.047 c
  25.442 +382.351 32.047 l
  25.443 +C
  25.444 +S 0 0 0 r f R
  25.445 +
  25.446 +N
  25.447 +383.543 32.047 m
  25.448 +383.543 32.047 l
  25.449 +383.543 25.4728 388.871 20.1407 395.445 20.1407 c
  25.450 +402.019 20.1407 407.351 25.4728 407.351 32.047 c
  25.451 +407.351 38.6212 402.019 43.9493 395.445 43.9493 c
  25.452 +388.871 43.9493 383.543 38.6212 383.543 32.047 c
  25.453 +383.543 32.047 l
  25.454 +C
  25.455 +S 0.5 0.5 1 r f R
  25.456 +
  25.457 +N
  25.458 +447.828 32.047 m
  25.459 +447.828 32.047 l
  25.460 +447.828 24.8165 453.691 18.9493 460.922 18.9493 c
  25.461 +468.152 18.9493 474.016 24.8165 474.016 32.047 c
  25.462 +474.016 39.2775 468.152 45.1407 460.922 45.1407 c
  25.463 +453.691 45.1407 447.828 39.2775 447.828 32.047 c
  25.464 +447.828 32.047 l
  25.465 +C
  25.466 +S 0 0 0 r f R
  25.467 +
  25.468 +N
  25.469 +449.016 32.047 m
  25.470 +449.016 32.047 l
  25.471 +449.016 25.4728 454.348 20.1407 460.922 20.1407 c
  25.472 +467.496 20.1407 472.824 25.4728 472.824 32.047 c
  25.473 +472.824 38.6212 467.496 43.9493 460.922 43.9493 c
  25.474 +454.348 43.9493 449.016 38.6212 449.016 32.047 c
  25.475 +449.016 32.047 l
  25.476 +C
  25.477 +S 0.5 0.5 1 r f R
  25.478 +
  25.479 +N
  25.480 +526.394 32.047 m
  25.481 +526.394 32.047 l
  25.482 +526.394 24.8165 532.262 18.9493 539.492 18.9493 c
  25.483 +546.723 18.9493 552.586 24.8165 552.586 32.047 c
  25.484 +552.586 39.2775 546.723 45.1407 539.492 45.1407 c
  25.485 +532.262 45.1407 526.394 39.2775 526.394 32.047 c
  25.486 +526.394 32.047 l
  25.487 +C
  25.488 +S 0 0 0 r f R
  25.489 +
  25.490 +N
  25.491 +527.586 32.047 m
  25.492 +527.586 32.047 l
  25.493 +527.586 25.4728 532.918 20.1407 539.492 20.1407 c
  25.494 +546.066 20.1407 551.394 25.4728 551.394 32.047 c
  25.495 +551.394 38.6212 546.066 43.9493 539.492 43.9493 c
  25.496 +532.918 43.9493 527.586 38.6212 527.586 32.047 c
  25.497 +527.586 32.047 l
  25.498 +C
  25.499 +S 0.5 0.5 1 r f R
  25.500 +
  25.501 +N
  25.502 +591.871 32.047 m
  25.503 +591.871 32.047 l
  25.504 +591.871 24.8165 597.734 18.9493 604.965 18.9493 c
  25.505 +612.195 18.9493 618.062 24.8165 618.062 32.047 c
  25.506 +618.062 39.2775 612.195 45.1407 604.965 45.1407 c
  25.507 +597.734 45.1407 591.871 39.2775 591.871 32.047 c
  25.508 +591.871 32.047 l
  25.509 +C
  25.510 +S 0 0 0 r f R
  25.511 +
  25.512 +N
  25.513 +593.062 32.047 m
  25.514 +593.062 32.047 l
  25.515 +593.062 25.4728 598.39 20.1407 604.965 20.1407 c
  25.516 +611.539 20.1407 616.871 25.4728 616.871 32.047 c
  25.517 +616.871 38.6212 611.539 43.9493 604.965 43.9493 c
  25.518 +598.39 43.9493 593.062 38.6212 593.062 32.047 c
  25.519 +593.062 32.047 l
  25.520 +C
  25.521 +S 0.5 0.5 1 r f R
  25.522 +
  25.523 +N
  25.524 +670.441 32.047 m
  25.525 +670.441 32.047 l
  25.526 +670.441 24.8165 676.305 18.9493 683.535 18.9493 c
  25.527 +690.766 18.9493 696.633 24.8165 696.633 32.047 c
  25.528 +696.633 39.2775 690.766 45.1407 683.535 45.1407 c
  25.529 +676.305 45.1407 670.441 39.2775 670.441 32.047 c
  25.530 +670.441 32.047 l
  25.531 +C
  25.532 +S 0 0 0 r f R
  25.533 +
  25.534 +N
  25.535 +671.633 32.047 m
  25.536 +671.633 32.047 l
  25.537 +671.633 25.4728 676.961 20.1407 683.535 20.1407 c
  25.538 +690.109 20.1407 695.441 25.4728 695.441 32.047 c
  25.539 +695.441 38.6212 690.109 43.9493 683.535 43.9493 c
  25.540 +676.961 43.9493 671.633 38.6212 671.633 32.047 c
  25.541 +671.633 32.047 l
  25.542 +C
  25.543 +S 0 0 1 r f R
  25.544 +
  25.545 +N
  25.546 +735.918 32.047 m
  25.547 +735.918 32.047 l
  25.548 +735.918 24.8165 741.781 18.9493 749.012 18.9493 c
  25.549 +756.242 18.9493 762.106 24.8165 762.106 32.047 c
  25.550 +762.106 39.2775 756.242 45.1407 749.012 45.1407 c
  25.551 +741.781 45.1407 735.918 39.2775 735.918 32.047 c
  25.552 +735.918 32.047 l
  25.553 +C
  25.554 +S 0 0 0 r f R
  25.555 +
  25.556 +N
  25.557 +737.105 32.047 m
  25.558 +737.105 32.047 l
  25.559 +737.105 25.4728 742.437 20.1407 749.012 20.1407 c
  25.560 +755.586 20.1407 760.914 25.4728 760.914 32.047 c
  25.561 +760.914 38.6212 755.586 43.9493 749.012 43.9493 c
  25.562 +742.437 43.9493 737.105 38.6212 737.105 32.047 c
  25.563 +737.105 32.047 l
  25.564 +C
  25.565 +S 0 0 1 r f R
  25.566 +
  25.567 +N
  25.568 +801.391 32.047 m
  25.569 +801.391 32.047 l
  25.570 +801.391 24.8165 807.254 18.9493 814.484 18.9493 c
  25.571 +821.715 18.9493 827.578 24.8165 827.578 32.047 c
  25.572 +827.578 39.2775 821.715 45.1407 814.484 45.1407 c
  25.573 +807.254 45.1407 801.391 39.2775 801.391 32.047 c
  25.574 +801.391 32.047 l
  25.575 +C
  25.576 +S 0 0 0 r f R
  25.577 +
  25.578 +N
  25.579 +802.582 32.047 m
  25.580 +802.582 32.047 l
  25.581 +802.582 25.4728 807.91 20.1407 814.484 20.1407 c
  25.582 +821.059 20.1407 826.387 25.4728 826.387 32.047 c
  25.583 +826.387 38.6212 821.059 43.9493 814.484 43.9493 c
  25.584 +807.91 43.9493 802.582 38.6212 802.582 32.047 c
  25.585 +802.582 32.047 l
  25.586 +C
  25.587 +S 0.5 0.5 1 r f R
  25.588 +
  25.589 +%%EOF
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/doc/images/bipartite_partitions.eps	Thu Nov 05 15:50:01 2009 +0100
    26.3 @@ -0,0 +1,114 @@
    26.4 +%!PS-Adobe-2.0 EPSF-2.0
    26.5 +%%Creator: LEMON, graphToEps()
    26.6 +%%CreationDate: Tue Nov 15 16:51:43 2005
    26.7 +%%BoundingBox: 0 0 842 596
    26.8 +%%EndComments
    26.9 +/lb { setlinewidth setrgbcolor newpath moveto
   26.10 +      4 2 roll 1 index 1 index curveto stroke } bind def
   26.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
   26.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
   26.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
   26.14 +      2 index 1 index sub 2 index 2 index add lineto
   26.15 +      2 index 1 index sub 2 index 2 index sub lineto
   26.16 +      2 index 1 index add 2 index 2 index sub lineto
   26.17 +      closepath pop pop pop} bind def
   26.18 +/di { newpath 2 index 1 index add 2 index moveto
   26.19 +      2 index             2 index 2 index add lineto
   26.20 +      2 index 1 index sub 2 index             lineto
   26.21 +      2 index             2 index 2 index sub lineto
   26.22 +      closepath pop pop pop} bind def
   26.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
   26.24 +     setrgbcolor 1.1 div c fill
   26.25 +   } bind def
   26.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
   26.27 +     setrgbcolor 1.1 div sq fill
   26.28 +   } bind def
   26.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
   26.30 +     setrgbcolor 1.1 div di fill
   26.31 +   } bind def
   26.32 +/arrl 1 def
   26.33 +/arrw 0.3 def
   26.34 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
   26.35 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
   26.36 +       /w exch def /len exch def
   26.37 +       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
   26.38 +       len w sub arrl sub dx dy lrl
   26.39 +       arrw dy dx neg lrl
   26.40 +       dx arrl w add mul dy w 2 div arrw add mul sub
   26.41 +       dy arrl w add mul dx w 2 div arrw add mul add rlineto
   26.42 +       dx arrl w add mul neg dy w 2 div arrw add mul sub
   26.43 +       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
   26.44 +       arrw dy dx neg lrl
   26.45 +       len w sub arrl sub neg dx dy lrl
   26.46 +       closepath fill } bind def
   26.47 +/cshow { 2 index 2 index moveto dup stringwidth pop
   26.48 +         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
   26.49 +
   26.50 +gsave
   26.51 +90 rotate
   26.52 +0 -842 translate
   26.53 +71.6378 15 translate
   26.54 +0.389093 dup scale
   26.55 +90 rotate
   26.56 +1197.47 -613.138 translate
   26.57 +%Edges:
   26.58 +gsave
   26.59 +513.857 -446.322 296.569 -487.43 79.2808 -528.539 0 0 0 2 lb
   26.60 +513.857 -446.322 575.52 -315.655 637.183 -184.989 0 0 0 2 lb
   26.61 +393.468 566.711 494.771 434.577 596.074 302.442 0 0 0 2 lb
   26.62 +393.468 566.711 155.625 579.925 -82.2171 593.138 0 0 0 2 lb
   26.63 +393.468 566.711 251.056 450.726 108.644 334.741 0 0 0 2 lb
   26.64 +869.153 52.8539 732.613 177.648 596.074 302.442 0 0 0 2 lb
   26.65 +869.153 52.8539 753.168 -66.0676 637.183 -184.989 0 0 0 2 lb
   26.66 +-82.2171 593.138 -91.0261 346.487 -99.8351 99.8351 0 0 0 2 lb
   26.67 +-663.61 546.157 -753.168 394.936 -842.726 243.715 0 0 0 2 lb
   26.68 +-663.61 546.157 -574.052 437.513 -484.494 328.869 0 0 0 2 lb
   26.69 +-1077.63 161.498 -960.178 202.606 -842.726 243.715 0 0 0 2 lb
   26.70 +-1077.63 161.498 -968.987 66.0674 -860.344 -29.3633 0 0 0 2 lb
   26.71 +-1177.47 -234.906 -1029.18 -381.722 -880.898 -528.539 0 0 0 2 lb
   26.72 +-1177.47 -234.906 -1018.91 -132.135 -860.344 -29.3633 0 0 0 2 lb
   26.73 +-880.898 -528.539 -744.359 -387.595 -607.82 -246.651 0 0 0 2 lb
   26.74 +-499.175 -499.175 -355.295 -475.685 -211.415 -452.194 0 0 0 2 lb
   26.75 +-499.175 -499.175 -553.498 -372.913 -607.82 -246.651 0 0 0 2 lb
   26.76 +-499.175 -499.175 -386.587 -315.087 -274 -131 0 0 0 2 lb
   26.77 +79.2808 -528.539 -66.0671 -490.366 -211.415 -452.194 0 0 0 2 lb
   26.78 +637.183 -184.989 421.363 -253.993 205.543 -322.996 0 0 0 2 lb
   26.79 +205.543 -322.996 162.966 -226.097 120.389 -129.198 0 0 0 2 lb
   26.80 +399.34 88.0898 259.865 -20.5541 120.389 -129.198 0 0 0 2 lb
   26.81 +399.34 88.0898 253.992 211.415 108.644 334.741 0 0 0 2 lb
   26.82 +-842.726 243.715 -471.281 171.775 -99.8351 99.8351 0 0 0 2 lb
   26.83 +-842.726 243.715 -558.363 56.3575 -274 -131 0 0 0 2 lb
   26.84 +-860.344 -29.3633 -734.082 -138.007 -607.82 -246.651 0 0 0 2 lb
   26.85 +-211.415 -452.194 -45.513 -290.696 120.389 -129.198 0 0 0 2 lb
   26.86 +-99.8351 99.8351 4.40445 217.288 108.644 334.741 0 0 0 2 lb
   26.87 +-99.8351 99.8351 -292.165 214.352 -484.494 328.869 0 0 0 2 lb
   26.88 +120.389 -129.198 -76.8055 -130.099 -274 -131 0 0 0 2 lb
   26.89 +grestore
   26.90 +%Nodes:
   26.91 +gsave
   26.92 +-274 -131 20 1 0 0 nc
   26.93 +-607.82 -246.651 20 1 0 0 nc
   26.94 +-484.494 328.869 20 0 0 1 nc
   26.95 +108.644 334.741 20 0 0 1 nc
   26.96 +120.389 -129.198 20 0 0 1 nc
   26.97 +-99.8351 99.8351 20 1 0 0 nc
   26.98 +-211.415 -452.194 20 1 0 0 nc
   26.99 +-860.344 -29.3633 20 0 0 1 nc
  26.100 +-842.726 243.715 20 0 0 1 nc
  26.101 +399.34 88.0898 20 1 0 0 nc
  26.102 +205.543 -322.996 20 1 0 0 nc
  26.103 +637.183 -184.989 20 0 0 1 nc
  26.104 +79.2808 -528.539 20 0 0 1 nc
  26.105 +-499.175 -499.175 20 0 0 1 nc
  26.106 +-880.898 -528.539 20 0 0 1 nc
  26.107 +-1177.47 -234.906 20 1 0 0 nc
  26.108 +-1077.63 161.498 20 1 0 0 nc
  26.109 +-663.61 546.157 20 1 0 0 nc
  26.110 +-82.2171 593.138 20 0 0 1 nc
  26.111 +596.074 302.442 20 0 0 1 nc
  26.112 +869.153 52.8539 20 1 0 0 nc
  26.113 +393.468 566.711 20 1 0 0 nc
  26.114 +513.857 -446.322 20 1 0 0 nc
  26.115 +grestore
  26.116 +grestore
  26.117 +showpage
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/doc/images/connected_components.eps	Thu Nov 05 15:50:01 2009 +0100
    27.3 @@ -0,0 +1,159 @@
    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 +%%BoundingBox: 0 0 842 596
    27.8 +%%EndComments
    27.9 +/lb { setlinewidth setrgbcolor newpath moveto
   27.10 +      4 2 roll 1 index 1 index curveto stroke } bind def
   27.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
   27.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
   27.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
   27.14 +      2 index 1 index sub 2 index 2 index add lineto
   27.15 +      2 index 1 index sub 2 index 2 index sub lineto
   27.16 +      2 index 1 index add 2 index 2 index sub lineto
   27.17 +      closepath pop pop pop} bind def
   27.18 +/di { newpath 2 index 1 index add 2 index moveto
   27.19 +      2 index             2 index 2 index add lineto
   27.20 +      2 index 1 index sub 2 index             lineto
   27.21 +      2 index             2 index 2 index sub lineto
   27.22 +      closepath pop pop pop} bind def
   27.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
   27.24 +     setrgbcolor 1.1 div c fill
   27.25 +   } bind def
   27.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
   27.27 +     setrgbcolor 1.1 div sq fill
   27.28 +   } bind def
   27.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
   27.30 +     setrgbcolor 1.1 div di fill
   27.31 +   } bind def
   27.32 +/arrl 1 def
   27.33 +/arrw 0.3 def
   27.34 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
   27.35 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
   27.36 +       /w exch def /len exch def
   27.37 +       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
   27.38 +       len w sub arrl sub dx dy lrl
   27.39 +       arrw dy dx neg lrl
   27.40 +       dx arrl w add mul dy w 2 div arrw add mul sub
   27.41 +       dy arrl w add mul dx w 2 div arrw add mul add rlineto
   27.42 +       dx arrl w add mul neg dy w 2 div arrw add mul sub
   27.43 +       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
   27.44 +       arrw dy dx neg lrl
   27.45 +       len w sub arrl sub neg dx dy lrl
   27.46 +       closepath fill } bind def
   27.47 +/cshow { 2 index 2 index moveto dup stringwidth pop
   27.48 +         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
   27.49 +
   27.50 +gsave
   27.51 +90 rotate
   27.52 +0 -842 translate
   27.53 +71.0944 15 translate
   27.54 +0.434694 dup scale
   27.55 +90 rotate
   27.56 +860.856 -588.349 translate
   27.57 +%Edges:
   27.58 +gsave
   27.59 +574.035 177.301 622.149 225.748 670.264 274.195 0 0 0 2 lb
   27.60 +694.579 115.483 682.421 194.839 670.264 274.195 0 0 0 2 lb
   27.61 +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 0 2 lb
   27.62 +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 0 2 lb
   27.63 +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 0 2 lb
   27.64 +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 0 2 lb
   27.65 +286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 0 2 lb
   27.66 +438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 0 2 lb
   27.67 +438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 0 2 lb
   27.68 +397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 0 2 lb
   27.69 +366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 0 2 lb
   27.70 +271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 0 2 lb
   27.71 +271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 0 2 lb
   27.72 +277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 0 2 lb
   27.73 +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0 0 2 lb
   27.74 +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0 2 lb
   27.75 +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0 2 lb
   27.76 +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0 2 lb
   27.77 +906.312 201.403 946.592 42.798 986.873 -115.807 0 0 0 2 lb
   27.78 +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 0 2 lb
   27.79 +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 0 2 lb
   27.80 +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0 0 0 2 lb
   27.81 +422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 0 2 lb
   27.82 +422.945 521.129 376.371 417.911 329.797 314.692 0 0 0 2 lb
   27.83 +422.945 521.129 474.554 276.928 526.164 32.7279 0 0 0 2 lb
   27.84 +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 0 2 lb
   27.85 +329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 0 2 lb
   27.86 +-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 0 2 lb
   27.87 +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 0 2 lb
   27.88 +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 0 2 lb
   27.89 +526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 0 2 lb
   27.90 +730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 0 2 lb
   27.91 +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 0 0 0 2 lb
   27.92 +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 0 2 lb
   27.93 +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 0 2 lb
   27.94 +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 0 2 lb
   27.95 +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 0 2 lb
   27.96 +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 0 2 lb
   27.97 +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 0 2 lb
   27.98 +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 0 2 lb
   27.99 +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 0 2 lb
  27.100 +116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 0 2 lb
  27.101 +-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 0 2 lb
  27.102 +-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 0 2 lb
  27.103 +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 0 2 lb
  27.104 +-180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 0 2 lb
  27.105 +-180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 0 2 lb
  27.106 +-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 0 2 lb
  27.107 +-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 0 2 lb
  27.108 +-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 0 2 lb
  27.109 +670.264 274.195 629.188 409.347 588.113 544.499 0 0 0 2 lb
  27.110 +670.264 274.195 797.466 341.771 924.667 409.347 0 0 0 2 lb
  27.111 +588.113 544.499 756.39 476.923 924.667 409.347 0 0 0 2 lb
  27.112 +-689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 0 2 lb
  27.113 +-689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 0 2 lb
  27.114 +grestore
  27.115 +%Nodes:
  27.116 +gsave
  27.117 +-567.302 43.6423 20 0 0 0 nc
  27.118 +-689.204 -237.261 20 0 0 0 nc
  27.119 +924.667 409.347 20 1 0 0 nc
  27.120 +588.113 544.499 20 1 0 0 nc
  27.121 +670.264 274.195 20 1 0 0 nc
  27.122 +-371.2 568.349 20 0 1 0 nc
  27.123 +-132.697 451.748 20 0 1 0 nc
  27.124 +-416.25 345.746 20 0 1 0 nc
  27.125 +-180.397 245.045 20 0 1 0 nc
  27.126 +-13.4452 133.743 20 0 1 0 nc
  27.127 +-262.548 107.243 20 0 1 0 nc
  27.128 +201.208 38.3422 20 0 1 0 nc
  27.129 +116.407 -173.66 20 0 1 0 nc
  27.130 +-26.6953 -19.9585 20 0 1 0 nc
  27.131 +-539.894 -262.64 20 0 0 1 nc
  27.132 +-323.543 -433.964 20 0 0 1 nc
  27.133 +-309.657 -57.9033 20 0 0 1 nc
  27.134 +-67.9734 -347.42 20 0 0 1 nc
  27.135 +415.393 -289.516 20 0 0 1 nc
  27.136 +730.084 -307.139 20 0 0 1 nc
  27.137 +526.164 32.7279 20 0 0 1 nc
  27.138 +762.812 -17.6227 20 0 0 1 nc
  27.139 +-67.9734 319.727 20 0 0 1 nc
  27.140 +329.797 314.692 20 0 0 1 nc
  27.141 +-5.03507 561.41 20 0 0 1 nc
  27.142 +422.945 521.129 20 0 0 1 nc
  27.143 +-470.779 158.605 20 0 0 1 nc
  27.144 +986.873 -115.807 20 0 0 1 nc
  27.145 +906.312 201.403 20 0 0 1 nc
  27.146 +-767.847 113.289 20 0 0 1 nc
  27.147 +-579.033 445.603 20 0 0 1 nc
  27.148 +-840.856 -246.718 20 0 0 1 nc
  27.149 +206.221 -205.967 20 1 1 0 nc
  27.150 +277.311 -252.33 20 1 1 0 nc
  27.151 +271.13 -175.058 20 1 1 0 nc
  27.152 +366.947 -110.15 20 1 1 0 nc
  27.153 +397.855 -196.694 20 1 1 0 nc
  27.154 +438.037 -88.514 20 1 1 0 nc
  27.155 +286.584 -48.3327 20 1 1 0 nc
  27.156 +212.403 -23.6057 20 1 1 0 nc
  27.157 +280.402 10.3938 20 1 1 0 nc
  27.158 +694.579 115.483 20 1 0 0 nc
  27.159 +574.035 177.301 20 1 0 0 nc
  27.160 +grestore
  27.161 +grestore
  27.162 +showpage
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/doc/images/edge_biconnected_components.eps	Thu Nov 05 15:50:01 2009 +0100
    28.3 @@ -0,0 +1,159 @@
    28.4 +%!PS-Adobe-2.0 EPSF-2.0
    28.5 +%%Creator: LEMON, graphToEps()
    28.6 +%%CreationDate: Fri Nov  4 13:47:12 2005
    28.7 +%%BoundingBox: 0 0 842 596
    28.8 +%%EndComments
    28.9 +/lb { setlinewidth setrgbcolor newpath moveto
   28.10 +      4 2 roll 1 index 1 index curveto stroke } bind def
   28.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
   28.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
   28.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
   28.14 +      2 index 1 index sub 2 index 2 index add lineto
   28.15 +      2 index 1 index sub 2 index 2 index sub lineto
   28.16 +      2 index 1 index add 2 index 2 index sub lineto
   28.17 +      closepath pop pop pop} bind def
   28.18 +/di { newpath 2 index 1 index add 2 index moveto
   28.19 +      2 index             2 index 2 index add lineto
   28.20 +      2 index 1 index sub 2 index             lineto
   28.21 +      2 index             2 index 2 index sub lineto
   28.22 +      closepath pop pop pop} bind def
   28.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
   28.24 +     setrgbcolor 1.1 div c fill
   28.25 +   } bind def
   28.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
   28.27 +     setrgbcolor 1.1 div sq fill
   28.28 +   } bind def
   28.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
   28.30 +     setrgbcolor 1.1 div di fill
   28.31 +   } bind def
   28.32 +/arrl 1 def
   28.33 +/arrw 0.3 def
   28.34 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
   28.35 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
   28.36 +       /w exch def /len exch def
   28.37 +       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
   28.38 +       len w sub arrl sub dx dy lrl
   28.39 +       arrw dy dx neg lrl
   28.40 +       dx arrl w add mul dy w 2 div arrw add mul sub
   28.41 +       dy arrl w add mul dx w 2 div arrw add mul add rlineto
   28.42 +       dx arrl w add mul neg dy w 2 div arrw add mul sub
   28.43 +       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
   28.44 +       arrw dy dx neg lrl
   28.45 +       len w sub arrl sub neg dx dy lrl
   28.46 +       closepath fill } bind def
   28.47 +/cshow { 2 index 2 index moveto dup stringwidth pop
   28.48 +         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
   28.49 +
   28.50 +gsave
   28.51 +90 rotate
   28.52 +0 -842 translate
   28.53 +71.0944 15 translate
   28.54 +0.434694 dup scale
   28.55 +90 rotate
   28.56 +860.856 -588.349 translate
   28.57 +%Edges:
   28.58 +gsave
   28.59 +574.035 177.301 622.149 225.748 670.264 274.195 1 0 0 2 lb
   28.60 +694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 2 lb
   28.61 +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 1 2 lb
   28.62 +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 1 2 lb
   28.63 +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 1 2 lb
   28.64 +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 1 2 lb
   28.65 +286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 1 2 lb
   28.66 +438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 1 2 lb
   28.67 +438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 1 2 lb
   28.68 +397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 1 2 lb
   28.69 +366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 1 2 lb
   28.70 +271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 1 2 lb
   28.71 +271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 1 2 lb
   28.72 +277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 1 2 lb
   28.73 +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 1 0 0 2 lb
   28.74 +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 1 2 lb
   28.75 +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 1 2 lb
   28.76 +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 1 2 lb
   28.77 +906.312 201.403 946.592 42.798 986.873 -115.807 0 0 1 2 lb
   28.78 +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 1 2 lb
   28.79 +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 1 2 lb
   28.80 +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 1 0 0 2 lb
   28.81 +422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 1 2 lb
   28.82 +422.945 521.129 376.371 417.911 329.797 314.692 0 0 1 2 lb
   28.83 +422.945 521.129 474.554 276.928 526.164 32.7279 0 0 1 2 lb
   28.84 +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 1 2 lb
   28.85 +329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 1 2 lb
   28.86 +-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 1 2 lb
   28.87 +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 1 2 lb
   28.88 +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 1 2 lb
   28.89 +526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 1 2 lb
   28.90 +730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 1 2 lb
   28.91 +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0 0 2 lb
   28.92 +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 1 2 lb
   28.93 +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 1 2 lb
   28.94 +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 1 2 lb
   28.95 +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 1 2 lb
   28.96 +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 1 2 lb
   28.97 +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 1 2 lb
   28.98 +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 1 2 lb
   28.99 +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 1 2 lb
  28.100 +116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 1 2 lb
  28.101 +-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 1 2 lb
  28.102 +-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 1 2 lb
  28.103 +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 1 2 lb
  28.104 +-180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 1 2 lb
  28.105 +-180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 1 2 lb
  28.106 +-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 1 2 lb
  28.107 +-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 1 2 lb
  28.108 +-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 1 2 lb
  28.109 +670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 2 lb
  28.110 +670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 2 lb
  28.111 +588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 2 lb
  28.112 +-689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 1 2 lb
  28.113 +-689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 1 2 lb
  28.114 +grestore
  28.115 +%Nodes:
  28.116 +gsave
  28.117 +-567.302 43.6423 20 0 0 0 nc
  28.118 +-689.204 -237.261 20 0 0 0 nc
  28.119 +924.667 409.347 20 0 0 1 nc
  28.120 +588.113 544.499 20 0 0 1 nc
  28.121 +670.264 274.195 20 0 0 1 nc
  28.122 +-371.2 568.349 20 1 1 0 nc
  28.123 +-132.697 451.748 20 1 1 0 nc
  28.124 +-416.25 345.746 20 1 1 0 nc
  28.125 +-180.397 245.045 20 1 1 0 nc
  28.126 +-13.4452 133.743 20 1 1 0 nc
  28.127 +-262.548 107.243 20 1 1 0 nc
  28.128 +201.208 38.3422 20 1 1 0 nc
  28.129 +116.407 -173.66 20 1 1 0 nc
  28.130 +-26.6953 -19.9585 20 1 1 0 nc
  28.131 +-539.894 -262.64 20 0 0.5 0 nc
  28.132 +-323.543 -433.964 20 0 0.5 0 nc
  28.133 +-309.657 -57.9033 20 0 0.5 0 nc
  28.134 +-67.9734 -347.42 20 0 0.5 0 nc
  28.135 +415.393 -289.516 20 0.5 0 0 nc
  28.136 +730.084 -307.139 20 0.5 0 0 nc
  28.137 +526.164 32.7279 20 0.5 0 0 nc
  28.138 +762.812 -17.6227 20 0.5 0 0 nc
  28.139 +-67.9734 319.727 20 0.5 0 0 nc
  28.140 +329.797 314.692 20 0.5 0 0 nc
  28.141 +-5.03507 561.41 20 0.5 0 0 nc
  28.142 +422.945 521.129 20 0.5 0 0 nc
  28.143 +-470.779 158.605 20 0 1 1 nc
  28.144 +986.873 -115.807 20 0.5 0 0 nc
  28.145 +906.312 201.403 20 0.5 0 0 nc
  28.146 +-767.847 113.289 20 0 1 1 nc
  28.147 +-579.033 445.603 20 0 1 1 nc
  28.148 +-840.856 -246.718 20 1 0 1 nc
  28.149 +206.221 -205.967 20 0 0 0.5 nc
  28.150 +277.311 -252.33 20 0 0 0.5 nc
  28.151 +271.13 -175.058 20 0 0 0.5 nc
  28.152 +366.947 -110.15 20 0 0 0.5 nc
  28.153 +397.855 -196.694 20 0 0 0.5 nc
  28.154 +438.037 -88.514 20 0 0 0.5 nc
  28.155 +286.584 -48.3327 20 0 0 0.5 nc
  28.156 +212.403 -23.6057 20 0 0 0.5 nc
  28.157 +280.402 10.3938 20 0 0 0.5 nc
  28.158 +694.579 115.483 20 1 0 0 nc
  28.159 +574.035 177.301 20 0 1 0 nc
  28.160 +grestore
  28.161 +grestore
  28.162 +showpage
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/doc/images/grid_graph.eps	Thu Nov 05 15:50:01 2009 +0100
    29.3 @@ -0,0 +1,286 @@
    29.4 +%!PS-Adobe-2.0 EPSF-2.0
    29.5 +%%Title: Grid undirected graph
    29.6 +%%Copyright: (C) 2006 LEMON Project
    29.7 +%%Creator: LEMON, graphToEps()
    29.8 +%%CreationDate: Fri Sep 29 11:55:56 2006
    29.9 +%%BoundingBox: 0 0 985 1144
   29.10 +%%EndComments
   29.11 +/lb { setlinewidth setrgbcolor newpath moveto
   29.12 +      4 2 roll 1 index 1 index curveto stroke } bind def
   29.13 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
   29.14 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
   29.15 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
   29.16 +      2 index 1 index sub 2 index 2 index add lineto
   29.17 +      2 index 1 index sub 2 index 2 index sub lineto
   29.18 +      2 index 1 index add 2 index 2 index sub lineto
   29.19 +      closepath pop pop pop} bind def
   29.20 +/di { newpath 2 index 1 index add 2 index moveto
   29.21 +      2 index             2 index 2 index add lineto
   29.22 +      2 index 1 index sub 2 index             lineto
   29.23 +      2 index             2 index 2 index sub lineto
   29.24 +      closepath pop pop pop} bind def
   29.25 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
   29.26 +     setrgbcolor 1.1 div c fill
   29.27 +   } bind def
   29.28 +/arrl 1 def
   29.29 +/arrw 0.3 def
   29.30 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
   29.31 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
   29.32 +       /w exch def /len exch def
   29.33 +       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
   29.34 +       len w sub arrl sub dx dy lrl
   29.35 +       arrw dy dx neg lrl
   29.36 +       dx arrl w add mul dy w 2 div arrw add mul sub
   29.37 +       dy arrl w add mul dx w 2 div arrw add mul add rlineto
   29.38 +       dx arrl w add mul neg dy w 2 div arrw add mul sub
   29.39 +       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
   29.40 +       arrw dy dx neg lrl
   29.41 +       len w sub arrl sub neg dx dy lrl
   29.42 +       closepath fill } bind def
   29.43 +/cshow { 2 index 2 index moveto dup stringwidth pop
   29.44 +         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
   29.45 +
   29.46 +gsave
   29.47 +2 2 scale
   29.48 +50 40 translate
   29.49 +5.5000 5.5000 scale
   29.50 +% 1.14018 1.14018 translate
   29.51 +%Edges:
   29.52 +gsave
   29.53 +70 80 70 90 0 0 0 0.5000 l
   29.54 +70 70 70 80 0 0 0 0.5000 l
   29.55 +70 60 70 70 0 0 0 0.5000 l
   29.56 +70 50 70 60 0 0 0 0.5000 l
   29.57 +70 40 70 50 0 0 0 0.5000 l
   29.58 +70 30 70 40 0 0 0 0.5000 l
   29.59 +70 20 70 30 0 0 0 0.5000 l
   29.60 +70 10 70 20 0 0 0 0.5000 l
   29.61 +70 0 70 10 0 0 0 0.5000 l
   29.62 +60 80 60 90 0 0 0 0.5000 l
   29.63 +60 70 60 80 0 0 0 0.5000 l
   29.64 +60 60 60 70 0 0 0 0.5000 l
   29.65 +60 50 60 60 0 0 0 0.5000 l
   29.66 +60 40 60 50 0 0 0 0.5000 l
   29.67 +60 30 60 40 0 0 0 0.5000 l
   29.68 +60 20 60 30 0 0 0 0.5000 l
   29.69 +60 10 60 20 0 0 0 0.5000 l
   29.70 +60 0 60 10 0 0 0 0.5000 l
   29.71 +50 80 50 90 0 0 0 0.5000 l
   29.72 +50 70 50 80 0 0 0 0.5000 l
   29.73 +50 60 50 70 0 0 0 0.5000 l
   29.74 +50 50 50 60 0 0 0 0.5000 l
   29.75 +50 40 50 50 0 0 0 0.5000 l
   29.76 +50 30 50 40 0 0 0 0.5000 l
   29.77 +50 20 50 30 0 0 0 0.5000 l
   29.78 +50 10 50 20 0 0 0 0.5000 l
   29.79 +50 0 50 10 0 0 0 0.5000 l
   29.80 +40 80 40 90 0 0 0 0.5000 l
   29.81 +40 70 40 80 0 0 0 0.5000 l
   29.82 +40 60 40 70 0 0 0 0.5000 l
   29.83 +40 50 40 60 0 0 0 0.5000 l
   29.84 +40 40 40 50 0 0 0 0.5000 l
   29.85 +40 30 40 40 0 0 0 0.5000 l
   29.86 +40 20 40 30 0 0 0 0.5000 l
   29.87 +40 10 40 20 0 0 0 0.5000 l
   29.88 +40 0 40 10 0 0 0 0.5000 l
   29.89 +30 80 30 90 0 0 0 0.5000 l
   29.90 +30 70 30 80 0 0 0 0.5000 l
   29.91 +30 60 30 70 0 0 0 0.5000 l
   29.92 +30 50 30 60 0 0 0 0.5000 l
   29.93 +30 40 30 50 0 0 0 0.5000 l
   29.94 +30 30 30 40 0 0 0 0.5000 l
   29.95 +30 20 30 30 0 0 0 0.5000 l
   29.96 +30 10 30 20 0 0 0 0.5000 l
   29.97 +30 0 30 10 0 0 0 0.5000 l
   29.98 +20 80 20 90 0 0 0 0.5000 l
   29.99 +20 70 20 80 0 0 0 0.5000 l
  29.100 +20 60 20 70 0 0 0 0.5000 l
  29.101 +20 50 20 60 0 0 0 0.5000 l
  29.102 +20 40 20 50 0 0 0 0.5000 l
  29.103 +20 30 20 40 0 0 0 0.5000 l
  29.104 +20 20 20 30 0 0 0 0.5000 l
  29.105 +20 10 20 20 0 0 0 0.5000 l
  29.106 +20 0 20 10 0 0 0 0.5000 l
  29.107 +10 80 10 90 0 0 0 0.5000 l
  29.108 +10 70 10 80 0 0 0 0.5000 l
  29.109 +10 60 10 70 0 0 0 0.5000 l
  29.110 +10 50 10 60 0 0 0 0.5000 l
  29.111 +10 40 10 50 0 0 0 0.5000 l
  29.112 +10 30 10 40 0 0 0 0.5000 l
  29.113 +10 20 10 30 0 0 0 0.5000 l
  29.114 +10 10 10 20 0 0 0 0.5000 l
  29.115 +10 0 10 10 0 0 0 0.5000 l
  29.116 +0 80 0 90 0 0 0 0.5000 l
  29.117 +0 70 0 80 0 0 0 0.5000 l
  29.118 +0 60 0 70 0 0 0 0.5000 l
  29.119 +0 50 0 60 0 0 0 0.5000 l
  29.120 +0 40 0 50 0 0 0 0.5000 l
  29.121 +0 30 0 40 0 0 0 0.5000 l
  29.122 +0 20 0 30 0 0 0 0.5000 l
  29.123 +0 10 0 20 0 0 0 0.5000 l
  29.124 +0 0 0 10 0 0 0 0.5000 l
  29.125 +60 90 70 90 0 0 0 0.5000 l
  29.126 +60 80 70 80 0 0 0 0.5000 l
  29.127 +60 70 70 70 0 0 0 0.5000 l
  29.128 +60 60 70 60 0 0 0 0.5000 l
  29.129 +60 50 70 50 0 0 0 0.5000 l
  29.130 +60 40 70 40 0 0 0 0.5000 l
  29.131 +60 30 70 30 0 0 0 0.5000 l
  29.132 +60 20 70 20 0 0 0 0.5000 l
  29.133 +60 10 70 10 0 0 0 0.5000 l
  29.134 +60 0 70 0 0 0 0 0.5000 l
  29.135 +50 90 60 90 0 0 0 0.5000 l
  29.136 +50 80 60 80 0 0 0 0.5000 l
  29.137 +50 70 60 70 0 0 0 0.5000 l
  29.138 +50 60 60 60 0 0 0 0.5000 l
  29.139 +50 50 60 50 0 0 0 0.5000 l
  29.140 +50 40 60 40 0 0 0 0.5000 l
  29.141 +50 30 60 30 0 0 0 0.5000 l
  29.142 +50 20 60 20 0 0 0 0.5000 l
  29.143 +50 10 60 10 0 0 0 0.5000 l
  29.144 +50 0 60 0 0 0 0 0.5000 l
  29.145 +40 90 50 90 0 0 0 0.5000 l
  29.146 +40 80 50 80 0 0 0 0.5000 l
  29.147 +40 70 50 70 0 0 0 0.5000 l
  29.148 +40 60 50 60 0 0 0 0.5000 l
  29.149 +40 50 50 50 0 0 0 0.5000 l
  29.150 +40 40 50 40 0 0 0 0.5000 l
  29.151 +40 30 50 30 0 0 0 0.5000 l
  29.152 +40 20 50 20 0 0 0 0.5000 l
  29.153 +40 10 50 10 0 0 0 0.5000 l
  29.154 +40 0 50 0 0 0 0 0.5000 l
  29.155 +30 90 40 90 0 0 0 0.5000 l
  29.156 +30 80 40 80 0 0 0 0.5000 l
  29.157 +30 70 40 70 0 0 0 0.5000 l
  29.158 +30 60 40 60 0 0 0 0.5000 l
  29.159 +30 50 40 50 0 0 0 0.5000 l
  29.160 +30 40 40 40 0 0 0 0.5000 l
  29.161 +30 30 40 30 0 0 0 0.5000 l
  29.162 +30 20 40 20 0 0 0 0.5000 l
  29.163 +30 10 40 10 0 0 0 0.5000 l
  29.164 +30 0 40 0 0 0 0 0.5000 l
  29.165 +20 90 30 90 0 0 0 0.5000 l
  29.166 +20 80 30 80 0 0 0 0.5000 l
  29.167 +20 70 30 70 0 0 0 0.5000 l
  29.168 +20 60 30 60 0 0 0 0.5000 l
  29.169 +20 50 30 50 0 0 0 0.5000 l
  29.170 +20 40 30 40 0 0 0 0.5000 l
  29.171 +20 30 30 30 0 0 0 0.5000 l
  29.172 +20 20 30 20 0 0 0 0.5000 l
  29.173 +20 10 30 10 0 0 0 0.5000 l
  29.174 +20 0 30 0 0 0 0 0.5000 l
  29.175 +10 90 20 90 0 0 0 0.5000 l
  29.176 +10 80 20 80 0 0 0 0.5000 l
  29.177 +10 70 20 70 0 0 0 0.5000 l
  29.178 +10 60 20 60 0 0 0 0.5000 l
  29.179 +10 50 20 50 0 0 0 0.5000 l
  29.180 +10 40 20 40 0 0 0 0.5000 l
  29.181 +10 30 20 30 0 0 0 0.5000 l
  29.182 +10 20 20 20 0 0 0 0.5000 l
  29.183 +10 10 20 10 0 0 0 0.5000 l
  29.184 +10 0 20 0 0 0 0 0.5000 l
  29.185 +0 90 10 90 0 0 0 0.5000 l
  29.186 +0 80 10 80 0 0 0 0.5000 l
  29.187 +0 70 10 70 0 0 0 0.5000 l
  29.188 +0 60 10 60 0 0 0 0.5000 l
  29.189 +0 50 10 50 0 0 0 0.5000 l
  29.190 +0 40 10 40 0 0 0 0.5000 l
  29.191 +0 30 10 30 0 0 0 0.5000 l
  29.192 +0 20 10 20 0 0 0 0.5000 l
  29.193 +0 10 10 10 0 0 0 0.5000 l
  29.194 +0 0 10 0 0 0 0 0.5000 l
  29.195 +grestore
  29.196 +%Nodes:
  29.197 +gsave
  29.198 +70 90 1.4000 0 0 0 nc
  29.199 +70 80 1.4000 1 1 1 nc
  29.200 +70 70 1.4000 1 1 1 nc
  29.201 +70 60 1.4000 1 1 1 nc
  29.202 +70 50 1.4000 1 1 1 nc
  29.203 +70 40 1.4000 1 1 1 nc
  29.204 +70 30 1.4000 1 1 1 nc
  29.205 +70 20 1.4000 1 1 1 nc
  29.206 +70 10 1.4000 1 1 1 nc
  29.207 +70 0 1.4000 0 0 0 nc
  29.208 +60 90 1.4000 1 1 1 nc
  29.209 +60 80 1.4000 1 1 1 nc
  29.210 +60 70 1.4000 1 1 1 nc
  29.211 +60 60 1.4000 1 1 1 nc
  29.212 +60 50 1.4000 1 1 1 nc
  29.213 +60 40 1.4000 1 1 1 nc
  29.214 +60 30 1.4000 1 1 1 nc
  29.215 +60 20 1.4000 1 1 1 nc
  29.216 +60 10 1.4000 1 1 1 nc
  29.217 +60 0 1.4000 1 1 1 nc
  29.218 +50 90 1.4000 1 1 1 nc
  29.219 +50 80 1.4000 1 1 1 nc
  29.220 +50 70 1.4000 1 1 1 nc
  29.221 +50 60 1.4000 1 1 1 nc
  29.222 +50 50 1.4000 1 1 1 nc
  29.223 +50 40 1.4000 1 1 1 nc
  29.224 +50 30 1.4000 1 1 1 nc
  29.225 +50 20 1.4000 1 1 1 nc
  29.226 +50 10 1.4000 1 1 1 nc
  29.227 +50 0 1.4000 1 1 1 nc
  29.228 +40 90 1.4000 1 1 1 nc
  29.229 +40 80 1.4000 1 1 1 nc
  29.230 +40 70 1.4000 1 1 1 nc
  29.231 +40 60 1.4000 1 1 1 nc
  29.232 +40 50 1.4000 1 1 1 nc
  29.233 +40 40 1.4000 1 1 1 nc
  29.234 +40 30 1.4000 1 1 1 nc
  29.235 +40 20 1.4000 1 1 1 nc
  29.236 +40 10 1.4000 1 1 1 nc
  29.237 +40 0 1.4000 1 1 1 nc
  29.238 +30 90 1.4000 1 1 1 nc
  29.239 +30 80 1.4000 1 1 1 nc
  29.240 +30 70 1.4000 1 1 1 nc
  29.241 +30 60 1.4000 1 1 1 nc
  29.242 +30 50 1.4000 1 1 1 nc
  29.243 +30 40 1.4000 1 1 1 nc
  29.244 +30 30 1.4000 1 1 1 nc
  29.245 +30 20 1.4000 1 1 1 nc
  29.246 +30 10 1.4000 1 1 1 nc
  29.247 +30 0 1.4000 1 1 1 nc
  29.248 +20 90 1.4000 1 1 1 nc
  29.249 +20 80 1.4000 1 1 1 nc
  29.250 +20 70 1.4000 1 1 1 nc
  29.251 +20 60 1.4000 1 1 1 nc
  29.252 +20 50 1.4000 1 1 1 nc
  29.253 +20 40 1.4000 1 1 1 nc
  29.254 +20 30 1.4000 1 1 1 nc
  29.255 +20 20 1.4000 1 1 1 nc
  29.256 +20 10 1.4000 1 1 1 nc
  29.257 +20 0 1.4000 1 1 1 nc
  29.258 +10 90 1.4000 1 1 1 nc
  29.259 +10 80 1.4000 1 1 1 nc
  29.260 +10 70 1.4000 1 1 1 nc
  29.261 +10 60 1.4000 1 1 1 nc
  29.262 +10 50 1.4000 1 1 1 nc
  29.263 +10 40 1.4000 1 1 1 nc
  29.264 +10 30 1.4000 1 1 1 nc
  29.265 +10 20 1.4000 1 1 1 nc
  29.266 +10 10 1.4000 1 1 1 nc
  29.267 +10 0 1.4000 1 1 1 nc
  29.268 +0 90 1.4000 0 0 0 nc
  29.269 +0 80 1.4000 1 1 1 nc
  29.270 +0 70 1.4000 1 1 1 nc
  29.271 +0 60 1.4000 1 1 1 nc
  29.272 +0 50 1.4000 1 1 1 nc
  29.273 +0 40 1.4000 1 1 1 nc
  29.274 +0 30 1.4000 1 1 1 nc
  29.275 +0 20 1.4000 1 1 1 nc
  29.276 +0 10 1.4000 1 1 1 nc
  29.277 +0 0 1.4000 0 0 0 nc
  29.278 +grestore
  29.279 +gsave
  29.280 +/fosi 3.5 def
  29.281 +(Helvetica) findfont fosi scalefont setfont
  29.282 +0 0 0 setrgbcolor
  29.283 +0 95 ((0,height-1)) cshow
  29.284 +67 95 ((width-1,height-1)) cshow
  29.285 +0 -5 ((0,0)) cshow
  29.286 +70 -5 ((width-1,0)) cshow
  29.287 +grestore
  29.288 +grestore
  29.289 +showpage
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/doc/images/node_biconnected_components.eps	Thu Nov 05 15:50:01 2009 +0100
    30.3 @@ -0,0 +1,159 @@
    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 +%%BoundingBox: 0 0 842 596
    30.8 +%%EndComments
    30.9 +/lb { setlinewidth setrgbcolor newpath moveto
   30.10 +      4 2 roll 1 index 1 index curveto stroke } bind def
   30.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
   30.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
   30.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
   30.14 +      2 index 1 index sub 2 index 2 index add lineto
   30.15 +      2 index 1 index sub 2 index 2 index sub lineto
   30.16 +      2 index 1 index add 2 index 2 index sub lineto
   30.17 +      closepath pop pop pop} bind def
   30.18 +/di { newpath 2 index 1 index add 2 index moveto
   30.19 +      2 index             2 index 2 index add lineto
   30.20 +      2 index 1 index sub 2 index             lineto
   30.21 +      2 index             2 index 2 index sub lineto
   30.22 +      closepath pop pop pop} bind def
   30.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
   30.24 +     setrgbcolor 1.1 div c fill
   30.25 +   } bind def
   30.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
   30.27 +     setrgbcolor 1.1 div sq fill
   30.28 +   } bind def
   30.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
   30.30 +     setrgbcolor 1.1 div di fill
   30.31 +   } bind def
   30.32 +/arrl 1 def
   30.33 +/arrw 0.3 def
   30.34 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
   30.35 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
   30.36 +       /w exch def /len exch def
   30.37 +       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
   30.38 +       len w sub arrl sub dx dy lrl
   30.39 +       arrw dy dx neg lrl
   30.40 +       dx arrl w add mul dy w 2 div arrw add mul sub
   30.41 +       dy arrl w add mul dx w 2 div arrw add mul add rlineto
   30.42 +       dx arrl w add mul neg dy w 2 div arrw add mul sub
   30.43 +       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
   30.44 +       arrw dy dx neg lrl
   30.45 +       len w sub arrl sub neg dx dy lrl
   30.46 +       closepath fill } bind def
   30.47 +/cshow { 2 index 2 index moveto dup stringwidth pop
   30.48 +         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
   30.49 +
   30.50 +gsave
   30.51 +90 rotate
   30.52 +0 -842 translate
   30.53 +71.0944 15 translate
   30.54 +0.434694 dup scale
   30.55 +90 rotate
   30.56 +860.856 -588.349 translate
   30.57 +%Edges:
   30.58 +gsave
   30.59 +574.035 177.301 622.149 225.748 670.264 274.195 0 1 0 5 lb
   30.60 +694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 5 lb
   30.61 +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 1 1 0.5 5 lb
   30.62 +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 1 1 0.5 5 lb
   30.63 +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 1 1 0.5 5 lb
   30.64 +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 1 0.5 1 5 lb
   30.65 +286.584 -48.3327 278.857 -111.695 271.13 -175.058 1 0.5 1 5 lb
   30.66 +438.037 -88.514 417.946 -142.604 397.855 -196.694 0.5 0.5 1 5 lb
   30.67 +438.037 -88.514 402.492 -99.332 366.947 -110.15 0.5 0.5 1 5 lb
   30.68 +397.855 -196.694 382.401 -153.422 366.947 -110.15 0.5 0.5 1 5 lb
   30.69 +366.947 -110.15 319.038 -142.604 271.13 -175.058 1 0.5 1 5 lb
   30.70 +271.13 -175.058 274.221 -213.694 277.311 -252.33 0.5 1 1 5 lb
   30.71 +271.13 -175.058 238.675 -190.512 206.221 -205.967 0.5 1 1 5 lb
   30.72 +277.311 -252.33 241.766 -229.149 206.221 -205.967 0.5 1 1 5 lb
   30.73 +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0.5 0 5 lb
   30.74 +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0.5 5 lb
   30.75 +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0.5 5 lb
   30.76 +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0.5 5 lb
   30.77 +906.312 201.403 946.592 42.798 986.873 -115.807 0 0.5 0.5 5 lb
   30.78 +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0.5 0.5 5 lb
   30.79 +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0.5 0.5 5 lb
   30.80 +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0.5 0.5 0 5 lb
   30.81 +422.945 521.129 208.955 541.269 -5.03507 561.41 0.5 0 0.5 5 lb
   30.82 +422.945 521.129 376.371 417.911 329.797 314.692 0.5 0 0.5 5 lb
   30.83 +422.945 521.129 474.554 276.928 526.164 32.7279 0.5 0 0.5 5 lb
   30.84 +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0.5 0 0.5 5 lb
   30.85 +329.797 314.692 130.912 317.209 -67.9734 319.727 0.5 0 0.5 5 lb
   30.86 +-67.9734 319.727 229.095 176.227 526.164 32.7279 0.5 0 0.5 5 lb
   30.87 +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0.5 0.5 0.5 5 lb
   30.88 +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0.5 0.5 0.5 5 lb
   30.89 +526.164 32.7279 470.779 -128.394 415.393 -289.516 0.5 0.5 0.5 5 lb
   30.90 +730.084 -307.139 572.738 -298.327 415.393 -289.516 0.5 0.5 0.5 5 lb
   30.91 +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0.5 0.5 5 lb
   30.92 +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0.5 1 0.5 5 lb
   30.93 +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0.5 1 0.5 5 lb
   30.94 +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0.5 1 0.5 5 lb
   30.95 +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0.5 1 0.5 5 lb
   30.96 +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 1 1 0 5 lb
   30.97 +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 1 1 0 5 lb
   30.98 +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 1 0 1 5 lb
   30.99 +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 1 0 1 5 lb
  30.100 +116.407 -173.66 158.808 -67.6589 201.208 38.3422 1 1 0 5 lb
  30.101 +-262.548 107.243 -137.997 120.493 -13.4452 133.743 1 0 1 5 lb
  30.102 +-262.548 107.243 -221.472 176.144 -180.397 245.045 1 0 1 5 lb
  30.103 +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 1 0 1 5 lb
  30.104 +-180.397 245.045 -140.307 344.649 -132.697 451.748 0 1 1 5 lb
  30.105 +-180.397 245.045 -172.787 352.144 -132.697 451.748 0 1 1 5 lb
  30.106 +-416.25 345.746 -274.474 398.747 -132.697 451.748 0.5 0 0 5 lb
  30.107 +-416.25 345.746 -393.725 457.048 -371.2 568.349 0.5 0 0 5 lb
  30.108 +-132.697 451.748 -251.948 510.048 -371.2 568.349 0.5 0 0 5 lb
  30.109 +670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 5 lb
  30.110 +670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 5 lb
  30.111 +588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 5 lb
  30.112 +-689.204 -237.261 -612.964 -103.444 -567.302 43.6423 0 0 0 5 lb
  30.113 +-689.204 -237.261 -643.542 -90.1744 -567.302 43.6423 0 0 0 5 lb
  30.114 +grestore
  30.115 +%Nodes:
  30.116 +gsave
  30.117 +-567.302 43.6423 20 0 0 1 nc
  30.118 +-689.204 -237.261 20 0 0 1 nc
  30.119 +924.667 409.347 20 0 0 1 nc
  30.120 +588.113 544.499 20 0 0 1 nc
  30.121 +670.264 274.195 20 1 0 0 nc
  30.122 +-371.2 568.349 20 0 0 1 nc
  30.123 +-132.697 451.748 20 1 0 0 nc
  30.124 +-416.25 345.746 20 0 0 1 nc
  30.125 +-180.397 245.045 20 1 0 0 nc
  30.126 +-13.4452 133.743 20 0 0 1 nc
  30.127 +-262.548 107.243 20 0 0 1 nc
  30.128 +201.208 38.3422 20 0 0 1 nc
  30.129 +116.407 -173.66 20 0 0 1 nc
  30.130 +-26.6953 -19.9585 20 1 0 0 nc
  30.131 +-539.894 -262.64 20 0 0 1 nc
  30.132 +-323.543 -433.964 20 0 0 1 nc
  30.133 +-309.657 -57.9033 20 1 0 0 nc
  30.134 +-67.9734 -347.42 20 1 0 0 nc
  30.135 +415.393 -289.516 20 1 0 0 nc
  30.136 +730.084 -307.139 20 0 0 1 nc
  30.137 +526.164 32.7279 20 1 0 0 nc
  30.138 +762.812 -17.6227 20 1 0 0 nc
  30.139 +-67.9734 319.727 20 0 0 1 nc
  30.140 +329.797 314.692 20 0 0 1 nc
  30.141 +-5.03507 561.41 20 0 0 1 nc
  30.142 +422.945 521.129 20 0 0 1 nc
  30.143 +-470.779 158.605 20 1 0 0 nc
  30.144 +986.873 -115.807 20 0 0 1 nc
  30.145 +906.312 201.403 20 0 0 1 nc
  30.146 +-767.847 113.289 20 1 0 0 nc
  30.147 +-579.033 445.603 20 0 0 1 nc
  30.148 +-840.856 -246.718 20 0 0 1 nc
  30.149 +206.221 -205.967 20 0 0 1 nc
  30.150 +277.311 -252.33 20 0 0 1 nc
  30.151 +271.13 -175.058 20 1 0 0 nc
  30.152 +366.947 -110.15 20 1 0 0 nc
  30.153 +397.855 -196.694 20 0 0 1 nc
  30.154 +438.037 -88.514 20 0 0 1 nc
  30.155 +286.584 -48.3327 20 1 0 0 nc
  30.156 +212.403 -23.6057 20 0 0 1 nc
  30.157 +280.402 10.3938 20 0 0 1 nc
  30.158 +694.579 115.483 20 0 0 1 nc
  30.159 +574.035 177.301 20 0 0 1 nc
  30.160 +grestore
  30.161 +grestore
  30.162 +showpage
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/doc/images/strongly_connected_components.eps	Thu Nov 05 15:50:01 2009 +0100
    31.3 @@ -0,0 +1,180 @@
    31.4 +%!PS-Adobe-2.0 EPSF-2.0
    31.5 +%%Creator: LEMON, graphToEps()
    31.6 +%%CreationDate: Fri Nov  4 13:47:12 2005
    31.7 +%%BoundingBox: 0 0 842 596
    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 +/arrl 10 def
   31.33 +/arrw 3 def
   31.34 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
   31.35 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
   31.36 +       /w exch def /len exch def
   31.37 +       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
   31.38 +       len w sub arrl sub dx dy lrl
   31.39 +       arrw dy dx neg lrl
   31.40 +       dx arrl w add mul dy w 2 div arrw add mul sub
   31.41 +       dy arrl w add mul dx w 2 div arrw add mul add rlineto
   31.42 +       dx arrl w add mul neg dy w 2 div arrw add mul sub
   31.43 +       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
   31.44 +       arrw dy dx neg lrl
   31.45 +       len w sub arrl sub neg dx dy lrl
   31.46 +       closepath fill } bind def
   31.47 +/cshow { 2 index 2 index moveto dup stringwidth pop
   31.48 +         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
   31.49 +
   31.50 +gsave
   31.51 +90 rotate
   31.52 +0 -842 translate
   31.53 +77.1122 15 translate
   31.54 +0.585745 dup scale
   31.55 +90 rotate
   31.56 +695.963 -397.916 translate
   31.57 +%Edges:
   31.58 +gsave
   31.59 +2 setlinewidth 0 0 1 setrgbcolor newpath
   31.60 +218.178 27.2723 moveto
   31.61 +192.373 -40.1551 188.622 -49.9556 169.228 -100.631 curveto stroke
   31.62 +newpath 164.939 -111.838 moveto 165.492 -99.2013 lineto 172.964 -102.061 lineto closepath fill
   31.63 +2 setlinewidth 0 0 1 setrgbcolor newpath
   31.64 +44.8044 15.5841 moveto
   31.65 +119.293 20.6059 129.775 21.3125 186.25 25.1199 curveto stroke
   31.66 +newpath 198.223 25.927 moveto 186.519 21.1289 lineto 185.981 29.1108 lineto closepath fill
   31.67 +2 setlinewidth 1 0 0 setrgbcolor newpath
   31.68 +218.178 27.2723 moveto
   31.69 +285.395 -87.4449 290.763 -96.6058 348.102 -194.464 curveto stroke
   31.70 +newpath 354.169 -204.818 moveto 344.651 -196.487 lineto 351.554 -192.442 lineto closepath fill
   31.71 +2 setlinewidth 0 0 1 setrgbcolor newpath
   31.72 +157.79 -130.517 moveto
   31.73 +108.71 -67.0521 102.27 -58.7243 64.3804 -9.72954 curveto stroke
   31.74 +newpath 57.0394 -0.236898 moveto 67.5446 -7.28254 lineto 61.2162 -12.1765 lineto closepath fill
   31.75 +2 setlinewidth 1 0 0 setrgbcolor newpath
   31.76 +-105.193 -261.035 moveto
   31.77 +-35.6576 -132.801 -30.5923 -123.459 29.5506 -12.5464 curveto stroke
   31.78 +newpath 35.2708 -1.99743 moveto 33.0669 -14.4531 lineto 26.0343 -10.6397 lineto closepath fill
   31.79 +2 setlinewidth 0 0 1 setrgbcolor newpath
   31.80 +-465.576 -42.8564 moveto
   31.81 +-559.078 -25.5413 -569.47 -23.6169 -644.498 -9.72286 curveto stroke
   31.82 +newpath -656.297 -7.5378 moveto -643.77 -5.78973 lineto -645.226 -13.656 lineto closepath fill
   31.83 +2 setlinewidth 0 0 1 setrgbcolor newpath
   31.84 +-574.666 -153.893 moveto
   31.85 +-528.842 -107.252 -521.515 -99.794 -488.002 -65.683 curveto stroke
   31.86 +newpath -479.592 -57.123 moveto -485.149 -68.4863 lineto -490.856 -62.8797 lineto closepath fill
   31.87 +2 setlinewidth 1 0 0 setrgbcolor newpath
   31.88 +-490.901 120.777 moveto
   31.89 +-480.122 51.1328 -478.519 40.7713 -470.47 -11.2329 curveto stroke
   31.90 +newpath -468.635 -23.0917 moveto -474.423 -11.8447 lineto -466.517 -10.6212 lineto closepath fill
   31.91 +2 setlinewidth 0 0 1 setrgbcolor newpath
   31.92 +-675.963 -3.89604 moveto
   31.93 +-632.116 -68.8235 -626.228 -77.5422 -592.575 -127.374 curveto stroke
   31.94 +newpath -585.859 -137.319 moveto -595.89 -129.612 lineto -589.26 -125.135 lineto closepath fill
   31.95 +2 setlinewidth 0 0 1 setrgbcolor newpath
   31.96 +-490.901 120.777 moveto
   31.97 +-435.445 215.844 -430.107 224.995 -384.3 303.522 curveto stroke
   31.98 +newpath -378.253 313.887 moveto -380.845 301.507 lineto -387.755 305.537 lineto closepath fill
   31.99 +2 setlinewidth 0 0 1 setrgbcolor newpath
  31.100 +-266.879 114.933 moveto
  31.101 +-367.067 117.547 -377.642 117.822 -458.912 119.943 curveto stroke
  31.102 +newpath -470.908 120.255 moveto -458.807 123.941 lineto -459.016 115.944 lineto closepath fill
  31.103 +2 setlinewidth 0 0 1 setrgbcolor newpath
  31.104 +-368.176 331.163 moveto
  31.105 +-322.511 233.685 -318.018 224.095 -280.454 143.911 curveto stroke
  31.106 +newpath -275.364 133.044 moveto -284.076 142.214 lineto -276.832 145.608 lineto closepath fill
  31.107 +2 setlinewidth 1 0 0 setrgbcolor newpath
  31.108 +-266.879 114.933 moveto
  31.109 +-224.004 235.52 -220.448 245.52 -184.094 347.765 curveto stroke
  31.110 +newpath -180.074 359.072 moveto -180.325 346.425 lineto -187.863 349.105 lineto closepath fill
  31.111 +2 setlinewidth 0 0 1 setrgbcolor newpath
  31.112 +-251.294 -335.059 moveto
  31.113 +-189.25 -303.624 -179.902 -298.887 -133.738 -275.498 curveto stroke
  31.114 +newpath -123.034 -270.074 moveto -131.93 -279.066 lineto -135.546 -271.93 lineto closepath fill
  31.115 +2 setlinewidth 0 0 1 setrgbcolor newpath
  31.116 +-389.604 -136.361 moveto
  31.117 +-327.15 -226.083 -321.098 -234.777 -269.576 -308.795 curveto stroke
  31.118 +newpath -262.72 -318.644 moveto -272.859 -311.081 lineto -266.293 -306.51 lineto closepath fill
  31.119 +2 setlinewidth 1 0 0 setrgbcolor newpath
  31.120 +5.84406 175.322 moveto
  31.121 +-76.0754 267.926 -83.1051 275.873 -152.172 353.948 curveto stroke
  31.122 +newpath -160.122 362.936 moveto -149.176 356.598 lineto -155.168 351.298 lineto closepath fill
  31.123 +2 setlinewidth 0 0 1 setrgbcolor newpath
  31.124 +169.478 311.683 moveto
  31.125 +96.8003 251.119 88.6819 244.353 30.4273 195.808 curveto stroke
  31.126 +newpath 21.2086 188.126 moveto 27.8666 198.881 lineto 32.988 192.735 lineto closepath fill
  31.127 +2 setlinewidth 0 0 1 setrgbcolor newpath
  31.128 +342.851 111.037 moveto
  31.129 +263.766 202.563 256.831 210.589 190.4 287.47 curveto stroke
  31.130 +newpath 182.554 296.55 moveto 193.427 290.085 lineto 187.373 284.855 lineto closepath fill
  31.131 +2 setlinewidth 0 0 1 setrgbcolor newpath
  31.132 +5.84406 175.322 moveto
  31.133 +163.16 145.314 173.605 143.321 311.418 117.033 curveto stroke
  31.134 +newpath 323.205 114.784 moveto 310.668 113.104 lineto 312.167 120.962 lineto closepath fill
  31.135 +2 setlinewidth 0 0 1 setrgbcolor newpath
  31.136 +342.851 111.037 moveto
  31.137 +497.255 2.58683 505.964 -3.53033 643.932 -100.436 curveto stroke
  31.138 +newpath 653.752 -107.334 moveto 641.633 -103.71 lineto 646.231 -97.163 lineto closepath fill
  31.139 +2 setlinewidth 0 0 1 setrgbcolor newpath
  31.140 +364.28 -222.074 moveto
  31.141 +354.298 -66.9063 353.616 -56.2971 344.905 79.1029 curveto stroke
  31.142 +newpath 344.135 91.0781 moveto 348.897 79.3597 lineto 340.914 78.8461 lineto closepath fill
  31.143 +2 setlinewidth 0 0 1 setrgbcolor newpath
  31.144 +670.118 -118.829 moveto
  31.145 +528.037 -166.793 517.967 -170.192 394.599 -211.839 curveto stroke
  31.146 +newpath 383.229 -215.677 moveto 393.32 -208.049 lineto 395.878 -215.629 lineto closepath fill
  31.147 +2 setlinewidth 1 0 0 setrgbcolor newpath
  31.148 +-105.193 -261.035 moveto
  31.149 +118.401 -242.479 129.015 -241.598 332.39 -224.721 curveto stroke
  31.150 +newpath 344.348 -223.728 moveto 332.72 -228.707 lineto 332.059 -220.734 lineto closepath fill
  31.151 +2 setlinewidth 0 0 1 setrgbcolor newpath
  31.152 +-105.193 -261.035 moveto
  31.153 +-160.867 -161.176 -166.028 -151.918 -212.336 -68.858 curveto stroke
  31.154 +newpath -218.179 -58.3769 moveto -208.842 -66.9102 lineto -215.829 -70.8058 lineto closepath fill
  31.155 +2 setlinewidth 0 0 1 setrgbcolor newpath
  31.156 +-227.918 -40.9084 moveto
  31.157 +-298.35 -82.4884 -307.42 -87.8432 -362.048 -120.093 curveto stroke
  31.158 +newpath -372.381 -126.193 moveto -364.081 -116.648 lineto -360.014 -123.537 lineto closepath fill
  31.159 +grestore
  31.160 +%Nodes:
  31.161 +gsave
  31.162 +-389.604 -136.361 20 0 1 0 nc
  31.163 +-227.918 -40.9084 20 0 1 0 nc
  31.164 +-105.193 -261.035 20 0 1 0 nc
  31.165 +364.28 -222.074 20 1 1 0 nc
  31.166 +670.118 -118.829 20 1 1 0 nc
  31.167 +342.851 111.037 20 1 1 0 nc
  31.168 +5.84406 175.322 20 1 1 0 nc
  31.169 +169.478 311.683 20 1 1 0 nc
  31.170 +-173.374 377.916 20 1 0 1 nc
  31.171 +-251.294 -335.059 20 0 1 0 nc
  31.172 +-266.879 114.933 20 0 0 0 nc
  31.173 +-368.176 331.163 20 0 0 0 nc
  31.174 +-490.901 120.777 20 0 0 0 nc
  31.175 +-574.666 -153.893 20 1 0 0 nc
  31.176 +-675.963 -3.89604 20 1 0 0 nc
  31.177 +-465.576 -42.8564 20 1 0 0 nc
  31.178 +44.8044 15.5841 20 0 0 1 nc
  31.179 +157.79 -130.517 20 0 0 1 nc
  31.180 +218.178 27.2723 20 0 0 1 nc
  31.181 +grestore
  31.182 +grestore
  31.183 +showpage
    32.1 --- a/doc/lgf.dox	Fri Oct 16 10:21:37 2009 +0200
    32.2 +++ b/doc/lgf.dox	Thu Nov 05 15:50:01 2009 +0100
    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-2008
    32.8 + * Copyright (C) 2003-2009
    32.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   32.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   32.11   *
    33.1 --- a/doc/license.dox	Fri Oct 16 10:21:37 2009 +0200
    33.2 +++ b/doc/license.dox	Thu Nov 05 15:50:01 2009 +0100
    33.3 @@ -2,7 +2,7 @@
    33.4   *
    33.5   * This file is a part of LEMON, a generic C++ optimization library.
    33.6   *
    33.7 - * Copyright (C) 2003-2008
    33.8 + * Copyright (C) 2003-2009
    33.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   33.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   33.11   *
    34.1 --- a/doc/mainpage.dox	Fri Oct 16 10:21:37 2009 +0200
    34.2 +++ b/doc/mainpage.dox	Thu Nov 05 15:50:01 2009 +0100
    34.3 @@ -2,7 +2,7 @@
    34.4   *
    34.5   * This file is a part of LEMON, a generic C++ optimization library.
    34.6   *
    34.7 - * Copyright (C) 2003-2008
    34.8 + * Copyright (C) 2003-2009
    34.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   34.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   34.11   *
   34.12 @@ -21,15 +21,11 @@
   34.13  
   34.14  \section intro Introduction
   34.15  
   34.16 -\subsection whatis What is LEMON
   34.17 -
   34.18 -LEMON stands for
   34.19 -<b>L</b>ibrary of <b>E</b>fficient <b>M</b>odels
   34.20 -and <b>O</b>ptimization in <b>N</b>etworks.
   34.21 -It is a C++ template
   34.22 -library aimed at combinatorial optimization tasks which
   34.23 -often involve in working
   34.24 -with graphs.
   34.25 +<b>LEMON</b> stands for <i><b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
   34.26 +and <b>O</b>ptimization in <b>N</b>etworks</i>.
   34.27 +It is a C++ template library providing efficient implementation of common
   34.28 +data structures and algorithms with focus on combinatorial optimization
   34.29 +problems in graphs and networks.
   34.30  
   34.31  <b>
   34.32  LEMON is an <a class="el" href="http://opensource.org/">open&nbsp;source</a>
   34.33 @@ -39,22 +35,22 @@
   34.34  \ref license "license terms".
   34.35  </b>
   34.36  
   34.37 -\subsection howtoread How to read the documentation
   34.38 +The project is maintained by the 
   34.39 +<a href="http://www.cs.elte.hu/egres/">Egerv&aacute;ry Research Group on
   34.40 +Combinatorial Optimization</a> \ref egres
   34.41 +at the Operations Research Department of the
   34.42 +<a href="http://www.elte.hu/">E&ouml;tv&ouml;s Lor&aacute;nd University,
   34.43 +Budapest</a>, Hungary.
   34.44 +LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
   34.45 +initiative \ref coinor.
   34.46  
   34.47 -If you want to get a quick start and see the most important features then
   34.48 -take a look at our \ref quicktour
   34.49 -"Quick Tour to LEMON" which will guide you along.
   34.50 +\section howtoread How to Read the Documentation
   34.51  
   34.52 -If you already feel like using our library, see the page that tells you
   34.53 -\ref getstart "How to start using LEMON".
   34.54 +If you would like to get to know the library, see
   34.55 +<a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
   34.56  
   34.57 -If you
   34.58 -want to see how LEMON works, see
   34.59 -some \ref demoprograms "demo programs".
   34.60 -
   34.61 -If you know what you are looking for then try to find it under the
   34.62 -<a class="el" href="modules.html">Modules</a>
   34.63 -section.
   34.64 +If you know what you are looking for, then try to find it under the
   34.65 +<a class="el" href="modules.html">Modules</a> section.
   34.66  
   34.67  If you are a user of the old (0.x) series of LEMON, please check out the
   34.68  \ref migration "Migration Guide" for the backward incompatibilities.
    35.1 --- a/doc/migration.dox	Fri Oct 16 10:21:37 2009 +0200
    35.2 +++ b/doc/migration.dox	Thu Nov 05 15:50:01 2009 +0100
    35.3 @@ -2,7 +2,7 @@
    35.4   *
    35.5   * This file is a part of LEMON, a generic C++ optimization library.
    35.6   *
    35.7 - * Copyright (C) 2003-2008
    35.8 + * Copyright (C) 2003-2009
    35.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   35.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   35.11   *
   35.12 @@ -25,7 +25,7 @@
   35.13  to the 0.x release series.
   35.14  
   35.15  Many of these changes adjusted automatically by the
   35.16 -<tt>script/lemon-0.x-to-1.x.sh</tt> tool. Those requiring manual
   35.17 +<tt>lemon-0.x-to-1.x.sh</tt> tool. Those requiring manual
   35.18  update are typeset <b>boldface</b>.
   35.19  
   35.20  \section migration-graph Graph Related Name Changes
   35.21 @@ -53,9 +53,11 @@
   35.22    for <tt>Arc</tt>s (directed edges).
   35.23  
   35.24  \warning
   35.25 -<b>The <tt>script/lemon-0.x-to-1.x.sh</tt> tool replaces all instances of
   35.26 -the words \c graph, \c digraph, \c edge and \c arc, so it replaces them
   35.27 -in strings, comments etc. as well as in all identifiers.</b>
   35.28 +<b>The <tt>lemon-0.x-to-1.x.sh</tt> script replaces the words \c graph,
   35.29 +\c ugraph, \c edge and \c uedge in your own identifiers and in
   35.30 +strings, comments etc. as well as in all LEMON specific identifiers.
   35.31 +So use the script carefully and make a backup copy of your source files
   35.32 +before applying the script to them.</b>
   35.33  
   35.34  \section migration-lgf LGF tools
   35.35   - The \ref lgf-format "LGF file format" has changed,
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/doc/min_cost_flow.dox	Thu Nov 05 15:50:01 2009 +0100
    36.3 @@ -0,0 +1,153 @@
    36.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    36.5 + *
    36.6 + * This file is a part of LEMON, a generic C++ optimization library.
    36.7 + *
    36.8 + * Copyright (C) 2003-2009
    36.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   36.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   36.11 + *
   36.12 + * Permission to use, modify and distribute this software is granted
   36.13 + * provided that this copyright notice appears in all copies. For
   36.14 + * precise terms see the accompanying LICENSE file.
   36.15 + *
   36.16 + * This software is provided "AS IS" with no warranty of any kind,
   36.17 + * express or implied, and with no claim as to its suitability for any
   36.18 + * purpose.
   36.19 + *
   36.20 + */
   36.21 +
   36.22 +namespace lemon {
   36.23 +
   36.24 +/**
   36.25 +\page min_cost_flow Minimum Cost Flow Problem
   36.26 +
   36.27 +\section mcf_def Definition (GEQ form)
   36.28 +
   36.29 +The \e minimum \e cost \e flow \e problem is to find a feasible flow of
   36.30 +minimum total cost from a set of supply nodes to a set of demand nodes
   36.31 +in a network with capacity constraints (lower and upper bounds)
   36.32 +and arc costs \ref amo93networkflows.
   36.33 +
   36.34 +Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
   36.35 +\f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
   36.36 +upper bounds for the flow values on the arcs, for which
   36.37 +\f$lower(uv) \leq upper(uv)\f$ must hold for all \f$uv\in A\f$,
   36.38 +\f$cost: A\rightarrow\mathbf{R}\f$ denotes the cost per unit flow
   36.39 +on the arcs and \f$sup: V\rightarrow\mathbf{R}\f$ denotes the
   36.40 +signed supply values of the nodes.
   36.41 +If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
   36.42 +supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
   36.43 +\f$-sup(u)\f$ demand.
   36.44 +A minimum cost flow is an \f$f: A\rightarrow\mathbf{R}\f$ solution
   36.45 +of the following optimization problem.
   36.46 +
   36.47 +\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
   36.48 +\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \geq
   36.49 +    sup(u) \quad \forall u\in V \f]
   36.50 +\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
   36.51 +
   36.52 +The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
   36.53 +zero or negative in order to have a feasible solution (since the sum
   36.54 +of the expressions on the left-hand side of the inequalities is zero).
   36.55 +It means that the total demand must be greater or equal to the total
   36.56 +supply and all the supplies have to be carried out from the supply nodes,
   36.57 +but there could be demands that are not satisfied.
   36.58 +If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
   36.59 +constraints have to be satisfied with equality, i.e. all demands
   36.60 +have to be satisfied and all supplies have to be used.
   36.61 +
   36.62 +
   36.63 +\section mcf_algs Algorithms
   36.64 +
   36.65 +LEMON contains several algorithms for solving this problem, for more
   36.66 +information see \ref min_cost_flow_algs "Minimum Cost Flow Algorithms".
   36.67 +
   36.68 +A feasible solution for this problem can be found using \ref Circulation.
   36.69 +
   36.70 +
   36.71 +\section mcf_dual Dual Solution
   36.72 +
   36.73 +The dual solution of the minimum cost flow problem is represented by
   36.74 +node potentials \f$\pi: V\rightarrow\mathbf{R}\f$.
   36.75 +An \f$f: A\rightarrow\mathbf{R}\f$ primal feasible solution is optimal
   36.76 +if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$ node potentials
   36.77 +the following \e complementary \e slackness optimality conditions hold.
   36.78 +
   36.79 + - For all \f$uv\in A\f$ arcs:
   36.80 +   - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
   36.81 +   - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
   36.82 +   - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
   36.83 + - For all \f$u\in V\f$ nodes:
   36.84 +   - \f$\pi(u)<=0\f$;
   36.85 +   - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
   36.86 +     then \f$\pi(u)=0\f$.
   36.87 + 
   36.88 +Here \f$cost^\pi(uv)\f$ denotes the \e reduced \e cost of the arc
   36.89 +\f$uv\in A\f$ with respect to the potential function \f$\pi\f$, i.e.
   36.90 +\f[ cost^\pi(uv) = cost(uv) + \pi(u) - \pi(v).\f]
   36.91 +
   36.92 +All algorithms provide dual solution (node potentials), as well,
   36.93 +if an optimal flow is found.
   36.94 +
   36.95 +
   36.96 +\section mcf_eq Equality Form
   36.97 +
   36.98 +The above \ref mcf_def "definition" is actually more general than the
   36.99 +usual formulation of the minimum cost flow problem, in which strict
  36.100 +equalities are required in the supply/demand contraints.
  36.101 +
  36.102 +\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
  36.103 +\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) =
  36.104 +    sup(u) \quad \forall u\in V \f]
  36.105 +\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
  36.106 +
  36.107 +However if the sum of the supply values is zero, then these two problems
  36.108 +are equivalent.
  36.109 +The \ref min_cost_flow_algs "algorithms" in LEMON support the general
  36.110 +form, so if you need the equality form, you have to ensure this additional
  36.111 +contraint manually.
  36.112 +
  36.113 +
  36.114 +\section mcf_leq Opposite Inequalites (LEQ Form)
  36.115 +
  36.116 +Another possible definition of the minimum cost flow problem is
  36.117 +when there are <em>"less or equal"</em> (LEQ) supply/demand constraints,
  36.118 +instead of the <em>"greater or equal"</em> (GEQ) constraints.
  36.119 +
  36.120 +\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
  36.121 +\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \leq
  36.122 +    sup(u) \quad \forall u\in V \f]
  36.123 +\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
  36.124 +
  36.125 +It means that the total demand must be less or equal to the 
  36.126 +total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
  36.127 +positive) and all the demands have to be satisfied, but there
  36.128 +could be supplies that are not carried out from the supply
  36.129 +nodes.
  36.130 +The equality form is also a special case of this form, of course.
  36.131 +
  36.132 +You could easily transform this case to the \ref mcf_def "GEQ form"
  36.133 +of the problem by reversing the direction of the arcs and taking the
  36.134 +negative of the supply values (e.g. using \ref ReverseDigraph and
  36.135 +\ref NegMap adaptors).
  36.136 +However \ref NetworkSimplex algorithm also supports this form directly
  36.137 +for the sake of convenience.
  36.138 +
  36.139 +Note that the optimality conditions for this supply constraint type are
  36.140 +slightly differ from the conditions that are discussed for the GEQ form,
  36.141 +namely the potentials have to be non-negative instead of non-positive.
  36.142 +An \f$f: A\rightarrow\mathbf{R}\f$ feasible solution of this problem
  36.143 +is optimal if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$
  36.144 +node potentials the following conditions hold.
  36.145 +
  36.146 + - For all \f$uv\in A\f$ arcs:
  36.147 +   - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
  36.148 +   - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
  36.149 +   - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
  36.150 + - For all \f$u\in V\f$ nodes:
  36.151 +   - \f$\pi(u)>=0\f$;
  36.152 +   - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
  36.153 +     then \f$\pi(u)=0\f$.
  36.154 +
  36.155 +*/
  36.156 +}
    37.1 --- a/doc/named-param.dox	Fri Oct 16 10:21:37 2009 +0200
    37.2 +++ b/doc/named-param.dox	Thu Nov 05 15:50:01 2009 +0100
    37.3 @@ -2,7 +2,7 @@
    37.4   *
    37.5   * This file is a part of LEMON, a generic C++ optimization library.
    37.6   *
    37.7 - * Copyright (C) 2003-2008
    37.8 + * Copyright (C) 2003-2009
    37.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   37.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   37.11   *
    38.1 --- a/doc/namespaces.dox	Fri Oct 16 10:21:37 2009 +0200
    38.2 +++ b/doc/namespaces.dox	Thu Nov 05 15:50:01 2009 +0100
    38.3 @@ -2,7 +2,7 @@
    38.4   *
    38.5   * This file is a part of LEMON, a generic C++ optimization library.
    38.6   *
    38.7 - * Copyright (C) 2003-2008
    38.8 + * Copyright (C) 2003-2009
    38.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   38.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   38.11   *
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/doc/references.bib	Thu Nov 05 15:50:01 2009 +0100
    39.3 @@ -0,0 +1,301 @@
    39.4 +%%%%% Defining LEMON %%%%%
    39.5 +
    39.6 +@misc{lemon,
    39.7 +  key =          {LEMON},
    39.8 +  title =        {{LEMON} -- {L}ibrary for {E}fficient {M}odeling and
    39.9 +                  {O}ptimization in {N}etworks},
   39.10 +  howpublished = {\url{http://lemon.cs.elte.hu/}},
   39.11 +  year =         2009
   39.12 +}
   39.13 +
   39.14 +@misc{egres,
   39.15 +  key =          {EGRES},
   39.16 +  title =        {{EGRES} -- {E}gerv{\'a}ry {R}esearch {G}roup on
   39.17 +                  {C}ombinatorial {O}ptimization},
   39.18 +  url =          {http://www.cs.elte.hu/egres/}
   39.19 +}
   39.20 +
   39.21 +@misc{coinor,
   39.22 +  key =          {COIN-OR},
   39.23 +  title =        {{COIN-OR} -- {C}omputational {I}nfrastructure for
   39.24 +                  {O}perations {R}esearch},
   39.25 +  url =          {http://www.coin-or.org/}
   39.26 +}
   39.27 +
   39.28 +
   39.29 +%%%%% Other libraries %%%%%%
   39.30 +
   39.31 +@misc{boost,
   39.32 +  key =          {Boost},
   39.33 +  title =        {{B}oost {C++} {L}ibraries},
   39.34 +  url =          {http://www.boost.org/}
   39.35 +}
   39.36 +
   39.37 +@book{bglbook,
   39.38 +  author =       {Jeremy G. Siek and Lee-Quan Lee and Andrew
   39.39 +                  Lumsdaine},
   39.40 +  title =        {The Boost Graph Library: User Guide and Reference
   39.41 +                  Manual},
   39.42 +  publisher =    {Addison-Wesley},
   39.43 +  year =         2002
   39.44 +}
   39.45 +
   39.46 +@misc{leda,
   39.47 +  key =          {LEDA},
   39.48 +  title =        {{LEDA} -- {L}ibrary of {E}fficient {D}ata {T}ypes and
   39.49 +                  {A}lgorithms},
   39.50 +  url =          {http://www.algorithmic-solutions.com/}
   39.51 +}
   39.52 +
   39.53 +@book{ledabook,
   39.54 +  author =       {Kurt Mehlhorn and Stefan N{\"a}her},
   39.55 +  title =        {{LEDA}: {A} platform for combinatorial and geometric
   39.56 +                  computing},
   39.57 +  isbn =         {0-521-56329-1},
   39.58 +  publisher =    {Cambridge University Press},
   39.59 +  address =      {New York, NY, USA},
   39.60 +  year =         1999
   39.61 +}
   39.62 +
   39.63 +
   39.64 +%%%%% Tools that LEMON depends on %%%%%
   39.65 +
   39.66 +@misc{cmake,
   39.67 +  key =          {CMake},
   39.68 +  title =        {{CMake} -- {C}ross {P}latform {M}ake},
   39.69 +  url =          {http://www.cmake.org/}
   39.70 +}
   39.71 +
   39.72 +@misc{doxygen,
   39.73 +  key =          {Doxygen},
   39.74 +  title =        {{Doxygen} -- {S}ource code documentation generator
   39.75 +                  tool},
   39.76 +  url =          {http://www.doxygen.org/}
   39.77 +}
   39.78 +
   39.79 +
   39.80 +%%%%% LP/MIP libraries %%%%%
   39.81 +
   39.82 +@misc{glpk,
   39.83 +  key =          {GLPK},
   39.84 +  title =        {{GLPK} -- {GNU} {L}inear {P}rogramming {K}it},
   39.85 +  url =          {http://www.gnu.org/software/glpk/}
   39.86 +}
   39.87 +
   39.88 +@misc{clp,
   39.89 +  key =          {Clp},
   39.90 +  title =        {{Clp} -- {Coin-Or} {L}inear {P}rogramming},
   39.91 +  url =          {http://projects.coin-or.org/Clp/}
   39.92 +}
   39.93 +
   39.94 +@misc{cbc,
   39.95 +  key =          {Cbc},
   39.96 +  title =        {{Cbc} -- {Coin-Or} {B}ranch and {C}ut},
   39.97 +  url =          {http://projects.coin-or.org/Cbc/}
   39.98 +}
   39.99 +
  39.100 +@misc{cplex,
  39.101 +  key =          {CPLEX},
  39.102 +  title =        {{ILOG} {CPLEX}},
  39.103 +  url =          {http://www.ilog.com/}
  39.104 +}
  39.105 +
  39.106 +@misc{soplex,
  39.107 +  key =          {SoPlex},
  39.108 +  title =        {{SoPlex} -- {T}he {S}equential {O}bject-{O}riented
  39.109 +                  {S}implex},
  39.110 +  url =          {http://soplex.zib.de/}
  39.111 +}
  39.112 +
  39.113 +
  39.114 +%%%%% General books %%%%%
  39.115 +
  39.116 +@book{amo93networkflows,
  39.117 +  author =       {Ravindra K. Ahuja and Thomas L. Magnanti and James
  39.118 +                  B. Orlin},
  39.119 +  title =        {Network Flows: Theory, Algorithms, and Applications},
  39.120 +  publisher =    {Prentice-Hall, Inc.},
  39.121 +  year =         1993,
  39.122 +  month =        feb,
  39.123 +  isbn =         {978-0136175490}
  39.124 +}
  39.125 +
  39.126 +@book{schrijver03combinatorial,
  39.127 +  author =       {Alexander Schrijver},
  39.128 +  title =        {Combinatorial Optimization: Polyhedra and Efficiency},
  39.129 +  publisher =    {Springer-Verlag},
  39.130 +  year =         2003,
  39.131 +  isbn =         {978-3540443896}
  39.132 +}
  39.133 +
  39.134 +@book{clrs01algorithms,
  39.135 +  author =       {Thomas H. Cormen and Charles E. Leiserson and Ronald
  39.136 +                  L. Rivest and Clifford Stein},
  39.137 +  title =        {Introduction to Algorithms},
  39.138 +  publisher =    {The MIT Press},
  39.139 +  year =         2001,
  39.140 +  edition =      {2nd}
  39.141 +}
  39.142 +
  39.143 +@book{stroustrup00cpp,
  39.144 +  author =       {Bjarne Stroustrup},
  39.145 +  title =        {The C++ Programming Language},
  39.146 +  edition =      {3rd},
  39.147 +  publisher =    {Addison-Wesley Professional},
  39.148 +  isbn =         0201700735,
  39.149 +  month =        {February},
  39.150 +  year =         2000
  39.151 +}
  39.152 +
  39.153 +
  39.154 +%%%%% Maximum flow algorithms %%%%%
  39.155 +
  39.156 +@article{edmondskarp72theoretical,
  39.157 +  author =       {Jack Edmonds and Richard M. Karp},
  39.158 +  title =        {Theoretical improvements in algorithmic efficiency
  39.159 +                  for network flow problems},
  39.160 +  journal =      {Journal of the ACM},
  39.161 +  year =         1972,
  39.162 +  volume =       19,
  39.163 +  number =       2,
  39.164 +  pages =        {248-264}
  39.165 +}
  39.166 +
  39.167 +@article{goldberg88newapproach,
  39.168 +  author =       {Andrew V. Goldberg and Robert E. Tarjan},
  39.169 +  title =        {A new approach to the maximum flow problem},
  39.170 +  journal =      {Journal of the ACM},
  39.171 +  year =         1988,
  39.172 +  volume =       35,
  39.173 +  number =       4,
  39.174 +  pages =        {921-940}
  39.175 +}
  39.176 +
  39.177 +@article{dinic70algorithm,
  39.178 +  author =       {E. A. Dinic},
  39.179 +  title =        {Algorithm for solution of a problem of maximum flow
  39.180 +                  in a network with power estimation},
  39.181 +  journal =      {Soviet Math. Doklady},
  39.182 +  year =         1970,
  39.183 +  volume =       11,
  39.184 +  pages =        {1277-1280}
  39.185 +}
  39.186 +
  39.187 +@article{goldberg08partial,
  39.188 +  author =       {Andrew V. Goldberg},
  39.189 +  title =        {The Partial Augment-Relabel Algorithm for the
  39.190 +                  Maximum Flow Problem},
  39.191 +  journal =      {16th Annual European Symposium on Algorithms},
  39.192 +  year =         2008,
  39.193 +  pages =        {466-477}
  39.194 +}
  39.195 +
  39.196 +@article{sleator83dynamic,
  39.197 +  author =       {Daniel D. Sleator and Robert E. Tarjan},
  39.198 +  title =        {A data structure for dynamic trees},
  39.199 +  journal =      {Journal of Computer and System Sciences},
  39.200 +  year =         1983,
  39.201 +  volume =       26,
  39.202 +  number =       3,
  39.203 +  pages =        {362-391}
  39.204 +}
  39.205 +
  39.206 +
  39.207 +%%%%% Minimum mean cycle algorithms %%%%%
  39.208 +
  39.209 +@article{karp78characterization,
  39.210 +  author =       {Richard M. Karp},
  39.211 +  title =        {A characterization of the minimum cycle mean in a
  39.212 +                  digraph},
  39.213 +  journal =      {Discrete Math.},
  39.214 +  year =         1978,
  39.215 +  volume =       23,
  39.216 +  pages =        {309-311}
  39.217 +}
  39.218 +
  39.219 +@article{dasdan98minmeancycle,
  39.220 +  author =       {Ali Dasdan and Rajesh K. Gupta},
  39.221 +  title =        {Faster Maximum and Minimum Mean Cycle Alogrithms for
  39.222 +                  System Performance Analysis},
  39.223 +  journal =      {IEEE Transactions on Computer-Aided Design of
  39.224 +                  Integrated Circuits and Systems},
  39.225 +  year =         1998,
  39.226 +  volume =       17,
  39.227 +  number =       10,
  39.228 +  pages =        {889-899}
  39.229 +}
  39.230 +
  39.231 +
  39.232 +%%%%% Minimum cost flow algorithms %%%%%
  39.233 +
  39.234 +@article{klein67primal,
  39.235 +  author =       {Morton Klein},
  39.236 +  title =        {A primal method for minimal cost flows with
  39.237 +                  applications to the assignment and transportation
  39.238 +                  problems},
  39.239 +  journal =      {Management Science},
  39.240 +  year =         1967,
  39.241 +  volume =       14,
  39.242 +  pages =        {205-220}
  39.243 +}
  39.244 +
  39.245 +@article{goldberg89cyclecanceling,
  39.246 +  author =       {Andrew V. Goldberg and Robert E. Tarjan},
  39.247 +  title =        {Finding minimum-cost circulations by canceling
  39.248 +                  negative cycles},
  39.249 +  journal =      {Journal of the ACM},
  39.250 +  year =         1989,
  39.251 +  volume =       36,
  39.252 +  number =       4,
  39.253 +  pages =        {873-886}
  39.254 +}
  39.255 +
  39.256 +@article{goldberg90approximation,
  39.257 +  author =       {Andrew V. Goldberg and Robert E. Tarjan},
  39.258 +  title =        {Finding Minimum-Cost Circulations by Successive
  39.259 +                  Approximation},
  39.260 +  journal =      {Mathematics of Operations Research},
  39.261 +  year =         1990,
  39.262 +  volume =       15,
  39.263 +  number =       3,
  39.264 +  pages =        {430-466}
  39.265 +}
  39.266 +
  39.267 +@article{goldberg97efficient,
  39.268 +  author =       {Andrew V. Goldberg},
  39.269 +  title =        {An Efficient Implementation of a Scaling
  39.270 +                  Minimum-Cost Flow Algorithm},
  39.271 +  journal =      {Journal of Algorithms},
  39.272 +  year =         1997,
  39.273 +  volume =       22,
  39.274 +  number =       1,
  39.275 +  pages =        {1-29}
  39.276 +}
  39.277 +
  39.278 +@article{bunnagel98efficient,
  39.279 +  author =       {Ursula B{\"u}nnagel and Bernhard Korte and Jens
  39.280 +                  Vygen},
  39.281 +  title =        {Efficient implementation of the {G}oldberg-{T}arjan
  39.282 +                  minimum-cost flow algorithm},
  39.283 +  journal =      {Optimization Methods and Software},
  39.284 +  year =         1998,
  39.285 +  volume =       10,
  39.286 +  pages =        {157-174}
  39.287 +}
  39.288 +
  39.289 +@book{dantzig63linearprog,
  39.290 +  author =       {George B. Dantzig},
  39.291 +  title =        {Linear Programming and Extensions},
  39.292 +  publisher =    {Princeton University Press},
  39.293 +  year =         1963
  39.294 +}
  39.295 +
  39.296 +@mastersthesis{kellyoneill91netsimplex,
  39.297 +  author =       {Damian J. Kelly and Garrett M. O'Neill},
  39.298 +  title =        {The Minimum Cost Flow Problem and The Network
  39.299 +                  Simplex Method},
  39.300 +  school =       {University College},
  39.301 +  address =      {Dublin, Ireland},
  39.302 +  year =         1991,
  39.303 +  month =        sep,
  39.304 +}
    40.1 --- a/doc/template.h	Fri Oct 16 10:21:37 2009 +0200
    40.2 +++ b/doc/template.h	Thu Nov 05 15:50:01 2009 +0100
    40.3 @@ -2,7 +2,7 @@
    40.4   *
    40.5   * This file is a part of LEMON, a generic C++ optimization library.
    40.6   *
    40.7 - * Copyright (C) 2003-2008
    40.8 + * Copyright (C) 2003-2009
    40.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   40.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   40.11   *
    41.1 --- a/lemon/CMakeLists.txt	Fri Oct 16 10:21:37 2009 +0200
    41.2 +++ b/lemon/CMakeLists.txt	Thu Nov 05 15:50:01 2009 +0100
    41.3 @@ -1,5 +1,5 @@
    41.4  INCLUDE_DIRECTORIES(
    41.5 -  ${CMAKE_SOURCE_DIR}
    41.6 +  ${PROJECT_SOURCE_DIR}
    41.7    ${PROJECT_BINARY_DIR}
    41.8  )
    41.9  
   41.10 @@ -8,26 +8,61 @@
   41.11    ${CMAKE_CURRENT_BINARY_DIR}/config.h
   41.12  )
   41.13  
   41.14 -ADD_LIBRARY(lemon
   41.15 +SET(LEMON_SOURCES
   41.16    arg_parser.cc
   41.17    base.cc
   41.18    color.cc
   41.19 +  lp_base.cc
   41.20 +  lp_skeleton.cc
   41.21    random.cc
   41.22    bits/windows.cc
   41.23  )
   41.24  
   41.25 +IF(LEMON_HAVE_GLPK)
   41.26 +  SET(LEMON_SOURCES ${LEMON_SOURCES} glpk.cc)
   41.27 +  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIRS})
   41.28 +  IF(WIN32)
   41.29 +    INSTALL(FILES ${GLPK_BIN_DIR}/glpk.dll DESTINATION bin)
   41.30 +    INSTALL(FILES ${GLPK_BIN_DIR}/libltdl3.dll DESTINATION bin)
   41.31 +    INSTALL(FILES ${GLPK_BIN_DIR}/zlib1.dll DESTINATION bin)
   41.32 +  ENDIF()
   41.33 +ENDIF()
   41.34 +
   41.35 +IF(LEMON_HAVE_CPLEX)
   41.36 +  SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc)
   41.37 +  INCLUDE_DIRECTORIES(${CPLEX_INCLUDE_DIRS})
   41.38 +ENDIF()
   41.39 +
   41.40 +IF(LEMON_HAVE_CLP)
   41.41 +  SET(LEMON_SOURCES ${LEMON_SOURCES} clp.cc)
   41.42 +  INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
   41.43 +ENDIF()
   41.44 +
   41.45 +IF(LEMON_HAVE_CBC)
   41.46 +  SET(LEMON_SOURCES ${LEMON_SOURCES} cbc.cc)
   41.47 +  INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
   41.48 +ENDIF()
   41.49 +
   41.50 +ADD_LIBRARY(lemon ${LEMON_SOURCES})
   41.51 +IF(UNIX)
   41.52 +  SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon)
   41.53 +ENDIF()
   41.54 +
   41.55  INSTALL(
   41.56    TARGETS lemon
   41.57    ARCHIVE DESTINATION lib
   41.58 -  COMPONENT library)
   41.59 +  COMPONENT library
   41.60 +)
   41.61  
   41.62  INSTALL(
   41.63    DIRECTORY . bits concepts
   41.64    DESTINATION include/lemon
   41.65    COMPONENT headers
   41.66 -  FILES_MATCHING PATTERN "*.h")
   41.67 +  FILES_MATCHING PATTERN "*.h"
   41.68 +)
   41.69  
   41.70  INSTALL(
   41.71    FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h
   41.72    DESTINATION include/lemon
   41.73 -  COMPONENT headers)
   41.74 +  COMPONENT headers
   41.75 +)
    42.1 --- a/lemon/Makefile.am	Fri Oct 16 10:21:37 2009 +0200
    42.2 +++ b/lemon/Makefile.am	Thu Nov 05 15:50:01 2009 +0100
    42.3 @@ -1,62 +1,139 @@
    42.4  EXTRA_DIST += \
    42.5  	lemon/lemon.pc.in \
    42.6 -	lemon/CMakeLists.txt
    42.7 +	lemon/CMakeLists.txt \
    42.8 +	lemon/config.h.cmake
    42.9  
   42.10  pkgconfig_DATA += lemon/lemon.pc
   42.11  
   42.12  lib_LTLIBRARIES += lemon/libemon.la
   42.13  
   42.14  lemon_libemon_la_SOURCES = \
   42.15 -        lemon/arg_parser.cc \
   42.16 -        lemon/base.cc \
   42.17 -        lemon/color.cc \
   42.18 -        lemon/random.cc \
   42.19 +	lemon/arg_parser.cc \
   42.20 +	lemon/base.cc \
   42.21 +	lemon/color.cc \
   42.22 +	lemon/lp_base.cc \
   42.23 +	lemon/lp_skeleton.cc \
   42.24 +	lemon/random.cc \
   42.25  	lemon/bits/windows.cc
   42.26  
   42.27 -#lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS)
   42.28 -#lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS)
   42.29 +nodist_lemon_HEADERS = lemon/config.h	
   42.30  
   42.31 -nodist_lemon_HEADERS = lemon/config.h
   42.32 +lemon_libemon_la_CXXFLAGS = \
   42.33 +	$(AM_CXXFLAGS) \
   42.34 +	$(GLPK_CFLAGS) \
   42.35 +	$(CPLEX_CFLAGS) \
   42.36 +	$(SOPLEX_CXXFLAGS) \
   42.37 +	$(CLP_CXXFLAGS) \
   42.38 +	$(CBC_CXXFLAGS)
   42.39 +
   42.40 +lemon_libemon_la_LDFLAGS = \
   42.41 +	$(GLPK_LIBS) \
   42.42 +	$(CPLEX_LIBS) \
   42.43 +	$(SOPLEX_LIBS) \
   42.44 +	$(CLP_LIBS) \
   42.45 +	$(CBC_LIBS)
   42.46 +
   42.47 +if HAVE_GLPK
   42.48 +lemon_libemon_la_SOURCES += lemon/glpk.cc
   42.49 +endif
   42.50 +
   42.51 +if HAVE_CPLEX
   42.52 +lemon_libemon_la_SOURCES += lemon/cplex.cc
   42.53 +endif
   42.54 +
   42.55 +if HAVE_SOPLEX
   42.56 +lemon_libemon_la_SOURCES += lemon/soplex.cc
   42.57 +endif
   42.58 +
   42.59 +if HAVE_CLP
   42.60 +lemon_libemon_la_SOURCES += lemon/clp.cc
   42.61 +endif
   42.62 +
   42.63 +if HAVE_CBC
   42.64 +lemon_libemon_la_SOURCES += lemon/cbc.cc
   42.65 +endif
   42.66  
   42.67  lemon_HEADERS += \
   42.68 -        lemon/arg_parser.h \
   42.69 +	lemon/adaptors.h \
   42.70 +	lemon/arg_parser.h \
   42.71  	lemon/assert.h \
   42.72 -        lemon/bfs.h \
   42.73 -        lemon/bin_heap.h \
   42.74 -        lemon/color.h \
   42.75 +	lemon/bellman_ford.h \
   42.76 +	lemon/bfs.h \
   42.77 +	lemon/bin_heap.h \
   42.78 +	lemon/binom_heap.h \
   42.79 +	lemon/bucket_heap.h \
   42.80 +	lemon/cbc.h \
   42.81 +	lemon/circulation.h \
   42.82 +	lemon/clp.h \
   42.83 +	lemon/color.h \
   42.84  	lemon/concept_check.h \
   42.85 -        lemon/counter.h \
   42.86 +	lemon/connectivity.h \
   42.87 +	lemon/counter.h \
   42.88  	lemon/core.h \
   42.89 -        lemon/dfs.h \
   42.90 -        lemon/dijkstra.h \
   42.91 -        lemon/dim2.h \
   42.92 +	lemon/cplex.h \
   42.93 +	lemon/dfs.h \
   42.94 +	lemon/dijkstra.h \
   42.95 +	lemon/dim2.h \
   42.96 +	lemon/dimacs.h \
   42.97 +	lemon/edge_set.h \
   42.98 +	lemon/elevator.h \
   42.99  	lemon/error.h \
  42.100 -        lemon/graph_to_eps.h \
  42.101 +	lemon/euler.h \
  42.102 +	lemon/fib_heap.h \
  42.103 +	lemon/fourary_heap.h \
  42.104 +	lemon/full_graph.h \
  42.105 +	lemon/glpk.h \
  42.106 +	lemon/gomory_hu.h \
  42.107 +	lemon/graph_to_eps.h \
  42.108 +	lemon/grid_graph.h \
  42.109 +	lemon/hartmann_orlin.h \
  42.110 +	lemon/howard.h \
  42.111 +	lemon/hypercube_graph.h \
  42.112 +	lemon/karp.h \
  42.113 +	lemon/kary_heap.h \
  42.114  	lemon/kruskal.h \
  42.115 +	lemon/hao_orlin.h \
  42.116  	lemon/lgf_reader.h \
  42.117  	lemon/lgf_writer.h \
  42.118  	lemon/list_graph.h \
  42.119 +	lemon/lp.h \
  42.120 +	lemon/lp_base.h \
  42.121 +	lemon/lp_skeleton.h \
  42.122  	lemon/maps.h \
  42.123 +	lemon/matching.h \
  42.124  	lemon/math.h \
  42.125 +	lemon/min_cost_arborescence.h \
  42.126 +	lemon/nauty_reader.h \
  42.127 +	lemon/network_simplex.h \
  42.128 +	lemon/pairing_heap.h \
  42.129  	lemon/path.h \
  42.130 -        lemon/random.h \
  42.131 +	lemon/preflow.h \
  42.132 +	lemon/radix_heap.h \
  42.133 +	lemon/radix_sort.h \
  42.134 +	lemon/random.h \
  42.135  	lemon/smart_graph.h \
  42.136 -        lemon/time_measure.h \
  42.137 -        lemon/tolerance.h \
  42.138 +	lemon/soplex.h \
  42.139 +	lemon/static_graph.h \
  42.140 +	lemon/suurballe.h \
  42.141 +	lemon/time_measure.h \
  42.142 +	lemon/tolerance.h \
  42.143  	lemon/unionfind.h \
  42.144  	lemon/bits/windows.h
  42.145  
  42.146  bits_HEADERS += \
  42.147  	lemon/bits/alteration_notifier.h \
  42.148  	lemon/bits/array_map.h \
  42.149 -	lemon/bits/base_extender.h \
  42.150 -        lemon/bits/bezier.h \
  42.151 +	lemon/bits/bezier.h \
  42.152  	lemon/bits/default_map.h \
  42.153 -        lemon/bits/enable_if.h \
  42.154 +	lemon/bits/edge_set_extender.h \
  42.155 +	lemon/bits/enable_if.h \
  42.156 +	lemon/bits/graph_adaptor_extender.h \
  42.157  	lemon/bits/graph_extender.h \
  42.158  	lemon/bits/map_extender.h \
  42.159  	lemon/bits/path_dump.h \
  42.160 +	lemon/bits/solver_bits.h \
  42.161  	lemon/bits/traits.h \
  42.162 +	lemon/bits/variant.h \
  42.163  	lemon/bits/vector_map.h
  42.164  
  42.165  concept_HEADERS += \
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/lemon/adaptors.h	Thu Nov 05 15:50:01 2009 +0100
    43.3 @@ -0,0 +1,3614 @@
    43.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    43.5 + *
    43.6 + * This file is a part of LEMON, a generic C++ optimization library.
    43.7 + *
    43.8 + * Copyright (C) 2003-2009
    43.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   43.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   43.11 + *
   43.12 + * Permission to use, modify and distribute this software is granted
   43.13 + * provided that this copyright notice appears in all copies. For
   43.14 + * precise terms see the accompanying LICENSE file.
   43.15 + *
   43.16 + * This software is provided "AS IS" with no warranty of any kind,
   43.17 + * express or implied, and with no claim as to its suitability for any
   43.18 + * purpose.
   43.19 + *
   43.20 + */
   43.21 +
   43.22 +#ifndef LEMON_ADAPTORS_H
   43.23 +#define LEMON_ADAPTORS_H
   43.24 +
   43.25 +/// \ingroup graph_adaptors
   43.26 +/// \file
   43.27 +/// \brief Adaptor classes for digraphs and graphs
   43.28 +///
   43.29 +/// This file contains several useful adaptors for digraphs and graphs.
   43.30 +
   43.31 +#include <lemon/core.h>
   43.32 +#include <lemon/maps.h>
   43.33 +#include <lemon/bits/variant.h>
   43.34 +
   43.35 +#include <lemon/bits/graph_adaptor_extender.h>
   43.36 +#include <lemon/bits/map_extender.h>
   43.37 +#include <lemon/tolerance.h>
   43.38 +
   43.39 +#include <algorithm>
   43.40 +
   43.41 +namespace lemon {
   43.42 +
   43.43 +#ifdef _MSC_VER
   43.44 +#define LEMON_SCOPE_FIX(OUTER, NESTED) OUTER::NESTED
   43.45 +#else
   43.46 +#define LEMON_SCOPE_FIX(OUTER, NESTED) typename OUTER::template NESTED
   43.47 +#endif
   43.48 +
   43.49 +  template<typename DGR>
   43.50 +  class DigraphAdaptorBase {
   43.51 +  public:
   43.52 +    typedef DGR Digraph;
   43.53 +    typedef DigraphAdaptorBase Adaptor;
   43.54 +
   43.55 +  protected:
   43.56 +    DGR* _digraph;
   43.57 +    DigraphAdaptorBase() : _digraph(0) { }
   43.58 +    void initialize(DGR& digraph) { _digraph = &digraph; }
   43.59 +
   43.60 +  public:
   43.61 +    DigraphAdaptorBase(DGR& digraph) : _digraph(&digraph) { }
   43.62 +
   43.63 +    typedef typename DGR::Node Node;
   43.64 +    typedef typename DGR::Arc Arc;
   43.65 +
   43.66 +    void first(Node& i) const { _digraph->first(i); }
   43.67 +    void first(Arc& i) const { _digraph->first(i); }
   43.68 +    void firstIn(Arc& i, const Node& n) const { _digraph->firstIn(i, n); }
   43.69 +    void firstOut(Arc& i, const Node& n ) const { _digraph->firstOut(i, n); }
   43.70 +
   43.71 +    void next(Node& i) const { _digraph->next(i); }
   43.72 +    void next(Arc& i) const { _digraph->next(i); }
   43.73 +    void nextIn(Arc& i) const { _digraph->nextIn(i); }
   43.74 +    void nextOut(Arc& i) const { _digraph->nextOut(i); }
   43.75 +
   43.76 +    Node source(const Arc& a) const { return _digraph->source(a); }
   43.77 +    Node target(const Arc& a) const { return _digraph->target(a); }
   43.78 +
   43.79 +    typedef NodeNumTagIndicator<DGR> NodeNumTag;
   43.80 +    int nodeNum() const { return _digraph->nodeNum(); }
   43.81 +
   43.82 +    typedef ArcNumTagIndicator<DGR> ArcNumTag;
   43.83 +    int arcNum() const { return _digraph->arcNum(); }
   43.84 +
   43.85 +    typedef FindArcTagIndicator<DGR> FindArcTag;
   43.86 +    Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) const {
   43.87 +      return _digraph->findArc(u, v, prev);
   43.88 +    }
   43.89 +
   43.90 +    Node addNode() { return _digraph->addNode(); }
   43.91 +    Arc addArc(const Node& u, const Node& v) { return _digraph->addArc(u, v); }
   43.92 +
   43.93 +    void erase(const Node& n) { _digraph->erase(n); }
   43.94 +    void erase(const Arc& a) { _digraph->erase(a); }
   43.95 +
   43.96 +    void clear() { _digraph->clear(); }
   43.97 +
   43.98 +    int id(const Node& n) const { return _digraph->id(n); }
   43.99 +    int id(const Arc& a) const { return _digraph->id(a); }
  43.100 +
  43.101 +    Node nodeFromId(int ix) const { return _digraph->nodeFromId(ix); }
  43.102 +    Arc arcFromId(int ix) const { return _digraph->arcFromId(ix); }
  43.103 +
  43.104 +    int maxNodeId() const { return _digraph->maxNodeId(); }
  43.105 +    int maxArcId() const { return _digraph->maxArcId(); }
  43.106 +
  43.107 +    typedef typename ItemSetTraits<DGR, Node>::ItemNotifier NodeNotifier;
  43.108 +    NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
  43.109 +
  43.110 +    typedef typename ItemSetTraits<DGR, Arc>::ItemNotifier ArcNotifier;
  43.111 +    ArcNotifier& notifier(Arc) const { return _digraph->notifier(Arc()); }
  43.112 +
  43.113 +    template <typename V>
  43.114 +    class NodeMap : public DGR::template NodeMap<V> {
  43.115 +      typedef typename DGR::template NodeMap<V> Parent;
  43.116 +
  43.117 +    public:
  43.118 +      explicit NodeMap(const Adaptor& adaptor)
  43.119 +        : Parent(*adaptor._digraph) {}
  43.120 +      NodeMap(const Adaptor& adaptor, const V& value)
  43.121 +        : Parent(*adaptor._digraph, value) { }
  43.122 +
  43.123 +    private:
  43.124 +      NodeMap& operator=(const NodeMap& cmap) {
  43.125 +        return operator=<NodeMap>(cmap);
  43.126 +      }
  43.127 +
  43.128 +      template <typename CMap>
  43.129 +      NodeMap& operator=(const CMap& cmap) {
  43.130 +        Parent::operator=(cmap);
  43.131 +        return *this;
  43.132 +      }
  43.133 +
  43.134 +    };
  43.135 +
  43.136 +    template <typename V>
  43.137 +    class ArcMap : public DGR::template ArcMap<V> {
  43.138 +      typedef typename DGR::template ArcMap<V> Parent;
  43.139 +
  43.140 +    public:
  43.141 +      explicit ArcMap(const DigraphAdaptorBase<DGR>& adaptor)
  43.142 +        : Parent(*adaptor._digraph) {}
  43.143 +      ArcMap(const DigraphAdaptorBase<DGR>& adaptor, const V& value)
  43.144 +        : Parent(*adaptor._digraph, value) {}
  43.145 +
  43.146 +    private:
  43.147 +      ArcMap& operator=(const ArcMap& cmap) {
  43.148 +        return operator=<ArcMap>(cmap);
  43.149 +      }
  43.150 +
  43.151 +      template <typename CMap>
  43.152 +      ArcMap& operator=(const CMap& cmap) {
  43.153 +        Parent::operator=(cmap);
  43.154 +        return *this;
  43.155 +      }
  43.156 +
  43.157 +    };
  43.158 +
  43.159 +  };
  43.160 +
  43.161 +  template<typename GR>
  43.162 +  class GraphAdaptorBase {
  43.163 +  public:
  43.164 +    typedef GR Graph;
  43.165 +
  43.166 +  protected:
  43.167 +    GR* _graph;
  43.168 +
  43.169 +    GraphAdaptorBase() : _graph(0) {}
  43.170 +
  43.171 +    void initialize(GR& graph) { _graph = &graph; }
  43.172 +
  43.173 +  public:
  43.174 +    GraphAdaptorBase(GR& graph) : _graph(&graph) {}
  43.175 +
  43.176 +    typedef typename GR::Node Node;
  43.177 +    typedef typename GR::Arc Arc;
  43.178 +    typedef typename GR::Edge Edge;
  43.179 +
  43.180 +    void first(Node& i) const { _graph->first(i); }
  43.181 +    void first(Arc& i) const { _graph->first(i); }
  43.182 +    void first(Edge& i) const { _graph->first(i); }
  43.183 +    void firstIn(Arc& i, const Node& n) const { _graph->firstIn(i, n); }
  43.184 +    void firstOut(Arc& i, const Node& n ) const { _graph->firstOut(i, n); }
  43.185 +    void firstInc(Edge &i, bool &d, const Node &n) const {
  43.186 +      _graph->firstInc(i, d, n);
  43.187 +    }
  43.188 +
  43.189 +    void next(Node& i) const { _graph->next(i); }
  43.190 +    void next(Arc& i) const { _graph->next(i); }
  43.191 +    void next(Edge& i) const { _graph->next(i); }
  43.192 +    void nextIn(Arc& i) const { _graph->nextIn(i); }
  43.193 +    void nextOut(Arc& i) const { _graph->nextOut(i); }
  43.194 +    void nextInc(Edge &i, bool &d) const { _graph->nextInc(i, d); }
  43.195 +
  43.196 +    Node u(const Edge& e) const { return _graph->u(e); }
  43.197 +    Node v(const Edge& e) const { return _graph->v(e); }
  43.198 +
  43.199 +    Node source(const Arc& a) const { return _graph->source(a); }
  43.200 +    Node target(const Arc& a) const { return _graph->target(a); }
  43.201 +
  43.202 +    typedef NodeNumTagIndicator<Graph> NodeNumTag;
  43.203 +    int nodeNum() const { return _graph->nodeNum(); }
  43.204 +
  43.205 +    typedef ArcNumTagIndicator<Graph> ArcNumTag;
  43.206 +    int arcNum() const { return _graph->arcNum(); }
  43.207 +
  43.208 +    typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
  43.209 +    int edgeNum() const { return _graph->edgeNum(); }
  43.210 +
  43.211 +    typedef FindArcTagIndicator<Graph> FindArcTag;
  43.212 +    Arc findArc(const Node& u, const Node& v,
  43.213 +                const Arc& prev = INVALID) const {
  43.214 +      return _graph->findArc(u, v, prev);
  43.215 +    }
  43.216 +
  43.217 +    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
  43.218 +    Edge findEdge(const Node& u, const Node& v,
  43.219 +                  const Edge& prev = INVALID) const {
  43.220 +      return _graph->findEdge(u, v, prev);
  43.221 +    }
  43.222 +
  43.223 +    Node addNode() { return _graph->addNode(); }
  43.224 +    Edge addEdge(const Node& u, const Node& v) { return _graph->addEdge(u, v); }
  43.225 +
  43.226 +    void erase(const Node& i) { _graph->erase(i); }
  43.227 +    void erase(const Edge& i) { _graph->erase(i); }
  43.228 +
  43.229 +    void clear() { _graph->clear(); }
  43.230 +
  43.231 +    bool direction(const Arc& a) const { return _graph->direction(a); }
  43.232 +    Arc direct(const Edge& e, bool d) const { return _graph->direct(e, d); }
  43.233 +
  43.234 +    int id(const Node& v) const { return _graph->id(v); }
  43.235 +    int id(const Arc& a) const { return _graph->id(a); }
  43.236 +    int id(const Edge& e) const { return _graph->id(e); }
  43.237 +
  43.238 +    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
  43.239 +    Arc arcFromId(int ix) const { return _graph->arcFromId(ix); }
  43.240 +    Edge edgeFromId(int ix) const { return _graph->edgeFromId(ix); }
  43.241 +
  43.242 +    int maxNodeId() const { return _graph->maxNodeId(); }
  43.243 +    int maxArcId() const { return _graph->maxArcId(); }
  43.244 +    int maxEdgeId() const { return _graph->maxEdgeId(); }
  43.245 +
  43.246 +    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
  43.247 +    NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
  43.248 +
  43.249 +    typedef typename ItemSetTraits<GR, Arc>::ItemNotifier ArcNotifier;
  43.250 +    ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
  43.251 +
  43.252 +    typedef typename ItemSetTraits<GR, Edge>::ItemNotifier EdgeNotifier;
  43.253 +    EdgeNotifier& notifier(Edge) const { return _graph->notifier(Edge()); }
  43.254 +
  43.255 +    template <typename V>
  43.256 +    class NodeMap : public GR::template NodeMap<V> {
  43.257 +      typedef typename GR::template NodeMap<V> Parent;
  43.258 +
  43.259 +    public:
  43.260 +      explicit NodeMap(const GraphAdaptorBase<GR>& adapter)
  43.261 +        : Parent(*adapter._graph) {}
  43.262 +      NodeMap(const GraphAdaptorBase<GR>& adapter, const V& value)
  43.263 +        : Parent(*adapter._graph, value) {}
  43.264 +
  43.265 +    private:
  43.266 +      NodeMap& operator=(const NodeMap& cmap) {
  43.267 +        return operator=<NodeMap>(cmap);
  43.268 +      }
  43.269 +
  43.270 +      template <typename CMap>
  43.271 +      NodeMap& operator=(const CMap& cmap) {
  43.272 +        Parent::operator=(cmap);
  43.273 +        return *this;
  43.274 +      }
  43.275 +
  43.276 +    };
  43.277 +
  43.278 +    template <typename V>
  43.279 +    class ArcMap : public GR::template ArcMap<V> {
  43.280 +      typedef typename GR::template ArcMap<V> Parent;
  43.281 +
  43.282 +    public:
  43.283 +      explicit ArcMap(const GraphAdaptorBase<GR>& adapter)
  43.284 +        : Parent(*adapter._graph) {}
  43.285 +      ArcMap(const GraphAdaptorBase<GR>& adapter, const V& value)
  43.286 +        : Parent(*adapter._graph, value) {}
  43.287 +
  43.288 +    private:
  43.289 +      ArcMap& operator=(const ArcMap& cmap) {
  43.290 +        return operator=<ArcMap>(cmap);
  43.291 +      }
  43.292 +
  43.293 +      template <typename CMap>
  43.294 +      ArcMap& operator=(const CMap& cmap) {
  43.295 +        Parent::operator=(cmap);
  43.296 +        return *this;
  43.297 +      }
  43.298 +    };
  43.299 +
  43.300 +    template <typename V>
  43.301 +    class EdgeMap : public GR::template EdgeMap<V> {
  43.302 +      typedef typename GR::template EdgeMap<V> Parent;
  43.303 +
  43.304 +    public:
  43.305 +      explicit EdgeMap(const GraphAdaptorBase<GR>& adapter)
  43.306 +        : Parent(*adapter._graph) {}
  43.307 +      EdgeMap(const GraphAdaptorBase<GR>& adapter, const V& value)
  43.308 +        : Parent(*adapter._graph, value) {}
  43.309 +
  43.310 +    private:
  43.311 +      EdgeMap& operator=(const EdgeMap& cmap) {
  43.312 +        return operator=<EdgeMap>(cmap);
  43.313 +      }
  43.314 +
  43.315 +      template <typename CMap>
  43.316 +      EdgeMap& operator=(const CMap& cmap) {
  43.317 +        Parent::operator=(cmap);
  43.318 +        return *this;
  43.319 +      }
  43.320 +    };
  43.321 +
  43.322 +  };
  43.323 +
  43.324 +  template <typename DGR>
  43.325 +  class ReverseDigraphBase : public DigraphAdaptorBase<DGR> {
  43.326 +    typedef DigraphAdaptorBase<DGR> Parent;
  43.327 +  public:
  43.328 +    typedef DGR Digraph;
  43.329 +  protected:
  43.330 +    ReverseDigraphBase() : Parent() { }
  43.331 +  public:
  43.332 +    typedef typename Parent::Node Node;
  43.333 +    typedef typename Parent::Arc Arc;
  43.334 +
  43.335 +    void firstIn(Arc& a, const Node& n) const { Parent::firstOut(a, n); }
  43.336 +    void firstOut(Arc& a, const Node& n ) const { Parent::firstIn(a, n); }
  43.337 +
  43.338 +    void nextIn(Arc& a) const { Parent::nextOut(a); }
  43.339 +    void nextOut(Arc& a) const { Parent::nextIn(a); }
  43.340 +
  43.341 +    Node source(const Arc& a) const { return Parent::target(a); }
  43.342 +    Node target(const Arc& a) const { return Parent::source(a); }
  43.343 +
  43.344 +    Arc addArc(const Node& u, const Node& v) { return Parent::addArc(v, u); }
  43.345 +
  43.346 +    typedef FindArcTagIndicator<DGR> FindArcTag;
  43.347 +    Arc findArc(const Node& u, const Node& v,
  43.348 +                const Arc& prev = INVALID) const {
  43.349 +      return Parent::findArc(v, u, prev);
  43.350 +    }
  43.351 +
  43.352 +  };
  43.353 +
  43.354 +  /// \ingroup graph_adaptors
  43.355 +  ///
  43.356 +  /// \brief Adaptor class for reversing the orientation of the arcs in
  43.357 +  /// a digraph.
  43.358 +  ///
  43.359 +  /// ReverseDigraph can be used for reversing the arcs in a digraph.
  43.360 +  /// It conforms to the \ref concepts::Digraph "Digraph" concept.
  43.361 +  ///
  43.362 +  /// The adapted digraph can also be modified through this adaptor
  43.363 +  /// by adding or removing nodes or arcs, unless the \c GR template
  43.364 +  /// parameter is set to be \c const.
  43.365 +  ///
  43.366 +  /// \tparam DGR The type of the adapted digraph.
  43.367 +  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
  43.368 +  /// It can also be specified to be \c const.
  43.369 +  ///
  43.370 +  /// \note The \c Node and \c Arc types of this adaptor and the adapted
  43.371 +  /// digraph are convertible to each other.
  43.372 +  template<typename DGR>
  43.373 +#ifdef DOXYGEN
  43.374 +  class ReverseDigraph {
  43.375 +#else
  43.376 +  class ReverseDigraph :
  43.377 +    public DigraphAdaptorExtender<ReverseDigraphBase<DGR> > {
  43.378 +#endif
  43.379 +    typedef DigraphAdaptorExtender<ReverseDigraphBase<DGR> > Parent;
  43.380 +  public:
  43.381 +    /// The type of the adapted digraph.
  43.382 +    typedef DGR Digraph;
  43.383 +  protected:
  43.384 +    ReverseDigraph() { }
  43.385 +  public:
  43.386 +
  43.387 +    /// \brief Constructor
  43.388 +    ///
  43.389 +    /// Creates a reverse digraph adaptor for the given digraph.
  43.390 +    explicit ReverseDigraph(DGR& digraph) {
  43.391 +      Parent::initialize(digraph);
  43.392 +    }
  43.393 +  };
  43.394 +
  43.395 +  /// \brief Returns a read-only ReverseDigraph adaptor
  43.396 +  ///
  43.397 +  /// This function just returns a read-only \ref ReverseDigraph adaptor.
  43.398 +  /// \ingroup graph_adaptors
  43.399 +  /// \relates ReverseDigraph
  43.400 +  template<typename DGR>
  43.401 +  ReverseDigraph<const DGR> reverseDigraph(const DGR& digraph) {
  43.402 +    return ReverseDigraph<const DGR>(digraph);
  43.403 +  }
  43.404 +
  43.405 +
  43.406 +  template <typename DGR, typename NF, typename AF, bool ch = true>
  43.407 +  class SubDigraphBase : public DigraphAdaptorBase<DGR> {
  43.408 +    typedef DigraphAdaptorBase<DGR> Parent;
  43.409 +  public:
  43.410 +    typedef DGR Digraph;
  43.411 +    typedef NF NodeFilterMap;
  43.412 +    typedef AF ArcFilterMap;
  43.413 +
  43.414 +    typedef SubDigraphBase Adaptor;
  43.415 +  protected:
  43.416 +    NF* _node_filter;
  43.417 +    AF* _arc_filter;
  43.418 +    SubDigraphBase()
  43.419 +      : Parent(), _node_filter(0), _arc_filter(0) { }
  43.420 +
  43.421 +    void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
  43.422 +      Parent::initialize(digraph);
  43.423 +      _node_filter = &node_filter;
  43.424 +      _arc_filter = &arc_filter;      
  43.425 +    }
  43.426 +
  43.427 +  public:
  43.428 +
  43.429 +    typedef typename Parent::Node Node;
  43.430 +    typedef typename Parent::Arc Arc;
  43.431 +
  43.432 +    void first(Node& i) const {
  43.433 +      Parent::first(i);
  43.434 +      while (i != INVALID && !(*_node_filter)[i]) Parent::next(i);
  43.435 +    }
  43.436 +
  43.437 +    void first(Arc& i) const {
  43.438 +      Parent::first(i);
  43.439 +      while (i != INVALID && (!(*_arc_filter)[i]
  43.440 +                              || !(*_node_filter)[Parent::source(i)]
  43.441 +                              || !(*_node_filter)[Parent::target(i)]))
  43.442 +        Parent::next(i);
  43.443 +    }
  43.444 +
  43.445 +    void firstIn(Arc& i, const Node& n) const {
  43.446 +      Parent::firstIn(i, n);
  43.447 +      while (i != INVALID && (!(*_arc_filter)[i]
  43.448 +                              || !(*_node_filter)[Parent::source(i)]))
  43.449 +        Parent::nextIn(i);
  43.450 +    }
  43.451 +
  43.452 +    void firstOut(Arc& i, const Node& n) const {
  43.453 +      Parent::firstOut(i, n);
  43.454 +      while (i != INVALID && (!(*_arc_filter)[i]
  43.455 +                              || !(*_node_filter)[Parent::target(i)]))
  43.456 +        Parent::nextOut(i);
  43.457 +    }
  43.458 +
  43.459 +    void next(Node& i) const {
  43.460 +      Parent::next(i);
  43.461 +      while (i != INVALID && !(*_node_filter)[i]) Parent::next(i);
  43.462 +    }
  43.463 +
  43.464 +    void next(Arc& i) const {
  43.465 +      Parent::next(i);
  43.466 +      while (i != INVALID && (!(*_arc_filter)[i]
  43.467 +                              || !(*_node_filter)[Parent::source(i)]
  43.468 +                              || !(*_node_filter)[Parent::target(i)]))
  43.469 +        Parent::next(i);
  43.470 +    }
  43.471 +
  43.472 +    void nextIn(Arc& i) const {
  43.473 +      Parent::nextIn(i);
  43.474 +      while (i != INVALID && (!(*_arc_filter)[i]
  43.475 +                              || !(*_node_filter)[Parent::source(i)]))
  43.476 +        Parent::nextIn(i);
  43.477 +    }
  43.478 +
  43.479 +    void nextOut(Arc& i) const {
  43.480 +      Parent::nextOut(i);
  43.481 +      while (i != INVALID && (!(*_arc_filter)[i]
  43.482 +                              || !(*_node_filter)[Parent::target(i)]))
  43.483 +        Parent::nextOut(i);
  43.484 +    }
  43.485 +
  43.486 +    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
  43.487 +    void status(const Arc& a, bool v) const { _arc_filter->set(a, v); }
  43.488 +
  43.489 +    bool status(const Node& n) const { return (*_node_filter)[n]; }
  43.490 +    bool status(const Arc& a) const { return (*_arc_filter)[a]; }
  43.491 +
  43.492 +    typedef False NodeNumTag;
  43.493 +    typedef False ArcNumTag;
  43.494 +
  43.495 +    typedef FindArcTagIndicator<DGR> FindArcTag;
  43.496 +    Arc findArc(const Node& source, const Node& target,
  43.497 +                const Arc& prev = INVALID) const {
  43.498 +      if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
  43.499 +        return INVALID;
  43.500 +      }
  43.501 +      Arc arc = Parent::findArc(source, target, prev);
  43.502 +      while (arc != INVALID && !(*_arc_filter)[arc]) {
  43.503 +        arc = Parent::findArc(source, target, arc);
  43.504 +      }
  43.505 +      return arc;
  43.506 +    }
  43.507 +
  43.508 +  public:
  43.509 +
  43.510 +    template <typename V>
  43.511 +    class NodeMap 
  43.512 +      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>, 
  43.513 +	      LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
  43.514 +      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
  43.515 +	LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
  43.516 +
  43.517 +    public:
  43.518 +      typedef V Value;
  43.519 +
  43.520 +      NodeMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
  43.521 +        : Parent(adaptor) {}
  43.522 +      NodeMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor, const V& value)
  43.523 +        : Parent(adaptor, value) {}
  43.524 +
  43.525 +    private:
  43.526 +      NodeMap& operator=(const NodeMap& cmap) {
  43.527 +        return operator=<NodeMap>(cmap);
  43.528 +      }
  43.529 +
  43.530 +      template <typename CMap>
  43.531 +      NodeMap& operator=(const CMap& cmap) {
  43.532 +        Parent::operator=(cmap);
  43.533 +        return *this;
  43.534 +      }
  43.535 +    };
  43.536 +
  43.537 +    template <typename V>
  43.538 +    class ArcMap 
  43.539 +      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
  43.540 +	      LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
  43.541 +      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
  43.542 +        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
  43.543 +
  43.544 +    public:
  43.545 +      typedef V Value;
  43.546 +
  43.547 +      ArcMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
  43.548 +        : Parent(adaptor) {}
  43.549 +      ArcMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor, const V& value)
  43.550 +        : Parent(adaptor, value) {}
  43.551 +
  43.552 +    private:
  43.553 +      ArcMap& operator=(const ArcMap& cmap) {
  43.554 +        return operator=<ArcMap>(cmap);
  43.555 +      }
  43.556 +
  43.557 +      template <typename CMap>
  43.558 +      ArcMap& operator=(const CMap& cmap) {
  43.559 +        Parent::operator=(cmap);
  43.560 +        return *this;
  43.561 +      }
  43.562 +    };
  43.563 +
  43.564 +  };
  43.565 +
  43.566 +  template <typename DGR, typename NF, typename AF>
  43.567 +  class SubDigraphBase<DGR, NF, AF, false>
  43.568 +    : public DigraphAdaptorBase<DGR> {
  43.569 +    typedef DigraphAdaptorBase<DGR> Parent;
  43.570 +  public:
  43.571 +    typedef DGR Digraph;
  43.572 +    typedef NF NodeFilterMap;
  43.573 +    typedef AF ArcFilterMap;
  43.574 +
  43.575 +    typedef SubDigraphBase Adaptor;
  43.576 +  protected:
  43.577 +    NF* _node_filter;
  43.578 +    AF* _arc_filter;
  43.579 +    SubDigraphBase()
  43.580 +      : Parent(), _node_filter(0), _arc_filter(0) { }
  43.581 +
  43.582 +    void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
  43.583 +      Parent::initialize(digraph);
  43.584 +      _node_filter = &node_filter;
  43.585 +      _arc_filter = &arc_filter;      
  43.586 +    }
  43.587 +
  43.588 +  public:
  43.589 +
  43.590 +    typedef typename Parent::Node Node;
  43.591 +    typedef typename Parent::Arc Arc;
  43.592 +
  43.593 +    void first(Node& i) const {
  43.594 +      Parent::first(i);
  43.595 +      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
  43.596 +    }
  43.597 +
  43.598 +    void first(Arc& i) const {
  43.599 +      Parent::first(i);
  43.600 +      while (i!=INVALID && !(*_arc_filter)[i]) Parent::next(i);
  43.601 +    }
  43.602 +
  43.603 +    void firstIn(Arc& i, const Node& n) const {
  43.604 +      Parent::firstIn(i, n);
  43.605 +      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextIn(i);
  43.606 +    }
  43.607 +
  43.608 +    void firstOut(Arc& i, const Node& n) const {
  43.609 +      Parent::firstOut(i, n);
  43.610 +      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextOut(i);
  43.611 +    }
  43.612 +
  43.613 +    void next(Node& i) const {
  43.614 +      Parent::next(i);
  43.615 +      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
  43.616 +    }
  43.617 +    void next(Arc& i) const {
  43.618 +      Parent::next(i);
  43.619 +      while (i!=INVALID && !(*_arc_filter)[i]) Parent::next(i);
  43.620 +    }
  43.621 +    void nextIn(Arc& i) const {
  43.622 +      Parent::nextIn(i);
  43.623 +      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextIn(i);
  43.624 +    }
  43.625 +
  43.626 +    void nextOut(Arc& i) const {
  43.627 +      Parent::nextOut(i);
  43.628 +      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextOut(i);
  43.629 +    }
  43.630 +
  43.631 +    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
  43.632 +    void status(const Arc& a, bool v) const { _arc_filter->set(a, v); }
  43.633 +
  43.634 +    bool status(const Node& n) const { return (*_node_filter)[n]; }
  43.635 +    bool status(const Arc& a) const { return (*_arc_filter)[a]; }
  43.636 +
  43.637 +    typedef False NodeNumTag;
  43.638 +    typedef False ArcNumTag;
  43.639 +
  43.640 +    typedef FindArcTagIndicator<DGR> FindArcTag;
  43.641 +    Arc findArc(const Node& source, const Node& target,
  43.642 +                const Arc& prev = INVALID) const {
  43.643 +      if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
  43.644 +        return INVALID;
  43.645 +      }
  43.646 +      Arc arc = Parent::findArc(source, target, prev);
  43.647 +      while (arc != INVALID && !(*_arc_filter)[arc]) {
  43.648 +        arc = Parent::findArc(source, target, arc);
  43.649 +      }
  43.650 +      return arc;
  43.651 +    }
  43.652 +
  43.653 +    template <typename V>
  43.654 +    class NodeMap 
  43.655 +      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
  43.656 +          LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
  43.657 +      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>, 
  43.658 +        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
  43.659 +
  43.660 +    public:
  43.661 +      typedef V Value;
  43.662 +
  43.663 +      NodeMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
  43.664 +        : Parent(adaptor) {}
  43.665 +      NodeMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor, const V& value)
  43.666 +        : Parent(adaptor, value) {}
  43.667 +
  43.668 +    private:
  43.669 +      NodeMap& operator=(const NodeMap& cmap) {
  43.670 +        return operator=<NodeMap>(cmap);
  43.671 +      }
  43.672 +
  43.673 +      template <typename CMap>
  43.674 +      NodeMap& operator=(const CMap& cmap) {
  43.675 +        Parent::operator=(cmap);
  43.676 +        return *this;
  43.677 +      }
  43.678 +    };
  43.679 +
  43.680 +    template <typename V>
  43.681 +    class ArcMap 
  43.682 +      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
  43.683 +          LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
  43.684 +      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
  43.685 +        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
  43.686 +
  43.687 +    public:
  43.688 +      typedef V Value;
  43.689 +
  43.690 +      ArcMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
  43.691 +        : Parent(adaptor) {}
  43.692 +      ArcMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor, const V& value)
  43.693 +        : Parent(adaptor, value) {}
  43.694 +
  43.695 +    private:
  43.696 +      ArcMap& operator=(const ArcMap& cmap) {
  43.697 +        return operator=<ArcMap>(cmap);
  43.698 +      }
  43.699 +
  43.700 +      template <typename CMap>
  43.701 +      ArcMap& operator=(const CMap& cmap) {
  43.702 +        Parent::operator=(cmap);
  43.703 +        return *this;
  43.704 +      }
  43.705 +    };
  43.706 +
  43.707 +  };
  43.708 +
  43.709 +  /// \ingroup graph_adaptors
  43.710 +  ///
  43.711 +  /// \brief Adaptor class for hiding nodes and arcs in a digraph
  43.712 +  ///
  43.713 +  /// SubDigraph can be used for hiding nodes and arcs in a digraph.
  43.714 +  /// A \c bool node map and a \c bool arc map must be specified, which
  43.715 +  /// define the filters for nodes and arcs.
  43.716 +  /// Only the nodes and arcs with \c true filter value are
  43.717 +  /// shown in the subdigraph. The arcs that are incident to hidden
  43.718 +  /// nodes are also filtered out.
  43.719 +  /// This adaptor conforms to the \ref concepts::Digraph "Digraph" concept.
  43.720 +  ///
  43.721 +  /// The adapted digraph can also be modified through this adaptor
  43.722 +  /// by adding or removing nodes or arcs, unless the \c GR template
  43.723 +  /// parameter is set to be \c const.
  43.724 +  ///
  43.725 +  /// \tparam DGR The type of the adapted digraph.
  43.726 +  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
  43.727 +  /// It can also be specified to be \c const.
  43.728 +  /// \tparam NF The type of the node filter map.
  43.729 +  /// It must be a \c bool (or convertible) node map of the
  43.730 +  /// adapted digraph. The default type is
  43.731 +  /// \ref concepts::Digraph::NodeMap "DGR::NodeMap<bool>".
  43.732 +  /// \tparam AF The type of the arc filter map.
  43.733 +  /// It must be \c bool (or convertible) arc map of the
  43.734 +  /// adapted digraph. The default type is
  43.735 +  /// \ref concepts::Digraph::ArcMap "DGR::ArcMap<bool>".
  43.736 +  ///
  43.737 +  /// \note The \c Node and \c Arc types of this adaptor and the adapted
  43.738 +  /// digraph are convertible to each other.
  43.739 +  ///
  43.740 +  /// \see FilterNodes
  43.741 +  /// \see FilterArcs
  43.742 +#ifdef DOXYGEN
  43.743 +  template<typename DGR, typename NF, typename AF>
  43.744 +  class SubDigraph {
  43.745 +#else
  43.746 +  template<typename DGR,
  43.747 +           typename NF = typename DGR::template NodeMap<bool>,
  43.748 +           typename AF = typename DGR::template ArcMap<bool> >
  43.749 +  class SubDigraph :
  43.750 +    public DigraphAdaptorExtender<SubDigraphBase<DGR, NF, AF, true> > {
  43.751 +#endif
  43.752 +  public:
  43.753 +    /// The type of the adapted digraph.
  43.754 +    typedef DGR Digraph;
  43.755 +    /// The type of the node filter map.
  43.756 +    typedef NF NodeFilterMap;
  43.757 +    /// The type of the arc filter map.
  43.758 +    typedef AF ArcFilterMap;
  43.759 +
  43.760 +    typedef DigraphAdaptorExtender<SubDigraphBase<DGR, NF, AF, true> >
  43.761 +      Parent;
  43.762 +
  43.763 +    typedef typename Parent::Node Node;
  43.764 +    typedef typename Parent::Arc Arc;
  43.765 +
  43.766 +  protected:
  43.767 +    SubDigraph() { }
  43.768 +  public:
  43.769 +
  43.770 +    /// \brief Constructor
  43.771 +    ///
  43.772 +    /// Creates a subdigraph for the given digraph with the
  43.773 +    /// given node and arc filter maps.
  43.774 +    SubDigraph(DGR& digraph, NF& node_filter, AF& arc_filter) {
  43.775 +      Parent::initialize(digraph, node_filter, arc_filter);
  43.776 +    }
  43.777 +
  43.778 +    /// \brief Sets the status of the given node
  43.779 +    ///
  43.780 +    /// This function sets the status of the given node.
  43.781 +    /// It is done by simply setting the assigned value of \c n
  43.782 +    /// to \c v in the node filter map.
  43.783 +    void status(const Node& n, bool v) const { Parent::status(n, v); }
  43.784 +
  43.785 +    /// \brief Sets the status of the given arc
  43.786 +    ///
  43.787 +    /// This function sets the status of the given arc.
  43.788 +    /// It is done by simply setting the assigned value of \c a
  43.789 +    /// to \c v in the arc filter map.
  43.790 +    void status(const Arc& a, bool v) const { Parent::status(a, v); }
  43.791 +
  43.792 +    /// \brief Returns the status of the given node
  43.793 +    ///
  43.794 +    /// This function returns the status of the given node.
  43.795 +    /// It is \c true if the given node is enabled (i.e. not hidden).
  43.796 +    bool status(const Node& n) const { return Parent::status(n); }
  43.797 +
  43.798 +    /// \brief Returns the status of the given arc
  43.799 +    ///
  43.800 +    /// This function returns the status of the given arc.
  43.801 +    /// It is \c true if the given arc is enabled (i.e. not hidden).
  43.802 +    bool status(const Arc& a) const { return Parent::status(a); }
  43.803 +
  43.804 +    /// \brief Disables the given node
  43.805 +    ///
  43.806 +    /// This function disables the given node in the subdigraph,
  43.807 +    /// so the iteration jumps over it.
  43.808 +    /// It is the same as \ref status() "status(n, false)".
  43.809 +    void disable(const Node& n) const { Parent::status(n, false); }
  43.810 +
  43.811 +    /// \brief Disables the given arc
  43.812 +    ///
  43.813 +    /// This function disables the given arc in the subdigraph,
  43.814 +    /// so the iteration jumps over it.
  43.815 +    /// It is the same as \ref status() "status(a, false)".
  43.816 +    void disable(const Arc& a) const { Parent::status(a, false); }
  43.817 +
  43.818 +    /// \brief Enables the given node
  43.819 +    ///
  43.820 +    /// This function enables the given node in the subdigraph.
  43.821 +    /// It is the same as \ref status() "status(n, true)".
  43.822 +    void enable(const Node& n) const { Parent::status(n, true); }
  43.823 +
  43.824 +    /// \brief Enables the given arc
  43.825 +    ///
  43.826 +    /// This function enables the given arc in the subdigraph.
  43.827 +    /// It is the same as \ref status() "status(a, true)".
  43.828 +    void enable(const Arc& a) const { Parent::status(a, true); }
  43.829 +
  43.830 +  };
  43.831 +
  43.832 +  /// \brief Returns a read-only SubDigraph adaptor
  43.833 +  ///
  43.834 +  /// This function just returns a read-only \ref SubDigraph adaptor.
  43.835 +  /// \ingroup graph_adaptors
  43.836 +  /// \relates SubDigraph
  43.837 +  template<typename DGR, typename NF, typename AF>
  43.838 +  SubDigraph<const DGR, NF, AF>
  43.839 +  subDigraph(const DGR& digraph,
  43.840 +             NF& node_filter, AF& arc_filter) {
  43.841 +    return SubDigraph<const DGR, NF, AF>
  43.842 +      (digraph, node_filter, arc_filter);
  43.843 +  }
  43.844 +
  43.845 +  template<typename DGR, typename NF, typename AF>
  43.846 +  SubDigraph<const DGR, const NF, AF>
  43.847 +  subDigraph(const DGR& digraph,
  43.848 +             const NF& node_filter, AF& arc_filter) {
  43.849 +    return SubDigraph<const DGR, const NF, AF>
  43.850 +      (digraph, node_filter, arc_filter);
  43.851 +  }
  43.852 +
  43.853 +  template<typename DGR, typename NF, typename AF>
  43.854 +  SubDigraph<const DGR, NF, const AF>
  43.855 +  subDigraph(const DGR& digraph,
  43.856 +             NF& node_filter, const AF& arc_filter) {
  43.857 +    return SubDigraph<const DGR, NF, const AF>
  43.858 +      (digraph, node_filter, arc_filter);
  43.859 +  }
  43.860 +
  43.861 +  template<typename DGR, typename NF, typename AF>
  43.862 +  SubDigraph<const DGR, const NF, const AF>
  43.863 +  subDigraph(const DGR& digraph,
  43.864 +             const NF& node_filter, const AF& arc_filter) {
  43.865 +    return SubDigraph<const DGR, const NF, const AF>
  43.866 +      (digraph, node_filter, arc_filter);
  43.867 +  }
  43.868 +
  43.869 +
  43.870 +  template <typename GR, typename NF, typename EF, bool ch = true>
  43.871 +  class SubGraphBase : public GraphAdaptorBase<GR> {
  43.872 +    typedef GraphAdaptorBase<GR> Parent;
  43.873 +  public:
  43.874 +    typedef GR Graph;
  43.875 +    typedef NF NodeFilterMap;
  43.876 +    typedef EF EdgeFilterMap;
  43.877 +
  43.878 +    typedef SubGraphBase Adaptor;
  43.879 +  protected:
  43.880 +
  43.881 +    NF* _node_filter;
  43.882 +    EF* _edge_filter;
  43.883 +
  43.884 +    SubGraphBase()
  43.885 +      : Parent(), _node_filter(0), _edge_filter(0) { }
  43.886 +
  43.887 +    void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
  43.888 +      Parent::initialize(graph);
  43.889 +      _node_filter = &node_filter;
  43.890 +      _edge_filter = &edge_filter;
  43.891 +    }
  43.892 +
  43.893 +  public:
  43.894 +
  43.895 +    typedef typename Parent::Node Node;
  43.896 +    typedef typename Parent::Arc Arc;
  43.897 +    typedef typename Parent::Edge Edge;
  43.898 +
  43.899 +    void first(Node& i) const {
  43.900 +      Parent::first(i);
  43.901 +      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
  43.902 +    }
  43.903 +
  43.904 +    void first(Arc& i) const {
  43.905 +      Parent::first(i);
  43.906 +      while (i!=INVALID && (!(*_edge_filter)[i]
  43.907 +                            || !(*_node_filter)[Parent::source(i)]
  43.908 +                            || !(*_node_filter)[Parent::target(i)]))
  43.909 +        Parent::next(i);
  43.910 +    }
  43.911 +
  43.912 +    void first(Edge& i) const {
  43.913 +      Parent::first(i);
  43.914 +      while (i!=INVALID && (!(*_edge_filter)[i]
  43.915 +                            || !(*_node_filter)[Parent::u(i)]
  43.916 +                            || !(*_node_filter)[Parent::v(i)]))
  43.917 +        Parent::next(i);
  43.918 +    }
  43.919 +
  43.920 +    void firstIn(Arc& i, const Node& n) const {
  43.921 +      Parent::firstIn(i, n);
  43.922 +      while (i!=INVALID && (!(*_edge_filter)[i]
  43.923 +                            || !(*_node_filter)[Parent::source(i)]))
  43.924 +        Parent::nextIn(i);
  43.925 +    }
  43.926 +
  43.927 +    void firstOut(Arc& i, const Node& n) const {
  43.928 +      Parent::firstOut(i, n);
  43.929 +      while (i!=INVALID && (!(*_edge_filter)[i]
  43.930 +                            || !(*_node_filter)[Parent::target(i)]))
  43.931 +        Parent::nextOut(i);
  43.932 +    }
  43.933 +
  43.934 +    void firstInc(Edge& i, bool& d, const Node& n) const {
  43.935 +      Parent::firstInc(i, d, n);
  43.936 +      while (i!=INVALID && (!(*_edge_filter)[i]
  43.937 +                            || !(*_node_filter)[Parent::u(i)]
  43.938 +                            || !(*_node_filter)[Parent::v(i)]))
  43.939 +        Parent::nextInc(i, d);
  43.940 +    }
  43.941 +
  43.942 +    void next(Node& i) const {
  43.943 +      Parent::next(i);
  43.944 +      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
  43.945 +    }
  43.946 +
  43.947 +    void next(Arc& i) const {
  43.948 +      Parent::next(i);
  43.949 +      while (i!=INVALID && (!(*_edge_filter)[i]
  43.950 +                            || !(*_node_filter)[Parent::source(i)]
  43.951 +                            || !(*_node_filter)[Parent::target(i)]))
  43.952 +        Parent::next(i);
  43.953 +    }
  43.954 +
  43.955 +    void next(Edge& i) const {
  43.956 +      Parent::next(i);
  43.957 +      while (i!=INVALID && (!(*_edge_filter)[i]
  43.958 +                            || !(*_node_filter)[Parent::u(i)]
  43.959 +                            || !(*_node_filter)[Parent::v(i)]))
  43.960 +        Parent::next(i);
  43.961 +    }
  43.962 +
  43.963 +    void nextIn(Arc& i) const {
  43.964 +      Parent::nextIn(i);
  43.965 +      while (i!=INVALID && (!(*_edge_filter)[i]
  43.966 +                            || !(*_node_filter)[Parent::source(i)]))
  43.967 +        Parent::nextIn(i);
  43.968 +    }
  43.969 +
  43.970 +    void nextOut(Arc& i) const {
  43.971 +      Parent::nextOut(i);
  43.972 +      while (i!=INVALID && (!(*_edge_filter)[i]
  43.973 +                            || !(*_node_filter)[Parent::target(i)]))
  43.974 +        Parent::nextOut(i);
  43.975 +    }
  43.976 +
  43.977 +    void nextInc(Edge& i, bool& d) const {
  43.978 +      Parent::nextInc(i, d);
  43.979 +      while (i!=INVALID && (!(*_edge_filter)[i]
  43.980 +                            || !(*_node_filter)[Parent::u(i)]
  43.981 +                            || !(*_node_filter)[Parent::v(i)]))
  43.982 +        Parent::nextInc(i, d);
  43.983 +    }
  43.984 +
  43.985 +    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
  43.986 +    void status(const Edge& e, bool v) const { _edge_filter->set(e, v); }
  43.987 +
  43.988 +    bool status(const Node& n) const { return (*_node_filter)[n]; }
  43.989 +    bool status(const Edge& e) const { return (*_edge_filter)[e]; }
  43.990 +
  43.991 +    typedef False NodeNumTag;
  43.992 +    typedef False ArcNumTag;
  43.993 +    typedef False EdgeNumTag;
  43.994 +
  43.995 +    typedef FindArcTagIndicator<Graph> FindArcTag;
  43.996 +    Arc findArc(const Node& u, const Node& v,
  43.997 +                const Arc& prev = INVALID) const {
  43.998 +      if (!(*_node_filter)[u] || !(*_node_filter)[v]) {
  43.999 +        return INVALID;
 43.1000 +      }
 43.1001 +      Arc arc = Parent::findArc(u, v, prev);
 43.1002 +      while (arc != INVALID && !(*_edge_filter)[arc]) {
 43.1003 +        arc = Parent::findArc(u, v, arc);
 43.1004 +      }
 43.1005 +      return arc;
 43.1006 +    }
 43.1007 +
 43.1008 +    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
 43.1009 +    Edge findEdge(const Node& u, const Node& v,
 43.1010 +                  const Edge& prev = INVALID) const {
 43.1011 +      if (!(*_node_filter)[u] || !(*_node_filter)[v]) {
 43.1012 +        return INVALID;
 43.1013 +      }
 43.1014 +      Edge edge = Parent::findEdge(u, v, prev);
 43.1015 +      while (edge != INVALID && !(*_edge_filter)[edge]) {
 43.1016 +        edge = Parent::findEdge(u, v, edge);
 43.1017 +      }
 43.1018 +      return edge;
 43.1019 +    }
 43.1020 +
 43.1021 +    template <typename V>
 43.1022 +    class NodeMap 
 43.1023 +      : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
 43.1024 +          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
 43.1025 +      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
 43.1026 +        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
 43.1027 +
 43.1028 +    public:
 43.1029 +      typedef V Value;
 43.1030 +
 43.1031 +      NodeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
 43.1032 +        : Parent(adaptor) {}
 43.1033 +      NodeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
 43.1034 +        : Parent(adaptor, value) {}
 43.1035 +
 43.1036 +    private:
 43.1037 +      NodeMap& operator=(const NodeMap& cmap) {
 43.1038 +        return operator=<NodeMap>(cmap);
 43.1039 +      }
 43.1040 +
 43.1041 +      template <typename CMap>
 43.1042 +      NodeMap& operator=(const CMap& cmap) {
 43.1043 +        Parent::operator=(cmap);
 43.1044 +        return *this;
 43.1045 +      }
 43.1046 +    };
 43.1047 +
 43.1048 +    template <typename V>
 43.1049 +    class ArcMap 
 43.1050 +      : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
 43.1051 +          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
 43.1052 +      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
 43.1053 +        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
 43.1054 +
 43.1055 +    public:
 43.1056 +      typedef V Value;
 43.1057 +
 43.1058 +      ArcMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
 43.1059 +        : Parent(adaptor) {}
 43.1060 +      ArcMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
 43.1061 +        : Parent(adaptor, value) {}
 43.1062 +
 43.1063 +    private:
 43.1064 +      ArcMap& operator=(const ArcMap& cmap) {
 43.1065 +        return operator=<ArcMap>(cmap);
 43.1066 +      }
 43.1067 +
 43.1068 +      template <typename CMap>
 43.1069 +      ArcMap& operator=(const CMap& cmap) {
 43.1070 +        Parent::operator=(cmap);
 43.1071 +        return *this;
 43.1072 +      }
 43.1073 +    };
 43.1074 +
 43.1075 +    template <typename V>
 43.1076 +    class EdgeMap 
 43.1077 +      : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
 43.1078 +        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
 43.1079 +      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
 43.1080 +        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
 43.1081 +
 43.1082 +    public:
 43.1083 +      typedef V Value;
 43.1084 +
 43.1085 +      EdgeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
 43.1086 +        : Parent(adaptor) {}
 43.1087 +
 43.1088 +      EdgeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
 43.1089 +        : Parent(adaptor, value) {}
 43.1090 +
 43.1091 +    private:
 43.1092 +      EdgeMap& operator=(const EdgeMap& cmap) {
 43.1093 +        return operator=<EdgeMap>(cmap);
 43.1094 +      }
 43.1095 +
 43.1096 +      template <typename CMap>
 43.1097 +      EdgeMap& operator=(const CMap& cmap) {
 43.1098 +        Parent::operator=(cmap);
 43.1099 +        return *this;
 43.1100 +      }
 43.1101 +    };
 43.1102 +
 43.1103 +  };
 43.1104 +
 43.1105 +  template <typename GR, typename NF, typename EF>
 43.1106 +  class SubGraphBase<GR, NF, EF, false>
 43.1107 +    : public GraphAdaptorBase<GR> {
 43.1108 +    typedef GraphAdaptorBase<GR> Parent;
 43.1109 +  public:
 43.1110 +    typedef GR Graph;
 43.1111 +    typedef NF NodeFilterMap;
 43.1112 +    typedef EF EdgeFilterMap;
 43.1113 +
 43.1114 +    typedef SubGraphBase Adaptor;
 43.1115 +  protected:
 43.1116 +    NF* _node_filter;
 43.1117 +    EF* _edge_filter;
 43.1118 +    SubGraphBase() 
 43.1119 +	  : Parent(), _node_filter(0), _edge_filter(0) { }
 43.1120 +
 43.1121 +    void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
 43.1122 +      Parent::initialize(graph);
 43.1123 +      _node_filter = &node_filter;
 43.1124 +      _edge_filter = &edge_filter;
 43.1125 +    }
 43.1126 +
 43.1127 +  public:
 43.1128 +
 43.1129 +    typedef typename Parent::Node Node;
 43.1130 +    typedef typename Parent::Arc Arc;
 43.1131 +    typedef typename Parent::Edge Edge;
 43.1132 +
 43.1133 +    void first(Node& i) const {
 43.1134 +      Parent::first(i);
 43.1135 +      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
 43.1136 +    }
 43.1137 +
 43.1138 +    void first(Arc& i) const {
 43.1139 +      Parent::first(i);
 43.1140 +      while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
 43.1141 +    }
 43.1142 +
 43.1143 +    void first(Edge& i) const {
 43.1144 +      Parent::first(i);
 43.1145 +      while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
 43.1146 +    }
 43.1147 +
 43.1148 +    void firstIn(Arc& i, const Node& n) const {
 43.1149 +      Parent::firstIn(i, n);
 43.1150 +      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextIn(i);
 43.1151 +    }
 43.1152 +
 43.1153 +    void firstOut(Arc& i, const Node& n) const {
 43.1154 +      Parent::firstOut(i, n);
 43.1155 +      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextOut(i);
 43.1156 +    }
 43.1157 +
 43.1158 +    void firstInc(Edge& i, bool& d, const Node& n) const {
 43.1159 +      Parent::firstInc(i, d, n);
 43.1160 +      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextInc(i, d);
 43.1161 +    }
 43.1162 +
 43.1163 +    void next(Node& i) const {
 43.1164 +      Parent::next(i);
 43.1165 +      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
 43.1166 +    }
 43.1167 +    void next(Arc& i) const {
 43.1168 +      Parent::next(i);
 43.1169 +      while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
 43.1170 +    }
 43.1171 +    void next(Edge& i) const {
 43.1172 +      Parent::next(i);
 43.1173 +      while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
 43.1174 +    }
 43.1175 +    void nextIn(Arc& i) const {
 43.1176 +      Parent::nextIn(i);
 43.1177 +      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextIn(i);
 43.1178 +    }
 43.1179 +
 43.1180 +    void nextOut(Arc& i) const {
 43.1181 +      Parent::nextOut(i);
 43.1182 +      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextOut(i);
 43.1183 +    }
 43.1184 +    void nextInc(Edge& i, bool& d) const {
 43.1185 +      Parent::nextInc(i, d);
 43.1186 +      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextInc(i, d);
 43.1187 +    }
 43.1188 +
 43.1189 +    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
 43.1190 +    void status(const Edge& e, bool v) const { _edge_filter->set(e, v); }
 43.1191 +
 43.1192 +    bool status(const Node& n) const { return (*_node_filter)[n]; }
 43.1193 +    bool status(const Edge& e) const { return (*_edge_filter)[e]; }
 43.1194 +
 43.1195 +    typedef False NodeNumTag;
 43.1196 +    typedef False ArcNumTag;
 43.1197 +    typedef False EdgeNumTag;
 43.1198 +
 43.1199 +    typedef FindArcTagIndicator<Graph> FindArcTag;
 43.1200 +    Arc findArc(const Node& u, const Node& v,
 43.1201 +                const Arc& prev = INVALID) const {
 43.1202 +      Arc arc = Parent::findArc(u, v, prev);
 43.1203 +      while (arc != INVALID && !(*_edge_filter)[arc]) {
 43.1204 +        arc = Parent::findArc(u, v, arc);
 43.1205 +      }
 43.1206 +      return arc;
 43.1207 +    }
 43.1208 +
 43.1209 +    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
 43.1210 +    Edge findEdge(const Node& u, const Node& v,
 43.1211 +                  const Edge& prev = INVALID) const {
 43.1212 +      Edge edge = Parent::findEdge(u, v, prev);
 43.1213 +      while (edge != INVALID && !(*_edge_filter)[edge]) {
 43.1214 +        edge = Parent::findEdge(u, v, edge);
 43.1215 +      }
 43.1216 +      return edge;
 43.1217 +    }
 43.1218 +
 43.1219 +    template <typename V>
 43.1220 +    class NodeMap 
 43.1221 +      : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
 43.1222 +          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
 43.1223 +      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
 43.1224 +        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
 43.1225 +
 43.1226 +    public:
 43.1227 +      typedef V Value;
 43.1228 +
 43.1229 +      NodeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
 43.1230 +        : Parent(adaptor) {}
 43.1231 +      NodeMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
 43.1232 +        : Parent(adaptor, value) {}
 43.1233 +
 43.1234 +    private:
 43.1235 +      NodeMap& operator=(const NodeMap& cmap) {
 43.1236 +        return operator=<NodeMap>(cmap);
 43.1237 +      }
 43.1238 +
 43.1239 +      template <typename CMap>
 43.1240 +      NodeMap& operator=(const CMap& cmap) {
 43.1241 +        Parent::operator=(cmap);
 43.1242 +        return *this;
 43.1243 +      }
 43.1244 +    };
 43.1245 +
 43.1246 +    template <typename V>
 43.1247 +    class ArcMap 
 43.1248 +      : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
 43.1249 +          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
 43.1250 +      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
 43.1251 +        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
 43.1252 +
 43.1253 +    public:
 43.1254 +      typedef V Value;
 43.1255 +
 43.1256 +      ArcMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
 43.1257 +        : Parent(adaptor) {}
 43.1258 +      ArcMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
 43.1259 +        : Parent(adaptor, value) {}
 43.1260 +
 43.1261 +    private:
 43.1262 +      ArcMap& operator=(const ArcMap& cmap) {
 43.1263 +        return operator=<ArcMap>(cmap);
 43.1264 +      }
 43.1265 +
 43.1266 +      template <typename CMap>
 43.1267 +      ArcMap& operator=(const CMap& cmap) {
 43.1268 +        Parent::operator=(cmap);
 43.1269 +        return *this;
 43.1270 +      }
 43.1271 +    };
 43.1272 +
 43.1273 +    template <typename V>
 43.1274 +    class EdgeMap 
 43.1275 +      : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
 43.1276 +        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
 43.1277 +      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
 43.1278 +	LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
 43.1279 +
 43.1280 +    public:
 43.1281 +      typedef V Value;
 43.1282 +
 43.1283 +      EdgeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
 43.1284 +        : Parent(adaptor) {}
 43.1285 +
 43.1286 +      EdgeMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
 43.1287 +        : Parent(adaptor, value) {}
 43.1288 +
 43.1289 +    private:
 43.1290 +      EdgeMap& operator=(const EdgeMap& cmap) {
 43.1291 +        return operator=<EdgeMap>(cmap);
 43.1292 +      }
 43.1293 +
 43.1294 +      template <typename CMap>
 43.1295 +      EdgeMap& operator=(const CMap& cmap) {
 43.1296 +        Parent::operator=(cmap);
 43.1297 +        return *this;
 43.1298 +      }
 43.1299 +    };
 43.1300 +
 43.1301 +  };
 43.1302 +
 43.1303 +  /// \ingroup graph_adaptors
 43.1304 +  ///
 43.1305 +  /// \brief Adaptor class for hiding nodes and edges in an undirected
 43.1306 +  /// graph.
 43.1307 +  ///
 43.1308 +  /// SubGraph can be used for hiding nodes and edges in a graph.
 43.1309 +  /// A \c bool node map and a \c bool edge map must be specified, which
 43.1310 +  /// define the filters for nodes and edges.
 43.1311 +  /// Only the nodes and edges with \c true filter value are
 43.1312 +  /// shown in the subgraph. The edges that are incident to hidden
 43.1313 +  /// nodes are also filtered out.
 43.1314 +  /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
 43.1315 +  ///
 43.1316 +  /// The adapted graph can also be modified through this adaptor
 43.1317 +  /// by adding or removing nodes or edges, unless the \c GR template
 43.1318 +  /// parameter is set to be \c const.
 43.1319 +  ///
 43.1320 +  /// \tparam GR The type of the adapted graph.
 43.1321 +  /// It must conform to the \ref concepts::Graph "Graph" concept.
 43.1322 +  /// It can also be specified to be \c const.
 43.1323 +  /// \tparam NF The type of the node filter map.
 43.1324 +  /// It must be a \c bool (or convertible) node map of the
 43.1325 +  /// adapted graph. The default type is
 43.1326 +  /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
 43.1327 +  /// \tparam EF The type of the edge filter map.
 43.1328 +  /// It must be a \c bool (or convertible) edge map of the
 43.1329 +  /// adapted graph. The default type is
 43.1330 +  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
 43.1331 +  ///
 43.1332 +  /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
 43.1333 +  /// adapted graph are convertible to each other.
 43.1334 +  ///
 43.1335 +  /// \see FilterNodes
 43.1336 +  /// \see FilterEdges
 43.1337 +#ifdef DOXYGEN
 43.1338 +  template<typename GR, typename NF, typename EF>
 43.1339 +  class SubGraph {
 43.1340 +#else
 43.1341 +  template<typename GR,
 43.1342 +           typename NF = typename GR::template NodeMap<bool>,
 43.1343 +           typename EF = typename GR::template EdgeMap<bool> >
 43.1344 +  class SubGraph :
 43.1345 +    public GraphAdaptorExtender<SubGraphBase<GR, NF, EF, true> > {
 43.1346 +#endif
 43.1347 +  public:
 43.1348 +    /// The type of the adapted graph.
 43.1349 +    typedef GR Graph;
 43.1350 +    /// The type of the node filter map.
 43.1351 +    typedef NF NodeFilterMap;
 43.1352 +    /// The type of the edge filter map.
 43.1353 +    typedef EF EdgeFilterMap;
 43.1354 +
 43.1355 +    typedef GraphAdaptorExtender<SubGraphBase<GR, NF, EF, true> >
 43.1356 +      Parent;
 43.1357 +
 43.1358 +    typedef typename Parent::Node Node;
 43.1359 +    typedef typename Parent::Edge Edge;
 43.1360 +
 43.1361 +  protected:
 43.1362 +    SubGraph() { }
 43.1363 +  public:
 43.1364 +
 43.1365 +    /// \brief Constructor
 43.1366 +    ///
 43.1367 +    /// Creates a subgraph for the given graph with the given node
 43.1368 +    /// and edge filter maps.
 43.1369 +    SubGraph(GR& graph, NF& node_filter, EF& edge_filter) {
 43.1370 +      initialize(graph, node_filter, edge_filter);
 43.1371 +    }
 43.1372 +
 43.1373 +    /// \brief Sets the status of the given node
 43.1374 +    ///
 43.1375 +    /// This function sets the status of the given node.
 43.1376 +    /// It is done by simply setting the assigned value of \c n
 43.1377 +    /// to \c v in the node filter map.
 43.1378 +    void status(const Node& n, bool v) const { Parent::status(n, v); }
 43.1379 +
 43.1380 +    /// \brief Sets the status of the given edge
 43.1381 +    ///
 43.1382 +    /// This function sets the status of the given edge.
 43.1383 +    /// It is done by simply setting the assigned value of \c e
 43.1384 +    /// to \c v in the edge filter map.
 43.1385 +    void status(const Edge& e, bool v) const { Parent::status(e, v); }
 43.1386 +
 43.1387 +    /// \brief Returns the status of the given node
 43.1388 +    ///
 43.1389 +    /// This function returns the status of the given node.
 43.1390 +    /// It is \c true if the given node is enabled (i.e. not hidden).
 43.1391 +    bool status(const Node& n) const { return Parent::status(n); }
 43.1392 +
 43.1393 +    /// \brief Returns the status of the given edge
 43.1394 +    ///
 43.1395 +    /// This function returns the status of the given edge.
 43.1396 +    /// It is \c true if the given edge is enabled (i.e. not hidden).
 43.1397 +    bool status(const Edge& e) const { return Parent::status(e); }
 43.1398 +
 43.1399 +    /// \brief Disables the given node
 43.1400 +    ///
 43.1401 +    /// This function disables the given node in the subdigraph,
 43.1402 +    /// so the iteration jumps over it.
 43.1403 +    /// It is the same as \ref status() "status(n, false)".
 43.1404 +    void disable(const Node& n) const { Parent::status(n, false); }
 43.1405 +
 43.1406 +    /// \brief Disables the given edge
 43.1407 +    ///
 43.1408 +    /// This function disables the given edge in the subgraph,
 43.1409 +    /// so the iteration jumps over it.
 43.1410 +    /// It is the same as \ref status() "status(e, false)".
 43.1411 +    void disable(const Edge& e) const { Parent::status(e, false); }
 43.1412 +
 43.1413 +    /// \brief Enables the given node
 43.1414 +    ///
 43.1415 +    /// This function enables the given node in the subdigraph.
 43.1416 +    /// It is the same as \ref status() "status(n, true)".
 43.1417 +    void enable(const Node& n) const { Parent::status(n, true); }
 43.1418 +
 43.1419 +    /// \brief Enables the given edge
 43.1420 +    ///
 43.1421 +    /// This function enables the given edge in the subgraph.
 43.1422 +    /// It is the same as \ref status() "status(e, true)".
 43.1423 +    void enable(const Edge& e) const { Parent::status(e, true); }
 43.1424 +
 43.1425 +  };
 43.1426 +
 43.1427 +  /// \brief Returns a read-only SubGraph adaptor
 43.1428 +  ///
 43.1429 +  /// This function just returns a read-only \ref SubGraph adaptor.
 43.1430 +  /// \ingroup graph_adaptors
 43.1431 +  /// \relates SubGraph
 43.1432 +  template<typename GR, typename NF, typename EF>
 43.1433 +  SubGraph<const GR, NF, EF>
 43.1434 +  subGraph(const GR& graph, NF& node_filter, EF& edge_filter) {
 43.1435 +    return SubGraph<const GR, NF, EF>
 43.1436 +      (graph, node_filter, edge_filter);
 43.1437 +  }
 43.1438 +
 43.1439 +  template<typename GR, typename NF, typename EF>
 43.1440 +  SubGraph<const GR, const NF, EF>
 43.1441 +  subGraph(const GR& graph, const NF& node_filter, EF& edge_filter) {
 43.1442 +    return SubGraph<const GR, const NF, EF>
 43.1443 +      (graph, node_filter, edge_filter);
 43.1444 +  }
 43.1445 +
 43.1446 +  template<typename GR, typename NF, typename EF>
 43.1447 +  SubGraph<const GR, NF, const EF>
 43.1448 +  subGraph(const GR& graph, NF& node_filter, const EF& edge_filter) {
 43.1449 +    return SubGraph<const GR, NF, const EF>
 43.1450 +      (graph, node_filter, edge_filter);
 43.1451 +  }
 43.1452 +
 43.1453 +  template<typename GR, typename NF, typename EF>
 43.1454 +  SubGraph<const GR, const NF, const EF>
 43.1455 +  subGraph(const GR& graph, const NF& node_filter, const EF& edge_filter) {
 43.1456 +    return SubGraph<const GR, const NF, const EF>
 43.1457 +      (graph, node_filter, edge_filter);
 43.1458 +  }
 43.1459 +
 43.1460 +
 43.1461 +  /// \ingroup graph_adaptors
 43.1462 +  ///
 43.1463 +  /// \brief Adaptor class for hiding nodes in a digraph or a graph.
 43.1464 +  ///
 43.1465 +  /// FilterNodes adaptor can be used for hiding nodes in a digraph or a
 43.1466 +  /// graph. A \c bool node map must be specified, which defines the filter
 43.1467 +  /// for the nodes. Only the nodes with \c true filter value and the
 43.1468 +  /// arcs/edges incident to nodes both with \c true filter value are shown
 43.1469 +  /// in the subgraph. This adaptor conforms to the \ref concepts::Digraph
 43.1470 +  /// "Digraph" concept or the \ref concepts::Graph "Graph" concept
 43.1471 +  /// depending on the \c GR template parameter.
 43.1472 +  ///
 43.1473 +  /// The adapted (di)graph can also be modified through this adaptor
 43.1474 +  /// by adding or removing nodes or arcs/edges, unless the \c GR template
 43.1475 +  /// parameter is set to be \c const.
 43.1476 +  ///
 43.1477 +  /// \tparam GR The type of the adapted digraph or graph.
 43.1478 +  /// It must conform to the \ref concepts::Digraph "Digraph" concept
 43.1479 +  /// or the \ref concepts::Graph "Graph" concept.
 43.1480 +  /// It can also be specified to be \c const.
 43.1481 +  /// \tparam NF The type of the node filter map.
 43.1482 +  /// It must be a \c bool (or convertible) node map of the
 43.1483 +  /// adapted (di)graph. The default type is
 43.1484 +  /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
 43.1485 +  ///
 43.1486 +  /// \note The \c Node and <tt>Arc/Edge</tt> types of this adaptor and the
 43.1487 +  /// adapted (di)graph are convertible to each other.
 43.1488 +#ifdef DOXYGEN
 43.1489 +  template<typename GR, typename NF>
 43.1490 +  class FilterNodes {
 43.1491 +#else
 43.1492 +  template<typename GR,
 43.1493 +           typename NF = typename GR::template NodeMap<bool>,
 43.1494 +           typename Enable = void>
 43.1495 +  class FilterNodes :
 43.1496 +    public DigraphAdaptorExtender<
 43.1497 +      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >,
 43.1498 +                     true> > {
 43.1499 +#endif
 43.1500 +    typedef DigraphAdaptorExtender<
 43.1501 +      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >, 
 43.1502 +                     true> > Parent;
 43.1503 +
 43.1504 +  public:
 43.1505 +
 43.1506 +    typedef GR Digraph;
 43.1507 +    typedef NF NodeFilterMap;
 43.1508 +
 43.1509 +    typedef typename Parent::Node Node;
 43.1510 +
 43.1511 +  protected:
 43.1512 +    ConstMap<typename Digraph::Arc, Const<bool, true> > const_true_map;
 43.1513 +
 43.1514 +    FilterNodes() : const_true_map() {}
 43.1515 +
 43.1516 +  public:
 43.1517 +
 43.1518 +    /// \brief Constructor
 43.1519 +    ///
 43.1520 +    /// Creates a subgraph for the given digraph or graph with the
 43.1521 +    /// given node filter map.
 43.1522 +    FilterNodes(GR& graph, NF& node_filter) 
 43.1523 +      : Parent(), const_true_map()
 43.1524 +    {
 43.1525 +      Parent::initialize(graph, node_filter, const_true_map);
 43.1526 +    }
 43.1527 +
 43.1528 +    /// \brief Sets the status of the given node
 43.1529 +    ///
 43.1530 +    /// This function sets the status of the given node.
 43.1531 +    /// It is done by simply setting the assigned value of \c n
 43.1532 +    /// to \c v in the node filter map.
 43.1533 +    void status(const Node& n, bool v) const { Parent::status(n, v); }
 43.1534 +
 43.1535 +    /// \brief Returns the status of the given node
 43.1536 +    ///
 43.1537 +    /// This function returns the status of the given node.
 43.1538 +    /// It is \c true if the given node is enabled (i.e. not hidden).
 43.1539 +    bool status(const Node& n) const { return Parent::status(n); }
 43.1540 +
 43.1541 +    /// \brief Disables the given node
 43.1542 +    ///
 43.1543 +    /// This function disables the given node, so the iteration
 43.1544 +    /// jumps over it.
 43.1545 +    /// It is the same as \ref status() "status(n, false)".
 43.1546 +    void disable(const Node& n) const { Parent::status(n, false); }
 43.1547 +
 43.1548 +    /// \brief Enables the given node
 43.1549 +    ///
 43.1550 +    /// This function enables the given node.
 43.1551 +    /// It is the same as \ref status() "status(n, true)".
 43.1552 +    void enable(const Node& n) const { Parent::status(n, true); }
 43.1553 +
 43.1554 +  };
 43.1555 +
 43.1556 +  template<typename GR, typename NF>
 43.1557 +  class FilterNodes<GR, NF,
 43.1558 +                    typename enable_if<UndirectedTagIndicator<GR> >::type> :
 43.1559 +    public GraphAdaptorExtender<
 43.1560 +      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 
 43.1561 +                   true> > {
 43.1562 +
 43.1563 +    typedef GraphAdaptorExtender<
 43.1564 +      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 
 43.1565 +                   true> > Parent;
 43.1566 +
 43.1567 +  public:
 43.1568 +
 43.1569 +    typedef GR Graph;
 43.1570 +    typedef NF NodeFilterMap;
 43.1571 +
 43.1572 +    typedef typename Parent::Node Node;
 43.1573 +
 43.1574 +  protected:
 43.1575 +    ConstMap<typename GR::Edge, Const<bool, true> > const_true_map;
 43.1576 +
 43.1577 +    FilterNodes() : const_true_map() {}
 43.1578 +
 43.1579 +  public:
 43.1580 +
 43.1581 +    FilterNodes(GR& graph, NodeFilterMap& node_filter) :
 43.1582 +      Parent(), const_true_map() {
 43.1583 +      Parent::initialize(graph, node_filter, const_true_map);
 43.1584 +    }
 43.1585 +
 43.1586 +    void status(const Node& n, bool v) const { Parent::status(n, v); }
 43.1587 +    bool status(const Node& n) const { return Parent::status(n); }
 43.1588 +    void disable(const Node& n) const { Parent::status(n, false); }
 43.1589 +    void enable(const Node& n) const { Parent::status(n, true); }
 43.1590 +
 43.1591 +  };
 43.1592 +
 43.1593 +
 43.1594 +  /// \brief Returns a read-only FilterNodes adaptor
 43.1595 +  ///
 43.1596 +  /// This function just returns a read-only \ref FilterNodes adaptor.
 43.1597 +  /// \ingroup graph_adaptors
 43.1598 +  /// \relates FilterNodes
 43.1599 +  template<typename GR, typename NF>
 43.1600 +  FilterNodes<const GR, NF>
 43.1601 +  filterNodes(const GR& graph, NF& node_filter) {
 43.1602 +    return FilterNodes<const GR, NF>(graph, node_filter);
 43.1603 +  }
 43.1604 +
 43.1605 +  template<typename GR, typename NF>
 43.1606 +  FilterNodes<const GR, const NF>
 43.1607 +  filterNodes(const GR& graph, const NF& node_filter) {
 43.1608 +    return FilterNodes<const GR, const NF>(graph, node_filter);
 43.1609 +  }
 43.1610 +
 43.1611 +  /// \ingroup graph_adaptors
 43.1612 +  ///
 43.1613 +  /// \brief Adaptor class for hiding arcs in a digraph.
 43.1614 +  ///
 43.1615 +  /// FilterArcs adaptor can be used for hiding arcs in a digraph.
 43.1616 +  /// A \c bool arc map must be specified, which defines the filter for
 43.1617 +  /// the arcs. Only the arcs with \c true filter value are shown in the
 43.1618 +  /// subdigraph. This adaptor conforms to the \ref concepts::Digraph
 43.1619 +  /// "Digraph" concept.
 43.1620 +  ///
 43.1621 +  /// The adapted digraph can also be modified through this adaptor
 43.1622 +  /// by adding or removing nodes or arcs, unless the \c GR template
 43.1623 +  /// parameter is set to be \c const.
 43.1624 +  ///
 43.1625 +  /// \tparam DGR The type of the adapted digraph.
 43.1626 +  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
 43.1627 +  /// It can also be specified to be \c const.
 43.1628 +  /// \tparam AF The type of the arc filter map.
 43.1629 +  /// It must be a \c bool (or convertible) arc map of the
 43.1630 +  /// adapted digraph. The default type is
 43.1631 +  /// \ref concepts::Digraph::ArcMap "DGR::ArcMap<bool>".
 43.1632 +  ///
 43.1633 +  /// \note The \c Node and \c Arc types of this adaptor and the adapted
 43.1634 +  /// digraph are convertible to each other.
 43.1635 +#ifdef DOXYGEN
 43.1636 +  template<typename DGR,
 43.1637 +           typename AF>
 43.1638 +  class FilterArcs {
 43.1639 +#else
 43.1640 +  template<typename DGR,
 43.1641 +           typename AF = typename DGR::template ArcMap<bool> >
 43.1642 +  class FilterArcs :
 43.1643 +    public DigraphAdaptorExtender<
 43.1644 +      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
 43.1645 +                     AF, false> > {
 43.1646 +#endif
 43.1647 +    typedef DigraphAdaptorExtender<
 43.1648 +      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >, 
 43.1649 +                     AF, false> > Parent;
 43.1650 +
 43.1651 +  public:
 43.1652 +
 43.1653 +    /// The type of the adapted digraph.
 43.1654 +    typedef DGR Digraph;
 43.1655 +    /// The type of the arc filter map.
 43.1656 +    typedef AF ArcFilterMap;
 43.1657 +
 43.1658 +    typedef typename Parent::Arc Arc;
 43.1659 +
 43.1660 +  protected:
 43.1661 +    ConstMap<typename DGR::Node, Const<bool, true> > const_true_map;
 43.1662 +
 43.1663 +    FilterArcs() : const_true_map() {}
 43.1664 +
 43.1665 +  public:
 43.1666 +
 43.1667 +    /// \brief Constructor
 43.1668 +    ///
 43.1669 +    /// Creates a subdigraph for the given digraph with the given arc
 43.1670 +    /// filter map.
 43.1671 +    FilterArcs(DGR& digraph, ArcFilterMap& arc_filter)
 43.1672 +      : Parent(), const_true_map() {
 43.1673 +      Parent::initialize(digraph, const_true_map, arc_filter);
 43.1674 +    }
 43.1675 +
 43.1676 +    /// \brief Sets the status of the given arc
 43.1677 +    ///
 43.1678 +    /// This function sets the status of the given arc.
 43.1679 +    /// It is done by simply setting the assigned value of \c a
 43.1680 +    /// to \c v in the arc filter map.
 43.1681 +    void status(const Arc& a, bool v) const { Parent::status(a, v); }
 43.1682 +
 43.1683 +    /// \brief Returns the status of the given arc
 43.1684 +    ///
 43.1685 +    /// This function returns the status of the given arc.
 43.1686 +    /// It is \c true if the given arc is enabled (i.e. not hidden).
 43.1687 +    bool status(const Arc& a) const { return Parent::status(a); }
 43.1688 +
 43.1689 +    /// \brief Disables the given arc
 43.1690 +    ///
 43.1691 +    /// This function disables the given arc in the subdigraph,
 43.1692 +    /// so the iteration jumps over it.
 43.1693 +    /// It is the same as \ref status() "status(a, false)".
 43.1694 +    void disable(const Arc& a) const { Parent::status(a, false); }
 43.1695 +
 43.1696 +    /// \brief Enables the given arc
 43.1697 +    ///
 43.1698 +    /// This function enables the given arc in the subdigraph.
 43.1699 +    /// It is the same as \ref status() "status(a, true)".
 43.1700 +    void enable(const Arc& a) const { Parent::status(a, true); }
 43.1701 +
 43.1702 +  };
 43.1703 +
 43.1704 +  /// \brief Returns a read-only FilterArcs adaptor
 43.1705 +  ///
 43.1706 +  /// This function just returns a read-only \ref FilterArcs adaptor.
 43.1707 +  /// \ingroup graph_adaptors
 43.1708 +  /// \relates FilterArcs
 43.1709 +  template<typename DGR, typename AF>
 43.1710 +  FilterArcs<const DGR, AF>
 43.1711 +  filterArcs(const DGR& digraph, AF& arc_filter) {
 43.1712 +    return FilterArcs<const DGR, AF>(digraph, arc_filter);
 43.1713 +  }
 43.1714 +
 43.1715 +  template<typename DGR, typename AF>
 43.1716 +  FilterArcs<const DGR, const AF>
 43.1717 +  filterArcs(const DGR& digraph, const AF& arc_filter) {
 43.1718 +    return FilterArcs<const DGR, const AF>(digraph, arc_filter);
 43.1719 +  }
 43.1720 +
 43.1721 +  /// \ingroup graph_adaptors
 43.1722 +  ///
 43.1723 +  /// \brief Adaptor class for hiding edges in a graph.
 43.1724 +  ///
 43.1725 +  /// FilterEdges adaptor can be used for hiding edges in a graph.
 43.1726 +  /// A \c bool edge map must be specified, which defines the filter for
 43.1727 +  /// the edges. Only the edges with \c true filter value are shown in the
 43.1728 +  /// subgraph. This adaptor conforms to the \ref concepts::Graph
 43.1729 +  /// "Graph" concept.
 43.1730 +  ///
 43.1731 +  /// The adapted graph can also be modified through this adaptor
 43.1732 +  /// by adding or removing nodes or edges, unless the \c GR template
 43.1733 +  /// parameter is set to be \c const.
 43.1734 +  ///
 43.1735 +  /// \tparam GR The type of the adapted graph.
 43.1736 +  /// It must conform to the \ref concepts::Graph "Graph" concept.
 43.1737 +  /// It can also be specified to be \c const.
 43.1738 +  /// \tparam EF The type of the edge filter map.
 43.1739 +  /// It must be a \c bool (or convertible) edge map of the
 43.1740 +  /// adapted graph. The default type is
 43.1741 +  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
 43.1742 +  ///
 43.1743 +  /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
 43.1744 +  /// adapted graph are convertible to each other.
 43.1745 +#ifdef DOXYGEN
 43.1746 +  template<typename GR,
 43.1747 +           typename EF>
 43.1748 +  class FilterEdges {
 43.1749 +#else
 43.1750 +  template<typename GR,
 43.1751 +           typename EF = typename GR::template EdgeMap<bool> >
 43.1752 +  class FilterEdges :
 43.1753 +    public GraphAdaptorExtender<
 43.1754 +      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >, 
 43.1755 +                   EF, false> > {
 43.1756 +#endif
 43.1757 +    typedef GraphAdaptorExtender<
 43.1758 +      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >, 
 43.1759 +                   EF, false> > Parent;
 43.1760 +
 43.1761 +  public:
 43.1762 +
 43.1763 +    /// The type of the adapted graph.
 43.1764 +    typedef GR Graph;
 43.1765 +    /// The type of the edge filter map.
 43.1766 +    typedef EF EdgeFilterMap;
 43.1767 +
 43.1768 +    typedef typename Parent::Edge Edge;
 43.1769 +
 43.1770 +  protected:
 43.1771 +    ConstMap<typename GR::Node, Const<bool, true> > const_true_map;
 43.1772 +
 43.1773 +    FilterEdges() : const_true_map(true) {
 43.1774 +      Parent::setNodeFilterMap(const_true_map);
 43.1775 +    }
 43.1776 +
 43.1777 +  public:
 43.1778 +
 43.1779 +    /// \brief Constructor
 43.1780 +    ///
 43.1781 +    /// Creates a subgraph for the given graph with the given edge
 43.1782 +    /// filter map.
 43.1783 +    FilterEdges(GR& graph, EF& edge_filter) 
 43.1784 +      : Parent(), const_true_map() {
 43.1785 +      Parent::initialize(graph, const_true_map, edge_filter);
 43.1786 +    }
 43.1787 +
 43.1788 +    /// \brief Sets the status of the given edge
 43.1789 +    ///
 43.1790 +    /// This function sets the status of the given edge.
 43.1791 +    /// It is done by simply setting the assigned value of \c e
 43.1792 +    /// to \c v in the edge filter map.
 43.1793 +    void status(const Edge& e, bool v) const { Parent::status(e, v); }
 43.1794 +
 43.1795 +    /// \brief Returns the status of the given edge
 43.1796 +    ///
 43.1797 +    /// This function returns the status of the given edge.
 43.1798 +    /// It is \c true if the given edge is enabled (i.e. not hidden).
 43.1799 +    bool status(const Edge& e) const { return Parent::status(e); }
 43.1800 +
 43.1801 +    /// \brief Disables the given edge
 43.1802 +    ///
 43.1803 +    /// This function disables the given edge in the subgraph,
 43.1804 +    /// so the iteration jumps over it.
 43.1805 +    /// It is the same as \ref status() "status(e, false)".
 43.1806 +    void disable(const Edge& e) const { Parent::status(e, false); }
 43.1807 +
 43.1808 +    /// \brief Enables the given edge
 43.1809 +    ///
 43.1810 +    /// This function enables the given edge in the subgraph.
 43.1811 +    /// It is the same as \ref status() "status(e, true)".
 43.1812 +    void enable(const Edge& e) const { Parent::status(e, true); }
 43.1813 +
 43.1814 +  };
 43.1815 +
 43.1816 +  /// \brief Returns a read-only FilterEdges adaptor
 43.1817 +  ///
 43.1818 +  /// This function just returns a read-only \ref FilterEdges adaptor.
 43.1819 +  /// \ingroup graph_adaptors
 43.1820 +  /// \relates FilterEdges
 43.1821 +  template<typename GR, typename EF>
 43.1822 +  FilterEdges<const GR, EF>
 43.1823 +  filterEdges(const GR& graph, EF& edge_filter) {
 43.1824 +    return FilterEdges<const GR, EF>(graph, edge_filter);
 43.1825 +  }
 43.1826 +
 43.1827 +  template<typename GR, typename EF>
 43.1828 +  FilterEdges<const GR, const EF>
 43.1829 +  filterEdges(const GR& graph, const EF& edge_filter) {
 43.1830 +    return FilterEdges<const GR, const EF>(graph, edge_filter);
 43.1831 +  }
 43.1832 +
 43.1833 +
 43.1834 +  template <typename DGR>
 43.1835 +  class UndirectorBase {
 43.1836 +  public:
 43.1837 +    typedef DGR Digraph;
 43.1838 +    typedef UndirectorBase Adaptor;
 43.1839 +
 43.1840 +    typedef True UndirectedTag;
 43.1841 +
 43.1842 +    typedef typename Digraph::Arc Edge;
 43.1843 +    typedef typename Digraph::Node Node;
 43.1844 +
 43.1845 +    class Arc {
 43.1846 +      friend class UndirectorBase;
 43.1847 +    protected:
 43.1848 +      Edge _edge;
 43.1849 +      bool _forward;
 43.1850 +
 43.1851 +      Arc(const Edge& edge, bool forward) 
 43.1852 +        : _edge(edge), _forward(forward) {}
 43.1853 +
 43.1854 +    public:
 43.1855 +      Arc() {}
 43.1856 +
 43.1857 +      Arc(Invalid) : _edge(INVALID), _forward(true) {}
 43.1858 +
 43.1859 +      operator const Edge&() const { return _edge; }
 43.1860 +
 43.1861 +      bool operator==(const Arc &other) const {
 43.1862 +        return _forward == other._forward && _edge == other._edge;
 43.1863 +      }
 43.1864 +      bool operator!=(const Arc &other) const {
 43.1865 +        return _forward != other._forward || _edge != other._edge;
 43.1866 +      }
 43.1867 +      bool operator<(const Arc &other) const {
 43.1868 +        return _forward < other._forward ||
 43.1869 +          (_forward == other._forward && _edge < other._edge);
 43.1870 +      }
 43.1871 +    };
 43.1872 +
 43.1873 +    void first(Node& n) const {
 43.1874 +      _digraph->first(n);
 43.1875 +    }
 43.1876 +
 43.1877 +    void next(Node& n) const {
 43.1878 +      _digraph->next(n);
 43.1879 +    }
 43.1880 +
 43.1881 +    void first(Arc& a) const {
 43.1882 +      _digraph->first(a._edge);
 43.1883 +      a._forward = true;
 43.1884 +    }
 43.1885 +
 43.1886 +    void next(Arc& a) const {
 43.1887 +      if (a._forward) {
 43.1888 +        a._forward = false;
 43.1889 +      } else {
 43.1890 +        _digraph->next(a._edge);
 43.1891 +        a._forward = true;
 43.1892 +      }
 43.1893 +    }
 43.1894 +
 43.1895 +    void first(Edge& e) const {
 43.1896 +      _digraph->first(e);
 43.1897 +    }
 43.1898 +
 43.1899 +    void next(Edge& e) const {
 43.1900 +      _digraph->next(e);
 43.1901 +    }
 43.1902 +
 43.1903 +    void firstOut(Arc& a, const Node& n) const {
 43.1904 +      _digraph->firstIn(a._edge, n);
 43.1905 +      if (a._edge != INVALID ) {
 43.1906 +        a._forward = false;
 43.1907 +      } else {
 43.1908 +        _digraph->firstOut(a._edge, n);
 43.1909 +        a._forward = true;
 43.1910 +      }
 43.1911 +    }
 43.1912 +    void nextOut(Arc &a) const {
 43.1913 +      if (!a._forward) {
 43.1914 +        Node n = _digraph->target(a._edge);
 43.1915 +        _digraph->nextIn(a._edge);
 43.1916 +        if (a._edge == INVALID) {
 43.1917 +          _digraph->firstOut(a._edge, n);
 43.1918 +          a._forward = true;
 43.1919 +        }
 43.1920 +      }
 43.1921 +      else {
 43.1922 +        _digraph->nextOut(a._edge);
 43.1923 +      }
 43.1924 +    }
 43.1925 +
 43.1926 +    void firstIn(Arc &a, const Node &n) const {
 43.1927 +      _digraph->firstOut(a._edge, n);
 43.1928 +      if (a._edge != INVALID ) {
 43.1929 +        a._forward = false;
 43.1930 +      } else {
 43.1931 +        _digraph->firstIn(a._edge, n);
 43.1932 +        a._forward = true;
 43.1933 +      }
 43.1934 +    }
 43.1935 +    void nextIn(Arc &a) const {
 43.1936 +      if (!a._forward) {
 43.1937 +        Node n = _digraph->source(a._edge);
 43.1938 +        _digraph->nextOut(a._edge);
 43.1939 +        if (a._edge == INVALID ) {
 43.1940 +          _digraph->firstIn(a._edge, n);
 43.1941 +          a._forward = true;
 43.1942 +        }
 43.1943 +      }
 43.1944 +      else {
 43.1945 +        _digraph->nextIn(a._edge);
 43.1946 +      }
 43.1947 +    }
 43.1948 +
 43.1949 +    void firstInc(Edge &e, bool &d, const Node &n) const {
 43.1950 +      d = true;
 43.1951 +      _digraph->firstOut(e, n);
 43.1952 +      if (e != INVALID) return;
 43.1953 +      d = false;
 43.1954 +      _digraph->firstIn(e, n);
 43.1955 +    }
 43.1956 +
 43.1957 +    void nextInc(Edge &e, bool &d) const {
 43.1958 +      if (d) {
 43.1959 +        Node s = _digraph->source(e);
 43.1960 +        _digraph->nextOut(e);
 43.1961 +        if (e != INVALID) return;
 43.1962 +        d = false;
 43.1963 +        _digraph->firstIn(e, s);
 43.1964 +      } else {
 43.1965 +        _digraph->nextIn(e);
 43.1966 +      }
 43.1967 +    }
 43.1968 +
 43.1969 +    Node u(const Edge& e) const {
 43.1970 +      return _digraph->source(e);
 43.1971 +    }
 43.1972 +
 43.1973 +    Node v(const Edge& e) const {
 43.1974 +      return _digraph->target(e);
 43.1975 +    }
 43.1976 +
 43.1977 +    Node source(const Arc &a) const {
 43.1978 +      return a._forward ? _digraph->source(a._edge) : _digraph->target(a._edge);
 43.1979 +    }
 43.1980 +
 43.1981 +    Node target(const Arc &a) const {
 43.1982 +      return a._forward ? _digraph->target(a._edge) : _digraph->source(a._edge);
 43.1983 +    }
 43.1984 +
 43.1985 +    static Arc direct(const Edge &e, bool d) {
 43.1986 +      return Arc(e, d);
 43.1987 +    }
 43.1988 +
 43.1989 +    static bool direction(const Arc &a) { return a._forward; }
 43.1990 +
 43.1991 +    Node nodeFromId(int ix) const { return _digraph->nodeFromId(ix); }
 43.1992 +    Arc arcFromId(int ix) const {
 43.1993 +      return direct(_digraph->arcFromId(ix >> 1), bool(ix & 1));
 43.1994 +    }
 43.1995 +    Edge edgeFromId(int ix) const { return _digraph->arcFromId(ix); }
 43.1996 +
 43.1997 +    int id(const Node &n) const { return _digraph->id(n); }
 43.1998 +    int id(const Arc &a) const {
 43.1999 +      return  (_digraph->id(a) << 1) | (a._forward ? 1 : 0);
 43.2000 +    }
 43.2001 +    int id(const Edge &e) const { return _digraph->id(e); }
 43.2002 +
 43.2003 +    int maxNodeId() const { return _digraph->maxNodeId(); }
 43.2004 +    int maxArcId() const { return (_digraph->maxArcId() << 1) | 1; }
 43.2005 +    int maxEdgeId() const { return _digraph->maxArcId(); }
 43.2006 +
 43.2007 +    Node addNode() { return _digraph->addNode(); }
 43.2008 +    Edge addEdge(const Node& u, const Node& v) {
 43.2009 +      return _digraph->addArc(u, v);
 43.2010 +    }
 43.2011 +
 43.2012 +    void erase(const Node& i) { _digraph->erase(i); }
 43.2013 +    void erase(const Edge& i) { _digraph->erase(i); }
 43.2014 +
 43.2015 +    void clear() { _digraph->clear(); }
 43.2016 +
 43.2017 +    typedef NodeNumTagIndicator<Digraph> NodeNumTag;
 43.2018 +    int nodeNum() const { return _digraph->nodeNum(); }
 43.2019 +
 43.2020 +    typedef ArcNumTagIndicator<Digraph> ArcNumTag;
 43.2021 +    int arcNum() const { return 2 * _digraph->arcNum(); }
 43.2022 +
 43.2023 +    typedef ArcNumTag EdgeNumTag;
 43.2024 +    int edgeNum() const { return _digraph->arcNum(); }
 43.2025 +
 43.2026 +    typedef FindArcTagIndicator<Digraph> FindArcTag;
 43.2027 +    Arc findArc(Node s, Node t, Arc p = INVALID) const {
 43.2028 +      if (p == INVALID) {
 43.2029 +        Edge arc = _digraph->findArc(s, t);
 43.2030 +        if (arc != INVALID) return direct(arc, true);
 43.2031 +        arc = _digraph->findArc(t, s);
 43.2032 +        if (arc != INVALID) return direct(arc, false);
 43.2033 +      } else if (direction(p)) {
 43.2034 +        Edge arc = _digraph->findArc(s, t, p);
 43.2035 +        if (arc != INVALID) return direct(arc, true);
 43.2036 +        arc = _digraph->findArc(t, s);
 43.2037 +        if (arc != INVALID) return direct(arc, false);
 43.2038 +      } else {
 43.2039 +        Edge arc = _digraph->findArc(t, s, p);
 43.2040 +        if (arc != INVALID) return direct(arc, false);
 43.2041 +      }
 43.2042 +      return INVALID;
 43.2043 +    }
 43.2044 +
 43.2045 +    typedef FindArcTag FindEdgeTag;
 43.2046 +    Edge findEdge(Node s, Node t, Edge p = INVALID) const {
 43.2047 +      if (s != t) {
 43.2048 +        if (p == INVALID) {
 43.2049 +          Edge arc = _digraph->findArc(s, t);
 43.2050 +          if (arc != INVALID) return arc;
 43.2051 +          arc = _digraph->findArc(t, s);
 43.2052 +          if (arc != INVALID) return arc;
 43.2053 +        } else if (_digraph->source(p) == s) {
 43.2054 +          Edge arc = _digraph->findArc(s, t, p);
 43.2055 +          if (arc != INVALID) return arc;
 43.2056 +          arc = _digraph->findArc(t, s);
 43.2057 +          if (arc != INVALID) return arc;
 43.2058 +        } else {
 43.2059 +          Edge arc = _digraph->findArc(t, s, p);
 43.2060 +          if (arc != INVALID) return arc;
 43.2061 +        }
 43.2062 +      } else {
 43.2063 +        return _digraph->findArc(s, t, p);
 43.2064 +      }
 43.2065 +      return INVALID;
 43.2066 +    }
 43.2067 +
 43.2068 +  private:
 43.2069 +
 43.2070 +    template <typename V>
 43.2071 +    class ArcMapBase {
 43.2072 +    private:
 43.2073 +
 43.2074 +      typedef typename DGR::template ArcMap<V> MapImpl;
 43.2075 +
 43.2076 +    public:
 43.2077 +
 43.2078 +      typedef typename MapTraits<MapImpl>::ReferenceMapTag ReferenceMapTag;
 43.2079 +
 43.2080 +      typedef V Value;
 43.2081 +      typedef Arc Key;
 43.2082 +      typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReturnValue;
 43.2083 +      typedef typename MapTraits<MapImpl>::ReturnValue ReturnValue;
 43.2084 +      typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReference;
 43.2085 +      typedef typename MapTraits<MapImpl>::ReturnValue Reference;
 43.2086 +
 43.2087 +      ArcMapBase(const UndirectorBase<DGR>& adaptor) :
 43.2088 +        _forward(*adaptor._digraph), _backward(*adaptor._digraph) {}
 43.2089 +
 43.2090 +      ArcMapBase(const UndirectorBase<DGR>& adaptor, const V& value)
 43.2091 +        : _forward(*adaptor._digraph, value), 
 43.2092 +          _backward(*adaptor._digraph, value) {}
 43.2093 +
 43.2094 +      void set(const Arc& a, const V& value) {
 43.2095 +        if (direction(a)) {
 43.2096 +          _forward.set(a, value);
 43.2097 +        } else {
 43.2098 +          _backward.set(a, value);
 43.2099 +        }
 43.2100 +      }
 43.2101 +
 43.2102 +      ConstReturnValue operator[](const Arc& a) const {
 43.2103 +        if (direction(a)) {
 43.2104 +          return _forward[a];
 43.2105 +        } else {
 43.2106 +          return _backward[a];
 43.2107 +        }
 43.2108 +      }
 43.2109 +
 43.2110 +      ReturnValue operator[](const Arc& a) {
 43.2111 +        if (direction(a)) {
 43.2112 +          return _forward[a];
 43.2113 +        } else {
 43.2114 +          return _backward[a];
 43.2115 +        }
 43.2116 +      }
 43.2117 +
 43.2118 +    protected:
 43.2119 +
 43.2120 +      MapImpl _forward, _backward;
 43.2121 +
 43.2122 +    };
 43.2123 +
 43.2124 +  public:
 43.2125 +
 43.2126 +    template <typename V>
 43.2127 +    class NodeMap : public DGR::template NodeMap<V> {
 43.2128 +      typedef typename DGR::template NodeMap<V> Parent;
 43.2129 +
 43.2130 +    public:
 43.2131 +      typedef V Value;
 43.2132 +
 43.2133 +      explicit NodeMap(const UndirectorBase<DGR>& adaptor)
 43.2134 +        : Parent(*adaptor._digraph) {}
 43.2135 +
 43.2136 +      NodeMap(const UndirectorBase<DGR>& adaptor, const V& value)
 43.2137 +        : Parent(*adaptor._digraph, value) { }
 43.2138 +
 43.2139 +    private:
 43.2140 +      NodeMap& operator=(const NodeMap& cmap) {
 43.2141 +        return operator=<NodeMap>(cmap);
 43.2142 +      }
 43.2143 +
 43.2144 +      template <typename CMap>
 43.2145 +      NodeMap& operator=(const CMap& cmap) {
 43.2146 +        Parent::operator=(cmap);
 43.2147 +        return *this;
 43.2148 +      }
 43.2149 +
 43.2150 +    };
 43.2151 +
 43.2152 +    template <typename V>
 43.2153 +    class ArcMap
 43.2154 +      : public SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> > {
 43.2155 +      typedef SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> > Parent;
 43.2156 +
 43.2157 +    public:
 43.2158 +      typedef V Value;
 43.2159 +
 43.2160 +      explicit ArcMap(const UndirectorBase<DGR>& adaptor)
 43.2161 +        : Parent(adaptor) {}
 43.2162 +
 43.2163 +      ArcMap(const UndirectorBase<DGR>& adaptor, const V& value)
 43.2164 +        : Parent(adaptor, value) {}
 43.2165 +
 43.2166 +    private:
 43.2167 +      ArcMap& operator=(const ArcMap& cmap) {
 43.2168 +        return operator=<ArcMap>(cmap);
 43.2169 +      }
 43.2170 +
 43.2171 +      template <typename CMap>
 43.2172 +      ArcMap& operator=(const CMap& cmap) {
 43.2173 +        Parent::operator=(cmap);
 43.2174 +        return *this;
 43.2175 +      }
 43.2176 +    };
 43.2177 +
 43.2178 +    template <typename V>
 43.2179 +    class EdgeMap : public Digraph::template ArcMap<V> {
 43.2180 +      typedef typename Digraph::template ArcMap<V> Parent;
 43.2181 +
 43.2182 +    public:
 43.2183 +      typedef V Value;
 43.2184 +
 43.2185 +      explicit EdgeMap(const UndirectorBase<DGR>& adaptor)
 43.2186 +        : Parent(*adaptor._digraph) {}
 43.2187 +
 43.2188 +      EdgeMap(const UndirectorBase<DGR>& adaptor, const V& value)
 43.2189 +        : Parent(*adaptor._digraph, value) {}
 43.2190 +
 43.2191 +    private:
 43.2192 +      EdgeMap& operator=(const EdgeMap& cmap) {
 43.2193 +        return operator=<EdgeMap>(cmap);
 43.2194 +      }
 43.2195 +
 43.2196 +      template <typename CMap>
 43.2197 +      EdgeMap& operator=(const CMap& cmap) {
 43.2198 +        Parent::operator=(cmap);
 43.2199 +        return *this;
 43.2200 +      }
 43.2201 +
 43.2202 +    };
 43.2203 +
 43.2204 +    typedef typename ItemSetTraits<DGR, Node>::ItemNotifier NodeNotifier;
 43.2205 +    NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
 43.2206 +
 43.2207 +    typedef typename ItemSetTraits<DGR, Edge>::ItemNotifier EdgeNotifier;
 43.2208 +    EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); }
 43.2209 +    
 43.2210 +    typedef EdgeNotifier ArcNotifier;
 43.2211 +    ArcNotifier& notifier(Arc) const { return _digraph->notifier(Edge()); }
 43.2212 +
 43.2213 +  protected:
 43.2214 +
 43.2215 +    UndirectorBase() : _digraph(0) {}
 43.2216 +
 43.2217 +    DGR* _digraph;
 43.2218 +
 43.2219 +    void initialize(DGR& digraph) {
 43.2220 +      _digraph = &digraph;
 43.2221 +    }
 43.2222 +
 43.2223 +  };
 43.2224 +
 43.2225 +  /// \ingroup graph_adaptors
 43.2226 +  ///
 43.2227 +  /// \brief Adaptor class for viewing a digraph as an undirected graph.
 43.2228 +  ///
 43.2229 +  /// Undirector adaptor can be used for viewing a digraph as an undirected
 43.2230 +  /// graph. All arcs of the underlying digraph are showed in the
 43.2231 +  /// adaptor as an edge (and also as a pair of arcs, of course).
 43.2232 +  /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
 43.2233 +  ///
 43.2234 +  /// The adapted digraph can also be modified through this adaptor
 43.2235 +  /// by adding or removing nodes or edges, unless the \c GR template
 43.2236 +  /// parameter is set to be \c const.
 43.2237 +  ///
 43.2238 +  /// \tparam DGR The type of the adapted digraph.
 43.2239 +  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
 43.2240 +  /// It can also be specified to be \c const.
 43.2241 +  ///
 43.2242 +  /// \note The \c Node type of this adaptor and the adapted digraph are
 43.2243 +  /// convertible to each other, moreover the \c Edge type of the adaptor
 43.2244 +  /// and the \c Arc type of the adapted digraph are also convertible to
 43.2245 +  /// each other.
 43.2246 +  /// (Thus the \c Arc type of the adaptor is convertible to the \c Arc type
 43.2247 +  /// of the adapted digraph.)
 43.2248 +  template<typename DGR>
 43.2249 +#ifdef DOXYGEN
 43.2250 +  class Undirector {
 43.2251 +#else
 43.2252 +  class Undirector :
 43.2253 +    public GraphAdaptorExtender<UndirectorBase<DGR> > {
 43.2254 +#endif
 43.2255 +    typedef GraphAdaptorExtender<UndirectorBase<DGR> > Parent;
 43.2256 +  public:
 43.2257 +    /// The type of the adapted digraph.
 43.2258 +    typedef DGR Digraph;
 43.2259 +  protected:
 43.2260 +    Undirector() { }
 43.2261 +  public:
 43.2262 +
 43.2263 +    /// \brief Constructor
 43.2264 +    ///
 43.2265 +    /// Creates an undirected graph from the given digraph.
 43.2266 +    Undirector(DGR& digraph) {
 43.2267 +      initialize(digraph);
 43.2268 +    }
 43.2269 +
 43.2270 +    /// \brief Arc map combined from two original arc maps
 43.2271 +    ///
 43.2272 +    /// This map adaptor class adapts two arc maps of the underlying
 43.2273 +    /// digraph to get an arc map of the undirected graph.
 43.2274 +    /// Its value type is inherited from the first arc map type (\c FW).
 43.2275 +    /// \tparam FW The type of the "foward" arc map.
 43.2276 +    /// \tparam BK The type of the "backward" arc map.
 43.2277 +    template <typename FW, typename BK>
 43.2278 +    class CombinedArcMap {
 43.2279 +    public:
 43.2280 +
 43.2281 +      /// The key type of the map
 43.2282 +      typedef typename Parent::Arc Key;
 43.2283 +      /// The value type of the map
 43.2284 +      typedef typename FW::Value Value;
 43.2285 +
 43.2286 +      typedef typename MapTraits<FW>::ReferenceMapTag ReferenceMapTag;
 43.2287 +
 43.2288 +      typedef typename MapTraits<FW>::ReturnValue ReturnValue;
 43.2289 +      typedef typename MapTraits<FW>::ConstReturnValue ConstReturnValue;
 43.2290 +      typedef typename MapTraits<FW>::ReturnValue Reference;
 43.2291 +      typedef typename MapTraits<FW>::ConstReturnValue ConstReference;
 43.2292 +
 43.2293 +      /// Constructor
 43.2294 +      CombinedArcMap(FW& forward, BK& backward)
 43.2295 +        : _forward(&forward), _backward(&backward) {}
 43.2296 +
 43.2297 +      /// Sets the value associated with the given key.
 43.2298 +      void set(const Key& e, const Value& a) {
 43.2299 +        if (Parent::direction(e)) {
 43.2300 +          _forward->set(e, a);
 43.2301 +        } else {
 43.2302 +          _backward->set(e, a);
 43.2303 +        }
 43.2304 +      }
 43.2305 +
 43.2306 +      /// Returns the value associated with the given key.
 43.2307 +      ConstReturnValue operator[](const Key& e) const {
 43.2308 +        if (Parent::direction(e)) {
 43.2309 +          return (*_forward)[e];
 43.2310 +        } else {
 43.2311 +          return (*_backward)[e];
 43.2312 +        }
 43.2313 +      }
 43.2314 +
 43.2315 +      /// Returns a reference to the value associated with the given key.
 43.2316 +      ReturnValue operator[](const Key& e) {
 43.2317 +        if (Parent::direction(e)) {
 43.2318 +          return (*_forward)[e];
 43.2319 +        } else {
 43.2320 +          return (*_backward)[e];
 43.2321 +        }
 43.2322 +      }
 43.2323 +
 43.2324 +    protected:
 43.2325 +
 43.2326 +      FW* _forward;
 43.2327 +      BK* _backward;
 43.2328 +
 43.2329 +    };
 43.2330 +
 43.2331 +    /// \brief Returns a combined arc map
 43.2332 +    ///
 43.2333 +    /// This function just returns a combined arc map.
 43.2334 +    template <typename FW, typename BK>
 43.2335 +    static CombinedArcMap<FW, BK>
 43.2336 +    combinedArcMap(FW& forward, BK& backward) {
 43.2337 +      return CombinedArcMap<FW, BK>(forward, backward);
 43.2338 +    }
 43.2339 +
 43.2340 +    template <typename FW, typename BK>
 43.2341 +    static CombinedArcMap<const FW, BK>
 43.2342 +    combinedArcMap(const FW& forward, BK& backward) {
 43.2343 +      return CombinedArcMap<const FW, BK>(forward, backward);
 43.2344 +    }
 43.2345 +
 43.2346 +    template <typename FW, typename BK>
 43.2347 +    static CombinedArcMap<FW, const BK>
 43.2348 +    combinedArcMap(FW& forward, const BK& backward) {
 43.2349 +      return CombinedArcMap<FW, const BK>(forward, backward);
 43.2350 +    }
 43.2351 +
 43.2352 +    template <typename FW, typename BK>
 43.2353 +    static CombinedArcMap<const FW, const BK>
 43.2354 +    combinedArcMap(const FW& forward, const BK& backward) {
 43.2355 +      return CombinedArcMap<const FW, const BK>(forward, backward);
 43.2356 +    }
 43.2357 +
 43.2358 +  };
 43.2359 +
 43.2360 +  /// \brief Returns a read-only Undirector adaptor
 43.2361 +  ///
 43.2362 +  /// This function just returns a read-only \ref Undirector adaptor.
 43.2363 +  /// \ingroup graph_adaptors
 43.2364 +  /// \relates Undirector
 43.2365 +  template<typename DGR>
 43.2366 +  Undirector<const DGR> undirector(const DGR& digraph) {
 43.2367 +    return Undirector<const DGR>(digraph);
 43.2368 +  }
 43.2369 +
 43.2370 +
 43.2371 +  template <typename GR, typename DM>
 43.2372 +  class OrienterBase {
 43.2373 +  public:
 43.2374 +
 43.2375 +    typedef GR Graph;
 43.2376 +    typedef DM DirectionMap;
 43.2377 +
 43.2378 +    typedef typename GR::Node Node;
 43.2379 +    typedef typename GR::Edge Arc;
 43.2380 +
 43.2381 +    void reverseArc(const Arc& arc) {
 43.2382 +      _direction->set(arc, !(*_direction)[arc]);
 43.2383 +    }
 43.2384 +
 43.2385 +    void first(Node& i) const { _graph->first(i); }
 43.2386 +    void first(Arc& i) const { _graph->first(i); }
 43.2387 +    void firstIn(Arc& i, const Node& n) const {
 43.2388 +      bool d = true;
 43.2389 +      _graph->firstInc(i, d, n);
 43.2390 +      while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d);
 43.2391 +    }
 43.2392 +    void firstOut(Arc& i, const Node& n ) const {
 43.2393 +      bool d = true;
 43.2394 +      _graph->firstInc(i, d, n);
 43.2395 +      while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
 43.2396 +    }
 43.2397 +
 43.2398 +    void next(Node& i) const { _graph->next(i); }
 43.2399 +    void next(Arc& i) const { _graph->next(i); }
 43.2400 +    void nextIn(Arc& i) const {
 43.2401 +      bool d = !(*_direction)[i];
 43.2402 +      _graph->nextInc(i, d);
 43.2403 +      while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d);
 43.2404 +    }
 43.2405 +    void nextOut(Arc& i) const {
 43.2406 +      bool d = (*_direction)[i];
 43.2407 +      _graph->nextInc(i, d);
 43.2408 +      while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
 43.2409 +    }
 43.2410 +
 43.2411 +    Node source(const Arc& e) const {
 43.2412 +      return (*_direction)[e] ? _graph->u(e) : _graph->v(e);
 43.2413 +    }
 43.2414 +    Node target(const Arc& e) const {
 43.2415 +      return (*_direction)[e] ? _graph->v(e) : _graph->u(e);
 43.2416 +    }
 43.2417 +
 43.2418 +    typedef NodeNumTagIndicator<Graph> NodeNumTag;
 43.2419 +    int nodeNum() const { return _graph->nodeNum(); }
 43.2420 +
 43.2421 +    typedef EdgeNumTagIndicator<Graph> ArcNumTag;
 43.2422 +    int arcNum() const { return _graph->edgeNum(); }
 43.2423 +
 43.2424 +    typedef FindEdgeTagIndicator<Graph> FindArcTag;
 43.2425 +    Arc findArc(const Node& u, const Node& v,
 43.2426 +                const Arc& prev = INVALID) const {
 43.2427 +      Arc arc = _graph->findEdge(u, v, prev);
 43.2428 +      while (arc != INVALID && source(arc) != u) {
 43.2429 +        arc = _graph->findEdge(u, v, arc);
 43.2430 +      }
 43.2431 +      return arc;
 43.2432 +    }
 43.2433 +
 43.2434 +    Node addNode() {
 43.2435 +      return Node(_graph->addNode());
 43.2436 +    }
 43.2437 +
 43.2438 +    Arc addArc(const Node& u, const Node& v) {
 43.2439 +      Arc arc = _graph->addEdge(u, v);
 43.2440 +      _direction->set(arc, _graph->u(arc) == u);
 43.2441 +      return arc;
 43.2442 +    }
 43.2443 +
 43.2444 +    void erase(const Node& i) { _graph->erase(i); }
 43.2445 +    void erase(const Arc& i) { _graph->erase(i); }
 43.2446 +
 43.2447 +    void clear() { _graph->clear(); }
 43.2448 +
 43.2449 +    int id(const Node& v) const { return _graph->id(v); }
 43.2450 +    int id(const Arc& e) const { return _graph->id(e); }
 43.2451 +
 43.2452 +    Node nodeFromId(int idx) const { return _graph->nodeFromId(idx); }
 43.2453 +    Arc arcFromId(int idx) const { return _graph->edgeFromId(idx); }
 43.2454 +
 43.2455 +    int maxNodeId() const { return _graph->maxNodeId(); }
 43.2456 +    int maxArcId() const { return _graph->maxEdgeId(); }
 43.2457 +
 43.2458 +    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
 43.2459 +    NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
 43.2460 +
 43.2461 +    typedef typename ItemSetTraits<GR, Arc>::ItemNotifier ArcNotifier;
 43.2462 +    ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
 43.2463 +
 43.2464 +    template <typename V>
 43.2465 +    class NodeMap : public GR::template NodeMap<V> {
 43.2466 +      typedef typename GR::template NodeMap<V> Parent;
 43.2467 +
 43.2468 +    public:
 43.2469 +
 43.2470 +      explicit NodeMap(const OrienterBase<GR, DM>& adapter)
 43.2471 +        : Parent(*adapter._graph) {}
 43.2472 +
 43.2473 +      NodeMap(const OrienterBase<GR, DM>& adapter, const V& value)
 43.2474 +        : Parent(*adapter._graph, value) {}
 43.2475 +
 43.2476 +    private:
 43.2477 +      NodeMap& operator=(const NodeMap& cmap) {
 43.2478 +        return operator=<NodeMap>(cmap);
 43.2479 +      }
 43.2480 +
 43.2481 +      template <typename CMap>
 43.2482 +      NodeMap& operator=(const CMap& cmap) {
 43.2483 +        Parent::operator=(cmap);
 43.2484 +        return *this;
 43.2485 +      }
 43.2486 +
 43.2487 +    };
 43.2488 +
 43.2489 +    template <typename V>
 43.2490 +    class ArcMap : public GR::template EdgeMap<V> {
 43.2491 +      typedef typename Graph::template EdgeMap<V> Parent;
 43.2492 +
 43.2493 +    public:
 43.2494 +
 43.2495 +      explicit ArcMap(const OrienterBase<GR, DM>& adapter)
 43.2496 +        : Parent(*adapter._graph) { }
 43.2497 +
 43.2498 +      ArcMap(const OrienterBase<GR, DM>& adapter, const V& value)
 43.2499 +        : Parent(*adapter._graph, value) { }
 43.2500 +
 43.2501 +    private:
 43.2502 +      ArcMap& operator=(const ArcMap& cmap) {
 43.2503 +        return operator=<ArcMap>(cmap);
 43.2504 +      }
 43.2505 +
 43.2506 +      template <typename CMap>
 43.2507 +      ArcMap& operator=(const CMap& cmap) {
 43.2508 +        Parent::operator=(cmap);
 43.2509 +        return *this;
 43.2510 +      }
 43.2511 +    };
 43.2512 +
 43.2513 +
 43.2514 +
 43.2515 +  protected:
 43.2516 +    Graph* _graph;
 43.2517 +    DM* _direction;
 43.2518 +
 43.2519 +    void initialize(GR& graph, DM& direction) {
 43.2520 +      _graph = &graph;
 43.2521 +      _direction = &direction;
 43.2522 +    }
 43.2523 +
 43.2524 +  };
 43.2525 +
 43.2526 +  /// \ingroup graph_adaptors
 43.2527 +  ///
 43.2528 +  /// \brief Adaptor class for orienting the edges of a graph to get a digraph
 43.2529 +  ///
 43.2530 +  /// Orienter adaptor can be used for orienting the edges of a graph to
 43.2531 +  /// get a digraph. A \c bool edge map of the underlying graph must be
 43.2532 +  /// specified, which define the direction of the arcs in the adaptor.
 43.2533 +  /// The arcs can be easily reversed by the \c reverseArc() member function
 43.2534 +  /// of the adaptor.
 43.2535 +  /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
 43.2536 +  ///
 43.2537 +  /// The adapted graph can also be modified through this adaptor
 43.2538 +  /// by adding or removing nodes or arcs, unless the \c GR template
 43.2539 +  /// parameter is set to be \c const.
 43.2540 +  ///
 43.2541 +  /// \tparam GR The type of the adapted graph.
 43.2542 +  /// It must conform to the \ref concepts::Graph "Graph" concept.
 43.2543 +  /// It can also be specified to be \c const.
 43.2544 +  /// \tparam DM The type of the direction map.
 43.2545 +  /// It must be a \c bool (or convertible) edge map of the
 43.2546 +  /// adapted graph. The default type is
 43.2547 +  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
 43.2548 +  ///
 43.2549 +  /// \note The \c Node type of this adaptor and the adapted graph are
 43.2550 +  /// convertible to each other, moreover the \c Arc type of the adaptor
 43.2551 +  /// and the \c Edge type of the adapted graph are also convertible to
 43.2552 +  /// each other.
 43.2553 +#ifdef DOXYGEN
 43.2554 +  template<typename GR,
 43.2555 +           typename DM>
 43.2556 +  class Orienter {
 43.2557 +#else
 43.2558 +  template<typename GR,
 43.2559 +           typename DM = typename GR::template EdgeMap<bool> >
 43.2560 +  class Orienter :
 43.2561 +    public DigraphAdaptorExtender<OrienterBase<GR, DM> > {
 43.2562 +#endif
 43.2563 +    typedef DigraphAdaptorExtender<OrienterBase<GR, DM> > Parent;
 43.2564 +  public:
 43.2565 +
 43.2566 +    /// The type of the adapted graph.
 43.2567 +    typedef GR Graph;
 43.2568 +    /// The type of the direction edge map.
 43.2569 +    typedef DM DirectionMap;
 43.2570 +
 43.2571 +    typedef typename Parent::Arc Arc;
 43.2572 +
 43.2573 +  protected:
 43.2574 +    Orienter() { }
 43.2575 +
 43.2576 +  public:
 43.2577 +
 43.2578 +    /// \brief Constructor
 43.2579 +    ///
 43.2580 +    /// Constructor of the adaptor.
 43.2581 +    Orienter(GR& graph, DM& direction) {
 43.2582 +      Parent::initialize(graph, direction);
 43.2583 +    }
 43.2584 +
 43.2585 +    /// \brief Reverses the given arc
 43.2586 +    ///
 43.2587 +    /// This function reverses the given arc.
 43.2588 +    /// It is done by simply negate the assigned value of \c a
 43.2589 +    /// in the direction map.
 43.2590 +    void reverseArc(const Arc& a) {
 43.2591 +      Parent::reverseArc(a);
 43.2592 +    }
 43.2593 +  };
 43.2594 +
 43.2595 +  /// \brief Returns a read-only Orienter adaptor
 43.2596 +  ///
 43.2597 +  /// This function just returns a read-only \ref Orienter adaptor.
 43.2598 +  /// \ingroup graph_adaptors
 43.2599 +  /// \relates Orienter
 43.2600 +  template<typename GR, typename DM>
 43.2601 +  Orienter<const GR, DM>
 43.2602 +  orienter(const GR& graph, DM& direction) {
 43.2603 +    return Orienter<const GR, DM>(graph, direction);
 43.2604 +  }
 43.2605 +
 43.2606 +  template<typename GR, typename DM>
 43.2607 +  Orienter<const GR, const DM>
 43.2608 +  orienter(const GR& graph, const DM& direction) {
 43.2609 +    return Orienter<const GR, const DM>(graph, direction);
 43.2610 +  }
 43.2611 +
 43.2612 +  namespace _adaptor_bits {
 43.2613 +
 43.2614 +    template <typename DGR, typename CM, typename FM, typename TL>
 43.2615 +    class ResForwardFilter {
 43.2616 +    public:
 43.2617 +
 43.2618 +      typedef typename DGR::Arc Key;
 43.2619 +      typedef bool Value;
 43.2620 +
 43.2621 +    private:
 43.2622 +
 43.2623 +      const CM* _capacity;
 43.2624 +      const FM* _flow;
 43.2625 +      TL _tolerance;
 43.2626 +
 43.2627 +    public:
 43.2628 +
 43.2629 +      ResForwardFilter(const CM& capacity, const FM& flow,
 43.2630 +                       const TL& tolerance = TL())
 43.2631 +        : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
 43.2632 +
 43.2633 +      bool operator[](const typename DGR::Arc& a) const {
 43.2634 +        return _tolerance.positive((*_capacity)[a] - (*_flow)[a]);
 43.2635 +      }
 43.2636 +    };
 43.2637 +
 43.2638 +    template<typename DGR,typename CM, typename FM, typename TL>
 43.2639 +    class ResBackwardFilter {
 43.2640 +    public:
 43.2641 +
 43.2642 +      typedef typename DGR::Arc Key;
 43.2643 +      typedef bool Value;
 43.2644 +
 43.2645 +    private:
 43.2646 +
 43.2647 +      const CM* _capacity;
 43.2648 +      const FM* _flow;
 43.2649 +      TL _tolerance;
 43.2650 +
 43.2651 +    public:
 43.2652 +
 43.2653 +      ResBackwardFilter(const CM& capacity, const FM& flow,
 43.2654 +                        const TL& tolerance = TL())
 43.2655 +        : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
 43.2656 +
 43.2657 +      bool operator[](const typename DGR::Arc& a) const {
 43.2658 +        return _tolerance.positive((*_flow)[a]);
 43.2659 +      }
 43.2660 +    };
 43.2661 +
 43.2662 +  }
 43.2663 +
 43.2664 +  /// \ingroup graph_adaptors
 43.2665 +  ///
 43.2666 +  /// \brief Adaptor class for composing the residual digraph for directed
 43.2667 +  /// flow and circulation problems.
 43.2668 +  ///
 43.2669 +  /// ResidualDigraph can be used for composing the \e residual digraph
 43.2670 +  /// for directed flow and circulation problems. Let \f$ G=(V, A) \f$
 43.2671 +  /// be a directed graph and let \f$ F \f$ be a number type.
 43.2672 +  /// Let \f$ flow, cap: A\to F \f$ be functions on the arcs.
 43.2673 +  /// This adaptor implements a digraph structure with node set \f$ V \f$
 43.2674 +  /// and arc set \f$ A_{forward}\cup A_{backward} \f$,
 43.2675 +  /// where \f$ A_{forward}=\{uv : uv\in A, flow(uv)<cap(uv)\} \f$ and
 43.2676 +  /// \f$ A_{backward}=\{vu : uv\in A, flow(uv)>0\} \f$, i.e. the so
 43.2677 +  /// called residual digraph.
 43.2678 +  /// When the union \f$ A_{forward}\cup A_{backward} \f$ is taken,
 43.2679 +  /// multiplicities are counted, i.e. the adaptor has exactly
 43.2680 +  /// \f$ |A_{forward}| + |A_{backward}|\f$ arcs (it may have parallel
 43.2681 +  /// arcs).
 43.2682 +  /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
 43.2683 +  ///
 43.2684 +  /// \tparam DGR The type of the adapted digraph.
 43.2685 +  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
 43.2686 +  /// It is implicitly \c const.
 43.2687 +  /// \tparam CM The type of the capacity map.
 43.2688 +  /// It must be an arc map of some numerical type, which defines
 43.2689 +  /// the capacities in the flow problem. It is implicitly \c const.
 43.2690 +  /// The default type is
 43.2691 +  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
 43.2692 +  /// \tparam FM The type of the flow map.
 43.2693 +  /// It must be an arc map of some numerical type, which defines
 43.2694 +  /// the flow values in the flow problem. The default type is \c CM.
 43.2695 +  /// \tparam TL The tolerance type for handling inexact computation.
 43.2696 +  /// The default tolerance type depends on the value type of the
 43.2697 +  /// capacity map.
 43.2698 +  ///
 43.2699 +  /// \note This adaptor is implemented using Undirector and FilterArcs
 43.2700 +  /// adaptors.
 43.2701 +  ///
 43.2702 +  /// \note The \c Node type of this adaptor and the adapted digraph are
 43.2703 +  /// convertible to each other, moreover the \c Arc type of the adaptor
 43.2704 +  /// is convertible to the \c Arc type of the adapted digraph.
 43.2705 +#ifdef DOXYGEN
 43.2706 +  template<typename DGR, typename CM, typename FM, typename TL>
 43.2707 +  class ResidualDigraph
 43.2708 +#else
 43.2709 +  template<typename DGR,
 43.2710 +           typename CM = typename DGR::template ArcMap<int>,
 43.2711 +           typename FM = CM,
 43.2712 +           typename TL = Tolerance<typename CM::Value> >
 43.2713 +  class ResidualDigraph 
 43.2714 +    : public SubDigraph<
 43.2715 +        Undirector<const DGR>,
 43.2716 +        ConstMap<typename DGR::Node, Const<bool, true> >,
 43.2717 +        typename Undirector<const DGR>::template CombinedArcMap<
 43.2718 +          _adaptor_bits::ResForwardFilter<const DGR, CM, FM, TL>,
 43.2719 +          _adaptor_bits::ResBackwardFilter<const DGR, CM, FM, TL> > >
 43.2720 +#endif
 43.2721 +  {
 43.2722 +  public:
 43.2723 +
 43.2724 +    /// The type of the underlying digraph.
 43.2725 +    typedef DGR Digraph;
 43.2726 +    /// The type of the capacity map.
 43.2727 +    typedef CM CapacityMap;
 43.2728 +    /// The type of the flow map.
 43.2729 +    typedef FM FlowMap;
 43.2730 +    /// The tolerance type.
 43.2731 +    typedef TL Tolerance;
 43.2732 +
 43.2733 +    typedef typename CapacityMap::Value Value;
 43.2734 +    typedef ResidualDigraph Adaptor;
 43.2735 +
 43.2736 +  protected:
 43.2737 +
 43.2738 +    typedef Undirector<const Digraph> Undirected;
 43.2739 +
 43.2740 +    typedef ConstMap<typename DGR::Node, Const<bool, true> > NodeFilter;
 43.2741 +
 43.2742 +    typedef _adaptor_bits::ResForwardFilter<const DGR, CM,
 43.2743 +                                            FM, TL> ForwardFilter;
 43.2744 +
 43.2745 +    typedef _adaptor_bits::ResBackwardFilter<const DGR, CM,
 43.2746 +                                             FM, TL> BackwardFilter;
 43.2747 +
 43.2748 +    typedef typename Undirected::
 43.2749 +      template CombinedArcMap<ForwardFilter, BackwardFilter> ArcFilter;
 43.2750 +
 43.2751 +    typedef SubDigraph<Undirected, NodeFilter, ArcFilter> Parent;
 43.2752 +
 43.2753 +    const CapacityMap* _capacity;
 43.2754 +    FlowMap* _flow;
 43.2755 +
 43.2756 +    Undirected _graph;
 43.2757 +    NodeFilter _node_filter;
 43.2758 +    ForwardFilter _forward_filter;
 43.2759 +    BackwardFilter _backward_filter;
 43.2760 +    ArcFilter _arc_filter;
 43.2761 +
 43.2762 +  public:
 43.2763 +
 43.2764 +    /// \brief Constructor
 43.2765 +    ///
 43.2766 +    /// Constructor of the residual digraph adaptor. The parameters are the
 43.2767 +    /// digraph, the capacity map, the flow map, and a tolerance object.
 43.2768 +    ResidualDigraph(const DGR& digraph, const CM& capacity,
 43.2769 +                    FM& flow, const TL& tolerance = Tolerance())
 43.2770 +      : Parent(), _capacity(&capacity), _flow(&flow), 
 43.2771 +        _graph(digraph), _node_filter(),
 43.2772 +        _forward_filter(capacity, flow, tolerance),
 43.2773 +        _backward_filter(capacity, flow, tolerance),
 43.2774 +        _arc_filter(_forward_filter, _backward_filter)
 43.2775 +    {
 43.2776 +      Parent::initialize(_graph, _node_filter, _arc_filter);
 43.2777 +    }
 43.2778 +
 43.2779 +    typedef typename Parent::Arc Arc;
 43.2780 +
 43.2781 +    /// \brief Returns the residual capacity of the given arc.
 43.2782 +    ///
 43.2783 +    /// Returns the residual capacity of the given arc.
 43.2784 +    Value residualCapacity(const Arc& a) const {
 43.2785 +      if (Undirected::direction(a)) {
 43.2786 +        return (*_capacity)[a] - (*_flow)[a];
 43.2787 +      } else {
 43.2788 +        return (*_flow)[a];
 43.2789 +      }
 43.2790 +    }
 43.2791 +
 43.2792 +    /// \brief Augments on the given arc in the residual digraph.
 43.2793 +    ///
 43.2794 +    /// Augments on the given arc in the residual digraph. It increases
 43.2795 +    /// or decreases the flow value on the original arc according to the
 43.2796 +    /// direction of the residual arc.
 43.2797 +    void augment(const Arc& a, const Value& v) const {
 43.2798 +      if (Undirected::direction(a)) {
 43.2799 +        _flow->set(a, (*_flow)[a] + v);
 43.2800 +      } else {
 43.2801 +        _flow->set(a, (*_flow)[a] - v);
 43.2802 +      }
 43.2803 +    }
 43.2804 +
 43.2805 +    /// \brief Returns \c true if the given residual arc is a forward arc.
 43.2806 +    ///
 43.2807 +    /// Returns \c true if the given residual arc has the same orientation
 43.2808 +    /// as the original arc, i.e. it is a so called forward arc.
 43.2809 +    static bool forward(const Arc& a) {
 43.2810 +      return Undirected::direction(a);
 43.2811 +    }
 43.2812 +
 43.2813 +    /// \brief Returns \c true if the given residual arc is a backward arc.
 43.2814 +    ///
 43.2815 +    /// Returns \c true if the given residual arc has the opposite orientation
 43.2816 +    /// than the original arc, i.e. it is a so called backward arc.
 43.2817 +    static bool backward(const Arc& a) {
 43.2818 +      return !Undirected::direction(a);
 43.2819 +    }
 43.2820 +
 43.2821 +    /// \brief Returns the forward oriented residual arc.
 43.2822 +    ///
 43.2823 +    /// Returns the forward oriented residual arc related to the given
 43.2824 +    /// arc of the underlying digraph.
 43.2825 +    static Arc forward(const typename Digraph::Arc& a) {
 43.2826 +      return Undirected::direct(a, true);
 43.2827 +    }
 43.2828 +
 43.2829 +    /// \brief Returns the backward oriented residual arc.
 43.2830 +    ///
 43.2831 +    /// Returns the backward oriented residual arc related to the given
 43.2832 +    /// arc of the underlying digraph.
 43.2833 +    static Arc backward(const typename Digraph::Arc& a) {
 43.2834 +      return Undirected::direct(a, false);
 43.2835 +    }
 43.2836 +
 43.2837 +    /// \brief Residual capacity map.
 43.2838 +    ///
 43.2839 +    /// This map adaptor class can be used for obtaining the residual
 43.2840 +    /// capacities as an arc map of the residual digraph.
 43.2841 +    /// Its value type is inherited from the capacity map.
 43.2842 +    class ResidualCapacity {
 43.2843 +    protected:
 43.2844 +      const Adaptor* _adaptor;
 43.2845 +    public:
 43.2846 +      /// The key type of the map
 43.2847 +      typedef Arc Key;
 43.2848 +      /// The value type of the map
 43.2849 +      typedef typename CapacityMap::Value Value;
 43.2850 +
 43.2851 +      /// Constructor
 43.2852 +      ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor) 
 43.2853 +        : _adaptor(&adaptor) {}
 43.2854 +
 43.2855 +      /// Returns the value associated with the given residual arc
 43.2856 +      Value operator[](const Arc& a) const {
 43.2857 +        return _adaptor->residualCapacity(a);
 43.2858 +      }
 43.2859 +
 43.2860 +    };
 43.2861 +
 43.2862 +    /// \brief Returns a residual capacity map
 43.2863 +    ///
 43.2864 +    /// This function just returns a residual capacity map.
 43.2865 +    ResidualCapacity residualCapacity() const {
 43.2866 +      return ResidualCapacity(*this);
 43.2867 +    }
 43.2868 +
 43.2869 +  };
 43.2870 +
 43.2871 +  /// \brief Returns a (read-only) Residual adaptor
 43.2872 +  ///
 43.2873 +  /// This function just returns a (read-only) \ref ResidualDigraph adaptor.
 43.2874 +  /// \ingroup graph_adaptors
 43.2875 +  /// \relates ResidualDigraph
 43.2876 +    template<typename DGR, typename CM, typename FM>
 43.2877 +  ResidualDigraph<DGR, CM, FM>
 43.2878 +  residualDigraph(const DGR& digraph, const CM& capacity_map, FM& flow_map) {
 43.2879 +    return ResidualDigraph<DGR, CM, FM> (digraph, capacity_map, flow_map);
 43.2880 +  }
 43.2881 +
 43.2882 +
 43.2883 +  template <typename DGR>
 43.2884 +  class SplitNodesBase {
 43.2885 +    typedef DigraphAdaptorBase<const DGR> Parent;
 43.2886 +
 43.2887 +  public:
 43.2888 +
 43.2889 +    typedef DGR Digraph;
 43.2890 +    typedef SplitNodesBase Adaptor;
 43.2891 +
 43.2892 +    typedef typename DGR::Node DigraphNode;
 43.2893 +    typedef typename DGR::Arc DigraphArc;
 43.2894 +
 43.2895 +    class Node;
 43.2896 +    class Arc;
 43.2897 +
 43.2898 +  private:
 43.2899 +
 43.2900 +    template <typename T> class NodeMapBase;
 43.2901 +    template <typename T> class ArcMapBase;
 43.2902 +
 43.2903 +  public:
 43.2904 +
 43.2905 +    class Node : public DigraphNode {
 43.2906 +      friend class SplitNodesBase;
 43.2907 +      template <typename T> friend class NodeMapBase;
 43.2908 +    private:
 43.2909 +
 43.2910 +      bool _in;
 43.2911 +      Node(DigraphNode node, bool in)
 43.2912 +        : DigraphNode(node), _in(in) {}
 43.2913 +
 43.2914 +    public:
 43.2915 +
 43.2916 +      Node() {}
 43.2917 +      Node(Invalid) : DigraphNode(INVALID), _in(true) {}
 43.2918 +
 43.2919 +      bool operator==(const Node& node) const {
 43.2920 +        return DigraphNode::operator==(node) && _in == node._in;
 43.2921 +      }
 43.2922 +
 43.2923 +      bool operator!=(const Node& node) const {
 43.2924 +        return !(*this == node);
 43.2925 +      }
 43.2926 +
 43.2927 +      bool operator<(const Node& node) const {
 43.2928 +        return DigraphNode::operator<(node) ||
 43.2929 +          (DigraphNode::operator==(node) && _in < node._in);
 43.2930 +      }
 43.2931 +    };
 43.2932 +
 43.2933 +    class Arc {
 43.2934 +      friend class SplitNodesBase;
 43.2935 +      template <typename T> friend class ArcMapBase;
 43.2936 +    private:
 43.2937 +      typedef BiVariant<DigraphArc, DigraphNode> ArcImpl;
 43.2938 +
 43.2939 +      explicit Arc(const DigraphArc& arc) : _item(arc) {}
 43.2940 +      explicit Arc(const DigraphNode& node) : _item(node) {}
 43.2941 +
 43.2942 +      ArcImpl _item;
 43.2943 +
 43.2944 +    public:
 43.2945 +      Arc() {}
 43.2946 +      Arc(Invalid) : _item(DigraphArc(INVALID)) {}
 43.2947 +
 43.2948 +      bool operator==(const Arc& arc) const {
 43.2949 +        if (_item.firstState()) {
 43.2950 +          if (arc._item.firstState()) {
 43.2951 +            return _item.first() == arc._item.first();
 43.2952 +          }
 43.2953 +        } else {
 43.2954 +          if (arc._item.secondState()) {
 43.2955 +            return _item.second() == arc._item.second();
 43.2956 +          }
 43.2957 +        }
 43.2958 +        return false;
 43.2959 +      }
 43.2960 +
 43.2961 +      bool operator!=(const Arc& arc) const {
 43.2962 +        return !(*this == arc);
 43.2963 +      }
 43.2964 +
 43.2965 +      bool operator<(const Arc& arc) const {
 43.2966 +        if (_item.firstState()) {
 43.2967 +          if (arc._item.firstState()) {
 43.2968 +            return _item.first() < arc._item.first();
 43.2969 +          }
 43.2970 +          return false;
 43.2971 +        } else {
 43.2972 +          if (arc._item.secondState()) {
 43.2973 +            return _item.second() < arc._item.second();
 43.2974 +          }
 43.2975 +          return true;
 43.2976 +        }
 43.2977 +      }
 43.2978 +
 43.2979 +      operator DigraphArc() const { return _item.first(); }
 43.2980 +      operator DigraphNode() const { return _item.second(); }
 43.2981 +
 43.2982 +    };
 43.2983 +
 43.2984 +    void first(Node& n) const {
 43.2985 +      _digraph->first(n);
 43.2986 +      n._in = true;
 43.2987 +    }
 43.2988 +
 43.2989 +    void next(Node& n) const {
 43.2990 +      if (n._in) {
 43.2991 +        n._in = false;
 43.2992 +      } else {
 43.2993 +        n._in = true;
 43.2994 +        _digraph->next(n);
 43.2995 +      }
 43.2996 +    }
 43.2997 +
 43.2998 +    void first(Arc& e) const {
 43.2999 +      e._item.setSecond();
 43.3000 +      _digraph->first(e._item.second());
 43.3001 +      if (e._item.second() == INVALID) {
 43.3002 +        e._item.setFirst();
 43.3003 +        _digraph->first(e._item.first());
 43.3004 +      }
 43.3005 +    }
 43.3006 +
 43.3007 +    void next(Arc& e) const {
 43.3008 +      if (e._item.secondState()) {
 43.3009 +        _digraph->next(e._item.second());
 43.3010 +        if (e._item.second() == INVALID) {
 43.3011 +          e._item.setFirst();
 43.3012 +          _digraph->first(e._item.first());
 43.3013 +        }
 43.3014 +      } else {
 43.3015 +        _digraph->next(e._item.first());
 43.3016 +      }
 43.3017 +    }
 43.3018 +
 43.3019 +    void firstOut(Arc& e, const Node& n) const {
 43.3020 +      if (n._in) {
 43.3021 +        e._item.setSecond(n);
 43.3022 +      } else {
 43.3023 +        e._item.setFirst();
 43.3024 +        _digraph->firstOut(e._item.first(), n);
 43.3025 +      }
 43.3026 +    }
 43.3027 +
 43.3028 +    void nextOut(Arc& e) const {
 43.3029 +      if (!e._item.firstState()) {
 43.3030 +        e._item.setFirst(INVALID);
 43.3031 +      } else {
 43.3032 +        _digraph->nextOut(e._item.first());
 43.3033 +      }
 43.3034 +    }
 43.3035 +
 43.3036 +    void firstIn(Arc& e, const Node& n) const {
 43.3037 +      if (!n._in) {
 43.3038 +        e._item.setSecond(n);
 43.3039 +      } else {
 43.3040 +        e._item.setFirst();
 43.3041 +        _digraph->firstIn(e._item.first(), n);
 43.3042 +      }
 43.3043 +    }
 43.3044 +
 43.3045 +    void nextIn(Arc& e) const {
 43.3046 +      if (!e._item.firstState()) {
 43.3047 +        e._item.setFirst(INVALID);
 43.3048 +      } else {
 43.3049 +        _digraph->nextIn(e._item.first());
 43.3050 +      }
 43.3051 +    }
 43.3052 +
 43.3053 +    Node source(const Arc& e) const {
 43.3054 +      if (e._item.firstState()) {
 43.3055 +        return Node(_digraph->source(e._item.first()), false);
 43.3056 +      } else {
 43.3057 +        return Node(e._item.second(), true);
 43.3058 +      }
 43.3059 +    }
 43.3060 +
 43.3061 +    Node target(const Arc& e) const {
 43.3062 +      if (e._item.firstState()) {
 43.3063 +        return Node(_digraph->target(e._item.first()), true);
 43.3064 +      } else {
 43.3065 +        return Node(e._item.second(), false);
 43.3066 +      }
 43.3067 +    }
 43.3068 +
 43.3069 +    int id(const Node& n) const {
 43.3070 +      return (_digraph->id(n) << 1) | (n._in ? 0 : 1);
 43.3071 +    }
 43.3072 +    Node nodeFromId(int ix) const {
 43.3073 +      return Node(_digraph->nodeFromId(ix >> 1), (ix & 1) == 0);
 43.3074 +    }
 43.3075 +    int maxNodeId() const {
 43.3076 +      return 2 * _digraph->maxNodeId() + 1;
 43.3077 +    }
 43.3078 +
 43.3079 +    int id(const Arc& e) const {
 43.3080 +      if (e._item.firstState()) {
 43.3081 +        return _digraph->id(e._item.first()) << 1;
 43.3082 +      } else {
 43.3083 +        return (_digraph->id(e._item.second()) << 1) | 1;
 43.3084 +      }
 43.3085 +    }
 43.3086 +    Arc arcFromId(int ix) const {
 43.3087 +      if ((ix & 1) == 0) {
 43.3088 +        return Arc(_digraph->arcFromId(ix >> 1));
 43.3089 +      } else {
 43.3090 +        return Arc(_digraph->nodeFromId(ix >> 1));
 43.3091 +      }
 43.3092 +    }
 43.3093 +    int maxArcId() const {
 43.3094 +      return std::max(_digraph->maxNodeId() << 1,
 43.3095 +                      (_digraph->maxArcId() << 1) | 1);
 43.3096 +    }
 43.3097 +
 43.3098 +    static bool inNode(const Node& n) {
 43.3099 +      return n._in;
 43.3100 +    }
 43.3101 +
 43.3102 +    static bool outNode(const Node& n) {
 43.3103 +      return !n._in;
 43.3104 +    }
 43.3105 +
 43.3106 +    static bool origArc(const Arc& e) {
 43.3107 +      return e._item.firstState();
 43.3108 +    }
 43.3109 +
 43.3110 +    static bool bindArc(const Arc& e) {
 43.3111 +      return e._item.secondState();
 43.3112 +    }
 43.3113 +
 43.3114 +    static Node inNode(const DigraphNode& n) {
 43.3115 +      return Node(n, true);
 43.3116 +    }
 43.3117 +
 43.3118 +    static Node outNode(const DigraphNode& n) {
 43.3119 +      return Node(n, false);
 43.3120 +    }
 43.3121 +
 43.3122 +    static Arc arc(const DigraphNode& n) {
 43.3123 +      return Arc(n);
 43.3124 +    }
 43.3125 +
 43.3126 +    static Arc arc(const DigraphArc& e) {
 43.3127 +      return Arc(e);
 43.3128 +    }
 43.3129 +
 43.3130 +    typedef True NodeNumTag;
 43.3131 +    int nodeNum() const {
 43.3132 +      return  2 * countNodes(*_digraph);
 43.3133 +    }
 43.3134 +
 43.3135 +    typedef True ArcNumTag;
 43.3136 +    int arcNum() const {
 43.3137 +      return countArcs(*_digraph) + countNodes(*_digraph);
 43.3138 +    }
 43.3139 +
 43.3140 +    typedef True FindArcTag;
 43.3141 +    Arc findArc(const Node& u, const Node& v,
 43.3142 +                const Arc& prev = INVALID) const {
 43.3143 +      if (inNode(u) && outNode(v)) {
 43.3144 +        if (static_cast<const DigraphNode&>(u) ==
 43.3145 +            static_cast<const DigraphNode&>(v) && prev == INVALID) {
 43.3146 +          return Arc(u);
 43.3147 +        }
 43.3148 +      }
 43.3149 +      else if (outNode(u) && inNode(v)) {
 43.3150 +        return Arc(::lemon::findArc(*_digraph, u, v, prev));
 43.3151 +      }
 43.3152 +      return INVALID;
 43.3153 +    }
 43.3154 +
 43.3155 +  private:
 43.3156 +
 43.3157 +    template <typename V>
 43.3158 +    class NodeMapBase
 43.3159 +      : public MapTraits<typename Parent::template NodeMap<V> > {
 43.3160 +      typedef typename Parent::template NodeMap<V> NodeImpl;
 43.3161 +    public:
 43.3162 +      typedef Node Key;
 43.3163 +      typedef V Value;
 43.3164 +      typedef typename MapTraits<NodeImpl>::ReferenceMapTag ReferenceMapTag;
 43.3165 +      typedef typename MapTraits<NodeImpl>::ReturnValue ReturnValue;
 43.3166 +      typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReturnValue;
 43.3167 +      typedef typename MapTraits<NodeImpl>::ReturnValue Reference;
 43.3168 +      typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReference;
 43.3169 +
 43.3170 +      NodeMapBase(const SplitNodesBase<DGR>& adaptor)
 43.3171 +        : _in_map(*adaptor._digraph), _out_map(*adaptor._digraph) {}
 43.3172 +      NodeMapBase(const SplitNodesBase<DGR>& adaptor, const V& value)
 43.3173 +        : _in_map(*adaptor._digraph, value),
 43.3174 +          _out_map(*adaptor._digraph, value) {}
 43.3175 +
 43.3176 +      void set(const Node& key, const V& val) {
 43.3177 +        if (SplitNodesBase<DGR>::inNode(key)) { _in_map.set(key, val); }
 43.3178 +        else {_out_map.set(key, val); }
 43.3179 +      }
 43.3180 +
 43.3181 +      ReturnValue operator[](const Node& key) {
 43.3182 +        if (SplitNodesBase<DGR>::inNode(key)) { return _in_map[key]; }
 43.3183 +        else { return _out_map[key]; }
 43.3184 +      }
 43.3185 +
 43.3186 +      ConstReturnValue operator[](const Node& key) const {
 43.3187 +        if (Adaptor::inNode(key)) { return _in_map[key]; }
 43.3188 +        else { return _out_map[key]; }
 43.3189 +      }
 43.3190 +
 43.3191 +    private:
 43.3192 +      NodeImpl _in_map, _out_map;
 43.3193 +    };
 43.3194 +
 43.3195 +    template <typename V>
 43.3196 +    class ArcMapBase
 43.3197 +      : public MapTraits<typename Parent::template ArcMap<V> > {
 43.3198 +      typedef typename Parent::template ArcMap<V> ArcImpl;
 43.3199 +      typedef typename Parent::template NodeMap<V> NodeImpl;
 43.3200 +    public:
 43.3201 +      typedef Arc Key;
 43.3202 +      typedef V Value;
 43.3203 +      typedef typename MapTraits<ArcImpl>::ReferenceMapTag ReferenceMapTag;
 43.3204 +      typedef typename MapTraits<ArcImpl>::ReturnValue ReturnValue;
 43.3205 +      typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReturnValue;
 43.3206 +      typedef typename MapTraits<ArcImpl>::ReturnValue Reference;
 43.3207 +      typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReference;
 43.3208 +
 43.3209 +      ArcMapBase(const SplitNodesBase<DGR>& adaptor)
 43.3210 +        : _arc_map(*adaptor._digraph), _node_map(*adaptor._digraph) {}
 43.3211 +      ArcMapBase(const SplitNodesBase<DGR>& adaptor, const V& value)
 43.3212 +        : _arc_map(*adaptor._digraph, value),
 43.3213 +          _node_map(*adaptor._digraph, value) {}
 43.3214 +
 43.3215 +      void set(const Arc& key, const V& val) {
 43.3216 +        if (SplitNodesBase<DGR>::origArc(key)) {
 43.3217 +          _arc_map.set(static_cast<const DigraphArc&>(key), val);
 43.3218 +        } else {
 43.3219 +          _node_map.set(static_cast<const DigraphNode&>(key), val);
 43.3220 +        }
 43.3221 +      }
 43.3222 +
 43.3223 +      ReturnValue operator[](const Arc& key) {
 43.3224 +        if (SplitNodesBase<DGR>::origArc(key)) {
 43.3225 +          return _arc_map[static_cast<const DigraphArc&>(key)];
 43.3226 +        } else {
 43.3227 +          return _node_map[static_cast<const DigraphNode&>(key)];
 43.3228 +        }
 43.3229 +      }
 43.3230 +
 43.3231 +      ConstReturnValue operator[](const Arc& key) const {
 43.3232 +        if (SplitNodesBase<DGR>::origArc(key)) {
 43.3233 +          return _arc_map[static_cast<const DigraphArc&>(key)];
 43.3234 +        } else {
 43.3235 +          return _node_map[static_cast<const DigraphNode&>(key)];
 43.3236 +        }
 43.3237 +      }
 43.3238 +
 43.3239 +    private:
 43.3240 +      ArcImpl _arc_map;
 43.3241 +      NodeImpl _node_map;
 43.3242 +    };
 43.3243 +
 43.3244 +  public:
 43.3245 +
 43.3246 +    template <typename V>
 43.3247 +    class NodeMap
 43.3248 +      : public SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> > {
 43.3249 +      typedef SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> > Parent;
 43.3250 +
 43.3251 +    public:
 43.3252 +      typedef V Value;
 43.3253 +
 43.3254 +      NodeMap(const SplitNodesBase<DGR>& adaptor)
 43.3255 +        : Parent(adaptor) {}
 43.3256 +
 43.3257 +      NodeMap(const SplitNodesBase<DGR>& adaptor, const V& value)
 43.3258 +        : Parent(adaptor, value) {}
 43.3259 +
 43.3260 +    private:
 43.3261 +      NodeMap& operator=(const NodeMap& cmap) {
 43.3262 +        return operator=<NodeMap>(cmap);
 43.3263 +      }
 43.3264 +
 43.3265 +      template <typename CMap>
 43.3266 +      NodeMap& operator=(const CMap& cmap) {
 43.3267 +        Parent::operator=(cmap);
 43.3268 +        return *this;
 43.3269 +      }
 43.3270 +    };
 43.3271 +
 43.3272 +    template <typename V>
 43.3273 +    class ArcMap
 43.3274 +      : public SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> > {
 43.3275 +      typedef SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> > Parent;
 43.3276 +
 43.3277 +    public:
 43.3278 +      typedef V Value;
 43.3279 +
 43.3280 +      ArcMap(const SplitNodesBase<DGR>& adaptor)
 43.3281 +        : Parent(adaptor) {}
 43.3282 +
 43.3283 +      ArcMap(const SplitNodesBase<DGR>& adaptor, const V& value)
 43.3284 +        : Parent(adaptor, value) {}
 43.3285 +
 43.3286 +    private:
 43.3287 +      ArcMap& operator=(const ArcMap& cmap) {
 43.3288 +        return operator=<ArcMap>(cmap);
 43.3289 +      }
 43.3290 +
 43.3291 +      template <typename CMap>
 43.3292 +      ArcMap& operator=(const CMap& cmap) {
 43.3293 +        Parent::operator=(cmap);
 43.3294 +        return *this;
 43.3295 +      }
 43.3296 +    };
 43.3297 +
 43.3298 +  protected:
 43.3299 +
 43.3300 +    SplitNodesBase() : _digraph(0) {}
 43.3301 +
 43.3302 +    DGR* _digraph;
 43.3303 +
 43.3304 +    void initialize(Digraph& digraph) {
 43.3305 +      _digraph = &digraph;
 43.3306 +    }
 43.3307 +
 43.3308 +  };
 43.3309 +
 43.3310 +  /// \ingroup graph_adaptors
 43.3311 +  ///
 43.3312 +  /// \brief Adaptor class for splitting the nodes of a digraph.
 43.3313 +  ///
 43.3314 +  /// SplitNodes adaptor can be used for splitting each node into an
 43.3315 +  /// \e in-node and an \e out-node in a digraph. Formaly, the adaptor
 43.3316 +  /// replaces each node \f$ u \f$ in the digraph with two nodes,
 43.3317 +  /// namely node \f$ u_{in} \f$ and node \f$ u_{out} \f$.
 43.3318 +  /// If there is a \f$ (v, u) \f$ arc in the original digraph, then the
 43.3319 +  /// new target of the arc will be \f$ u_{in} \f$ and similarly the
 43.3320 +  /// source of each original \f$ (u, v) \f$ arc will be \f$ u_{out} \f$.
 43.3321 +  /// The adaptor adds an additional \e bind \e arc from \f$ u_{in} \f$
 43.3322 +  /// to \f$ u_{out} \f$ for each node \f$ u \f$ of the original digraph.
 43.3323 +  ///
 43.3324 +  /// The aim of this class is running an algorithm with respect to node
 43.3325 +  /// costs or capacities if the algorithm considers only arc costs or
 43.3326 +  /// capacities directly.
 43.3327 +  /// In this case you can use \c SplitNodes adaptor, and set the node
 43.3328 +  /// costs/capacities of the original digraph to the \e bind \e arcs
 43.3329 +  /// in the adaptor.
 43.3330 +  ///
 43.3331 +  /// \tparam DGR The type of the adapted digraph.
 43.3332 +  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
 43.3333 +  /// It is implicitly \c const.
 43.3334 +  ///
 43.3335 +  /// \note The \c Node type of this adaptor is converible to the \c Node
 43.3336 +  /// type of the adapted digraph.
 43.3337 +  template <typename DGR>
 43.3338 +#ifdef DOXYGEN
 43.3339 +  class SplitNodes {
 43.3340 +#else
 43.3341 +  class SplitNodes
 43.3342 +    : public DigraphAdaptorExtender<SplitNodesBase<const DGR> > {
 43.3343 +#endif
 43.3344 +    typedef DigraphAdaptorExtender<SplitNodesBase<const DGR> > Parent;
 43.3345 +
 43.3346 +  public:
 43.3347 +    typedef DGR Digraph;
 43.3348 +
 43.3349 +    typedef typename DGR::Node DigraphNode;
 43.3350 +    typedef typename DGR::Arc DigraphArc;
 43.3351 +
 43.3352 +    typedef typename Parent::Node Node;
 43.3353 +    typedef typename Parent::Arc Arc;
 43.3354 +
 43.3355 +    /// \brief Constructor
 43.3356 +    ///
 43.3357 +    /// Constructor of the adaptor.
 43.3358 +    SplitNodes(const DGR& g) {
 43.3359 +      Parent::initialize(g);
 43.3360 +    }
 43.3361 +
 43.3362 +    /// \brief Returns \c true if the given node is an in-node.
 43.3363 +    ///
 43.3364 +    /// Returns \c true if the given node is an in-node.
 43.3365 +    static bool inNode(const Node& n) {
 43.3366 +      return Parent::inNode(n);
 43.3367 +    }
 43.3368 +
 43.3369 +    /// \brief Returns \c true if the given node is an out-node.
 43.3370 +    ///
 43.3371 +    /// Returns \c true if the given node is an out-node.
 43.3372 +    static bool outNode(const Node& n) {
 43.3373 +      return Parent::outNode(n);
 43.3374 +    }
 43.3375 +
 43.3376 +    /// \brief Returns \c true if the given arc is an original arc.
 43.3377 +    ///
 43.3378 +    /// Returns \c true if the given arc is one of the arcs in the
 43.3379 +    /// original digraph.
 43.3380 +    static bool origArc(const Arc& a) {
 43.3381 +      return Parent::origArc(a);
 43.3382 +    }
 43.3383 +
 43.3384 +    /// \brief Returns \c true if the given arc is a bind arc.
 43.3385 +    ///
 43.3386 +    /// Returns \c true if the given arc is a bind arc, i.e. it connects
 43.3387 +    /// an in-node and an out-node.
 43.3388 +    static bool bindArc(const Arc& a) {
 43.3389 +      return Parent::bindArc(a);
 43.3390 +    }
 43.3391 +
 43.3392 +    /// \brief Returns the in-node created from the given original node.
 43.3393 +    ///
 43.3394 +    /// Returns the in-node created from the given original node.
 43.3395 +    static Node inNode(const DigraphNode& n) {
 43.3396 +      return Parent::inNode(n);
 43.3397 +    }
 43.3398 +
 43.3399 +    /// \brief Returns the out-node created from the given original node.
 43.3400 +    ///
 43.3401 +    /// Returns the out-node created from the given original node.
 43.3402 +    static Node outNode(const DigraphNode& n) {
 43.3403 +      return Parent::outNode(n);
 43.3404 +    }
 43.3405 +
 43.3406 +    /// \brief Returns the bind arc that corresponds to the given
 43.3407 +    /// original node.
 43.3408 +    ///
 43.3409 +    /// Returns the bind arc in the adaptor that corresponds to the given
 43.3410 +    /// original node, i.e. the arc connecting the in-node and out-node
 43.3411 +    /// of \c n.
 43.3412 +    static Arc arc(const DigraphNode& n) {
 43.3413 +      return Parent::arc(n);
 43.3414 +    }
 43.3415 +
 43.3416 +    /// \brief Returns the arc that corresponds to the given original arc.
 43.3417 +    ///
 43.3418 +    /// Returns the arc in the adaptor that corresponds to the given
 43.3419 +    /// original arc.
 43.3420 +    static Arc arc(const DigraphArc& a) {
 43.3421 +      return Parent::arc(a);
 43.3422 +    }
 43.3423 +
 43.3424 +    /// \brief Node map combined from two original node maps
 43.3425 +    ///
 43.3426 +    /// This map adaptor class adapts two node maps of the original digraph
 43.3427 +    /// to get a node map of the split digraph.
 43.3428 +    /// Its value type is inherited from the first node map type (\c IN).
 43.3429 +    /// \tparam IN The type of the node map for the in-nodes. 
 43.3430 +    /// \tparam OUT The type of the node map for the out-nodes.
 43.3431 +    template <typename IN, typename OUT>
 43.3432 +    class CombinedNodeMap {
 43.3433 +    public:
 43.3434 +
 43.3435 +      /// The key type of the map
 43.3436 +      typedef Node Key;
 43.3437 +      /// The value type of the map
 43.3438 +      typedef typename IN::Value Value;
 43.3439 +
 43.3440 +      typedef typename MapTraits<IN>::ReferenceMapTag ReferenceMapTag;
 43.3441 +      typedef typename MapTraits<IN>::ReturnValue ReturnValue;
 43.3442 +      typedef typename MapTraits<IN>::ConstReturnValue ConstReturnValue;
 43.3443 +      typedef typename MapTraits<IN>::ReturnValue Reference;
 43.3444 +      typedef typename MapTraits<IN>::ConstReturnValue ConstReference;
 43.3445 +
 43.3446 +      /// Constructor
 43.3447 +      CombinedNodeMap(IN& in_map, OUT& out_map)
 43.3448 +        : _in_map(in_map), _out_map(out_map) {}
 43.3449 +
 43.3450 +      /// Returns the value associated with the given key.
 43.3451 +      Value operator[](const Key& key) const {
 43.3452 +        if (SplitNodesBase<const DGR>::inNode(key)) {
 43.3453 +          return _in_map[key];
 43.3454 +        } else {
 43.3455 +          return _out_map[key];
 43.3456 +        }
 43.3457 +      }
 43.3458 +
 43.3459 +      /// Returns a reference to the value associated with the given key.
 43.3460 +      Value& operator[](const Key& key) {
 43.3461 +        if (SplitNodesBase<const DGR>::inNode(key)) {
 43.3462 +          return _in_map[key];
 43.3463 +        } else {
 43.3464 +          return _out_map[key];
 43.3465 +        }
 43.3466 +      }
 43.3467 +
 43.3468 +      /// Sets the value associated with the given key.
 43.3469 +      void set(const Key& key, const Value& value) {
 43.3470 +        if (SplitNodesBase<const DGR>::inNode(key)) {
 43.3471 +          _in_map.set(key, value);
 43.3472 +        } else {
 43.3473 +          _out_map.set(key, value);
 43.3474 +        }
 43.3475 +      }
 43.3476 +
 43.3477 +    private:
 43.3478 +
 43.3479 +      IN& _in_map;
 43.3480 +      OUT& _out_map;
 43.3481 +
 43.3482 +    };
 43.3483 +
 43.3484 +
 43.3485 +    /// \brief Returns a combined node map
 43.3486 +    ///
 43.3487 +    /// This function just returns a combined node map.
 43.3488 +    template <typename IN, typename OUT>
 43.3489 +    static CombinedNodeMap<IN, OUT>
 43.3490 +    combinedNodeMap(IN& in_map, OUT& out_map) {
 43.3491 +      return CombinedNodeMap<IN, OUT>(in_map, out_map);
 43.3492 +    }
 43.3493 +
 43.3494 +    template <typename IN, typename OUT>
 43.3495 +    static CombinedNodeMap<const IN, OUT>
 43.3496 +    combinedNodeMap(const IN& in_map, OUT& out_map) {
 43.3497 +      return CombinedNodeMap<const IN, OUT>(in_map, out_map);
 43.3498 +    }
 43.3499 +
 43.3500 +    template <typename IN, typename OUT>
 43.3501 +    static CombinedNodeMap<IN, const OUT>
 43.3502 +    combinedNodeMap(IN& in_map, const OUT& out_map) {
 43.3503 +      return CombinedNodeMap<IN, const OUT>(in_map, out_map);
 43.3504 +    }
 43.3505 +
 43.3506 +    template <typename IN, typename OUT>
 43.3507 +    static CombinedNodeMap<const IN, const OUT>
 43.3508 +    combinedNodeMap(const IN& in_map, const OUT& out_map) {
 43.3509 +      return CombinedNodeMap<const IN, const OUT>(in_map, out_map);
 43.3510 +    }
 43.3511 +
 43.3512 +    /// \brief Arc map combined from an arc map and a node map of the
 43.3513 +    /// original digraph.
 43.3514 +    ///
 43.3515 +    /// This map adaptor class adapts an arc map and a node map of the
 43.3516 +    /// original digraph to get an arc map of the split digraph.
 43.3517 +    /// Its value type is inherited from the original arc map type (\c AM).
 43.3518 +    /// \tparam AM The type of the arc map.
 43.3519 +    /// \tparam NM the type of the node map.
 43.3520 +    template <typename AM, typename NM>
 43.3521 +    class CombinedArcMap {
 43.3522 +    public:
 43.3523 +
 43.3524 +      /// The key type of the map
 43.3525 +      typedef Arc Key;
 43.3526 +      /// The value type of the map
 43.3527 +      typedef typename AM::Value Value;
 43.3528 +
 43.3529 +      typedef typename MapTraits<AM>::ReferenceMapTag ReferenceMapTag;
 43.3530 +      typedef typename MapTraits<AM>::ReturnValue ReturnValue;
 43.3531 +      typedef typename MapTraits<AM>::ConstReturnValue ConstReturnValue;
 43.3532 +      typedef typename MapTraits<AM>::ReturnValue Reference;
 43.3533 +      typedef typename MapTraits<AM>::ConstReturnValue ConstReference;
 43.3534 +
 43.3535 +      /// Constructor
 43.3536 +      CombinedArcMap(AM& arc_map, NM& node_map)
 43.3537 +        : _arc_map(arc_map), _node_map(node_map) {}
 43.3538 +
 43.3539 +      /// Returns the value associated with the given key.
 43.3540 +      Value operator[](const Key& arc) const {
 43.3541 +        if (SplitNodesBase<const DGR>::origArc(arc)) {
 43.3542 +          return _arc_map[arc];
 43.3543 +        } else {
 43.3544 +          return _node_map[arc];
 43.3545 +        }
 43.3546 +      }
 43.3547 +
 43.3548 +      /// Returns a reference to the value associated with the given key.
 43.3549 +      Value& operator[](const Key& arc) {
 43.3550 +        if (SplitNodesBase<const DGR>::origArc(arc)) {
 43.3551 +          return _arc_map[arc];
 43.3552 +        } else {
 43.3553 +          return _node_map[arc];
 43.3554 +        }
 43.3555 +      }
 43.3556 +
 43.3557 +      /// Sets the value associated with the given key.
 43.3558 +      void set(const Arc& arc, const Value& val) {
 43.3559 +        if (SplitNodesBase<const DGR>::origArc(arc)) {
 43.3560 +          _arc_map.set(arc, val);
 43.3561 +        } else {
 43.3562 +          _node_map.set(arc, val);
 43.3563 +        }
 43.3564 +      }
 43.3565 +
 43.3566 +    private:
 43.3567 +
 43.3568 +      AM& _arc_map;
 43.3569 +      NM& _node_map;
 43.3570 +
 43.3571 +    };
 43.3572 +
 43.3573 +    /// \brief Returns a combined arc map
 43.3574 +    ///
 43.3575 +    /// This function just returns a combined arc map.
 43.3576 +    template <typename ArcMap, typename NodeMap>
 43.3577 +    static CombinedArcMap<ArcMap, NodeMap>
 43.3578 +    combinedArcMap(ArcMap& arc_map, NodeMap& node_map) {
 43.3579 +      return CombinedArcMap<ArcMap, NodeMap>(arc_map, node_map);
 43.3580 +    }
 43.3581 +
 43.3582 +    template <typename ArcMap, typename NodeMap>
 43.3583 +    static CombinedArcMap<const ArcMap, NodeMap>
 43.3584 +    combinedArcMap(const ArcMap& arc_map, NodeMap& node_map) {
 43.3585 +      return CombinedArcMap<const ArcMap, NodeMap>(arc_map, node_map);
 43.3586 +    }
 43.3587 +
 43.3588 +    template <typename ArcMap, typename NodeMap>
 43.3589 +    static CombinedArcMap<ArcMap, const NodeMap>
 43.3590 +    combinedArcMap(ArcMap& arc_map, const NodeMap& node_map) {
 43.3591 +      return CombinedArcMap<ArcMap, const NodeMap>(arc_map, node_map);
 43.3592 +    }
 43.3593 +
 43.3594 +    template <typename ArcMap, typename NodeMap>
 43.3595 +    static CombinedArcMap<const ArcMap, const NodeMap>
 43.3596 +    combinedArcMap(const ArcMap& arc_map, const NodeMap& node_map) {
 43.3597 +      return CombinedArcMap<const ArcMap, const NodeMap>(arc_map, node_map);
 43.3598 +    }
 43.3599 +
 43.3600 +  };
 43.3601 +
 43.3602 +  /// \brief Returns a (read-only) SplitNodes adaptor
 43.3603 +  ///
 43.3604 +  /// This function just returns a (read-only) \ref SplitNodes adaptor.
 43.3605 +  /// \ingroup graph_adaptors
 43.3606 +  /// \relates SplitNodes
 43.3607 +  template<typename DGR>
 43.3608 +  SplitNodes<DGR>
 43.3609 +  splitNodes(const DGR& digraph) {
 43.3610 +    return SplitNodes<DGR>(digraph);
 43.3611 +  }
 43.3612 +
 43.3613 +#undef LEMON_SCOPE_FIX
 43.3614 +
 43.3615 +} //namespace lemon
 43.3616 +
 43.3617 +#endif //LEMON_ADAPTORS_H
    44.1 --- a/lemon/arg_parser.cc	Fri Oct 16 10:21:37 2009 +0200
    44.2 +++ b/lemon/arg_parser.cc	Thu Nov 05 15:50:01 2009 +0100
    44.3 @@ -2,7 +2,7 @@
    44.4   *
    44.5   * This file is a part of LEMON, a generic C++ optimization library.
    44.6   *
    44.7 - * Copyright (C) 2003-2008
    44.8 + * Copyright (C) 2003-2009
    44.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   44.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   44.11   *
    45.1 --- a/lemon/arg_parser.h	Fri Oct 16 10:21:37 2009 +0200
    45.2 +++ b/lemon/arg_parser.h	Thu Nov 05 15:50:01 2009 +0100
    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-2008
    45.8 + * Copyright (C) 2003-2009
    45.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   45.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   45.11   *
    46.1 --- a/lemon/assert.h	Fri Oct 16 10:21:37 2009 +0200
    46.2 +++ b/lemon/assert.h	Thu Nov 05 15:50:01 2009 +0100
    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-2008
    46.8 + * Copyright (C) 2003-2009
    46.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   46.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   46.11   *
    47.1 --- a/lemon/base.cc	Fri Oct 16 10:21:37 2009 +0200
    47.2 +++ b/lemon/base.cc	Thu Nov 05 15:50:01 2009 +0100
    47.3 @@ -2,7 +2,7 @@
    47.4   *
    47.5   * This file is a part of LEMON, a generic C++ optimization library.
    47.6   *
    47.7 - * Copyright (C) 2003-2008
    47.8 + * Copyright (C) 2003-2009
    47.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   47.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   47.11   *
   47.12 @@ -23,7 +23,7 @@
   47.13  #include<lemon/core.h>
   47.14  namespace lemon {
   47.15  
   47.16 -  float Tolerance<float>::def_epsilon = 1e-4;
   47.17 +  float Tolerance<float>::def_epsilon = static_cast<float>(1e-4);
   47.18    double Tolerance<double>::def_epsilon = 1e-10;
   47.19    long double Tolerance<long double>::def_epsilon = 1e-14;
   47.20  
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/lemon/bellman_ford.h	Thu Nov 05 15:50:01 2009 +0100
    48.3 @@ -0,0 +1,1101 @@
    48.4 +/* -*- C++ -*-
    48.5 + *
    48.6 + * This file is a part of LEMON, a generic C++ optimization library
    48.7 + *
    48.8 + * Copyright (C) 2003-2008
    48.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   48.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   48.11 + *
   48.12 + * Permission to use, modify and distribute this software is granted
   48.13 + * provided that this copyright notice appears in all copies. For
   48.14 + * precise terms see the accompanying LICENSE file.
   48.15 + *
   48.16 + * This software is provided "AS IS" with no warranty of any kind,
   48.17 + * express or implied, and with no claim as to its suitability for any
   48.18 + * purpose.
   48.19 + *
   48.20 + */
   48.21 +
   48.22 +#ifndef LEMON_BELLMAN_FORD_H
   48.23 +#define LEMON_BELLMAN_FORD_H
   48.24 +
   48.25 +/// \ingroup shortest_path
   48.26 +/// \file
   48.27 +/// \brief Bellman-Ford algorithm.
   48.28 +
   48.29 +#include <lemon/list_graph.h>
   48.30 +#include <lemon/bits/path_dump.h>
   48.31 +#include <lemon/core.h>
   48.32 +#include <lemon/error.h>
   48.33 +#include <lemon/maps.h>
   48.34 +#include <lemon/path.h>
   48.35 +
   48.36 +#include <limits>
   48.37 +
   48.38 +namespace lemon {
   48.39 +
   48.40 +  /// \brief Default OperationTraits for the BellmanFord algorithm class.
   48.41 +  ///  
   48.42 +  /// This operation traits class defines all computational operations
   48.43 +  /// and constants that are used in the Bellman-Ford algorithm.
   48.44 +  /// The default implementation is based on the \c numeric_limits class.
   48.45 +  /// If the numeric type does not have infinity value, then the maximum
   48.46 +  /// value is used as extremal infinity value.
   48.47 +  template <
   48.48 +    typename V, 
   48.49 +    bool has_inf = std::numeric_limits<V>::has_infinity>
   48.50 +  struct BellmanFordDefaultOperationTraits {
   48.51 +    /// \e
   48.52 +    typedef V Value;
   48.53 +    /// \brief Gives back the zero value of the type.
   48.54 +    static Value zero() {
   48.55 +      return static_cast<Value>(0);
   48.56 +    }
   48.57 +    /// \brief Gives back the positive infinity value of the type.
   48.58 +    static Value infinity() {
   48.59 +      return std::numeric_limits<Value>::infinity();
   48.60 +    }
   48.61 +    /// \brief Gives back the sum of the given two elements.
   48.62 +    static Value plus(const Value& left, const Value& right) {
   48.63 +      return left + right;
   48.64 +    }
   48.65 +    /// \brief Gives back \c true only if the first value is less than
   48.66 +    /// the second.
   48.67 +    static bool less(const Value& left, const Value& right) {
   48.68 +      return left < right;
   48.69 +    }
   48.70 +  };
   48.71 +
   48.72 +  template <typename V>
   48.73 +  struct BellmanFordDefaultOperationTraits<V, false> {
   48.74 +    typedef V Value;
   48.75 +    static Value zero() {
   48.76 +      return static_cast<Value>(0);
   48.77 +    }
   48.78 +    static Value infinity() {
   48.79 +      return std::numeric_limits<Value>::max();
   48.80 +    }
   48.81 +    static Value plus(const Value& left, const Value& right) {
   48.82 +      if (left == infinity() || right == infinity()) return infinity();
   48.83 +      return left + right;
   48.84 +    }
   48.85 +    static bool less(const Value& left, const Value& right) {
   48.86 +      return left < right;
   48.87 +    }
   48.88 +  };
   48.89 +  
   48.90 +  /// \brief Default traits class of BellmanFord class.
   48.91 +  ///
   48.92 +  /// Default traits class of BellmanFord class.
   48.93 +  /// \param GR The type of the digraph.
   48.94 +  /// \param LEN The type of the length map.
   48.95 +  template<typename GR, typename LEN>
   48.96 +  struct BellmanFordDefaultTraits {
   48.97 +    /// The type of the digraph the algorithm runs on. 
   48.98 +    typedef GR Digraph;
   48.99 +
  48.100 +    /// \brief The type of the map that stores the arc lengths.
  48.101 +    ///
  48.102 +    /// The type of the map that stores the arc lengths.
  48.103 +    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
  48.104 +    typedef LEN LengthMap;
  48.105 +
  48.106 +    /// The type of the arc lengths.
  48.107 +    typedef typename LEN::Value Value;
  48.108 +
  48.109 +    /// \brief Operation traits for Bellman-Ford algorithm.
  48.110 +    ///
  48.111 +    /// It defines the used operations and the infinity value for the
  48.112 +    /// given \c Value type.
  48.113 +    /// \see BellmanFordDefaultOperationTraits
  48.114 +    typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
  48.115 + 
  48.116 +    /// \brief The type of the map that stores the last arcs of the 
  48.117 +    /// shortest paths.
  48.118 +    /// 
  48.119 +    /// The type of the map that stores the last
  48.120 +    /// arcs of the shortest paths.
  48.121 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  48.122 +    typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
  48.123 +
  48.124 +    /// \brief Instantiates a \c PredMap.
  48.125 +    /// 
  48.126 +    /// This function instantiates a \ref PredMap. 
  48.127 +    /// \param g is the digraph to which we would like to define the
  48.128 +    /// \ref PredMap.
  48.129 +    static PredMap *createPredMap(const GR& g) {
  48.130 +      return new PredMap(g);
  48.131 +    }
  48.132 +
  48.133 +    /// \brief The type of the map that stores the distances of the nodes.
  48.134 +    ///
  48.135 +    /// The type of the map that stores the distances of the nodes.
  48.136 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  48.137 +    typedef typename GR::template NodeMap<typename LEN::Value> DistMap;
  48.138 +
  48.139 +    /// \brief Instantiates a \c DistMap.
  48.140 +    ///
  48.141 +    /// This function instantiates a \ref DistMap. 
  48.142 +    /// \param g is the digraph to which we would like to define the 
  48.143 +    /// \ref DistMap.
  48.144 +    static DistMap *createDistMap(const GR& g) {
  48.145 +      return new DistMap(g);
  48.146 +    }
  48.147 +
  48.148 +  };
  48.149 +  
  48.150 +  /// \brief %BellmanFord algorithm class.
  48.151 +  ///
  48.152 +  /// \ingroup shortest_path
  48.153 +  /// This class provides an efficient implementation of the Bellman-Ford 
  48.154 +  /// algorithm. The maximum time complexity of the algorithm is
  48.155 +  /// <tt>O(ne)</tt>.
  48.156 +  ///
  48.157 +  /// The Bellman-Ford algorithm solves the single-source shortest path
  48.158 +  /// problem when the arcs can have negative lengths, but the digraph
  48.159 +  /// should not contain directed cycles with negative total length.
  48.160 +  /// If all arc costs are non-negative, consider to use the Dijkstra
  48.161 +  /// algorithm instead, since it is more efficient.
  48.162 +  ///
  48.163 +  /// The arc lengths are passed to the algorithm using a
  48.164 +  /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any 
  48.165 +  /// kind of length. The type of the length values is determined by the
  48.166 +  /// \ref concepts::ReadMap::Value "Value" type of the length map.
  48.167 +  ///
  48.168 +  /// There is also a \ref bellmanFord() "function-type interface" for the
  48.169 +  /// Bellman-Ford algorithm, which is convenient in the simplier cases and
  48.170 +  /// it can be used easier.
  48.171 +  ///
  48.172 +  /// \tparam GR The type of the digraph the algorithm runs on.
  48.173 +  /// The default type is \ref ListDigraph.
  48.174 +  /// \tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
  48.175 +  /// the lengths of the arcs. The default map type is
  48.176 +  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
  48.177 +#ifdef DOXYGEN
  48.178 +  template <typename GR, typename LEN, typename TR>
  48.179 +#else
  48.180 +  template <typename GR=ListDigraph,
  48.181 +            typename LEN=typename GR::template ArcMap<int>,
  48.182 +            typename TR=BellmanFordDefaultTraits<GR,LEN> >
  48.183 +#endif
  48.184 +  class BellmanFord {
  48.185 +  public:
  48.186 +
  48.187 +    ///The type of the underlying digraph.
  48.188 +    typedef typename TR::Digraph Digraph;
  48.189 +    
  48.190 +    /// \brief The type of the arc lengths.
  48.191 +    typedef typename TR::LengthMap::Value Value;
  48.192 +    /// \brief The type of the map that stores the arc lengths.
  48.193 +    typedef typename TR::LengthMap LengthMap;
  48.194 +    /// \brief The type of the map that stores the last
  48.195 +    /// arcs of the shortest paths.
  48.196 +    typedef typename TR::PredMap PredMap;
  48.197 +    /// \brief The type of the map that stores the distances of the nodes.
  48.198 +    typedef typename TR::DistMap DistMap;
  48.199 +    /// The type of the paths.
  48.200 +    typedef PredMapPath<Digraph, PredMap> Path;
  48.201 +    ///\brief The \ref BellmanFordDefaultOperationTraits
  48.202 +    /// "operation traits class" of the algorithm.
  48.203 +    typedef typename TR::OperationTraits OperationTraits;
  48.204 +
  48.205 +    ///The \ref BellmanFordDefaultTraits "traits class" of the algorithm.
  48.206 +    typedef TR Traits;
  48.207 +
  48.208 +  private:
  48.209 +
  48.210 +    typedef typename Digraph::Node Node;
  48.211 +    typedef typename Digraph::NodeIt NodeIt;
  48.212 +    typedef typename Digraph::Arc Arc;
  48.213 +    typedef typename Digraph::OutArcIt OutArcIt;
  48.214 +
  48.215 +    // Pointer to the underlying digraph.
  48.216 +    const Digraph *_gr;
  48.217 +    // Pointer to the length map
  48.218 +    const LengthMap *_length;
  48.219 +    // Pointer to the map of predecessors arcs.
  48.220 +    PredMap *_pred;
  48.221 +    // Indicates if _pred is locally allocated (true) or not.
  48.222 +    bool _local_pred;
  48.223 +    // Pointer to the map of distances.
  48.224 +    DistMap *_dist;
  48.225 +    // Indicates if _dist is locally allocated (true) or not.
  48.226 +    bool _local_dist;
  48.227 +
  48.228 +    typedef typename Digraph::template NodeMap<bool> MaskMap;
  48.229 +    MaskMap *_mask;
  48.230 +
  48.231 +    std::vector<Node> _process;
  48.232 +
  48.233 +    // Creates the maps if necessary.
  48.234 +    void create_maps() {
  48.235 +      if(!_pred) {
  48.236 +	_local_pred = true;
  48.237 +	_pred = Traits::createPredMap(*_gr);
  48.238 +      }
  48.239 +      if(!_dist) {
  48.240 +	_local_dist = true;
  48.241 +	_dist = Traits::createDistMap(*_gr);
  48.242 +      }
  48.243 +      _mask = new MaskMap(*_gr, false);
  48.244 +    }
  48.245 +    
  48.246 +  public :
  48.247 + 
  48.248 +    typedef BellmanFord Create;
  48.249 +
  48.250 +    /// \name Named Template Parameters
  48.251 +
  48.252 +    ///@{
  48.253 +
  48.254 +    template <class T>
  48.255 +    struct SetPredMapTraits : public Traits {
  48.256 +      typedef T PredMap;
  48.257 +      static PredMap *createPredMap(const Digraph&) {
  48.258 +        LEMON_ASSERT(false, "PredMap is not initialized");
  48.259 +        return 0; // ignore warnings
  48.260 +      }
  48.261 +    };
  48.262 +
  48.263 +    /// \brief \ref named-templ-param "Named parameter" for setting
  48.264 +    /// \c PredMap type.
  48.265 +    ///
  48.266 +    /// \ref named-templ-param "Named parameter" for setting
  48.267 +    /// \c PredMap type.
  48.268 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  48.269 +    template <class T>
  48.270 +    struct SetPredMap 
  48.271 +      : public BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > {
  48.272 +      typedef BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > Create;
  48.273 +    };
  48.274 +    
  48.275 +    template <class T>
  48.276 +    struct SetDistMapTraits : public Traits {
  48.277 +      typedef T DistMap;
  48.278 +      static DistMap *createDistMap(const Digraph&) {
  48.279 +        LEMON_ASSERT(false, "DistMap is not initialized");
  48.280 +        return 0; // ignore warnings
  48.281 +      }
  48.282 +    };
  48.283 +
  48.284 +    /// \brief \ref named-templ-param "Named parameter" for setting
  48.285 +    /// \c DistMap type.
  48.286 +    ///
  48.287 +    /// \ref named-templ-param "Named parameter" for setting
  48.288 +    /// \c DistMap type.
  48.289 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  48.290 +    template <class T>
  48.291 +    struct SetDistMap 
  48.292 +      : public BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > {
  48.293 +      typedef BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > Create;
  48.294 +    };
  48.295 +
  48.296 +    template <class T>
  48.297 +    struct SetOperationTraitsTraits : public Traits {
  48.298 +      typedef T OperationTraits;
  48.299 +    };
  48.300 +    
  48.301 +    /// \brief \ref named-templ-param "Named parameter" for setting 
  48.302 +    /// \c OperationTraits type.
  48.303 +    ///
  48.304 +    /// \ref named-templ-param "Named parameter" for setting
  48.305 +    /// \c OperationTraits type.
  48.306 +    /// For more information see \ref BellmanFordDefaultOperationTraits.
  48.307 +    template <class T>
  48.308 +    struct SetOperationTraits
  48.309 +      : public BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> > {
  48.310 +      typedef BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> >
  48.311 +      Create;
  48.312 +    };
  48.313 +    
  48.314 +    ///@}
  48.315 +
  48.316 +  protected:
  48.317 +    
  48.318 +    BellmanFord() {}
  48.319 +
  48.320 +  public:      
  48.321 +    
  48.322 +    /// \brief Constructor.
  48.323 +    ///
  48.324 +    /// Constructor.
  48.325 +    /// \param g The digraph the algorithm runs on.
  48.326 +    /// \param length The length map used by the algorithm.
  48.327 +    BellmanFord(const Digraph& g, const LengthMap& length) :
  48.328 +      _gr(&g), _length(&length),
  48.329 +      _pred(0), _local_pred(false),
  48.330 +      _dist(0), _local_dist(false), _mask(0) {}
  48.331 +    
  48.332 +    ///Destructor.
  48.333 +    ~BellmanFord() {
  48.334 +      if(_local_pred) delete _pred;
  48.335 +      if(_local_dist) delete _dist;
  48.336 +      if(_mask) delete _mask;
  48.337 +    }
  48.338 +
  48.339 +    /// \brief Sets the length map.
  48.340 +    ///
  48.341 +    /// Sets the length map.
  48.342 +    /// \return <tt>(*this)</tt>
  48.343 +    BellmanFord &lengthMap(const LengthMap &map) {
  48.344 +      _length = &map;
  48.345 +      return *this;
  48.346 +    }
  48.347 +
  48.348 +    /// \brief Sets the map that stores the predecessor arcs.
  48.349 +    ///
  48.350 +    /// Sets the map that stores the predecessor arcs.
  48.351 +    /// If you don't use this function before calling \ref run()
  48.352 +    /// or \ref init(), an instance will be allocated automatically.
  48.353 +    /// The destructor deallocates this automatically allocated map,
  48.354 +    /// of course.
  48.355 +    /// \return <tt>(*this)</tt>
  48.356 +    BellmanFord &predMap(PredMap &map) {
  48.357 +      if(_local_pred) {
  48.358 +	delete _pred;
  48.359 +	_local_pred=false;
  48.360 +      }
  48.361 +      _pred = &map;
  48.362 +      return *this;
  48.363 +    }
  48.364 +
  48.365 +    /// \brief Sets the map that stores the distances of the nodes.
  48.366 +    ///
  48.367 +    /// Sets the map that stores the distances of the nodes calculated
  48.368 +    /// by the algorithm.
  48.369 +    /// If you don't use this function before calling \ref run()
  48.370 +    /// or \ref init(), an instance will be allocated automatically.
  48.371 +    /// The destructor deallocates this automatically allocated map,
  48.372 +    /// of course.
  48.373 +    /// \return <tt>(*this)</tt>
  48.374 +    BellmanFord &distMap(DistMap &map) {
  48.375 +      if(_local_dist) {
  48.376 +	delete _dist;
  48.377 +	_local_dist=false;
  48.378 +      }
  48.379 +      _dist = &map;
  48.380 +      return *this;
  48.381 +    }
  48.382 +
  48.383 +    /// \name Execution Control
  48.384 +    /// The simplest way to execute the Bellman-Ford algorithm is to use
  48.385 +    /// one of the member functions called \ref run().\n
  48.386 +    /// If you need better control on the execution, you have to call
  48.387 +    /// \ref init() first, then you can add several source nodes
  48.388 +    /// with \ref addSource(). Finally the actual path computation can be
  48.389 +    /// performed with \ref start(), \ref checkedStart() or
  48.390 +    /// \ref limitedStart().
  48.391 +
  48.392 +    ///@{
  48.393 +
  48.394 +    /// \brief Initializes the internal data structures.
  48.395 +    /// 
  48.396 +    /// Initializes the internal data structures. The optional parameter
  48.397 +    /// is the initial distance of each node.
  48.398 +    void init(const Value value = OperationTraits::infinity()) {
  48.399 +      create_maps();
  48.400 +      for (NodeIt it(*_gr); it != INVALID; ++it) {
  48.401 +	_pred->set(it, INVALID);
  48.402 +	_dist->set(it, value);
  48.403 +      }
  48.404 +      _process.clear();
  48.405 +      if (OperationTraits::less(value, OperationTraits::infinity())) {
  48.406 +	for (NodeIt it(*_gr); it != INVALID; ++it) {
  48.407 +	  _process.push_back(it);
  48.408 +	  _mask->set(it, true);
  48.409 +	}
  48.410 +      }
  48.411 +    }
  48.412 +    
  48.413 +    /// \brief Adds a new source node.
  48.414 +    ///
  48.415 +    /// This function adds a new source node. The optional second parameter
  48.416 +    /// is the initial distance of the node.
  48.417 +    void addSource(Node source, Value dst = OperationTraits::zero()) {
  48.418 +      _dist->set(source, dst);
  48.419 +      if (!(*_mask)[source]) {
  48.420 +	_process.push_back(source);
  48.421 +	_mask->set(source, true);
  48.422 +      }
  48.423 +    }
  48.424 +
  48.425 +    /// \brief Executes one round from the Bellman-Ford algorithm.
  48.426 +    ///
  48.427 +    /// If the algoritm calculated the distances in the previous round
  48.428 +    /// exactly for the paths of at most \c k arcs, then this function
  48.429 +    /// will calculate the distances exactly for the paths of at most
  48.430 +    /// <tt>k+1</tt> arcs. Performing \c k iterations using this function
  48.431 +    /// calculates the shortest path distances exactly for the paths
  48.432 +    /// consisting of at most \c k arcs.
  48.433 +    ///
  48.434 +    /// \warning The paths with limited arc number cannot be retrieved
  48.435 +    /// easily with \ref path() or \ref predArc() functions. If you also
  48.436 +    /// need the shortest paths and not only the distances, you should
  48.437 +    /// store the \ref predMap() "predecessor map" after each iteration
  48.438 +    /// and build the path manually.
  48.439 +    ///
  48.440 +    /// \return \c true when the algorithm have not found more shorter
  48.441 +    /// paths.
  48.442 +    ///
  48.443 +    /// \see ActiveIt
  48.444 +    bool processNextRound() {
  48.445 +      for (int i = 0; i < int(_process.size()); ++i) {
  48.446 +	_mask->set(_process[i], false);
  48.447 +      }
  48.448 +      std::vector<Node> nextProcess;
  48.449 +      std::vector<Value> values(_process.size());
  48.450 +      for (int i = 0; i < int(_process.size()); ++i) {
  48.451 +	values[i] = (*_dist)[_process[i]];
  48.452 +      }
  48.453 +      for (int i = 0; i < int(_process.size()); ++i) {
  48.454 +	for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
  48.455 +	  Node target = _gr->target(it);
  48.456 +	  Value relaxed = OperationTraits::plus(values[i], (*_length)[it]);
  48.457 +	  if (OperationTraits::less(relaxed, (*_dist)[target])) {
  48.458 +	    _pred->set(target, it);
  48.459 +	    _dist->set(target, relaxed);
  48.460 +	    if (!(*_mask)[target]) {
  48.461 +	      _mask->set(target, true);
  48.462 +	      nextProcess.push_back(target);
  48.463 +	    }
  48.464 +	  }	  
  48.465 +	}
  48.466 +      }
  48.467 +      _process.swap(nextProcess);
  48.468 +      return _process.empty();
  48.469 +    }
  48.470 +
  48.471 +    /// \brief Executes one weak round from the Bellman-Ford algorithm.
  48.472 +    ///
  48.473 +    /// If the algorithm calculated the distances in the previous round
  48.474 +    /// at least for the paths of at most \c k arcs, then this function
  48.475 +    /// will calculate the distances at least for the paths of at most
  48.476 +    /// <tt>k+1</tt> arcs.
  48.477 +    /// This function does not make it possible to calculate the shortest
  48.478 +    /// path distances exactly for paths consisting of at most \c k arcs,
  48.479 +    /// this is why it is called weak round.
  48.480 +    ///
  48.481 +    /// \return \c true when the algorithm have not found more shorter
  48.482 +    /// paths.
  48.483 +    ///
  48.484 +    /// \see ActiveIt
  48.485 +    bool processNextWeakRound() {
  48.486 +      for (int i = 0; i < int(_process.size()); ++i) {
  48.487 +	_mask->set(_process[i], false);
  48.488 +      }
  48.489 +      std::vector<Node> nextProcess;
  48.490 +      for (int i = 0; i < int(_process.size()); ++i) {
  48.491 +	for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
  48.492 +	  Node target = _gr->target(it);
  48.493 +	  Value relaxed = 
  48.494 +	    OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]);
  48.495 +	  if (OperationTraits::less(relaxed, (*_dist)[target])) {
  48.496 +	    _pred->set(target, it);
  48.497 +	    _dist->set(target, relaxed);
  48.498 +	    if (!(*_mask)[target]) {
  48.499 +	      _mask->set(target, true);
  48.500 +	      nextProcess.push_back(target);
  48.501 +	    }
  48.502 +	  }	  
  48.503 +	}
  48.504 +      }
  48.505 +      _process.swap(nextProcess);
  48.506 +      return _process.empty();
  48.507 +    }
  48.508 +
  48.509 +    /// \brief Executes the algorithm.
  48.510 +    ///
  48.511 +    /// Executes the algorithm.
  48.512 +    ///
  48.513 +    /// This method runs the Bellman-Ford algorithm from the root node(s)
  48.514 +    /// in order to compute the shortest path to each node.
  48.515 +    ///
  48.516 +    /// The algorithm computes
  48.517 +    /// - the shortest path tree (forest),
  48.518 +    /// - the distance of each node from the root(s).
  48.519 +    ///
  48.520 +    /// \pre init() must be called and at least one root node should be
  48.521 +    /// added with addSource() before using this function.
  48.522 +    void start() {
  48.523 +      int num = countNodes(*_gr) - 1;
  48.524 +      for (int i = 0; i < num; ++i) {
  48.525 +	if (processNextWeakRound()) break;
  48.526 +      }
  48.527 +    }
  48.528 +
  48.529 +    /// \brief Executes the algorithm and checks the negative cycles.
  48.530 +    ///
  48.531 +    /// Executes the algorithm and checks the negative cycles.
  48.532 +    ///
  48.533 +    /// This method runs the Bellman-Ford algorithm from the root node(s)
  48.534 +    /// in order to compute the shortest path to each node and also checks
  48.535 +    /// if the digraph contains cycles with negative total length.
  48.536 +    ///
  48.537 +    /// The algorithm computes 
  48.538 +    /// - the shortest path tree (forest),
  48.539 +    /// - the distance of each node from the root(s).
  48.540 +    /// 
  48.541 +    /// \return \c false if there is a negative cycle in the digraph.
  48.542 +    ///
  48.543 +    /// \pre init() must be called and at least one root node should be
  48.544 +    /// added with addSource() before using this function. 
  48.545 +    bool checkedStart() {
  48.546 +      int num = countNodes(*_gr);
  48.547 +      for (int i = 0; i < num; ++i) {
  48.548 +	if (processNextWeakRound()) return true;
  48.549 +      }
  48.550 +      return _process.empty();
  48.551 +    }
  48.552 +
  48.553 +    /// \brief Executes the algorithm with arc number limit.
  48.554 +    ///
  48.555 +    /// Executes the algorithm with arc number limit.
  48.556 +    ///
  48.557 +    /// This method runs the Bellman-Ford algorithm from the root node(s)
  48.558 +    /// in order to compute the shortest path distance for each node
  48.559 +    /// using only the paths consisting of at most \c num arcs.
  48.560 +    ///
  48.561 +    /// The algorithm computes
  48.562 +    /// - the limited distance of each node from the root(s),
  48.563 +    /// - the predecessor arc for each node.
  48.564 +    ///
  48.565 +    /// \warning The paths with limited arc number cannot be retrieved
  48.566 +    /// easily with \ref path() or \ref predArc() functions. If you also
  48.567 +    /// need the shortest paths and not only the distances, you should
  48.568 +    /// store the \ref predMap() "predecessor map" after each iteration
  48.569 +    /// and build the path manually.
  48.570 +    ///
  48.571 +    /// \pre init() must be called and at least one root node should be
  48.572 +    /// added with addSource() before using this function. 
  48.573 +    void limitedStart(int num) {
  48.574 +      for (int i = 0; i < num; ++i) {
  48.575 +	if (processNextRound()) break;
  48.576 +      }
  48.577 +    }
  48.578 +    
  48.579 +    /// \brief Runs the algorithm from the given root node.
  48.580 +    ///    
  48.581 +    /// This method runs the Bellman-Ford algorithm from the given root
  48.582 +    /// node \c s in order to compute the shortest path to each node.
  48.583 +    ///
  48.584 +    /// The algorithm computes
  48.585 +    /// - the shortest path tree (forest),
  48.586 +    /// - the distance of each node from the root(s).
  48.587 +    ///
  48.588 +    /// \note bf.run(s) is just a shortcut of the following code.
  48.589 +    /// \code
  48.590 +    ///   bf.init();
  48.591 +    ///   bf.addSource(s);
  48.592 +    ///   bf.start();
  48.593 +    /// \endcode
  48.594 +    void run(Node s) {
  48.595 +      init();
  48.596 +      addSource(s);
  48.597 +      start();
  48.598 +    }
  48.599 +    
  48.600 +    /// \brief Runs the algorithm from the given root node with arc
  48.601 +    /// number limit.
  48.602 +    ///    
  48.603 +    /// This method runs the Bellman-Ford algorithm from the given root
  48.604 +    /// node \c s in order to compute the shortest path distance for each
  48.605 +    /// node using only the paths consisting of at most \c num arcs.
  48.606 +    ///
  48.607 +    /// The algorithm computes
  48.608 +    /// - the limited distance of each node from the root(s),
  48.609 +    /// - the predecessor arc for each node.
  48.610 +    ///
  48.611 +    /// \warning The paths with limited arc number cannot be retrieved
  48.612 +    /// easily with \ref path() or \ref predArc() functions. If you also
  48.613 +    /// need the shortest paths and not only the distances, you should
  48.614 +    /// store the \ref predMap() "predecessor map" after each iteration
  48.615 +    /// and build the path manually.
  48.616 +    ///
  48.617 +    /// \note bf.run(s, num) is just a shortcut of the following code.
  48.618 +    /// \code
  48.619 +    ///   bf.init();
  48.620 +    ///   bf.addSource(s);
  48.621 +    ///   bf.limitedStart(num);
  48.622 +    /// \endcode
  48.623 +    void run(Node s, int num) {
  48.624 +      init();
  48.625 +      addSource(s);
  48.626 +      limitedStart(num);
  48.627 +    }
  48.628 +    
  48.629 +    ///@}
  48.630 +
  48.631 +    /// \brief LEMON iterator for getting the active nodes.
  48.632 +    ///
  48.633 +    /// This class provides a common style LEMON iterator that traverses
  48.634 +    /// the active nodes of the Bellman-Ford algorithm after the last
  48.635 +    /// phase. These nodes should be checked in the next phase to
  48.636 +    /// find augmenting arcs outgoing from them.
  48.637 +    class ActiveIt {
  48.638 +    public:
  48.639 +
  48.640 +      /// \brief Constructor.
  48.641 +      ///
  48.642 +      /// Constructor for getting the active nodes of the given BellmanFord
  48.643 +      /// instance. 
  48.644 +      ActiveIt(const BellmanFord& algorithm) : _algorithm(&algorithm)
  48.645 +      {
  48.646 +        _index = _algorithm->_process.size() - 1;
  48.647 +      }
  48.648 +
  48.649 +      /// \brief Invalid constructor.
  48.650 +      ///
  48.651 +      /// Invalid constructor.
  48.652 +      ActiveIt(Invalid) : _algorithm(0), _index(-1) {}
  48.653 +
  48.654 +      /// \brief Conversion to \c Node.
  48.655 +      ///
  48.656 +      /// Conversion to \c Node.
  48.657 +      operator Node() const { 
  48.658 +        return _index >= 0 ? _algorithm->_process[_index] : INVALID;
  48.659 +      }
  48.660 +
  48.661 +      /// \brief Increment operator.
  48.662 +      ///
  48.663 +      /// Increment operator.
  48.664 +      ActiveIt& operator++() {
  48.665 +        --_index;
  48.666 +        return *this; 
  48.667 +      }
  48.668 +
  48.669 +      bool operator==(const ActiveIt& it) const { 
  48.670 +        return static_cast<Node>(*this) == static_cast<Node>(it); 
  48.671 +      }
  48.672 +      bool operator!=(const ActiveIt& it) const { 
  48.673 +        return static_cast<Node>(*this) != static_cast<Node>(it); 
  48.674 +      }
  48.675 +      bool operator<(const ActiveIt& it) const { 
  48.676 +        return static_cast<Node>(*this) < static_cast<Node>(it); 
  48.677 +      }
  48.678 +      
  48.679 +    private:
  48.680 +      const BellmanFord* _algorithm;
  48.681 +      int _index;
  48.682 +    };
  48.683 +    
  48.684 +    /// \name Query Functions
  48.685 +    /// The result of the Bellman-Ford algorithm can be obtained using these
  48.686 +    /// functions.\n
  48.687 +    /// Either \ref run() or \ref init() should be called before using them.
  48.688 +    
  48.689 +    ///@{
  48.690 +
  48.691 +    /// \brief The shortest path to the given node.
  48.692 +    ///    
  48.693 +    /// Gives back the shortest path to the given node from the root(s).
  48.694 +    ///
  48.695 +    /// \warning \c t should be reached from the root(s).
  48.696 +    ///
  48.697 +    /// \pre Either \ref run() or \ref init() must be called before
  48.698 +    /// using this function.
  48.699 +    Path path(Node t) const
  48.700 +    {
  48.701 +      return Path(*_gr, *_pred, t);
  48.702 +    }
  48.703 +	  
  48.704 +    /// \brief The distance of the given node from the root(s).
  48.705 +    ///
  48.706 +    /// Returns the distance of the given node from the root(s).
  48.707 +    ///
  48.708 +    /// \warning If node \c v is not reached from the root(s), then
  48.709 +    /// the return value of this function is undefined.
  48.710 +    ///
  48.711 +    /// \pre Either \ref run() or \ref init() must be called before
  48.712 +    /// using this function.
  48.713 +    Value dist(Node v) const { return (*_dist)[v]; }
  48.714 +
  48.715 +    /// \brief Returns the 'previous arc' of the shortest path tree for
  48.716 +    /// the given node.
  48.717 +    ///
  48.718 +    /// This function returns the 'previous arc' of the shortest path
  48.719 +    /// tree for node \c v, i.e. it returns the last arc of a
  48.720 +    /// shortest path from a root to \c v. It is \c INVALID if \c v
  48.721 +    /// is not reached from the root(s) or if \c v is a root.
  48.722 +    ///
  48.723 +    /// The shortest path tree used here is equal to the shortest path
  48.724 +    /// tree used in \ref predNode() and \predMap().
  48.725 +    ///
  48.726 +    /// \pre Either \ref run() or \ref init() must be called before
  48.727 +    /// using this function.
  48.728 +    Arc predArc(Node v) const { return (*_pred)[v]; }
  48.729 +
  48.730 +    /// \brief Returns the 'previous node' of the shortest path tree for
  48.731 +    /// the given node.
  48.732 +    ///
  48.733 +    /// This function returns the 'previous node' of the shortest path
  48.734 +    /// tree for node \c v, i.e. it returns the last but one node of
  48.735 +    /// a shortest path from a root to \c v. It is \c INVALID if \c v
  48.736 +    /// is not reached from the root(s) or if \c v is a root.
  48.737 +    ///
  48.738 +    /// The shortest path tree used here is equal to the shortest path
  48.739 +    /// tree used in \ref predArc() and \predMap().
  48.740 +    ///
  48.741 +    /// \pre Either \ref run() or \ref init() must be called before
  48.742 +    /// using this function.
  48.743 +    Node predNode(Node v) const { 
  48.744 +      return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]); 
  48.745 +    }
  48.746 +    
  48.747 +    /// \brief Returns a const reference to the node map that stores the
  48.748 +    /// distances of the nodes.
  48.749 +    ///
  48.750 +    /// Returns a const reference to the node map that stores the distances
  48.751 +    /// of the nodes calculated by the algorithm.
  48.752 +    ///
  48.753 +    /// \pre Either \ref run() or \ref init() must be called before
  48.754 +    /// using this function.
  48.755 +    const DistMap &distMap() const { return *_dist;}
  48.756 + 
  48.757 +    /// \brief Returns a const reference to the node map that stores the
  48.758 +    /// predecessor arcs.
  48.759 +    ///
  48.760 +    /// Returns a const reference to the node map that stores the predecessor
  48.761 +    /// arcs, which form the shortest path tree (forest).
  48.762 +    ///
  48.763 +    /// \pre Either \ref run() or \ref init() must be called before
  48.764 +    /// using this function.
  48.765 +    const PredMap &predMap() const { return *_pred; }
  48.766 + 
  48.767 +    /// \brief Checks if a node is reached from the root(s).
  48.768 +    ///
  48.769 +    /// Returns \c true if \c v is reached from the root(s).
  48.770 +    ///
  48.771 +    /// \pre Either \ref run() or \ref init() must be called before
  48.772 +    /// using this function.
  48.773 +    bool reached(Node v) const {
  48.774 +      return (*_dist)[v] != OperationTraits::infinity();
  48.775 +    }
  48.776 +
  48.777 +    /// \brief Gives back a negative cycle.
  48.778 +    ///    
  48.779 +    /// This function gives back a directed cycle with negative total
  48.780 +    /// length if the algorithm has already found one.
  48.781 +    /// Otherwise it gives back an empty path.
  48.782 +    lemon::Path<Digraph> negativeCycle() const {
  48.783 +      typename Digraph::template NodeMap<int> state(*_gr, -1);
  48.784 +      lemon::Path<Digraph> cycle;
  48.785 +      for (int i = 0; i < int(_process.size()); ++i) {
  48.786 +        if (state[_process[i]] != -1) continue;
  48.787 +        for (Node v = _process[i]; (*_pred)[v] != INVALID;
  48.788 +             v = _gr->source((*_pred)[v])) {
  48.789 +          if (state[v] == i) {
  48.790 +            cycle.addFront((*_pred)[v]);
  48.791 +            for (Node u = _gr->source((*_pred)[v]); u != v;
  48.792 +                 u = _gr->source((*_pred)[u])) {
  48.793 +              cycle.addFront((*_pred)[u]);
  48.794 +            }
  48.795 +            return cycle;
  48.796 +          }
  48.797 +          else if (state[v] >= 0) {
  48.798 +            break;
  48.799 +          }
  48.800 +          state[v] = i;
  48.801 +        }
  48.802 +      }
  48.803 +      return cycle;
  48.804 +    }
  48.805 +    
  48.806 +    ///@}
  48.807 +  };
  48.808 + 
  48.809 +  /// \brief Default traits class of bellmanFord() function.
  48.810 +  ///
  48.811 +  /// Default traits class of bellmanFord() function.
  48.812 +  /// \tparam GR The type of the digraph.
  48.813 +  /// \tparam LEN The type of the length map.
  48.814 +  template <typename GR, typename LEN>
  48.815 +  struct BellmanFordWizardDefaultTraits {
  48.816 +    /// The type of the digraph the algorithm runs on. 
  48.817 +    typedef GR Digraph;
  48.818 +
  48.819 +    /// \brief The type of the map that stores the arc lengths.
  48.820 +    ///
  48.821 +    /// The type of the map that stores the arc lengths.
  48.822 +    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
  48.823 +    typedef LEN LengthMap;
  48.824 +
  48.825 +    /// The type of the arc lengths.
  48.826 +    typedef typename LEN::Value Value;
  48.827 +
  48.828 +    /// \brief Operation traits for Bellman-Ford algorithm.
  48.829 +    ///
  48.830 +    /// It defines the used operations and the infinity value for the
  48.831 +    /// given \c Value type.
  48.832 +    /// \see BellmanFordDefaultOperationTraits
  48.833 +    typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
  48.834 +
  48.835 +    /// \brief The type of the map that stores the last
  48.836 +    /// arcs of the shortest paths.
  48.837 +    /// 
  48.838 +    /// The type of the map that stores the last arcs of the shortest paths.
  48.839 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  48.840 +    typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
  48.841 +
  48.842 +    /// \brief Instantiates a \c PredMap.
  48.843 +    /// 
  48.844 +    /// This function instantiates a \ref PredMap.
  48.845 +    /// \param g is the digraph to which we would like to define the
  48.846 +    /// \ref PredMap.
  48.847 +    static PredMap *createPredMap(const GR &g) {
  48.848 +      return new PredMap(g);
  48.849 +    }
  48.850 +
  48.851 +    /// \brief The type of the map that stores the distances of the nodes.
  48.852 +    ///
  48.853 +    /// The type of the map that stores the distances of the nodes.
  48.854 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  48.855 +    typedef typename GR::template NodeMap<Value> DistMap;
  48.856 +
  48.857 +    /// \brief Instantiates a \c DistMap.
  48.858 +    ///
  48.859 +    /// This function instantiates a \ref DistMap. 
  48.860 +    /// \param g is the digraph to which we would like to define the
  48.861 +    /// \ref DistMap.
  48.862 +    static DistMap *createDistMap(const GR &g) {
  48.863 +      return new DistMap(g);
  48.864 +    }
  48.865 +
  48.866 +    ///The type of the shortest paths.
  48.867 +
  48.868 +    ///The type of the shortest paths.
  48.869 +    ///It must meet the \ref concepts::Path "Path" concept.
  48.870 +    typedef lemon::Path<Digraph> Path;
  48.871 +  };
  48.872 +  
  48.873 +  /// \brief Default traits class used by BellmanFordWizard.
  48.874 +  ///
  48.875 +  /// Default traits class used by BellmanFordWizard.
  48.876 +  /// \tparam GR The type of the digraph.
  48.877 +  /// \tparam LEN The type of the length map.
  48.878 +  template <typename GR, typename LEN>
  48.879 +  class BellmanFordWizardBase 
  48.880 +    : public BellmanFordWizardDefaultTraits<GR, LEN> {
  48.881 +
  48.882 +    typedef BellmanFordWizardDefaultTraits<GR, LEN> Base;
  48.883 +  protected:
  48.884 +    // Type of the nodes in the digraph.
  48.885 +    typedef typename Base::Digraph::Node Node;
  48.886 +
  48.887 +    // Pointer to the underlying digraph.
  48.888 +    void *_graph;
  48.889 +    // Pointer to the length map
  48.890 +    void *_length;
  48.891 +    // Pointer to the map of predecessors arcs.
  48.892 +    void *_pred;
  48.893 +    // Pointer to the map of distances.
  48.894 +    void *_dist;
  48.895 +    //Pointer to the shortest path to the target node.
  48.896 +    void *_path;
  48.897 +    //Pointer to the distance of the target node.
  48.898 +    void *_di;
  48.899 +
  48.900 +    public:
  48.901 +    /// Constructor.
  48.902 +    
  48.903 +    /// This constructor does not require parameters, it initiates
  48.904 +    /// all of the attributes to default values \c 0.
  48.905 +    BellmanFordWizardBase() :
  48.906 +      _graph(0), _length(0), _pred(0), _dist(0), _path(0), _di(0) {}
  48.907 +
  48.908 +    /// Constructor.
  48.909 +    
  48.910 +    /// This constructor requires two parameters,
  48.911 +    /// others are initiated to \c 0.
  48.912 +    /// \param gr The digraph the algorithm runs on.
  48.913 +    /// \param len The length map.
  48.914 +    BellmanFordWizardBase(const GR& gr, 
  48.915 +			  const LEN& len) :
  48.916 +      _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))), 
  48.917 +      _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))), 
  48.918 +      _pred(0), _dist(0), _path(0), _di(0) {}
  48.919 +
  48.920 +  };
  48.921 +  
  48.922 +  /// \brief Auxiliary class for the function-type interface of the
  48.923 +  /// \ref BellmanFord "Bellman-Ford" algorithm.
  48.924 +  ///
  48.925 +  /// This auxiliary class is created to implement the
  48.926 +  /// \ref bellmanFord() "function-type interface" of the
  48.927 +  /// \ref BellmanFord "Bellman-Ford" algorithm.
  48.928 +  /// It does not have own \ref run() method, it uses the
  48.929 +  /// functions and features of the plain \ref BellmanFord.
  48.930 +  ///
  48.931 +  /// This class should only be used through the \ref bellmanFord()
  48.932 +  /// function, which makes it easier to use the algorithm.
  48.933 +  template<class TR>
  48.934 +  class BellmanFordWizard : public TR {
  48.935 +    typedef TR Base;
  48.936 +
  48.937 +    typedef typename TR::Digraph Digraph;
  48.938 +
  48.939 +    typedef typename Digraph::Node Node;
  48.940 +    typedef typename Digraph::NodeIt NodeIt;
  48.941 +    typedef typename Digraph::Arc Arc;
  48.942 +    typedef typename Digraph::OutArcIt ArcIt;
  48.943 +    
  48.944 +    typedef typename TR::LengthMap LengthMap;
  48.945 +    typedef typename LengthMap::Value Value;
  48.946 +    typedef typename TR::PredMap PredMap;
  48.947 +    typedef typename TR::DistMap DistMap;
  48.948 +    typedef typename TR::Path Path;
  48.949 +
  48.950 +  public:
  48.951 +    /// Constructor.
  48.952 +    BellmanFordWizard() : TR() {}
  48.953 +
  48.954 +    /// \brief Constructor that requires parameters.
  48.955 +    ///
  48.956 +    /// Constructor that requires parameters.
  48.957 +    /// These parameters will be the default values for the traits class.
  48.958 +    /// \param gr The digraph the algorithm runs on.
  48.959 +    /// \param len The length map.
  48.960 +    BellmanFordWizard(const Digraph& gr, const LengthMap& len) 
  48.961 +      : TR(gr, len) {}
  48.962 +
  48.963 +    /// \brief Copy constructor
  48.964 +    BellmanFordWizard(const TR &b) : TR(b) {}
  48.965 +
  48.966 +    ~BellmanFordWizard() {}
  48.967 +
  48.968 +    /// \brief Runs the Bellman-Ford algorithm from the given source node.
  48.969 +    ///    
  48.970 +    /// This method runs the Bellman-Ford algorithm from the given source
  48.971 +    /// node in order to compute the shortest path to each node.
  48.972 +    void run(Node s) {
  48.973 +      BellmanFord<Digraph,LengthMap,TR> 
  48.974 +	bf(*reinterpret_cast<const Digraph*>(Base::_graph), 
  48.975 +           *reinterpret_cast<const LengthMap*>(Base::_length));
  48.976 +      if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
  48.977 +      if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
  48.978 +      bf.run(s);
  48.979 +    }
  48.980 +
  48.981 +    /// \brief Runs the Bellman-Ford algorithm to find the shortest path
  48.982 +    /// between \c s and \c t.
  48.983 +    ///
  48.984 +    /// This method runs the Bellman-Ford algorithm from node \c s
  48.985 +    /// in order to compute the shortest path to node \c t.
  48.986 +    /// Actually, it computes the shortest path to each node, but using
  48.987 +    /// this function you can retrieve the distance and the shortest path
  48.988 +    /// for a single target node easier.
  48.989 +    ///
  48.990 +    /// \return \c true if \c t is reachable form \c s.
  48.991 +    bool run(Node s, Node t) {
  48.992 +      BellmanFord<Digraph,LengthMap,TR>
  48.993 +        bf(*reinterpret_cast<const Digraph*>(Base::_graph),
  48.994 +           *reinterpret_cast<const LengthMap*>(Base::_length));
  48.995 +      if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
  48.996 +      if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
  48.997 +      bf.run(s);
  48.998 +      if (Base::_path) *reinterpret_cast<Path*>(Base::_path) = bf.path(t);
  48.999 +      if (Base::_di) *reinterpret_cast<Value*>(Base::_di) = bf.dist(t);
 48.1000 +      return bf.reached(t);
 48.1001 +    }
 48.1002 +
 48.1003 +    template<class T>
 48.1004 +    struct SetPredMapBase : public Base {
 48.1005 +      typedef T PredMap;
 48.1006 +      static PredMap *createPredMap(const Digraph &) { return 0; };
 48.1007 +      SetPredMapBase(const TR &b) : TR(b) {}
 48.1008 +    };
 48.1009 +    
 48.1010 +    /// \brief \ref named-templ-param "Named parameter" for setting
 48.1011 +    /// the predecessor map.
 48.1012 +    ///
 48.1013 +    /// \ref named-templ-param "Named parameter" for setting
 48.1014 +    /// the map that stores the predecessor arcs of the nodes.
 48.1015 +    template<class T>
 48.1016 +    BellmanFordWizard<SetPredMapBase<T> > predMap(const T &t) {
 48.1017 +      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
 48.1018 +      return BellmanFordWizard<SetPredMapBase<T> >(*this);
 48.1019 +    }
 48.1020 +    
 48.1021 +    template<class T>
 48.1022 +    struct SetDistMapBase : public Base {
 48.1023 +      typedef T DistMap;
 48.1024 +      static DistMap *createDistMap(const Digraph &) { return 0; };
 48.1025 +      SetDistMapBase(const TR &b) : TR(b) {}
 48.1026 +    };
 48.1027 +    
 48.1028 +    /// \brief \ref named-templ-param "Named parameter" for setting
 48.1029 +    /// the distance map.
 48.1030 +    ///
 48.1031 +    /// \ref named-templ-param "Named parameter" for setting
 48.1032 +    /// the map that stores the distances of the nodes calculated
 48.1033 +    /// by the algorithm.
 48.1034 +    template<class T>
 48.1035 +    BellmanFordWizard<SetDistMapBase<T> > distMap(const T &t) {
 48.1036 +      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
 48.1037 +      return BellmanFordWizard<SetDistMapBase<T> >(*this);
 48.1038 +    }
 48.1039 +
 48.1040 +    template<class T>
 48.1041 +    struct SetPathBase : public Base {
 48.1042 +      typedef T Path;
 48.1043 +      SetPathBase(const TR &b) : TR(b) {}
 48.1044 +    };
 48.1045 +
 48.1046 +    /// \brief \ref named-func-param "Named parameter" for getting
 48.1047 +    /// the shortest path to the target node.
 48.1048 +    ///
 48.1049 +    /// \ref named-func-param "Named parameter" for getting
 48.1050 +    /// the shortest path to the target node.
 48.1051 +    template<class T>
 48.1052 +    BellmanFordWizard<SetPathBase<T> > path(const T &t)
 48.1053 +    {
 48.1054 +      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
 48.1055 +      return BellmanFordWizard<SetPathBase<T> >(*this);
 48.1056 +    }
 48.1057 +
 48.1058 +    /// \brief \ref named-func-param "Named parameter" for getting
 48.1059 +    /// the distance of the target node.
 48.1060 +    ///
 48.1061 +    /// \ref named-func-param "Named parameter" for getting
 48.1062 +    /// the distance of the target node.
 48.1063 +    BellmanFordWizard dist(const Value &d)
 48.1064 +    {
 48.1065 +      Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
 48.1066 +      return *this;
 48.1067 +    }
 48.1068 +    
 48.1069 +  };
 48.1070 +  
 48.1071 +  /// \brief Function type interface for the \ref BellmanFord "Bellman-Ford"
 48.1072 +  /// algorithm.
 48.1073 +  ///
 48.1074 +  /// \ingroup shortest_path
 48.1075 +  /// Function type interface for the \ref BellmanFord "Bellman-Ford"
 48.1076 +  /// algorithm.
 48.1077 +  ///
 48.1078 +  /// This function also has several \ref named-templ-func-param 
 48.1079 +  /// "named parameters", they are declared as the members of class 
 48.1080 +  /// \ref BellmanFordWizard.
 48.1081 +  /// The following examples show how to use these parameters.
 48.1082 +  /// \code
 48.1083 +  ///   // Compute shortest path from node s to each node
 48.1084 +  ///   bellmanFord(g,length).predMap(preds).distMap(dists).run(s);
 48.1085 +  ///
 48.1086 +  ///   // Compute shortest path from s to t
 48.1087 +  ///   bool reached = bellmanFord(g,length).path(p).dist(d).run(s,t);
 48.1088 +  /// \endcode
 48.1089 +  /// \warning Don't forget to put the \ref BellmanFordWizard::run() "run()"
 48.1090 +  /// to the end of the parameter list.
 48.1091 +  /// \sa BellmanFordWizard
 48.1092 +  /// \sa BellmanFord
 48.1093 +  template<typename GR, typename LEN>
 48.1094 +  BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >
 48.1095 +  bellmanFord(const GR& digraph,
 48.1096 +	      const LEN& length)
 48.1097 +  {
 48.1098 +    return BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >(digraph, length);
 48.1099 +  }
 48.1100 +
 48.1101 +} //END OF NAMESPACE LEMON
 48.1102 +
 48.1103 +#endif
 48.1104 +
    49.1 --- a/lemon/bfs.h	Fri Oct 16 10:21:37 2009 +0200
    49.2 +++ b/lemon/bfs.h	Thu Nov 05 15:50:01 2009 +0100
    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-2008
    49.8 + * Copyright (C) 2003-2009
    49.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   49.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   49.11   *
   49.12 @@ -47,13 +47,13 @@
   49.13      ///
   49.14      ///The type of the map that stores the predecessor
   49.15      ///arcs of the shortest paths.
   49.16 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   49.17 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   49.18      typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
   49.19 -    ///Instantiates a PredMap.
   49.20 +    ///Instantiates a \c PredMap.
   49.21  
   49.22 -    ///This function instantiates a PredMap.
   49.23 +    ///This function instantiates a \ref PredMap.
   49.24      ///\param g is the digraph, to which we would like to define the
   49.25 -    ///PredMap.
   49.26 +    ///\ref PredMap.
   49.27      static PredMap *createPredMap(const Digraph &g)
   49.28      {
   49.29        return new PredMap(g);
   49.30 @@ -62,13 +62,14 @@
   49.31      ///The type of the map that indicates which nodes are processed.
   49.32  
   49.33      ///The type of the map that indicates which nodes are processed.
   49.34 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   49.35 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   49.36 +    ///By default it is a NullMap.
   49.37      typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
   49.38 -    ///Instantiates a ProcessedMap.
   49.39 +    ///Instantiates a \c ProcessedMap.
   49.40  
   49.41 -    ///This function instantiates a ProcessedMap.
   49.42 +    ///This function instantiates a \ref ProcessedMap.
   49.43      ///\param g is the digraph, to which
   49.44 -    ///we would like to define the ProcessedMap
   49.45 +    ///we would like to define the \ref ProcessedMap
   49.46  #ifdef DOXYGEN
   49.47      static ProcessedMap *createProcessedMap(const Digraph &g)
   49.48  #else
   49.49 @@ -81,13 +82,13 @@
   49.50      ///The type of the map that indicates which nodes are reached.
   49.51  
   49.52      ///The type of the map that indicates which nodes are reached.
   49.53 -    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   49.54 +    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   49.55      typedef typename Digraph::template NodeMap<bool> ReachedMap;
   49.56 -    ///Instantiates a ReachedMap.
   49.57 +    ///Instantiates a \c ReachedMap.
   49.58  
   49.59 -    ///This function instantiates a ReachedMap.
   49.60 +    ///This function instantiates a \ref ReachedMap.
   49.61      ///\param g is the digraph, to which
   49.62 -    ///we would like to define the ReachedMap.
   49.63 +    ///we would like to define the \ref ReachedMap.
   49.64      static ReachedMap *createReachedMap(const Digraph &g)
   49.65      {
   49.66        return new ReachedMap(g);
   49.67 @@ -96,13 +97,13 @@
   49.68      ///The type of the map that stores the distances of the nodes.
   49.69  
   49.70      ///The type of the map that stores the distances of the nodes.
   49.71 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   49.72 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   49.73      typedef typename Digraph::template NodeMap<int> DistMap;
   49.74 -    ///Instantiates a DistMap.
   49.75 +    ///Instantiates a \c DistMap.
   49.76  
   49.77 -    ///This function instantiates a DistMap.
   49.78 +    ///This function instantiates a \ref DistMap.
   49.79      ///\param g is the digraph, to which we would like to define the
   49.80 -    ///DistMap.
   49.81 +    ///\ref DistMap.
   49.82      static DistMap *createDistMap(const Digraph &g)
   49.83      {
   49.84        return new DistMap(g);
   49.85 @@ -119,13 +120,7 @@
   49.86    ///used easier.
   49.87    ///
   49.88    ///\tparam GR The type of the digraph the algorithm runs on.
   49.89 -  ///The default value is \ref ListDigraph. The value of GR is not used
   49.90 -  ///directly by \ref Bfs, it is only passed to \ref BfsDefaultTraits.
   49.91 -  ///\tparam TR Traits class to set various data types used by the algorithm.
   49.92 -  ///The default traits class is
   49.93 -  ///\ref BfsDefaultTraits "BfsDefaultTraits<GR>".
   49.94 -  ///See \ref BfsDefaultTraits for the documentation of
   49.95 -  ///a Bfs traits class.
   49.96 +  ///The default type is \ref ListDigraph.
   49.97  #ifdef DOXYGEN
   49.98    template <typename GR,
   49.99              typename TR>
  49.100 @@ -151,7 +146,7 @@
  49.101      ///The type of the paths.
  49.102      typedef PredMapPath<Digraph, PredMap> Path;
  49.103  
  49.104 -    ///The traits class.
  49.105 +    ///The \ref BfsDefaultTraits "traits class" of the algorithm.
  49.106      typedef TR Traits;
  49.107  
  49.108    private:
  49.109 @@ -213,7 +208,7 @@
  49.110  
  49.111      typedef Bfs Create;
  49.112  
  49.113 -    ///\name Named template parameters
  49.114 +    ///\name Named Template Parameters
  49.115  
  49.116      ///@{
  49.117  
  49.118 @@ -227,10 +222,11 @@
  49.119        }
  49.120      };
  49.121      ///\brief \ref named-templ-param "Named parameter" for setting
  49.122 -    ///PredMap type.
  49.123 +    ///\c PredMap type.
  49.124      ///
  49.125      ///\ref named-templ-param "Named parameter" for setting
  49.126 -    ///PredMap type.
  49.127 +    ///\c PredMap type.
  49.128 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  49.129      template <class T>
  49.130      struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
  49.131        typedef Bfs< Digraph, SetPredMapTraits<T> > Create;
  49.132 @@ -246,10 +242,11 @@
  49.133        }
  49.134      };
  49.135      ///\brief \ref named-templ-param "Named parameter" for setting
  49.136 -    ///DistMap type.
  49.137 +    ///\c DistMap type.
  49.138      ///
  49.139      ///\ref named-templ-param "Named parameter" for setting
  49.140 -    ///DistMap type.
  49.141 +    ///\c DistMap type.
  49.142 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  49.143      template <class T>
  49.144      struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
  49.145        typedef Bfs< Digraph, SetDistMapTraits<T> > Create;
  49.146 @@ -265,10 +262,11 @@
  49.147        }
  49.148      };
  49.149      ///\brief \ref named-templ-param "Named parameter" for setting
  49.150 -    ///ReachedMap type.
  49.151 +    ///\c ReachedMap type.
  49.152      ///
  49.153      ///\ref named-templ-param "Named parameter" for setting
  49.154 -    ///ReachedMap type.
  49.155 +    ///\c ReachedMap type.
  49.156 +    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  49.157      template <class T>
  49.158      struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
  49.159        typedef Bfs< Digraph, SetReachedMapTraits<T> > Create;
  49.160 @@ -284,10 +282,11 @@
  49.161        }
  49.162      };
  49.163      ///\brief \ref named-templ-param "Named parameter" for setting
  49.164 -    ///ProcessedMap type.
  49.165 +    ///\c ProcessedMap type.
  49.166      ///
  49.167      ///\ref named-templ-param "Named parameter" for setting
  49.168 -    ///ProcessedMap type.
  49.169 +    ///\c ProcessedMap type.
  49.170 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  49.171      template <class T>
  49.172      struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
  49.173        typedef Bfs< Digraph, SetProcessedMapTraits<T> > Create;
  49.174 @@ -302,10 +301,10 @@
  49.175        }
  49.176      };
  49.177      ///\brief \ref named-templ-param "Named parameter" for setting
  49.178 -    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
  49.179 +    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
  49.180      ///
  49.181      ///\ref named-templ-param "Named parameter" for setting
  49.182 -    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
  49.183 +    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
  49.184      ///If you don't set it explicitly, it will be automatically allocated.
  49.185      struct SetStandardProcessedMap :
  49.186        public Bfs< Digraph, SetStandardProcessedMapTraits > {
  49.187 @@ -340,9 +339,10 @@
  49.188      ///Sets the map that stores the predecessor arcs.
  49.189  
  49.190      ///Sets the map that stores the predecessor arcs.
  49.191 -    ///If you don't use this function before calling \ref run(),
  49.192 -    ///it will allocate one. The destructor deallocates this
  49.193 -    ///automatically allocated map, of course.
  49.194 +    ///If you don't use this function before calling \ref run(Node) "run()"
  49.195 +    ///or \ref init(), an instance will be allocated automatically.
  49.196 +    ///The destructor deallocates this automatically allocated map,
  49.197 +    ///of course.
  49.198      ///\return <tt> (*this) </tt>
  49.199      Bfs &predMap(PredMap &m)
  49.200      {
  49.201 @@ -357,9 +357,10 @@
  49.202      ///Sets the map that indicates which nodes are reached.
  49.203  
  49.204      ///Sets the map that indicates which nodes are reached.
  49.205 -    ///If you don't use this function before calling \ref run(),
  49.206 -    ///it will allocate one. The destructor deallocates this
  49.207 -    ///automatically allocated map, of course.
  49.208 +    ///If you don't use this function before calling \ref run(Node) "run()"
  49.209 +    ///or \ref init(), an instance will be allocated automatically.
  49.210 +    ///The destructor deallocates this automatically allocated map,
  49.211 +    ///of course.
  49.212      ///\return <tt> (*this) </tt>
  49.213      Bfs &reachedMap(ReachedMap &m)
  49.214      {
  49.215 @@ -374,9 +375,10 @@
  49.216      ///Sets the map that indicates which nodes are processed.
  49.217  
  49.218      ///Sets the map that indicates which nodes are processed.
  49.219 -    ///If you don't use this function before calling \ref run(),
  49.220 -    ///it will allocate one. The destructor deallocates this
  49.221 -    ///automatically allocated map, of course.
  49.222 +    ///If you don't use this function before calling \ref run(Node) "run()"
  49.223 +    ///or \ref init(), an instance will be allocated automatically.
  49.224 +    ///The destructor deallocates this automatically allocated map,
  49.225 +    ///of course.
  49.226      ///\return <tt> (*this) </tt>
  49.227      Bfs &processedMap(ProcessedMap &m)
  49.228      {
  49.229 @@ -392,9 +394,10 @@
  49.230  
  49.231      ///Sets the map that stores the distances of the nodes calculated by
  49.232      ///the algorithm.
  49.233 -    ///If you don't use this function before calling \ref run(),
  49.234 -    ///it will allocate one. The destructor deallocates this
  49.235 -    ///automatically allocated map, of course.
  49.236 +    ///If you don't use this function before calling \ref run(Node) "run()"
  49.237 +    ///or \ref init(), an instance will be allocated automatically.
  49.238 +    ///The destructor deallocates this automatically allocated map,
  49.239 +    ///of course.
  49.240      ///\return <tt> (*this) </tt>
  49.241      Bfs &distMap(DistMap &m)
  49.242      {
  49.243 @@ -408,22 +411,19 @@
  49.244  
  49.245    public:
  49.246  
  49.247 -    ///\name Execution control
  49.248 -    ///The simplest way to execute the algorithm is to use
  49.249 -    ///one of the member functions called \ref lemon::Bfs::run() "run()".
  49.250 -    ///\n
  49.251 -    ///If you need more control on the execution, first you must call
  49.252 -    ///\ref lemon::Bfs::init() "init()", then you can add several source
  49.253 -    ///nodes with \ref lemon::Bfs::addSource() "addSource()".
  49.254 -    ///Finally \ref lemon::Bfs::start() "start()" will perform the
  49.255 -    ///actual path computation.
  49.256 +    ///\name Execution Control
  49.257 +    ///The simplest way to execute the BFS algorithm is to use one of the
  49.258 +    ///member functions called \ref run(Node) "run()".\n
  49.259 +    ///If you need better control on the execution, you have to call
  49.260 +    ///\ref init() first, then you can add several source nodes with
  49.261 +    ///\ref addSource(). Finally the actual path computation can be
  49.262 +    ///performed with one of the \ref start() functions.
  49.263  
  49.264      ///@{
  49.265  
  49.266 +    ///\brief Initializes the internal data structures.
  49.267 +    ///
  49.268      ///Initializes the internal data structures.
  49.269 -
  49.270 -    ///Initializes the internal data structures.
  49.271 -    ///
  49.272      void init()
  49.273      {
  49.274        create_maps();
  49.275 @@ -557,16 +557,16 @@
  49.276        return _queue_tail<_queue_head?_queue[_queue_tail]:INVALID;
  49.277      }
  49.278  
  49.279 -    ///\brief Returns \c false if there are nodes
  49.280 -    ///to be processed.
  49.281 -    ///
  49.282 -    ///Returns \c false if there are nodes
  49.283 -    ///to be processed in the queue.
  49.284 +    ///Returns \c false if there are nodes to be processed.
  49.285 +
  49.286 +    ///Returns \c false if there are nodes to be processed
  49.287 +    ///in the queue.
  49.288      bool emptyQueue() const { return _queue_tail==_queue_head; }
  49.289  
  49.290      ///Returns the number of the nodes to be processed.
  49.291  
  49.292 -    ///Returns the number of the nodes to be processed in the queue.
  49.293 +    ///Returns the number of the nodes to be processed
  49.294 +    ///in the queue.
  49.295      int queueSize() const { return _queue_head-_queue_tail; }
  49.296  
  49.297      ///Executes the algorithm.
  49.298 @@ -731,60 +731,62 @@
  49.299      ///@}
  49.300  
  49.301      ///\name Query Functions
  49.302 -    ///The result of the %BFS algorithm can be obtained using these
  49.303 +    ///The results of the BFS algorithm can be obtained using these
  49.304      ///functions.\n
  49.305 -    ///Either \ref lemon::Bfs::run() "run()" or \ref lemon::Bfs::start()
  49.306 -    ///"start()" must be called before using them.
  49.307 +    ///Either \ref run(Node) "run()" or \ref start() should be called
  49.308 +    ///before using them.
  49.309  
  49.310      ///@{
  49.311  
  49.312 -    ///The shortest path to a node.
  49.313 +    ///The shortest path to the given node.
  49.314  
  49.315 -    ///Returns the shortest path to a node.
  49.316 +    ///Returns the shortest path to the given node from the root(s).
  49.317      ///
  49.318 -    ///\warning \c t should be reachable from the root(s).
  49.319 +    ///\warning \c t should be reached from the root(s).
  49.320      ///
  49.321 -    ///\pre Either \ref run() or \ref start() must be called before
  49.322 -    ///using this function.
  49.323 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  49.324 +    ///must be called before using this function.
  49.325      Path path(Node t) const { return Path(*G, *_pred, t); }
  49.326  
  49.327 -    ///The distance of a node from the root(s).
  49.328 +    ///The distance of the given node from the root(s).
  49.329  
  49.330 -    ///Returns the distance of a node from the root(s).
  49.331 +    ///Returns the distance of the given node from the root(s).
  49.332      ///
  49.333 -    ///\warning If node \c v is not reachable from the root(s), then
  49.334 +    ///\warning If node \c v is not reached from the root(s), then
  49.335      ///the return value of this function is undefined.
  49.336      ///
  49.337 -    ///\pre Either \ref run() or \ref start() must be called before
  49.338 -    ///using this function.
  49.339 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  49.340 +    ///must be called before using this function.
  49.341      int dist(Node v) const { return (*_dist)[v]; }
  49.342  
  49.343 -    ///Returns the 'previous arc' of the shortest path tree for a node.
  49.344 -
  49.345 +    ///\brief Returns the 'previous arc' of the shortest path tree for
  49.346 +    ///the given node.
  49.347 +    ///
  49.348      ///This function returns the 'previous arc' of the shortest path
  49.349      ///tree for the node \c v, i.e. it returns the last arc of a
  49.350 -    ///shortest path from the root(s) to \c v. It is \c INVALID if \c v
  49.351 -    ///is not reachable from the root(s) or if \c v is a root.
  49.352 +    ///shortest path from a root to \c v. It is \c INVALID if \c v
  49.353 +    ///is not reached from the root(s) or if \c v is a root.
  49.354      ///
  49.355      ///The shortest path tree used here is equal to the shortest path
  49.356 -    ///tree used in \ref predNode().
  49.357 +    ///tree used in \ref predNode() and \ref predMap().
  49.358      ///
  49.359 -    ///\pre Either \ref run() or \ref start() must be called before
  49.360 -    ///using this function.
  49.361 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  49.362 +    ///must be called before using this function.
  49.363      Arc predArc(Node v) const { return (*_pred)[v];}
  49.364  
  49.365 -    ///Returns the 'previous node' of the shortest path tree for a node.
  49.366 -
  49.367 +    ///\brief Returns the 'previous node' of the shortest path tree for
  49.368 +    ///the given node.
  49.369 +    ///
  49.370      ///This function returns the 'previous node' of the shortest path
  49.371      ///tree for the node \c v, i.e. it returns the last but one node
  49.372 -    ///from a shortest path from the root(s) to \c v. It is \c INVALID
  49.373 -    ///if \c v is not reachable from the root(s) or if \c v is a root.
  49.374 +    ///of a shortest path from a root to \c v. It is \c INVALID
  49.375 +    ///if \c v is not reached from the root(s) or if \c v is a root.
  49.376      ///
  49.377      ///The shortest path tree used here is equal to the shortest path
  49.378 -    ///tree used in \ref predArc().
  49.379 +    ///tree used in \ref predArc() and \ref predMap().
  49.380      ///
  49.381 -    ///\pre Either \ref run() or \ref start() must be called before
  49.382 -    ///using this function.
  49.383 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  49.384 +    ///must be called before using this function.
  49.385      Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
  49.386                                    G->source((*_pred)[v]); }
  49.387  
  49.388 @@ -794,7 +796,7 @@
  49.389      ///Returns a const reference to the node map that stores the distances
  49.390      ///of the nodes calculated by the algorithm.
  49.391      ///
  49.392 -    ///\pre Either \ref run() or \ref init()
  49.393 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  49.394      ///must be called before using this function.
  49.395      const DistMap &distMap() const { return *_dist;}
  49.396  
  49.397 @@ -802,16 +804,17 @@
  49.398      ///predecessor arcs.
  49.399      ///
  49.400      ///Returns a const reference to the node map that stores the predecessor
  49.401 -    ///arcs, which form the shortest path tree.
  49.402 +    ///arcs, which form the shortest path tree (forest).
  49.403      ///
  49.404 -    ///\pre Either \ref run() or \ref init()
  49.405 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  49.406      ///must be called before using this function.
  49.407      const PredMap &predMap() const { return *_pred;}
  49.408  
  49.409 -    ///Checks if a node is reachable from the root(s).
  49.410 +    ///Checks if the given node is reached from the root(s).
  49.411  
  49.412 -    ///Returns \c true if \c v is reachable from the root(s).
  49.413 -    ///\pre Either \ref run() or \ref start()
  49.414 +    ///Returns \c true if \c v is reached from the root(s).
  49.415 +    ///
  49.416 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  49.417      ///must be called before using this function.
  49.418      bool reached(Node v) const { return (*_reached)[v]; }
  49.419  
  49.420 @@ -833,7 +836,7 @@
  49.421      ///
  49.422      ///The type of the map that stores the predecessor
  49.423      ///arcs of the shortest paths.
  49.424 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  49.425 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  49.426      typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
  49.427      ///Instantiates a PredMap.
  49.428  
  49.429 @@ -848,7 +851,7 @@
  49.430      ///The type of the map that indicates which nodes are processed.
  49.431  
  49.432      ///The type of the map that indicates which nodes are processed.
  49.433 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  49.434 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  49.435      ///By default it is a NullMap.
  49.436      typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
  49.437      ///Instantiates a ProcessedMap.
  49.438 @@ -868,7 +871,7 @@
  49.439      ///The type of the map that indicates which nodes are reached.
  49.440  
  49.441      ///The type of the map that indicates which nodes are reached.
  49.442 -    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  49.443 +    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  49.444      typedef typename Digraph::template NodeMap<bool> ReachedMap;
  49.445      ///Instantiates a ReachedMap.
  49.446  
  49.447 @@ -883,7 +886,7 @@
  49.448      ///The type of the map that stores the distances of the nodes.
  49.449  
  49.450      ///The type of the map that stores the distances of the nodes.
  49.451 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  49.452 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  49.453      typedef typename Digraph::template NodeMap<int> DistMap;
  49.454      ///Instantiates a DistMap.
  49.455  
  49.456 @@ -898,18 +901,14 @@
  49.457      ///The type of the shortest paths.
  49.458  
  49.459      ///The type of the shortest paths.
  49.460 -    ///It must meet the \ref concepts::Path "Path" concept.
  49.461 +    ///It must conform to the \ref concepts::Path "Path" concept.
  49.462      typedef lemon::Path<Digraph> Path;
  49.463    };
  49.464  
  49.465    /// Default traits class used by BfsWizard
  49.466  
  49.467 -  /// To make it easier to use Bfs algorithm
  49.468 -  /// we have created a wizard class.
  49.469 -  /// This \ref BfsWizard class needs default traits,
  49.470 -  /// as well as the \ref Bfs class.
  49.471 -  /// The \ref BfsWizardBase is a class to be the default traits of the
  49.472 -  /// \ref BfsWizard class.
  49.473 +  /// Default traits class used by BfsWizard.
  49.474 +  /// \tparam GR The type of the digraph.
  49.475    template<class GR>
  49.476    class BfsWizardBase : public BfsWizardDefaultTraits<GR>
  49.477    {
  49.478 @@ -937,7 +936,7 @@
  49.479      public:
  49.480      /// Constructor.
  49.481  
  49.482 -    /// This constructor does not require parameters, therefore it initiates
  49.483 +    /// This constructor does not require parameters, it initiates
  49.484      /// all of the attributes to \c 0.
  49.485      BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
  49.486                        _dist(0), _path(0), _di(0) {}
  49.487 @@ -957,8 +956,8 @@
  49.488  
  49.489    /// This auxiliary class is created to implement the
  49.490    /// \ref bfs() "function-type interface" of \ref Bfs algorithm.
  49.491 -  /// It does not have own \ref run() method, it uses the functions
  49.492 -  /// and features of the plain \ref Bfs.
  49.493 +  /// It does not have own \ref run(Node) "run()" method, it uses the
  49.494 +  /// functions and features of the plain \ref Bfs.
  49.495    ///
  49.496    /// This class should only be used through the \ref bfs() function,
  49.497    /// which makes it easier to use the algorithm.
  49.498 @@ -967,7 +966,6 @@
  49.499    {
  49.500      typedef TR Base;
  49.501  
  49.502 -    ///The type of the digraph the algorithm runs on.
  49.503      typedef typename TR::Digraph Digraph;
  49.504  
  49.505      typedef typename Digraph::Node Node;
  49.506 @@ -975,16 +973,10 @@
  49.507      typedef typename Digraph::Arc Arc;
  49.508      typedef typename Digraph::OutArcIt OutArcIt;
  49.509  
  49.510 -    ///\brief The type of the map that stores the predecessor
  49.511 -    ///arcs of the shortest paths.
  49.512      typedef typename TR::PredMap PredMap;
  49.513 -    ///\brief The type of the map that stores the distances of the nodes.
  49.514      typedef typename TR::DistMap DistMap;
  49.515 -    ///\brief The type of the map that indicates which nodes are reached.
  49.516      typedef typename TR::ReachedMap ReachedMap;
  49.517 -    ///\brief The type of the map that indicates which nodes are processed.
  49.518      typedef typename TR::ProcessedMap ProcessedMap;
  49.519 -    ///The type of the shortest paths
  49.520      typedef typename TR::Path Path;
  49.521  
  49.522    public:
  49.523 @@ -1067,11 +1059,12 @@
  49.524        static PredMap *createPredMap(const Digraph &) { return 0; };
  49.525        SetPredMapBase(const TR &b) : TR(b) {}
  49.526      };
  49.527 -    ///\brief \ref named-func-param "Named parameter"
  49.528 -    ///for setting PredMap object.
  49.529 +
  49.530 +    ///\brief \ref named-templ-param "Named parameter" for setting
  49.531 +    ///the predecessor map.
  49.532      ///
  49.533 -    ///\ref named-func-param "Named parameter"
  49.534 -    ///for setting PredMap object.
  49.535 +    ///\ref named-templ-param "Named parameter" function for setting
  49.536 +    ///the map that stores the predecessor arcs of the nodes.
  49.537      template<class T>
  49.538      BfsWizard<SetPredMapBase<T> > predMap(const T &t)
  49.539      {
  49.540 @@ -1085,11 +1078,12 @@
  49.541        static ReachedMap *createReachedMap(const Digraph &) { return 0; };
  49.542        SetReachedMapBase(const TR &b) : TR(b) {}
  49.543      };
  49.544 -    ///\brief \ref named-func-param "Named parameter"
  49.545 -    ///for setting ReachedMap object.
  49.546 +
  49.547 +    ///\brief \ref named-templ-param "Named parameter" for setting
  49.548 +    ///the reached map.
  49.549      ///
  49.550 -    /// \ref named-func-param "Named parameter"
  49.551 -    ///for setting ReachedMap object.
  49.552 +    ///\ref named-templ-param "Named parameter" function for setting
  49.553 +    ///the map that indicates which nodes are reached.
  49.554      template<class T>
  49.555      BfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
  49.556      {
  49.557 @@ -1103,11 +1097,13 @@
  49.558        static DistMap *createDistMap(const Digraph &) { return 0; };
  49.559        SetDistMapBase(const TR &b) : TR(b) {}
  49.560      };
  49.561 -    ///\brief \ref named-func-param "Named parameter"
  49.562 -    ///for setting DistMap object.
  49.563 +
  49.564 +    ///\brief \ref named-templ-param "Named parameter" for setting
  49.565 +    ///the distance map.
  49.566      ///
  49.567 -    /// \ref named-func-param "Named parameter"
  49.568 -    ///for setting DistMap object.
  49.569 +    ///\ref named-templ-param "Named parameter" function for setting
  49.570 +    ///the map that stores the distances of the nodes calculated
  49.571 +    ///by the algorithm.
  49.572      template<class T>
  49.573      BfsWizard<SetDistMapBase<T> > distMap(const T &t)
  49.574      {
  49.575 @@ -1121,11 +1117,12 @@
  49.576        static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
  49.577        SetProcessedMapBase(const TR &b) : TR(b) {}
  49.578      };
  49.579 -    ///\brief \ref named-func-param "Named parameter"
  49.580 -    ///for setting ProcessedMap object.
  49.581 +
  49.582 +    ///\brief \ref named-func-param "Named parameter" for setting
  49.583 +    ///the processed map.
  49.584      ///
  49.585 -    /// \ref named-func-param "Named parameter"
  49.586 -    ///for setting ProcessedMap object.
  49.587 +    ///\ref named-templ-param "Named parameter" function for setting
  49.588 +    ///the map that indicates which nodes are processed.
  49.589      template<class T>
  49.590      BfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
  49.591      {
  49.592 @@ -1178,7 +1175,7 @@
  49.593    ///  // Compute shortest path from s to t
  49.594    ///  bool reached = bfs(g).path(p).dist(d).run(s,t);
  49.595    ///\endcode
  49.596 -  ///\warning Don't forget to put the \ref BfsWizard::run() "run()"
  49.597 +  ///\warning Don't forget to put the \ref BfsWizard::run(Node) "run()"
  49.598    ///to the end of the parameter list.
  49.599    ///\sa BfsWizard
  49.600    ///\sa Bfs
  49.601 @@ -1194,9 +1191,9 @@
  49.602    ///
  49.603    /// This class defines the interface of the BfsVisit events, and
  49.604    /// it could be the base of a real visitor class.
  49.605 -  template <typename _Digraph>
  49.606 +  template <typename GR>
  49.607    struct BfsVisitor {
  49.608 -    typedef _Digraph Digraph;
  49.609 +    typedef GR Digraph;
  49.610      typedef typename Digraph::Arc Arc;
  49.611      typedef typename Digraph::Node Node;
  49.612      /// \brief Called for the source node(s) of the BFS.
  49.613 @@ -1224,9 +1221,9 @@
  49.614      void examine(const Arc& arc) {}
  49.615    };
  49.616  #else
  49.617 -  template <typename _Digraph>
  49.618 +  template <typename GR>
  49.619    struct BfsVisitor {
  49.620 -    typedef _Digraph Digraph;
  49.621 +    typedef GR Digraph;
  49.622      typedef typename Digraph::Arc Arc;
  49.623      typedef typename Digraph::Node Node;
  49.624      void start(const Node&) {}
  49.625 @@ -1254,17 +1251,17 @@
  49.626    /// \brief Default traits class of BfsVisit class.
  49.627    ///
  49.628    /// Default traits class of BfsVisit class.
  49.629 -  /// \tparam _Digraph The type of the digraph the algorithm runs on.
  49.630 -  template<class _Digraph>
  49.631 +  /// \tparam GR The type of the digraph the algorithm runs on.
  49.632 +  template<class GR>
  49.633    struct BfsVisitDefaultTraits {
  49.634  
  49.635      /// \brief The type of the digraph the algorithm runs on.
  49.636 -    typedef _Digraph Digraph;
  49.637 +    typedef GR Digraph;
  49.638  
  49.639      /// \brief The type of the map that indicates which nodes are reached.
  49.640      ///
  49.641      /// The type of the map that indicates which nodes are reached.
  49.642 -    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  49.643 +    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  49.644      typedef typename Digraph::template NodeMap<bool> ReachedMap;
  49.645  
  49.646      /// \brief Instantiates a ReachedMap.
  49.647 @@ -1280,12 +1277,12 @@
  49.648  
  49.649    /// \ingroup search
  49.650    ///
  49.651 -  /// \brief %BFS algorithm class with visitor interface.
  49.652 +  /// \brief BFS algorithm class with visitor interface.
  49.653    ///
  49.654 -  /// This class provides an efficient implementation of the %BFS algorithm
  49.655 +  /// This class provides an efficient implementation of the BFS algorithm
  49.656    /// with visitor interface.
  49.657    ///
  49.658 -  /// The %BfsVisit class provides an alternative interface to the Bfs
  49.659 +  /// The BfsVisit class provides an alternative interface to the Bfs
  49.660    /// class. It works with callback mechanism, the BfsVisit object calls
  49.661    /// the member functions of the \c Visitor class on every BFS event.
  49.662    ///
  49.663 @@ -1294,37 +1291,37 @@
  49.664    /// events of the BFS algorithm. Otherwise consider to use Bfs or bfs()
  49.665    /// instead.
  49.666    ///
  49.667 -  /// \tparam _Digraph The type of the digraph the algorithm runs on.
  49.668 -  /// The default value is
  49.669 -  /// \ref ListDigraph. The value of _Digraph is not used directly by
  49.670 -  /// \ref BfsVisit, it is only passed to \ref BfsVisitDefaultTraits.
  49.671 -  /// \tparam _Visitor The Visitor type that is used by the algorithm.
  49.672 -  /// \ref BfsVisitor "BfsVisitor<_Digraph>" is an empty visitor, which
  49.673 +  /// \tparam GR The type of the digraph the algorithm runs on.
  49.674 +  /// The default type is \ref ListDigraph.
  49.675 +  /// The value of GR is not used directly by \ref BfsVisit,
  49.676 +  /// it is only passed to \ref BfsVisitDefaultTraits.
  49.677 +  /// \tparam VS The Visitor type that is used by the algorithm.
  49.678 +  /// \ref BfsVisitor "BfsVisitor<GR>" is an empty visitor, which
  49.679    /// does not observe the BFS events. If you want to observe the BFS
  49.680    /// events, you should implement your own visitor class.
  49.681 -  /// \tparam _Traits Traits class to set various data types used by the
  49.682 +  /// \tparam TR Traits class to set various data types used by the
  49.683    /// algorithm. The default traits class is
  49.684 -  /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<_Digraph>".
  49.685 +  /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<GR>".
  49.686    /// See \ref BfsVisitDefaultTraits for the documentation of
  49.687    /// a BFS visit traits class.
  49.688  #ifdef DOXYGEN
  49.689 -  template <typename _Digraph, typename _Visitor, typename _Traits>
  49.690 +  template <typename GR, typename VS, typename TR>
  49.691  #else
  49.692 -  template <typename _Digraph = ListDigraph,
  49.693 -            typename _Visitor = BfsVisitor<_Digraph>,
  49.694 -            typename _Traits = BfsVisitDefaultTraits<_Digraph> >
  49.695 +  template <typename GR = ListDigraph,
  49.696 +            typename VS = BfsVisitor<GR>,
  49.697 +            typename TR = BfsVisitDefaultTraits<GR> >
  49.698  #endif
  49.699    class BfsVisit {
  49.700    public:
  49.701  
  49.702      ///The traits class.
  49.703 -    typedef _Traits Traits;
  49.704 +    typedef TR Traits;
  49.705  
  49.706      ///The type of the digraph the algorithm runs on.
  49.707      typedef typename Traits::Digraph Digraph;
  49.708  
  49.709      ///The visitor type used by the algorithm.
  49.710 -    typedef _Visitor Visitor;
  49.711 +    typedef VS Visitor;
  49.712  
  49.713      ///The type of the map that indicates which nodes are reached.
  49.714      typedef typename Traits::ReachedMap ReachedMap;
  49.715 @@ -1364,7 +1361,7 @@
  49.716  
  49.717      typedef BfsVisit Create;
  49.718  
  49.719 -    /// \name Named template parameters
  49.720 +    /// \name Named Template Parameters
  49.721  
  49.722      ///@{
  49.723      template <class T>
  49.724 @@ -1406,9 +1403,10 @@
  49.725      /// \brief Sets the map that indicates which nodes are reached.
  49.726      ///
  49.727      /// Sets the map that indicates which nodes are reached.
  49.728 -    /// If you don't use this function before calling \ref run(),
  49.729 -    /// it will allocate one. The destructor deallocates this
  49.730 -    /// automatically allocated map, of course.
  49.731 +    /// If you don't use this function before calling \ref run(Node) "run()"
  49.732 +    /// or \ref init(), an instance will be allocated automatically.
  49.733 +    /// The destructor deallocates this automatically allocated map,
  49.734 +    /// of course.
  49.735      /// \return <tt> (*this) </tt>
  49.736      BfsVisit &reachedMap(ReachedMap &m) {
  49.737        if(local_reached) {
  49.738 @@ -1421,16 +1419,13 @@
  49.739  
  49.740    public:
  49.741  
  49.742 -    /// \name Execution control
  49.743 -    /// The simplest way to execute the algorithm is to use
  49.744 -    /// one of the member functions called \ref lemon::BfsVisit::run()
  49.745 -    /// "run()".
  49.746 -    /// \n
  49.747 -    /// If you need more control on the execution, first you must call
  49.748 -    /// \ref lemon::BfsVisit::init() "init()", then you can add several
  49.749 -    /// source nodes with \ref lemon::BfsVisit::addSource() "addSource()".
  49.750 -    /// Finally \ref lemon::BfsVisit::start() "start()" will perform the
  49.751 -    /// actual path computation.
  49.752 +    /// \name Execution Control
  49.753 +    /// The simplest way to execute the BFS algorithm is to use one of the
  49.754 +    /// member functions called \ref run(Node) "run()".\n
  49.755 +    /// If you need better control on the execution, you have to call
  49.756 +    /// \ref init() first, then you can add several source nodes with
  49.757 +    /// \ref addSource(). Finally the actual path computation can be
  49.758 +    /// performed with one of the \ref start() functions.
  49.759  
  49.760      /// @{
  49.761  
  49.762 @@ -1730,19 +1725,20 @@
  49.763      ///@}
  49.764  
  49.765      /// \name Query Functions
  49.766 -    /// The result of the %BFS algorithm can be obtained using these
  49.767 +    /// The results of the BFS algorithm can be obtained using these
  49.768      /// functions.\n
  49.769 -    /// Either \ref lemon::BfsVisit::run() "run()" or
  49.770 -    /// \ref lemon::BfsVisit::start() "start()" must be called before
  49.771 -    /// using them.
  49.772 +    /// Either \ref run(Node) "run()" or \ref start() should be called
  49.773 +    /// before using them.
  49.774 +
  49.775      ///@{
  49.776  
  49.777 -    /// \brief Checks if a node is reachable from the root(s).
  49.778 +    /// \brief Checks if the given node is reached from the root(s).
  49.779      ///
  49.780 -    /// Returns \c true if \c v is reachable from the root(s).
  49.781 -    /// \pre Either \ref run() or \ref start()
  49.782 +    /// Returns \c true if \c v is reached from the root(s).
  49.783 +    ///
  49.784 +    /// \pre Either \ref run(Node) "run()" or \ref init()
  49.785      /// must be called before using this function.
  49.786 -    bool reached(Node v) { return (*_reached)[v]; }
  49.787 +    bool reached(Node v) const { return (*_reached)[v]; }
  49.788  
  49.789      ///@}
  49.790  
    50.1 --- a/lemon/bin_heap.h	Fri Oct 16 10:21:37 2009 +0200
    50.2 +++ b/lemon/bin_heap.h	Thu Nov 05 15:50:01 2009 +0100
    50.3 @@ -2,7 +2,7 @@
    50.4   *
    50.5   * This file is a part of LEMON, a generic C++ optimization library.
    50.6   *
    50.7 - * Copyright (C) 2003-2008
    50.8 + * Copyright (C) 2003-2009
    50.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   50.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   50.11   *
   50.12 @@ -19,9 +19,9 @@
   50.13  #ifndef LEMON_BIN_HEAP_H
   50.14  #define LEMON_BIN_HEAP_H
   50.15  
   50.16 -///\ingroup auxdat
   50.17 +///\ingroup heaps
   50.18  ///\file
   50.19 -///\brief Binary Heap implementation.
   50.20 +///\brief Binary heap implementation.
   50.21  
   50.22  #include <vector>
   50.23  #include <utility>
   50.24 @@ -29,112 +29,110 @@
   50.25  
   50.26  namespace lemon {
   50.27  
   50.28 -  ///\ingroup auxdat
   50.29 +  /// \ingroup heaps
   50.30    ///
   50.31 -  ///\brief A Binary Heap implementation.
   50.32 +  /// \brief Binary heap data structure.
   50.33    ///
   50.34 -  ///This class implements the \e binary \e heap data structure. A \e heap
   50.35 -  ///is a data structure for storing items with specified values called \e
   50.36 -  ///priorities in such a way that finding the item with minimum priority is
   50.37 -  ///efficient. \c Compare specifies the ordering of the priorities. In a heap
   50.38 -  ///one can change the priority of an item, add or erase an item, etc.
   50.39 +  /// This class implements the \e binary \e heap data structure.
   50.40 +  /// It fully conforms to the \ref concepts::Heap "heap concept".
   50.41    ///
   50.42 -  ///\tparam _Prio Type of the priority of the items.
   50.43 -  ///\tparam _ItemIntMap A read and writable Item int map, used internally
   50.44 -  ///to handle the cross references.
   50.45 -  ///\tparam _Compare A class for the ordering of the priorities. The
   50.46 -  ///default is \c std::less<_Prio>.
   50.47 -  ///
   50.48 -  ///\sa FibHeap
   50.49 -  ///\sa Dijkstra
   50.50 -  template <typename _Prio, typename _ItemIntMap,
   50.51 -            typename _Compare = std::less<_Prio> >
   50.52 +  /// \tparam PR Type of the priorities of the items.
   50.53 +  /// \tparam IM A read-writable item map with \c int values, used
   50.54 +  /// internally to handle the cross references.
   50.55 +  /// \tparam CMP A functor class for comparing the priorities.
   50.56 +  /// The default is \c std::less<PR>.
   50.57 +#ifdef DOXYGEN
   50.58 +  template <typename PR, typename IM, typename CMP>
   50.59 +#else
   50.60 +  template <typename PR, typename IM, typename CMP = std::less<PR> >
   50.61 +#endif
   50.62    class BinHeap {
   50.63 +  public:
   50.64  
   50.65 -  public:
   50.66 -    ///\e
   50.67 -    typedef _ItemIntMap ItemIntMap;
   50.68 -    ///\e
   50.69 -    typedef _Prio Prio;
   50.70 -    ///\e
   50.71 +    /// Type of the item-int map.
   50.72 +    typedef IM ItemIntMap;
   50.73 +    /// Type of the priorities.
   50.74 +    typedef PR Prio;
   50.75 +    /// Type of the items stored in the heap.
   50.76      typedef typename ItemIntMap::Key Item;
   50.77 -    ///\e
   50.78 +    /// Type of the item-priority pairs.
   50.79      typedef std::pair<Item,Prio> Pair;
   50.80 -    ///\e
   50.81 -    typedef _Compare Compare;
   50.82 +    /// Functor type for comparing the priorities.
   50.83 +    typedef CMP Compare;
   50.84  
   50.85 -    /// \brief Type to represent the items states.
   50.86 +    /// \brief Type to represent the states of the items.
   50.87      ///
   50.88 -    /// Each Item element have a state associated to it. It may be "in heap",
   50.89 -    /// "pre heap" or "post heap". The latter two are indifferent from the
   50.90 +    /// Each item has a state associated to it. It can be "in heap",
   50.91 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
   50.92      /// heap's point of view, but may be useful to the user.
   50.93      ///
   50.94 -    /// The ItemIntMap \e should be initialized in such way that it maps
   50.95 -    /// PRE_HEAP (-1) to any element to be put in the heap...
   50.96 +    /// The item-int map must be initialized in such way that it assigns
   50.97 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
   50.98      enum State {
   50.99 -      IN_HEAP = 0,
  50.100 -      PRE_HEAP = -1,
  50.101 -      POST_HEAP = -2
  50.102 +      IN_HEAP = 0,    ///< = 0.
  50.103 +      PRE_HEAP = -1,  ///< = -1.
  50.104 +      POST_HEAP = -2  ///< = -2.
  50.105      };
  50.106  
  50.107    private:
  50.108 -    std::vector<Pair> data;
  50.109 -    Compare comp;
  50.110 -    ItemIntMap &iim;
  50.111 +    std::vector<Pair> _data;
  50.112 +    Compare _comp;
  50.113 +    ItemIntMap &_iim;
  50.114  
  50.115    public:
  50.116 -    /// \brief The constructor.
  50.117 +
  50.118 +    /// \brief Constructor.
  50.119      ///
  50.120 -    /// The constructor.
  50.121 -    /// \param _iim should be given to the constructor, since it is used
  50.122 -    /// internally to handle the cross references. The value of the map
  50.123 -    /// should be PRE_HEAP (-1) for each element.
  50.124 -    explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {}
  50.125 +    /// Constructor.
  50.126 +    /// \param map A map that assigns \c int values to the items.
  50.127 +    /// It is used internally to handle the cross references.
  50.128 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  50.129 +    explicit BinHeap(ItemIntMap &map) : _iim(map) {}
  50.130  
  50.131 -    /// \brief The constructor.
  50.132 +    /// \brief Constructor.
  50.133      ///
  50.134 -    /// The constructor.
  50.135 -    /// \param _iim should be given to the constructor, since it is used
  50.136 -    /// internally to handle the cross references. The value of the map
  50.137 -    /// should be PRE_HEAP (-1) for each element.
  50.138 +    /// Constructor.
  50.139 +    /// \param map A map that assigns \c int values to the items.
  50.140 +    /// It is used internally to handle the cross references.
  50.141 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  50.142 +    /// \param comp The function object used for comparing the priorities.
  50.143 +    BinHeap(ItemIntMap &map, const Compare &comp)
  50.144 +      : _iim(map), _comp(comp) {}
  50.145 +
  50.146 +
  50.147 +    /// \brief The number of items stored in the heap.
  50.148      ///
  50.149 -    /// \param _comp The comparator function object.
  50.150 -    BinHeap(ItemIntMap &_iim, const Compare &_comp)
  50.151 -      : iim(_iim), comp(_comp) {}
  50.152 +    /// This function returns the number of items stored in the heap.
  50.153 +    int size() const { return _data.size(); }
  50.154  
  50.155 +    /// \brief Check if the heap is empty.
  50.156 +    ///
  50.157 +    /// This function returns \c true if the heap is empty.
  50.158 +    bool empty() const { return _data.empty(); }
  50.159  
  50.160 -    /// The number of items stored in the heap.
  50.161 +    /// \brief Make the heap empty.
  50.162      ///
  50.163 -    /// \brief Returns the number of items stored in the heap.
  50.164 -    int size() const { return data.size(); }
  50.165 -
  50.166 -    /// \brief Checks if the heap stores no items.
  50.167 -    ///
  50.168 -    /// Returns \c true if and only if the heap stores no items.
  50.169 -    bool empty() const { return data.empty(); }
  50.170 -
  50.171 -    /// \brief Make empty this heap.
  50.172 -    ///
  50.173 -    /// Make empty this heap. It does not change the cross reference map.
  50.174 -    /// If you want to reuse what is not surely empty you should first clear
  50.175 -    /// the heap and after that you should set the cross reference map for
  50.176 -    /// each item to \c PRE_HEAP.
  50.177 +    /// This functon makes the heap empty.
  50.178 +    /// It does not change the cross reference map. If you want to reuse
  50.179 +    /// a heap that is not surely empty, you should first clear it and
  50.180 +    /// then you should set the cross reference map to \c PRE_HEAP
  50.181 +    /// for each item.
  50.182      void clear() {
  50.183 -      data.clear();
  50.184 +      _data.clear();
  50.185      }
  50.186  
  50.187    private:
  50.188      static int parent(int i) { return (i-1)/2; }
  50.189  
  50.190 -    static int second_child(int i) { return 2*i+2; }
  50.191 +    static int secondChild(int i) { return 2*i+2; }
  50.192      bool less(const Pair &p1, const Pair &p2) const {
  50.193 -      return comp(p1.second, p2.second);
  50.194 +      return _comp(p1.second, p2.second);
  50.195      }
  50.196  
  50.197 -    int bubble_up(int hole, Pair p) {
  50.198 +    int bubbleUp(int hole, Pair p) {
  50.199        int par = parent(hole);
  50.200 -      while( hole>0 && less(p,data[par]) ) {
  50.201 -        move(data[par],hole);
  50.202 +      while( hole>0 && less(p,_data[par]) ) {
  50.203 +        move(_data[par],hole);
  50.204          hole = par;
  50.205          par = parent(hole);
  50.206        }
  50.207 @@ -142,21 +140,21 @@
  50.208        return hole;
  50.209      }
  50.210  
  50.211 -    int bubble_down(int hole, Pair p, int length) {
  50.212 -      int child = second_child(hole);
  50.213 +    int bubbleDown(int hole, Pair p, int length) {
  50.214 +      int child = secondChild(hole);
  50.215        while(child < length) {
  50.216 -        if( less(data[child-1], data[child]) ) {
  50.217 +        if( less(_data[child-1], _data[child]) ) {
  50.218            --child;
  50.219          }
  50.220 -        if( !less(data[child], p) )
  50.221 +        if( !less(_data[child], p) )
  50.222            goto ok;
  50.223 -        move(data[child], hole);
  50.224 +        move(_data[child], hole);
  50.225          hole = child;
  50.226 -        child = second_child(hole);
  50.227 +        child = secondChild(hole);
  50.228        }
  50.229        child--;
  50.230 -      if( child<length && less(data[child], p) ) {
  50.231 -        move(data[child], hole);
  50.232 +      if( child<length && less(_data[child], p) ) {
  50.233 +        move(_data[child], hole);
  50.234          hole=child;
  50.235        }
  50.236      ok:
  50.237 @@ -165,151 +163,153 @@
  50.238      }
  50.239  
  50.240      void move(const Pair &p, int i) {
  50.241 -      data[i] = p;
  50.242 -      iim.set(p.first, i);
  50.243 +      _data[i] = p;
  50.244 +      _iim.set(p.first, i);
  50.245      }
  50.246  
  50.247    public:
  50.248 +
  50.249      /// \brief Insert a pair of item and priority into the heap.
  50.250      ///
  50.251 -    /// Adds \c p.first to the heap with priority \c p.second.
  50.252 +    /// This function inserts \c p.first to the heap with priority
  50.253 +    /// \c p.second.
  50.254      /// \param p The pair to insert.
  50.255 +    /// \pre \c p.first must not be stored in the heap.
  50.256      void push(const Pair &p) {
  50.257 -      int n = data.size();
  50.258 -      data.resize(n+1);
  50.259 -      bubble_up(n, p);
  50.260 +      int n = _data.size();
  50.261 +      _data.resize(n+1);
  50.262 +      bubbleUp(n, p);
  50.263      }
  50.264  
  50.265 -    /// \brief Insert an item into the heap with the given heap.
  50.266 +    /// \brief Insert an item into the heap with the given priority.
  50.267      ///
  50.268 -    /// Adds \c i to the heap with priority \c p.
  50.269 +    /// This function inserts the given item into the heap with the
  50.270 +    /// given priority.
  50.271      /// \param i The item to insert.
  50.272      /// \param p The priority of the item.
  50.273 +    /// \pre \e i must not be stored in the heap.
  50.274      void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
  50.275  
  50.276 -    /// \brief Returns the item with minimum priority relative to \c Compare.
  50.277 +    /// \brief Return the item having minimum priority.
  50.278      ///
  50.279 -    /// This method returns the item with minimum priority relative to \c
  50.280 -    /// Compare.
  50.281 -    /// \pre The heap must be nonempty.
  50.282 +    /// This function returns the item having minimum priority.
  50.283 +    /// \pre The heap must be non-empty.
  50.284      Item top() const {
  50.285 -      return data[0].first;
  50.286 +      return _data[0].first;
  50.287      }
  50.288  
  50.289 -    /// \brief Returns the minimum priority relative to \c Compare.
  50.290 +    /// \brief The minimum priority.
  50.291      ///
  50.292 -    /// It returns the minimum priority relative to \c Compare.
  50.293 -    /// \pre The heap must be nonempty.
  50.294 +    /// This function returns the minimum priority.
  50.295 +    /// \pre The heap must be non-empty.
  50.296      Prio prio() const {
  50.297 -      return data[0].second;
  50.298 +      return _data[0].second;
  50.299      }
  50.300  
  50.301 -    /// \brief Deletes the item with minimum priority relative to \c Compare.
  50.302 +    /// \brief Remove the item having minimum priority.
  50.303      ///
  50.304 -    /// This method deletes the item with minimum priority relative to \c
  50.305 -    /// Compare from the heap.
  50.306 +    /// This function removes the item having minimum priority.
  50.307      /// \pre The heap must be non-empty.
  50.308      void pop() {
  50.309 -      int n = data.size()-1;
  50.310 -      iim.set(data[0].first, POST_HEAP);
  50.311 +      int n = _data.size()-1;
  50.312 +      _iim.set(_data[0].first, POST_HEAP);
  50.313        if (n > 0) {
  50.314 -        bubble_down(0, data[n], n);
  50.315 +        bubbleDown(0, _data[n], n);
  50.316        }
  50.317 -      data.pop_back();
  50.318 +      _data.pop_back();
  50.319      }
  50.320  
  50.321 -    /// \brief Deletes \c i from the heap.
  50.322 +    /// \brief Remove the given item from the heap.
  50.323      ///
  50.324 -    /// This method deletes item \c i from the heap.
  50.325 -    /// \param i The item to erase.
  50.326 -    /// \pre The item should be in the heap.
  50.327 +    /// This function removes the given item from the heap if it is
  50.328 +    /// already stored.
  50.329 +    /// \param i The item to delete.
  50.330 +    /// \pre \e i must be in the heap.
  50.331      void erase(const Item &i) {
  50.332 -      int h = iim[i];
  50.333 -      int n = data.size()-1;
  50.334 -      iim.set(data[h].first, POST_HEAP);
  50.335 +      int h = _iim[i];
  50.336 +      int n = _data.size()-1;
  50.337 +      _iim.set(_data[h].first, POST_HEAP);
  50.338        if( h < n ) {
  50.339 -        if ( bubble_up(h, data[n]) == h) {
  50.340 -          bubble_down(h, data[n], n);
  50.341 +        if ( bubbleUp(h, _data[n]) == h) {
  50.342 +          bubbleDown(h, _data[n], n);
  50.343          }
  50.344        }
  50.345 -      data.pop_back();
  50.346 +      _data.pop_back();
  50.347      }
  50.348  
  50.349 -
  50.350 -    /// \brief Returns the priority of \c i.
  50.351 +    /// \brief The priority of the given item.
  50.352      ///
  50.353 -    /// This function returns the priority of item \c i.
  50.354 -    /// \pre \c i must be in the heap.
  50.355 +    /// This function returns the priority of the given item.
  50.356      /// \param i The item.
  50.357 +    /// \pre \e i must be in the heap.
  50.358      Prio operator[](const Item &i) const {
  50.359 -      int idx = iim[i];
  50.360 -      return data[idx].second;
  50.361 +      int idx = _iim[i];
  50.362 +      return _data[idx].second;
  50.363      }
  50.364  
  50.365 -    /// \brief \c i gets to the heap with priority \c p independently
  50.366 -    /// if \c i was already there.
  50.367 +    /// \brief Set the priority of an item or insert it, if it is
  50.368 +    /// not stored in the heap.
  50.369      ///
  50.370 -    /// This method calls \ref push(\c i, \c p) if \c i is not stored
  50.371 -    /// in the heap and sets the priority of \c i to \c p otherwise.
  50.372 +    /// This method sets the priority of the given item if it is
  50.373 +    /// already stored in the heap. Otherwise it inserts the given
  50.374 +    /// item into the heap with the given priority.
  50.375      /// \param i The item.
  50.376      /// \param p The priority.
  50.377      void set(const Item &i, const Prio &p) {
  50.378 -      int idx = iim[i];
  50.379 +      int idx = _iim[i];
  50.380        if( idx < 0 ) {
  50.381          push(i,p);
  50.382        }
  50.383 -      else if( comp(p, data[idx].second) ) {
  50.384 -        bubble_up(idx, Pair(i,p));
  50.385 +      else if( _comp(p, _data[idx].second) ) {
  50.386 +        bubbleUp(idx, Pair(i,p));
  50.387        }
  50.388        else {
  50.389 -        bubble_down(idx, Pair(i,p), data.size());
  50.390 +        bubbleDown(idx, Pair(i,p), _data.size());
  50.391        }
  50.392      }
  50.393  
  50.394 -    /// \brief Decreases the priority of \c i to \c p.
  50.395 +    /// \brief Decrease the priority of an item to the given value.
  50.396      ///
  50.397 -    /// This method decreases the priority of item \c i to \c p.
  50.398 -    /// \pre \c i must be stored in the heap with priority at least \c
  50.399 -    /// p relative to \c Compare.
  50.400 +    /// This function decreases the priority of an item to the given value.
  50.401      /// \param i The item.
  50.402      /// \param p The priority.
  50.403 +    /// \pre \e i must be stored in the heap with priority at least \e p.
  50.404      void decrease(const Item &i, const Prio &p) {
  50.405 -      int idx = iim[i];
  50.406 -      bubble_up(idx, Pair(i,p));
  50.407 +      int idx = _iim[i];
  50.408 +      bubbleUp(idx, Pair(i,p));
  50.409      }
  50.410  
  50.411 -    /// \brief Increases the priority of \c i to \c p.
  50.412 +    /// \brief Increase the priority of an item to the given value.
  50.413      ///
  50.414 -    /// This method sets the priority of item \c i to \c p.
  50.415 -    /// \pre \c i must be stored in the heap with priority at most \c
  50.416 -    /// p relative to \c Compare.
  50.417 +    /// This function increases the priority of an item to the given value.
  50.418      /// \param i The item.
  50.419      /// \param p The priority.
  50.420 +    /// \pre \e i must be stored in the heap with priority at most \e p.
  50.421      void increase(const Item &i, const Prio &p) {
  50.422 -      int idx = iim[i];
  50.423 -      bubble_down(idx, Pair(i,p), data.size());
  50.424 +      int idx = _iim[i];
  50.425 +      bubbleDown(idx, Pair(i,p), _data.size());
  50.426      }
  50.427  
  50.428 -    /// \brief Returns if \c item is in, has already been in, or has
  50.429 -    /// never been in the heap.
  50.430 +    /// \brief Return the state of an item.
  50.431      ///
  50.432 -    /// This method returns PRE_HEAP if \c item has never been in the
  50.433 -    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
  50.434 -    /// otherwise. In the latter case it is possible that \c item will
  50.435 -    /// get back to the heap again.
  50.436 +    /// This method returns \c PRE_HEAP if the given item has never
  50.437 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  50.438 +    /// and \c POST_HEAP otherwise.
  50.439 +    /// In the latter case it is possible that the item will get back
  50.440 +    /// to the heap again.
  50.441      /// \param i The item.
  50.442      State state(const Item &i) const {
  50.443 -      int s = iim[i];
  50.444 +      int s = _iim[i];
  50.445        if( s>=0 )
  50.446          s=0;
  50.447        return State(s);
  50.448      }
  50.449  
  50.450 -    /// \brief Sets the state of the \c item in the heap.
  50.451 +    /// \brief Set the state of an item in the heap.
  50.452      ///
  50.453 -    /// Sets the state of the \c item in the heap. It can be used to
  50.454 -    /// manually clear the heap when it is important to achive the
  50.455 -    /// better time complexity.
  50.456 +    /// This function sets the state of the given item in the heap.
  50.457 +    /// It can be used to manually clear the heap when it is important
  50.458 +    /// to achive better time complexity.
  50.459      /// \param i The item.
  50.460      /// \param st The state. It should not be \c IN_HEAP.
  50.461      void state(const Item& i, State st) {
  50.462 @@ -319,24 +319,25 @@
  50.463          if (state(i) == IN_HEAP) {
  50.464            erase(i);
  50.465          }
  50.466 -        iim[i] = st;
  50.467 +        _iim[i] = st;
  50.468          break;
  50.469        case IN_HEAP:
  50.470          break;
  50.471        }
  50.472      }
  50.473  
  50.474 -    /// \brief Replaces an item in the heap.
  50.475 +    /// \brief Replace an item in the heap.
  50.476      ///
  50.477 -    /// The \c i item is replaced with \c j item. The \c i item should
  50.478 -    /// be in the heap, while the \c j should be out of the heap. The
  50.479 -    /// \c i item will out of the heap and \c j will be in the heap
  50.480 -    /// with the same prioriority as prevoiusly the \c i item.
  50.481 +    /// This function replaces item \c i with item \c j.
  50.482 +    /// Item \c i must be in the heap, while \c j must be out of the heap.
  50.483 +    /// After calling this method, item \c i will be out of the
  50.484 +    /// heap and \c j will be in the heap with the same prioriority
  50.485 +    /// as item \c i had before.
  50.486      void replace(const Item& i, const Item& j) {
  50.487 -      int idx = iim[i];
  50.488 -      iim.set(i, iim[j]);
  50.489 -      iim.set(j, idx);
  50.490 -      data[idx].first = j;
  50.491 +      int idx = _iim[i];
  50.492 +      _iim.set(i, _iim[j]);
  50.493 +      _iim.set(j, idx);
  50.494 +      _data[idx].first = j;
  50.495      }
  50.496  
  50.497    }; // class BinHeap
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/lemon/binom_heap.h	Thu Nov 05 15:50:01 2009 +0100
    51.3 @@ -0,0 +1,445 @@
    51.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    51.5 + *
    51.6 + * This file is a part of LEMON, a generic C++ optimization library.
    51.7 + *
    51.8 + * Copyright (C) 2003-2009
    51.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   51.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   51.11 + *
   51.12 + * Permission to use, modify and distribute this software is granted
   51.13 + * provided that this copyright notice appears in all copies. For
   51.14 + * precise terms see the accompanying LICENSE file.
   51.15 + *
   51.16 + * This software is provided "AS IS" with no warranty of any kind,
   51.17 + * express or implied, and with no claim as to its suitability for any
   51.18 + * purpose.
   51.19 + *
   51.20 + */
   51.21 +
   51.22 +#ifndef LEMON_BINOM_HEAP_H
   51.23 +#define LEMON_BINOM_HEAP_H
   51.24 +
   51.25 +///\file
   51.26 +///\ingroup heaps
   51.27 +///\brief Binomial Heap implementation.
   51.28 +
   51.29 +#include <vector>
   51.30 +#include <utility>
   51.31 +#include <functional>
   51.32 +#include <lemon/math.h>
   51.33 +#include <lemon/counter.h>
   51.34 +
   51.35 +namespace lemon {
   51.36 +
   51.37 +  /// \ingroup heaps
   51.38 +  ///
   51.39 +  ///\brief Binomial heap data structure.
   51.40 +  ///
   51.41 +  /// This class implements the \e binomial \e heap data structure.
   51.42 +  /// It fully conforms to the \ref concepts::Heap "heap concept".
   51.43 +  ///
   51.44 +  /// The methods \ref increase() and \ref erase() are not efficient
   51.45 +  /// in a binomial heap. In case of many calls of these operations,
   51.46 +  /// it is better to use other heap structure, e.g. \ref BinHeap
   51.47 +  /// "binary heap".
   51.48 +  ///
   51.49 +  /// \tparam PR Type of the priorities of the items.
   51.50 +  /// \tparam IM A read-writable item map with \c int values, used
   51.51 +  /// internally to handle the cross references.
   51.52 +  /// \tparam CMP A functor class for comparing the priorities.
   51.53 +  /// The default is \c std::less<PR>.
   51.54 +#ifdef DOXYGEN
   51.55 +  template <typename PR, typename IM, typename CMP>
   51.56 +#else
   51.57 +  template <typename PR, typename IM, typename CMP = std::less<PR> >
   51.58 +#endif
   51.59 +  class BinomHeap {
   51.60 +  public:
   51.61 +    /// Type of the item-int map.
   51.62 +    typedef IM ItemIntMap;
   51.63 +    /// Type of the priorities.
   51.64 +    typedef PR Prio;
   51.65 +    /// Type of the items stored in the heap.
   51.66 +    typedef typename ItemIntMap::Key Item;
   51.67 +    /// Functor type for comparing the priorities.
   51.68 +    typedef CMP Compare;
   51.69 +
   51.70 +    /// \brief Type to represent the states of the items.
   51.71 +    ///
   51.72 +    /// Each item has a state associated to it. It can be "in heap",
   51.73 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
   51.74 +    /// heap's point of view, but may be useful to the user.
   51.75 +    ///
   51.76 +    /// The item-int map must be initialized in such way that it assigns
   51.77 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
   51.78 +    enum State {
   51.79 +      IN_HEAP = 0,    ///< = 0.
   51.80 +      PRE_HEAP = -1,  ///< = -1.
   51.81 +      POST_HEAP = -2  ///< = -2.
   51.82 +    };
   51.83 +
   51.84 +  private:
   51.85 +    class Store;
   51.86 +
   51.87 +    std::vector<Store> _data;
   51.88 +    int _min, _head;
   51.89 +    ItemIntMap &_iim;
   51.90 +    Compare _comp;
   51.91 +    int _num_items;
   51.92 +
   51.93 +  public:
   51.94 +    /// \brief Constructor.
   51.95 +    ///
   51.96 +    /// Constructor.
   51.97 +    /// \param map A map that assigns \c int values to the items.
   51.98 +    /// It is used internally to handle the cross references.
   51.99 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  51.100 +    explicit BinomHeap(ItemIntMap &map)
  51.101 +      : _min(0), _head(-1), _iim(map), _num_items(0) {}
  51.102 +
  51.103 +    /// \brief Constructor.
  51.104 +    ///
  51.105 +    /// Constructor.
  51.106 +    /// \param map A map that assigns \c int values to the items.
  51.107 +    /// It is used internally to handle the cross references.
  51.108 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  51.109 +    /// \param comp The function object used for comparing the priorities.
  51.110 +    BinomHeap(ItemIntMap &map, const Compare &comp)
  51.111 +      : _min(0), _head(-1), _iim(map), _comp(comp), _num_items(0) {}
  51.112 +
  51.113 +    /// \brief The number of items stored in the heap.
  51.114 +    ///
  51.115 +    /// This function returns the number of items stored in the heap.
  51.116 +    int size() const { return _num_items; }
  51.117 +
  51.118 +    /// \brief Check if the heap is empty.
  51.119 +    ///
  51.120 +    /// This function returns \c true if the heap is empty.
  51.121 +    bool empty() const { return _num_items==0; }
  51.122 +
  51.123 +    /// \brief Make the heap empty.
  51.124 +    ///
  51.125 +    /// This functon makes the heap empty.
  51.126 +    /// It does not change the cross reference map. If you want to reuse
  51.127 +    /// a heap that is not surely empty, you should first clear it and
  51.128 +    /// then you should set the cross reference map to \c PRE_HEAP
  51.129 +    /// for each item.
  51.130 +    void clear() {
  51.131 +      _data.clear(); _min=0; _num_items=0; _head=-1;
  51.132 +    }
  51.133 +
  51.134 +    /// \brief Set the priority of an item or insert it, if it is
  51.135 +    /// not stored in the heap.
  51.136 +    ///
  51.137 +    /// This method sets the priority of the given item if it is
  51.138 +    /// already stored in the heap. Otherwise it inserts the given
  51.139 +    /// item into the heap with the given priority.
  51.140 +    /// \param item The item.
  51.141 +    /// \param value The priority.
  51.142 +    void set (const Item& item, const Prio& value) {
  51.143 +      int i=_iim[item];
  51.144 +      if ( i >= 0 && _data[i].in ) {
  51.145 +        if ( _comp(value, _data[i].prio) ) decrease(item, value);
  51.146 +        if ( _comp(_data[i].prio, value) ) increase(item, value);
  51.147 +      } else push(item, value);
  51.148 +    }
  51.149 +
  51.150 +    /// \brief Insert an item into the heap with the given priority.
  51.151 +    ///
  51.152 +    /// This function inserts the given item into the heap with the
  51.153 +    /// given priority.
  51.154 +    /// \param item The item to insert.
  51.155 +    /// \param value The priority of the item.
  51.156 +    /// \pre \e item must not be stored in the heap.
  51.157 +    void push (const Item& item, const Prio& value) {
  51.158 +      int i=_iim[item];
  51.159 +      if ( i<0 ) {
  51.160 +        int s=_data.size();
  51.161 +        _iim.set( item,s );
  51.162 +        Store st;
  51.163 +        st.name=item;
  51.164 +        st.prio=value;
  51.165 +        _data.push_back(st);
  51.166 +        i=s;
  51.167 +      }
  51.168 +      else {
  51.169 +        _data[i].parent=_data[i].right_neighbor=_data[i].child=-1;
  51.170 +        _data[i].degree=0;
  51.171 +        _data[i].in=true;
  51.172 +        _data[i].prio=value;
  51.173 +      }
  51.174 +
  51.175 +      if( 0==_num_items ) {
  51.176 +        _head=i;
  51.177 +        _min=i;
  51.178 +      } else {
  51.179 +        merge(i);
  51.180 +        if( _comp(_data[i].prio, _data[_min].prio) ) _min=i;
  51.181 +      }
  51.182 +      ++_num_items;
  51.183 +    }
  51.184 +
  51.185 +    /// \brief Return the item having minimum priority.
  51.186 +    ///
  51.187 +    /// This function returns the item having minimum priority.
  51.188 +    /// \pre The heap must be non-empty.
  51.189 +    Item top() const { return _data[_min].name; }
  51.190 +
  51.191 +    /// \brief The minimum priority.
  51.192 +    ///
  51.193 +    /// This function returns the minimum priority.
  51.194 +    /// \pre The heap must be non-empty.
  51.195 +    Prio prio() const { return _data[_min].prio; }
  51.196 +
  51.197 +    /// \brief The priority of the given item.
  51.198 +    ///
  51.199 +    /// This function returns the priority of the given item.
  51.200 +    /// \param item The item.
  51.201 +    /// \pre \e item must be in the heap.
  51.202 +    const Prio& operator[](const Item& item) const {
  51.203 +      return _data[_iim[item]].prio;
  51.204 +    }
  51.205 +
  51.206 +    /// \brief Remove the item having minimum priority.
  51.207 +    ///
  51.208 +    /// This function removes the item having minimum priority.
  51.209 +    /// \pre The heap must be non-empty.
  51.210 +    void pop() {
  51.211 +      _data[_min].in=false;
  51.212 +
  51.213 +      int head_child=-1;
  51.214 +      if ( _data[_min].child!=-1 ) {
  51.215 +        int child=_data[_min].child;
  51.216 +        int neighb;
  51.217 +        while( child!=-1 ) {
  51.218 +          neighb=_data[child].right_neighbor;
  51.219 +          _data[child].parent=-1;
  51.220 +          _data[child].right_neighbor=head_child;
  51.221 +          head_child=child;
  51.222 +          child=neighb;
  51.223 +        }
  51.224 +      }
  51.225 +
  51.226 +      if ( _data[_head].right_neighbor==-1 ) {
  51.227 +        // there was only one root
  51.228 +        _head=head_child;
  51.229 +      }
  51.230 +      else {
  51.231 +        // there were more roots
  51.232 +        if( _head!=_min )  { unlace(_min); }
  51.233 +        else { _head=_data[_head].right_neighbor; }
  51.234 +        merge(head_child);
  51.235 +      }
  51.236 +      _min=findMin();
  51.237 +      --_num_items;
  51.238 +    }
  51.239 +
  51.240 +    /// \brief Remove the given item from the heap.
  51.241 +    ///
  51.242 +    /// This function removes the given item from the heap if it is
  51.243 +    /// already stored.
  51.244 +    /// \param item The item to delete.
  51.245 +    /// \pre \e item must be in the heap.
  51.246 +    void erase (const Item& item) {
  51.247 +      int i=_iim[item];
  51.248 +      if ( i >= 0 && _data[i].in ) {
  51.249 +        decrease( item, _data[_min].prio-1 );
  51.250 +        pop();
  51.251 +      }
  51.252 +    }
  51.253 +
  51.254 +    /// \brief Decrease the priority of an item to the given value.
  51.255 +    ///
  51.256 +    /// This function decreases the priority of an item to the given value.
  51.257 +    /// \param item The item.
  51.258 +    /// \param value The priority.
  51.259 +    /// \pre \e item must be stored in the heap with priority at least \e value.
  51.260 +    void decrease (Item item, const Prio& value) {
  51.261 +      int i=_iim[item];
  51.262 +      int p=_data[i].parent;
  51.263 +      _data[i].prio=value;
  51.264 +      
  51.265 +      while( p!=-1 && _comp(value, _data[p].prio) ) {
  51.266 +        _data[i].name=_data[p].name;
  51.267 +        _data[i].prio=_data[p].prio;
  51.268 +        _data[p].name=item;
  51.269 +        _data[p].prio=value;
  51.270 +        _iim[_data[i].name]=i;
  51.271 +        i=p;
  51.272 +        p=_data[p].parent;
  51.273 +      }
  51.274 +      _iim[item]=i;
  51.275 +      if ( _comp(value, _data[_min].prio) ) _min=i;
  51.276 +    }
  51.277 +
  51.278 +    /// \brief Increase the priority of an item to the given value.
  51.279 +    ///
  51.280 +    /// This function increases the priority of an item to the given value.
  51.281 +    /// \param item The item.
  51.282 +    /// \param value The priority.
  51.283 +    /// \pre \e item must be stored in the heap with priority at most \e value.
  51.284 +    void increase (Item item, const Prio& value) {
  51.285 +      erase(item);
  51.286 +      push(item, value);
  51.287 +    }
  51.288 +
  51.289 +    /// \brief Return the state of an item.
  51.290 +    ///
  51.291 +    /// This method returns \c PRE_HEAP if the given item has never
  51.292 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  51.293 +    /// and \c POST_HEAP otherwise.
  51.294 +    /// In the latter case it is possible that the item will get back
  51.295 +    /// to the heap again.
  51.296 +    /// \param item The item.
  51.297 +    State state(const Item &item) const {
  51.298 +      int i=_iim[item];
  51.299 +      if( i>=0 ) {
  51.300 +        if ( _data[i].in ) i=0;
  51.301 +        else i=-2;
  51.302 +      }
  51.303 +      return State(i);
  51.304 +    }
  51.305 +
  51.306 +    /// \brief Set the state of an item in the heap.
  51.307 +    ///
  51.308 +    /// This function sets the state of the given item in the heap.
  51.309 +    /// It can be used to manually clear the heap when it is important
  51.310 +    /// to achive better time complexity.
  51.311 +    /// \param i The item.
  51.312 +    /// \param st The state. It should not be \c IN_HEAP.
  51.313 +    void state(const Item& i, State st) {
  51.314 +      switch (st) {
  51.315 +      case POST_HEAP:
  51.316 +      case PRE_HEAP:
  51.317 +        if (state(i) == IN_HEAP) {
  51.318 +          erase(i);
  51.319 +        }
  51.320 +        _iim[i] = st;
  51.321 +        break;
  51.322 +      case IN_HEAP:
  51.323 +        break;
  51.324 +      }
  51.325 +    }
  51.326 +
  51.327 +  private:
  51.328 +    
  51.329 +    // Find the minimum of the roots
  51.330 +    int findMin() {
  51.331 +      if( _head!=-1 ) {
  51.332 +        int min_loc=_head, min_val=_data[_head].prio;
  51.333 +        for( int x=_data[_head].right_neighbor; x!=-1;
  51.334 +             x=_data[x].right_neighbor ) {
  51.335 +          if( _comp( _data[x].prio,min_val ) ) {
  51.336 +            min_val=_data[x].prio;
  51.337 +            min_loc=x;
  51.338 +          }
  51.339 +        }
  51.340 +        return min_loc;
  51.341 +      }
  51.342 +      else return -1;
  51.343 +    }
  51.344 +
  51.345 +    // Merge the heap with another heap starting at the given position
  51.346 +    void merge(int a) {
  51.347 +      if( _head==-1 || a==-1 ) return;
  51.348 +      if( _data[a].right_neighbor==-1 &&
  51.349 +          _data[a].degree<=_data[_head].degree ) {
  51.350 +        _data[a].right_neighbor=_head;
  51.351 +        _head=a;
  51.352 +      } else {
  51.353 +        interleave(a);
  51.354 +      }
  51.355 +      if( _data[_head].right_neighbor==-1 ) return;
  51.356 +      
  51.357 +      int x=_head;
  51.358 +      int x_prev=-1, x_next=_data[x].right_neighbor;
  51.359 +      while( x_next!=-1 ) {
  51.360 +        if( _data[x].degree!=_data[x_next].degree ||
  51.361 +            ( _data[x_next].right_neighbor!=-1 &&
  51.362 +              _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
  51.363 +          x_prev=x;
  51.364 +          x=x_next;
  51.365 +        }
  51.366 +        else {
  51.367 +          if( _comp(_data[x_next].prio,_data[x].prio) ) {
  51.368 +            if( x_prev==-1 ) {
  51.369 +              _head=x_next;
  51.370 +            } else {
  51.371 +              _data[x_prev].right_neighbor=x_next;
  51.372 +            }
  51.373 +            fuse(x,x_next);
  51.374 +            x=x_next;
  51.375 +          }
  51.376 +          else {
  51.377 +            _data[x].right_neighbor=_data[x_next].right_neighbor;
  51.378 +            fuse(x_next,x);
  51.379 +          }
  51.380 +        }
  51.381 +        x_next=_data[x].right_neighbor;
  51.382 +      }
  51.383 +    }
  51.384 +
  51.385 +    // Interleave the elements of the given list into the list of the roots
  51.386 +    void interleave(int a) {
  51.387 +      int p=_head, q=a;
  51.388 +      int curr=_data.size();
  51.389 +      _data.push_back(Store());
  51.390 +      
  51.391 +      while( p!=-1 || q!=-1 ) {
  51.392 +        if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
  51.393 +          _data[curr].right_neighbor=p;
  51.394 +          curr=p;
  51.395 +          p=_data[p].right_neighbor;
  51.396 +        }
  51.397 +        else {
  51.398 +          _data[curr].right_neighbor=q;
  51.399 +          curr=q;
  51.400 +          q=_data[q].right_neighbor;
  51.401 +        }
  51.402 +      }
  51.403 +      
  51.404 +      _head=_data.back().right_neighbor;
  51.405 +      _data.pop_back();
  51.406 +    }
  51.407 +
  51.408 +    // Lace node a under node b
  51.409 +    void fuse(int a, int b) {
  51.410 +      _data[a].parent=b;
  51.411 +      _data[a].right_neighbor=_data[b].child;
  51.412 +      _data[b].child=a;
  51.413 +
  51.414 +      ++_data[b].degree;
  51.415 +    }
  51.416 +
  51.417 +    // Unlace node a (if it has siblings)
  51.418 +    void unlace(int a) {
  51.419 +      int neighb=_data[a].right_neighbor;
  51.420 +      int other=_head;
  51.421 +
  51.422 +      while( _data[other].right_neighbor!=a )
  51.423 +        other=_data[other].right_neighbor;
  51.424 +      _data[other].right_neighbor=neighb;
  51.425 +    }
  51.426 +
  51.427 +  private:
  51.428 +
  51.429 +    class Store {
  51.430 +      friend class BinomHeap;
  51.431 +
  51.432 +      Item name;
  51.433 +      int parent;
  51.434 +      int right_neighbor;
  51.435 +      int child;
  51.436 +      int degree;
  51.437 +      bool in;
  51.438 +      Prio prio;
  51.439 +
  51.440 +      Store() : parent(-1), right_neighbor(-1), child(-1), degree(0),
  51.441 +        in(true) {}
  51.442 +    };
  51.443 +  };
  51.444 +
  51.445 +} //namespace lemon
  51.446 +
  51.447 +#endif //LEMON_BINOM_HEAP_H
  51.448 +
    52.1 --- a/lemon/bits/alteration_notifier.h	Fri Oct 16 10:21:37 2009 +0200
    52.2 +++ b/lemon/bits/alteration_notifier.h	Thu Nov 05 15:50:01 2009 +0100
    52.3 @@ -2,7 +2,7 @@
    52.4   *
    52.5   * This file is a part of LEMON, a generic C++ optimization library.
    52.6   *
    52.7 - * Copyright (C) 2003-2008
    52.8 + * Copyright (C) 2003-2009
    52.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   52.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   52.11   *
   52.12 @@ -35,61 +35,62 @@
   52.13    // \brief Notifier class to notify observes about alterations in
   52.14    // a container.
   52.15    //
   52.16 -  // The simple graph's can be refered as two containers, one node container
   52.17 -  // and one edge container. But they are not standard containers they
   52.18 -  // does not store values directly they are just key continars for more
   52.19 -  // value containers which are the node and edge maps.
   52.20 +  // The simple graphs can be refered as two containers: a node container
   52.21 +  // and an edge container. But they do not store values directly, they
   52.22 +  // are just key continars for more value containers, which are the
   52.23 +  // node and edge maps.
   52.24    //
   52.25 -  // The graph's node and edge sets can be changed as we add or erase
   52.26 +  // The node and edge sets of the graphs can be changed as we add or erase
   52.27    // nodes and edges in the graph. LEMON would like to handle easily
   52.28    // that the node and edge maps should contain values for all nodes or
   52.29    // edges. If we want to check on every indicing if the map contains
   52.30    // the current indicing key that cause a drawback in the performance
   52.31 -  // in the library. We use another solution we notify all maps about
   52.32 +  // in the library. We use another solution: we notify all maps about
   52.33    // an alteration in the graph, which cause only drawback on the
   52.34    // alteration of the graph.
   52.35    //
   52.36 -  // This class provides an interface to the container. The \e first() and \e
   52.37 -  // next() member functions make possible to iterate on the keys of the
   52.38 -  // container. The \e id() function returns an integer id for each key.
   52.39 -  // The \e maxId() function gives back an upper bound of the ids.
   52.40 +  // This class provides an interface to a node or edge container.
   52.41 +  // The first() and next() member functions make possible
   52.42 +  // to iterate on the keys of the container.
   52.43 +  // The id() function returns an integer id for each key.
   52.44 +  // The maxId() function gives back an upper bound of the ids.
   52.45    //
   52.46    // For the proper functonality of this class, we should notify it
   52.47 -  // about each alteration in the container. The alterations have four type
   52.48 -  // as \e add(), \e erase(), \e build() and \e clear(). The \e add() and
   52.49 -  // \e erase() signals that only one or few items added or erased to or
   52.50 -  // from the graph. If all items are erased from the graph or from an empty
   52.51 -  // graph a new graph is builded then it can be signaled with the
   52.52 +  // about each alteration in the container. The alterations have four type:
   52.53 +  // add(), erase(), build() and clear(). The add() and
   52.54 +  // erase() signal that only one or few items added or erased to or
   52.55 +  // from the graph. If all items are erased from the graph or if a new graph
   52.56 +  // is built from an empty graph, then it can be signaled with the
   52.57    // clear() and build() members. Important rule that if we erase items
   52.58 -  // from graph we should first signal the alteration and after that erase
   52.59 +  // from graphs we should first signal the alteration and after that erase
   52.60    // them from the container, on the other way on item addition we should
   52.61    // first extend the container and just after that signal the alteration.
   52.62    //
   52.63    // The alteration can be observed with a class inherited from the
   52.64 -  // \e ObserverBase nested class. The signals can be handled with
   52.65 +  // ObserverBase nested class. The signals can be handled with
   52.66    // overriding the virtual functions defined in the base class.  The
   52.67    // observer base can be attached to the notifier with the
   52.68 -  // \e attach() member and can be detached with detach() function. The
   52.69 +  // attach() member and can be detached with detach() function. The
   52.70    // alteration handlers should not call any function which signals
   52.71    // an other alteration in the same notifier and should not
   52.72    // detach any observer from the notifier.
   52.73    //
   52.74 -  // Alteration observers try to be exception safe. If an \e add() or
   52.75 -  // a \e clear() function throws an exception then the remaining
   52.76 +  // Alteration observers try to be exception safe. If an add() or
   52.77 +  // a clear() function throws an exception then the remaining
   52.78    // observeres will not be notified and the fulfilled additions will
   52.79 -  // be rolled back by calling the \e erase() or \e clear()
   52.80 -  // functions. Thence the \e erase() and \e clear() should not throw
   52.81 -  // exception. Actullay, it can be throw only \ref ImmediateDetach
   52.82 -  // exception which detach the observer from the notifier.
   52.83 +  // be rolled back by calling the erase() or clear() functions.
   52.84 +  // Hence erase() and clear() should not throw exception.
   52.85 +  // Actullay, they can throw only \ref ImmediateDetach exception,
   52.86 +  // which detach the observer from the notifier.
   52.87    //
   52.88 -  // There are some place when the alteration observing is not completly
   52.89 +  // There are some cases, when the alteration observing is not completly
   52.90    // reliable. If we want to carry out the node degree in the graph
   52.91 -  // as in the \ref InDegMap and we use the reverseEdge that cause
   52.92 +  // as in the \ref InDegMap and we use the reverseArc(), then it cause
   52.93    // unreliable functionality. Because the alteration observing signals
   52.94 -  // only erasing and adding but not the reversing it will stores bad
   52.95 -  // degrees. The sub graph adaptors cannot signal the alterations because
   52.96 -  // just a setting in the filter map can modify the graph and this cannot
   52.97 -  // be watched in any way.
   52.98 +  // only erasing and adding but not the reversing, it will stores bad
   52.99 +  // degrees. Apart form that the subgraph adaptors cannot even signal
  52.100 +  // the alterations because just a setting in the filter map can modify
  52.101 +  // the graph and this cannot be watched in any way.
  52.102    //
  52.103    // \param _Container The container which is observed.
  52.104    // \param _Item The item type which is obserbved.
  52.105 @@ -103,13 +104,13 @@
  52.106      typedef _Container Container;
  52.107      typedef _Item Item;
  52.108  
  52.109 -    // \brief Exception which can be called from \e clear() and
  52.110 -    // \e erase().
  52.111 +    // \brief Exception which can be called from clear() and
  52.112 +    // erase().
  52.113      //
  52.114 -    // From the \e clear() and \e erase() function only this
  52.115 +    // From the clear() and erase() function only this
  52.116      // exception is allowed to throw. The exception immediatly
  52.117      // detaches the current observer from the notifier. Because the
  52.118 -    // \e clear() and \e erase() should not throw other exceptions
  52.119 +    // clear() and erase() should not throw other exceptions
  52.120      // it can be used to invalidate the observer.
  52.121      struct ImmediateDetach {};
  52.122  
  52.123 @@ -121,8 +122,7 @@
  52.124      //
  52.125      // The observer interface contains some pure virtual functions
  52.126      // to override. The add() and erase() functions are
  52.127 -    // to notify the oberver when one item is added or
  52.128 -    // erased.
  52.129 +    // to notify the oberver when one item is added or erased.
  52.130      //
  52.131      // The build() and clear() members are to notify the observer
  52.132      // about the container is built from an empty container or
    53.1 --- a/lemon/bits/array_map.h	Fri Oct 16 10:21:37 2009 +0200
    53.2 +++ b/lemon/bits/array_map.h	Thu Nov 05 15:50:01 2009 +0100
    53.3 @@ -2,7 +2,7 @@
    53.4   *
    53.5   * This file is a part of LEMON, a generic C++ optimization library.
    53.6   *
    53.7 - * Copyright (C) 2003-2008
    53.8 + * Copyright (C) 2003-2009
    53.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   53.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   53.11   *
   53.12 @@ -36,25 +36,24 @@
   53.13    //
   53.14    // \brief Graph map based on the array storage.
   53.15    //
   53.16 -  // The ArrayMap template class is graph map structure what
   53.17 -  // automatically updates the map when a key is added to or erased from
   53.18 -  // the map. This map uses the allocators to implement
   53.19 -  // the container functionality.
   53.20 +  // The ArrayMap template class is graph map structure that automatically
   53.21 +  // updates the map when a key is added to or erased from the graph.
   53.22 +  // This map uses the allocators to implement the container functionality.
   53.23    //
   53.24 -  // The template parameters are the Graph the current Item type and
   53.25 +  // The template parameters are the Graph, the current Item type and
   53.26    // the Value type of the map.
   53.27    template <typename _Graph, typename _Item, typename _Value>
   53.28    class ArrayMap
   53.29      : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
   53.30    public:
   53.31 -    // The graph type of the maps.
   53.32 -    typedef _Graph Graph;
   53.33 -    // The item type of the map.
   53.34 +    // The graph type.
   53.35 +    typedef _Graph GraphType;
   53.36 +    // The item type.
   53.37      typedef _Item Item;
   53.38      // The reference map tag.
   53.39      typedef True ReferenceMapTag;
   53.40  
   53.41 -    // The key type of the maps.
   53.42 +    // The key type of the map.
   53.43      typedef _Item Key;
   53.44      // The value type of the map.
   53.45      typedef _Value Value;
   53.46 @@ -64,13 +63,17 @@
   53.47      // The reference type of the map.
   53.48      typedef _Value& Reference;
   53.49  
   53.50 +    // The map type.
   53.51 +    typedef ArrayMap Map;
   53.52 +
   53.53      // The notifier type.
   53.54      typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
   53.55  
   53.56 +  private:
   53.57 +  
   53.58      // The MapBase of the Map which imlements the core regisitry function.
   53.59      typedef typename Notifier::ObserverBase Parent;
   53.60  
   53.61 -  private:
   53.62      typedef std::allocator<Value> Allocator;
   53.63  
   53.64    public:
   53.65 @@ -78,7 +81,7 @@
   53.66      // \brief Graph initialized map constructor.
   53.67      //
   53.68      // Graph initialized map constructor.
   53.69 -    explicit ArrayMap(const Graph& graph) {
   53.70 +    explicit ArrayMap(const GraphType& graph) {
   53.71        Parent::attach(graph.notifier(Item()));
   53.72        allocate_memory();
   53.73        Notifier* nf = Parent::notifier();
   53.74 @@ -92,7 +95,7 @@
   53.75      // \brief Constructor to use default value to initialize the map.
   53.76      //
   53.77      // It constructs a map and initialize all of the the map.
   53.78 -    ArrayMap(const Graph& graph, const Value& value) {
   53.79 +    ArrayMap(const GraphType& graph, const Value& value) {
   53.80        Parent::attach(graph.notifier(Item()));
   53.81        allocate_memory();
   53.82        Notifier* nf = Parent::notifier();
   53.83 @@ -136,7 +139,7 @@
   53.84  
   53.85      // \brief Template assign operator.
   53.86      //
   53.87 -    // The given parameter should be conform to the ReadMap
   53.88 +    // The given parameter should conform to the ReadMap
   53.89      // concecpt and could be indiced by the current item set of
   53.90      // the NodeMap. In this case the value for each item
   53.91      // is assigned by the value of the given ReadMap.
   53.92 @@ -200,7 +203,7 @@
   53.93  
   53.94      // \brief Adds a new key to the map.
   53.95      //
   53.96 -    // It adds a new key to the map. It called by the observer notifier
   53.97 +    // It adds a new key to the map. It is called by the observer notifier
   53.98      // and it overrides the add() member function of the observer base.
   53.99      virtual void add(const Key& key) {
  53.100        Notifier* nf = Parent::notifier();
  53.101 @@ -228,7 +231,7 @@
  53.102  
  53.103      // \brief Adds more new keys to the map.
  53.104      //
  53.105 -    // It adds more new keys to the map. It called by the observer notifier
  53.106 +    // It adds more new keys to the map. It is called by the observer notifier
  53.107      // and it overrides the add() member function of the observer base.
  53.108      virtual void add(const std::vector<Key>& keys) {
  53.109        Notifier* nf = Parent::notifier();
  53.110 @@ -272,7 +275,7 @@
  53.111  
  53.112      // \brief Erase a key from the map.
  53.113      //
  53.114 -    // Erase a key from the map. It called by the observer notifier
  53.115 +    // Erase a key from the map. It is called by the observer notifier
  53.116      // and it overrides the erase() member function of the observer base.
  53.117      virtual void erase(const Key& key) {
  53.118        int id = Parent::notifier()->id(key);
  53.119 @@ -281,7 +284,7 @@
  53.120  
  53.121      // \brief Erase more keys from the map.
  53.122      //
  53.123 -    // Erase more keys from the map. It called by the observer notifier
  53.124 +    // Erase more keys from the map. It is called by the observer notifier
  53.125      // and it overrides the erase() member function of the observer base.
  53.126      virtual void erase(const std::vector<Key>& keys) {
  53.127        for (int i = 0; i < int(keys.size()); ++i) {
  53.128 @@ -290,9 +293,9 @@
  53.129        }
  53.130      }
  53.131  
  53.132 -    // \brief Buildes the map.
  53.133 +    // \brief Builds the map.
  53.134      //
  53.135 -    // It buildes the map. It called by the observer notifier
  53.136 +    // It builds the map. It is called by the observer notifier
  53.137      // and it overrides the build() member function of the observer base.
  53.138      virtual void build() {
  53.139        Notifier* nf = Parent::notifier();
  53.140 @@ -306,7 +309,7 @@
  53.141  
  53.142      // \brief Clear the map.
  53.143      //
  53.144 -    // It erase all items from the map. It called by the observer notifier
  53.145 +    // It erase all items from the map. It is called by the observer notifier
  53.146      // and it overrides the clear() member function of the observer base.
  53.147      virtual void clear() {
  53.148        Notifier* nf = Parent::notifier();
    54.1 --- a/lemon/bits/base_extender.h	Fri Oct 16 10:21:37 2009 +0200
    54.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.3 @@ -1,494 +0,0 @@
    54.4 -/* -*- mode: C++; indent-tabs-mode: nil; -*-
    54.5 - *
    54.6 - * This file is a part of LEMON, a generic C++ optimization library.
    54.7 - *
    54.8 - * Copyright (C) 2003-2008
    54.9 - * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   54.10 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
   54.11 - *
   54.12 - * Permission to use, modify and distribute this software is granted
   54.13 - * provided that this copyright notice appears in all copies. For
   54.14 - * precise terms see the accompanying LICENSE file.
   54.15 - *
   54.16 - * This software is provided "AS IS" with no warranty of any kind,
   54.17 - * express or implied, and with no claim as to its suitability for any
   54.18 - * purpose.
   54.19 - *
   54.20 - */
   54.21 -
   54.22 -#ifndef LEMON_BITS_BASE_EXTENDER_H
   54.23 -#define LEMON_BITS_BASE_EXTENDER_H
   54.24 -
   54.25 -#include <lemon/core.h>
   54.26 -#include <lemon/error.h>
   54.27 -
   54.28 -#include <lemon/bits/map_extender.h>
   54.29 -#include <lemon/bits/default_map.h>
   54.30 -
   54.31 -#include <lemon/concept_check.h>
   54.32 -#include <lemon/concepts/maps.h>
   54.33 -
   54.34 -//\ingroup digraphbits
   54.35 -//\file
   54.36 -//\brief Extenders for the digraph types
   54.37 -namespace lemon {
   54.38 -
   54.39 -  // \ingroup digraphbits
   54.40 -  //
   54.41 -  // \brief BaseDigraph to BaseGraph extender
   54.42 -  template <typename Base>
   54.43 -  class UndirDigraphExtender : public Base {
   54.44 -
   54.45 -  public:
   54.46 -
   54.47 -    typedef Base Parent;
   54.48 -    typedef typename Parent::Arc Edge;
   54.49 -    typedef typename Parent::Node Node;
   54.50 -
   54.51 -    typedef True UndirectedTag;
   54.52 -
   54.53 -    class Arc : public Edge {
   54.54 -      friend class UndirDigraphExtender;
   54.55 -
   54.56 -    protected:
   54.57 -      bool forward;
   54.58 -
   54.59 -      Arc(const Edge &ue, bool _forward) :
   54.60 -        Edge(ue), forward(_forward) {}
   54.61 -
   54.62 -    public:
   54.63 -      Arc() {}
   54.64 -
   54.65 -      // Invalid arc constructor
   54.66 -      Arc(Invalid i) : Edge(i), forward(true) {}
   54.67 -
   54.68 -      bool operator==(const Arc &that) const {
   54.69 -        return forward==that.forward && Edge(*this)==Edge(that);
   54.70 -      }
   54.71 -      bool operator!=(const Arc &that) const {
   54.72 -        return forward!=that.forward || Edge(*this)!=Edge(that);
   54.73 -      }
   54.74 -      bool operator<(const Arc &that) const {
   54.75 -        return forward<that.forward ||
   54.76 -          (!(that.forward<forward) && Edge(*this)<Edge(that));
   54.77 -      }
   54.78 -    };
   54.79 -
   54.80 -    // First node of the edge
   54.81 -    Node u(const Edge &e) const {
   54.82 -      return Parent::source(e);
   54.83 -    }
   54.84 -
   54.85 -    // Source of the given arc
   54.86 -    Node source(const Arc &e) const {
   54.87 -      return e.forward ? Parent::source(e) : Parent::target(e);
   54.88 -    }
   54.89 -
   54.90 -    // Second node of the edge
   54.91 -    Node v(const Edge &e) const {
   54.92 -      return Parent::target(e);
   54.93 -    }
   54.94 -
   54.95 -    // Target of the given arc
   54.96 -    Node target(const Arc &e) const {
   54.97 -      return e.forward ? Parent::target(e) : Parent::source(e);
   54.98 -    }
   54.99 -
  54.100 -    // \brief Directed arc from an edge.
  54.101 -    //
  54.102 -    // Returns a directed arc corresponding to the specified edge.
  54.103 -    // If the given bool is true, the first node of the given edge and
  54.104 -    // the source node of the returned arc are the same.
  54.105 -    static Arc direct(const Edge &e, bool d) {
  54.106 -      return Arc(e, d);
  54.107 -    }
  54.108 -
  54.109 -    // Returns whether the given directed arc has the same orientation
  54.110 -    // as the corresponding edge.
  54.111 -    static bool direction(const Arc &a) { return a.forward; }
  54.112 -
  54.113 -    using Parent::first;
  54.114 -    using Parent::next;
  54.115 -
  54.116 -    void first(Arc &e) const {
  54.117 -      Parent::first(e);
  54.118 -      e.forward=true;
  54.119 -    }
  54.120 -
  54.121 -    void next(Arc &e) const {
  54.122 -      if( e.forward ) {
  54.123 -        e.forward = false;
  54.124 -      }
  54.125 -      else {
  54.126 -        Parent::next(e);
  54.127 -        e.forward = true;
  54.128 -      }
  54.129 -    }
  54.130 -
  54.131 -    void firstOut(Arc &e, const Node &n) const {
  54.132 -      Parent::firstIn(e,n);
  54.133 -      if( Edge(e) != INVALID ) {
  54.134 -        e.forward = false;
  54.135 -      }
  54.136 -      else {
  54.137 -        Parent::firstOut(e,n);
  54.138 -        e.forward = true;
  54.139 -      }
  54.140 -    }
  54.141 -    void nextOut(Arc &e) const {
  54.142 -      if( ! e.forward ) {
  54.143 -        Node n = Parent::target(e);
  54.144 -        Parent::nextIn(e);
  54.145 -        if( Edge(e) == INVALID ) {
  54.146 -          Parent::firstOut(e, n);
  54.147 -          e.forward = true;
  54.148 -        }
  54.149 -      }
  54.150 -      else {
  54.151 -        Parent::nextOut(e);
  54.152 -      }
  54.153 -    }
  54.154 -
  54.155 -    void firstIn(Arc &e, const Node &n) const {
  54.156 -      Parent::firstOut(e,n);
  54.157 -      if( Edge(e) != INVALID ) {
  54.158 -        e.forward = false;
  54.159 -      }
  54.160 -      else {
  54.161 -        Parent::firstIn(e,n);
  54.162 -        e.forward = true;
  54.163 -      }
  54.164 -    }
  54.165 -    void nextIn(Arc &e) const {
  54.166 -      if( ! e.forward ) {
  54.167 -        Node n = Parent::source(e);
  54.168 -        Parent::nextOut(e);
  54.169 -        if( Edge(e) == INVALID ) {
  54.170 -          Parent::firstIn(e, n);
  54.171 -          e.forward = true;
  54.172 -        }
  54.173 -      }
  54.174 -      else {
  54.175 -        Parent::nextIn(e);
  54.176 -      }
  54.177 -    }
  54.178 -
  54.179 -    void firstInc(Edge &e, bool &d, const Node &n) const {
  54.180 -      d = true;
  54.181 -      Parent::firstOut(e, n);
  54.182 -      if (e != INVALID) return;
  54.183 -      d = false;
  54.184 -      Parent::firstIn(e, n);
  54.185 -    }
  54.186 -
  54.187 -    void nextInc(Edge &e, bool &d) const {
  54.188 -      if (d) {
  54.189 -        Node s = Parent::source(e);
  54.190 -        Parent::nextOut(e);
  54.191 -        if (e != INVALID) return;
  54.192 -        d = false;
  54.193 -        Parent::firstIn(e, s);
  54.194 -      } else {
  54.195 -        Parent::nextIn(e);
  54.196 -      }
  54.197 -    }
  54.198 -
  54.199 -    Node nodeFromId(int ix) const {
  54.200 -      return Parent::nodeFromId(ix);
  54.201 -    }
  54.202 -
  54.203 -    Arc arcFromId(int ix) const {
  54.204 -      return direct(Parent::arcFromId(ix >> 1), bool(ix & 1));
  54.205 -    }
  54.206 -
  54.207 -    Edge edgeFromId(int ix) const {
  54.208 -      return Parent::arcFromId(ix);
  54.209 -    }
  54.210 -
  54.211 -    int id(const Node &n) const {
  54.212 -      return Parent::id(n);
  54.213 -    }
  54.214 -
  54.215 -    int id(const Edge &e) const {
  54.216 -      return Parent::id(e);
  54.217 -    }
  54.218 -
  54.219 -    int id(const Arc &e) const {
  54.220 -      return 2 * Parent::id(e) + int(e.forward);
  54.221 -    }
  54.222 -
  54.223 -    int maxNodeId() const {
  54.224 -      return Parent::maxNodeId();
  54.225 -    }
  54.226 -
  54.227 -    int maxArcId() const {
  54.228 -      return 2 * Parent::maxArcId() + 1;
  54.229 -    }
  54.230 -
  54.231 -    int maxEdgeId() const {
  54.232 -      return Parent::maxArcId();
  54.233 -    }
  54.234 -
  54.235 -    int arcNum() const {
  54.236 -      return 2 * Parent::arcNum();
  54.237 -    }
  54.238 -
  54.239 -    int edgeNum() const {
  54.240 -      return Parent::arcNum();
  54.241 -    }
  54.242 -
  54.243 -    Arc findArc(Node s, Node t, Arc p = INVALID) const {
  54.244 -      if (p == INVALID) {
  54.245 -        Edge arc = Parent::findArc(s, t);
  54.246 -        if (arc != INVALID) return direct(arc, true);
  54.247 -        arc = Parent::findArc(t, s);
  54.248 -        if (arc != INVALID) return direct(arc, false);
  54.249 -      } else if (direction(p)) {
  54.250 -        Edge arc = Parent::findArc(s, t, p);
  54.251 -        if (arc != INVALID) return direct(arc, true);
  54.252 -        arc = Parent::findArc(t, s);
  54.253 -        if (arc != INVALID) return direct(arc, false);
  54.254 -      } else {
  54.255 -        Edge arc = Parent::findArc(t, s, p);
  54.256 -        if (arc != INVALID) return direct(arc, false);
  54.257 -      }
  54.258 -      return INVALID;
  54.259 -    }
  54.260 -
  54.261 -    Edge findEdge(Node s, Node t, Edge p = INVALID) const {
  54.262 -      if (s != t) {
  54.263 -        if (p == INVALID) {
  54.264 -          Edge arc = Parent::findArc(s, t);
  54.265 -          if (arc != INVALID) return arc;
  54.266 -          arc = Parent::findArc(t, s);
  54.267 -          if (arc != INVALID) return arc;
  54.268 -        } else if (Parent::s(p) == s) {
  54.269 -          Edge arc = Parent::findArc(s, t, p);
  54.270 -          if (arc != INVALID) return arc;
  54.271 -          arc = Parent::findArc(t, s);
  54.272 -          if (arc != INVALID) return arc;
  54.273 -        } else {
  54.274 -          Edge arc = Parent::findArc(t, s, p);
  54.275 -          if (arc != INVALID) return arc;
  54.276 -        }
  54.277 -      } else {
  54.278 -        return Parent::findArc(s, t, p);
  54.279 -      }
  54.280 -      return INVALID;
  54.281 -    }
  54.282 -  };
  54.283 -
  54.284 -  template <typename Base>
  54.285 -  class BidirBpGraphExtender : public Base {
  54.286 -  public:
  54.287 -    typedef Base Parent;
  54.288 -    typedef BidirBpGraphExtender Digraph;
  54.289 -
  54.290 -    typedef typename Parent::Node Node;
  54.291 -    typedef typename Parent::Edge Edge;
  54.292 -
  54.293 -
  54.294 -    using Parent::first;
  54.295 -    using Parent::next;
  54.296 -
  54.297 -    using Parent::id;
  54.298 -
  54.299 -    class Red : public Node {
  54.300 -      friend class BidirBpGraphExtender;
  54.301 -    public:
  54.302 -      Red() {}
  54.303 -      Red(const Node& node) : Node(node) {
  54.304 -        LEMON_DEBUG(Parent::red(node) || node == INVALID,
  54.305 -                    typename Parent::NodeSetError());
  54.306 -      }
  54.307 -      Red& operator=(const Node& node) {
  54.308 -        LEMON_DEBUG(Parent::red(node) || node == INVALID,
  54.309 -                    typename Parent::NodeSetError());
  54.310 -        Node::operator=(node);
  54.311 -        return *this;
  54.312 -      }
  54.313 -      Red(Invalid) : Node(INVALID) {}
  54.314 -      Red& operator=(Invalid) {
  54.315 -        Node::operator=(INVALID);
  54.316 -        return *this;
  54.317 -      }
  54.318 -    };
  54.319 -
  54.320 -    void first(Red& node) const {
  54.321 -      Parent::firstRed(static_cast<Node&>(node));
  54.322 -    }
  54.323 -    void next(Red& node) const {
  54.324 -      Parent::nextRed(static_cast<Node&>(node));
  54.325 -    }
  54.326 -
  54.327 -    int id(const Red& node) const {
  54.328 -      return Parent::redId(node);
  54.329 -    }
  54.330 -
  54.331 -    class Blue : public Node {
  54.332 -      friend class BidirBpGraphExtender;
  54.333 -    public:
  54.334 -      Blue() {}
  54.335 -      Blue(const Node& node) : Node(node) {
  54.336 -        LEMON_DEBUG(Parent::blue(node) || node == INVALID,
  54.337 -                    typename Parent::NodeSetError());
  54.338 -      }
  54.339 -      Blue& operator=(const Node& node) {
  54.340 -        LEMON_DEBUG(Parent::blue(node) || node == INVALID,
  54.341 -                    typename Parent::NodeSetError());
  54.342 -        Node::operator=(node);
  54.343 -        return *this;
  54.344 -      }
  54.345 -      Blue(Invalid) : Node(INVALID) {}
  54.346 -      Blue& operator=(Invalid) {
  54.347 -        Node::operator=(INVALID);
  54.348 -        return *this;
  54.349 -      }
  54.350 -    };
  54.351 -
  54.352 -    void first(Blue& node) const {
  54.353 -      Parent::firstBlue(static_cast<Node&>(node));
  54.354 -    }
  54.355 -    void next(Blue& node) const {
  54.356 -      Parent::nextBlue(static_cast<Node&>(node));
  54.357 -    }
  54.358 -
  54.359 -    int id(const Blue& node) const {
  54.360 -      return Parent::redId(node);
  54.361 -    }
  54.362 -
  54.363 -    Node source(const Edge& arc) const {
  54.364 -      return red(arc);
  54.365 -    }
  54.366 -    Node target(const Edge& arc) const {
  54.367 -      return blue(arc);
  54.368 -    }
  54.369 -
  54.370 -    void firstInc(Edge& arc, bool& dir, const Node& node) const {
  54.371 -      if (Parent::red(node)) {
  54.372 -        Parent::firstFromRed(arc, node);
  54.373 -        dir = true;
  54.374 -      } else {
  54.375 -        Parent::firstFromBlue(arc, node);
  54.376 -        dir = static_cast<Edge&>(arc) == INVALID;
  54.377 -      }
  54.378 -    }
  54.379 -    void nextInc(Edge& arc, bool& dir) const {
  54.380 -      if (dir) {
  54.381 -        Parent::nextFromRed(arc);
  54.382 -      } else {
  54.383 -        Parent::nextFromBlue(arc);
  54.384 -        if (arc == INVALID) dir = true;
  54.385 -      }
  54.386 -    }
  54.387 -
  54.388 -    class Arc : public Edge {
  54.389 -      friend class BidirBpGraphExtender;
  54.390 -    protected:
  54.391 -      bool forward;
  54.392 -
  54.393 -      Arc(const Edge& arc, bool _forward)
  54.394 -        : Edge(arc), forward(_forward) {}
  54.395 -
  54.396 -    public:
  54.397 -      Arc() {}
  54.398 -      Arc (Invalid) : Edge(INVALID), forward(true) {}
  54.399 -      bool operator==(const Arc& i) const {
  54.400 -        return Edge::operator==(i) && forward == i.forward;
  54.401 -      }
  54.402 -      bool operator!=(const Arc& i) const {
  54.403 -        return Edge::operator!=(i) || forward != i.forward;
  54.404 -      }
  54.405 -      bool operator<(const Arc& i) const {
  54.406 -        return Edge::operator<(i) ||
  54.407 -          (!(i.forward<forward) && Edge(*this)<Edge(i));
  54.408 -      }
  54.409 -    };
  54.410 -
  54.411 -    void first(Arc& arc) const {
  54.412 -      Parent::first(static_cast<Edge&>(arc));
  54.413 -      arc.forward = true;
  54.414 -    }
  54.415 -
  54.416 -    void next(Arc& arc) const {
  54.417 -      if (!arc.forward) {
  54.418 -        Parent::next(static_cast<Edge&>(arc));
  54.419 -      }
  54.420 -      arc.forward = !arc.forward;
  54.421 -    }
  54.422 -
  54.423 -    void firstOut(Arc& arc, const Node& node) const {
  54.424 -      if (Parent::red(node)) {
  54.425 -        Parent::firstFromRed(arc, node);
  54.426 -        arc.forward = true;
  54.427 -      } else {
  54.428 -        Parent::firstFromBlue(arc, node);
  54.429 -        arc.forward = static_cast<Edge&>(arc) == INVALID;
  54.430 -      }
  54.431 -    }
  54.432 -    void nextOut(Arc& arc) const {
  54.433 -      if (arc.forward) {
  54.434 -        Parent::nextFromRed(arc);
  54.435 -      } else {
  54.436 -        Parent::nextFromBlue(arc);
  54.437 -        arc.forward = static_cast<Edge&>(arc) == INVALID;
  54.438 -      }
  54.439 -    }
  54.440 -
  54.441 -    void firstIn(Arc& arc, const Node& node) const {
  54.442 -      if (Parent::blue(node)) {
  54.443 -        Parent::firstFromBlue(arc, node);
  54.444 -        arc.forward = true;
  54.445 -      } else {
  54.446 -        Parent::firstFromRed(arc, node);
  54.447 -        arc.forward = static_cast<Edge&>(arc) == INVALID;
  54.448 -      }
  54.449 -    }
  54.450 -    void nextIn(Arc& arc) const {
  54.451 -      if (arc.forward) {
  54.452 -        Parent::nextFromBlue(arc);
  54.453 -      } else {
  54.454 -        Parent::nextFromRed(arc);
  54.455 -        arc.forward = static_cast<Edge&>(arc) == INVALID;
  54.456 -      }
  54.457 -    }
  54.458 -
  54.459 -    Node source(const Arc& arc) const {
  54.460 -      return arc.forward ? Parent::red(arc) : Parent::blue(arc);
  54.461 -    }
  54.462 -    Node target(const Arc& arc) const {
  54.463 -      return arc.forward ? Parent::blue(arc) : Parent::red(arc);
  54.464 -    }
  54.465 -
  54.466 -    int id(const Arc& arc) const {
  54.467 -      return (Parent::id(static_cast<const Edge&>(arc)) << 1) +
  54.468 -        (arc.forward ? 0 : 1);
  54.469 -    }
  54.470 -    Arc arcFromId(int ix) const {
  54.471 -      return Arc(Parent::fromEdgeId(ix >> 1), (ix & 1) == 0);
  54.472 -    }
  54.473 -    int maxArcId() const {
  54.474 -      return (Parent::maxEdgeId() << 1) + 1;
  54.475 -    }
  54.476 -
  54.477 -    bool direction(const Arc& arc) const {
  54.478 -      return arc.forward;
  54.479 -    }
  54.480 -
  54.481 -    Arc direct(const Edge& arc, bool dir) const {
  54.482 -      return Arc(arc, dir);
  54.483 -    }
  54.484 -
  54.485 -    int arcNum() const {
  54.486 -      return 2 * Parent::edgeNum();
  54.487 -    }
  54.488 -
  54.489 -    int edgeNum() const {
  54.490 -      return Parent::edgeNum();
  54.491 -    }
  54.492 -
  54.493 -
  54.494 -  };
  54.495 -}
  54.496 -
  54.497 -#endif
    55.1 --- a/lemon/bits/bezier.h	Fri Oct 16 10:21:37 2009 +0200
    55.2 +++ b/lemon/bits/bezier.h	Thu Nov 05 15:50:01 2009 +0100
    55.3 @@ -2,7 +2,7 @@
    55.4   *
    55.5   * This file is a part of LEMON, a generic C++ optimization library.
    55.6   *
    55.7 - * Copyright (C) 2003-2008
    55.8 + * Copyright (C) 2003-2009
    55.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   55.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   55.11   *
    56.1 --- a/lemon/bits/default_map.h	Fri Oct 16 10:21:37 2009 +0200
    56.2 +++ b/lemon/bits/default_map.h	Thu Nov 05 15:50:01 2009 +0100
    56.3 @@ -2,7 +2,7 @@
    56.4   *
    56.5   * This file is a part of LEMON, a generic C++ optimization library.
    56.6   *
    56.7 - * Copyright (C) 2003-2008
    56.8 + * Copyright (C) 2003-2009
    56.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   56.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   56.11   *
   56.12 @@ -153,15 +153,16 @@
   56.13    template <typename _Graph, typename _Item, typename _Value>
   56.14    class DefaultMap
   56.15      : public DefaultMapSelector<_Graph, _Item, _Value>::Map {
   56.16 +    typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
   56.17 +
   56.18    public:
   56.19 -    typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
   56.20      typedef DefaultMap<_Graph, _Item, _Value> Map;
   56.21 -
   56.22 -    typedef typename Parent::Graph Graph;
   56.23 +    
   56.24 +    typedef typename Parent::GraphType GraphType;
   56.25      typedef typename Parent::Value Value;
   56.26  
   56.27 -    explicit DefaultMap(const Graph& graph) : Parent(graph) {}
   56.28 -    DefaultMap(const Graph& graph, const Value& value)
   56.29 +    explicit DefaultMap(const GraphType& graph) : Parent(graph) {}
   56.30 +    DefaultMap(const GraphType& graph, const Value& value)
   56.31        : Parent(graph, value) {}
   56.32  
   56.33      DefaultMap& operator=(const DefaultMap& cmap) {
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/lemon/bits/edge_set_extender.h	Thu Nov 05 15:50:01 2009 +0100
    57.3 @@ -0,0 +1,625 @@
    57.4 +/* -*- C++ -*-
    57.5 + *
    57.6 + * This file is a part of LEMON, a generic C++ optimization library
    57.7 + *
    57.8 + * Copyright (C) 2003-2008
    57.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   57.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   57.11 + *
   57.12 + * Permission to use, modify and distribute this software is granted
   57.13 + * provided that this copyright notice appears in all copies. For
   57.14 + * precise terms see the accompanying LICENSE file.
   57.15 + *
   57.16 + * This software is provided "AS IS" with no warranty of any kind,
   57.17 + * express or implied, and with no claim as to its suitability for any
   57.18 + * purpose.
   57.19 + *
   57.20 + */
   57.21 +
   57.22 +#ifndef LEMON_BITS_EDGE_SET_EXTENDER_H
   57.23 +#define LEMON_BITS_EDGE_SET_EXTENDER_H
   57.24 +
   57.25 +#include <lemon/core.h>
   57.26 +#include <lemon/error.h>
   57.27 +#include <lemon/bits/default_map.h>
   57.28 +#include <lemon/bits/map_extender.h>
   57.29 +
   57.30 +//\ingroup digraphbits
   57.31 +//\file
   57.32 +//\brief Extenders for the arc set types
   57.33 +namespace lemon {
   57.34 +
   57.35 +  // \ingroup digraphbits
   57.36 +  //
   57.37 +  // \brief Extender for the ArcSets
   57.38 +  template <typename Base>
   57.39 +  class ArcSetExtender : public Base {
   57.40 +    typedef Base Parent;
   57.41 +
   57.42 +  public:
   57.43 +
   57.44 +    typedef ArcSetExtender Digraph;
   57.45 +
   57.46 +    // Base extensions
   57.47 +
   57.48 +    typedef typename Parent::Node Node;
   57.49 +    typedef typename Parent::Arc Arc;
   57.50 +
   57.51 +    int maxId(Node) const {
   57.52 +      return Parent::maxNodeId();
   57.53 +    }
   57.54 +
   57.55 +    int maxId(Arc) const {
   57.56 +      return Parent::maxArcId();
   57.57 +    }
   57.58 +
   57.59 +    Node fromId(int id, Node) const {
   57.60 +      return Parent::nodeFromId(id);
   57.61 +    }
   57.62 +
   57.63 +    Arc fromId(int id, Arc) const {
   57.64 +      return Parent::arcFromId(id);
   57.65 +    }
   57.66 +
   57.67 +    Node oppositeNode(const Node &n, const Arc &e) const {
   57.68 +      if (n == Parent::source(e))
   57.69 +	return Parent::target(e);
   57.70 +      else if(n==Parent::target(e))
   57.71 +	return Parent::source(e);
   57.72 +      else
   57.73 +	return INVALID;
   57.74 +    }
   57.75 +
   57.76 +
   57.77 +    // Alteration notifier extensions
   57.78 +
   57.79 +    // The arc observer registry.
   57.80 +    typedef AlterationNotifier<ArcSetExtender, Arc> ArcNotifier;
   57.81 +
   57.82 +  protected:
   57.83 +
   57.84 +    mutable ArcNotifier arc_notifier;
   57.85 +
   57.86 +  public:
   57.87 +
   57.88 +    using Parent::notifier;
   57.89 +
   57.90 +    // Gives back the arc alteration notifier.
   57.91 +    ArcNotifier& notifier(Arc) const {
   57.92 +      return arc_notifier;
   57.93 +    }
   57.94 +
   57.95 +    // Iterable extensions
   57.96 +
   57.97 +    class NodeIt : public Node { 
   57.98 +      const Digraph* digraph;
   57.99 +    public:
  57.100 +
  57.101 +      NodeIt() {}
  57.102 +
  57.103 +      NodeIt(Invalid i) : Node(i) { }
  57.104 +
  57.105 +      explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
  57.106 +	_graph.first(static_cast<Node&>(*this));
  57.107 +      }
  57.108 +
  57.109 +      NodeIt(const Digraph& _graph, const Node& node) 
  57.110 +	: Node(node), digraph(&_graph) {}
  57.111 +
  57.112 +      NodeIt& operator++() { 
  57.113 +	digraph->next(*this);
  57.114 +	return *this; 
  57.115 +      }
  57.116 +
  57.117 +    };
  57.118 +
  57.119 +
  57.120 +    class ArcIt : public Arc { 
  57.121 +      const Digraph* digraph;
  57.122 +    public:
  57.123 +
  57.124 +      ArcIt() { }
  57.125 +
  57.126 +      ArcIt(Invalid i) : Arc(i) { }
  57.127 +
  57.128 +      explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
  57.129 +	_graph.first(static_cast<Arc&>(*this));
  57.130 +      }
  57.131 +
  57.132 +      ArcIt(const Digraph& _graph, const Arc& e) : 
  57.133 +	Arc(e), digraph(&_graph) { }
  57.134 +
  57.135 +      ArcIt& operator++() { 
  57.136 +	digraph->next(*this);
  57.137 +	return *this; 
  57.138 +      }
  57.139 +
  57.140 +    };
  57.141 +
  57.142 +
  57.143 +    class OutArcIt : public Arc { 
  57.144 +      const Digraph* digraph;
  57.145 +    public:
  57.146 +
  57.147 +      OutArcIt() { }
  57.148 +
  57.149 +      OutArcIt(Invalid i) : Arc(i) { }
  57.150 +
  57.151 +      OutArcIt(const Digraph& _graph, const Node& node) 
  57.152 +	: digraph(&_graph) {
  57.153 +	_graph.firstOut(*this, node);
  57.154 +      }
  57.155 +
  57.156 +      OutArcIt(const Digraph& _graph, const Arc& arc) 
  57.157 +	: Arc(arc), digraph(&_graph) {}
  57.158 +
  57.159 +      OutArcIt& operator++() { 
  57.160 +	digraph->nextOut(*this);
  57.161 +	return *this; 
  57.162 +      }
  57.163 +
  57.164 +    };
  57.165 +
  57.166 +
  57.167 +    class InArcIt : public Arc { 
  57.168 +      const Digraph* digraph;
  57.169 +    public:
  57.170 +
  57.171 +      InArcIt() { }
  57.172 +
  57.173 +      InArcIt(Invalid i) : Arc(i) { }
  57.174 +
  57.175 +      InArcIt(const Digraph& _graph, const Node& node) 
  57.176 +	: digraph(&_graph) {
  57.177 +	_graph.firstIn(*this, node);
  57.178 +      }
  57.179 +
  57.180 +      InArcIt(const Digraph& _graph, const Arc& arc) : 
  57.181 +	Arc(arc), digraph(&_graph) {}
  57.182 +
  57.183 +      InArcIt& operator++() { 
  57.184 +	digraph->nextIn(*this);
  57.185 +	return *this; 
  57.186 +      }
  57.187 +
  57.188 +    };
  57.189 +
  57.190 +    // \brief Base node of the iterator
  57.191 +    //
  57.192 +    // Returns the base node (ie. the source in this case) of the iterator
  57.193 +    Node baseNode(const OutArcIt &e) const {
  57.194 +      return Parent::source(static_cast<const Arc&>(e));
  57.195 +    }
  57.196 +    // \brief Running node of the iterator
  57.197 +    //
  57.198 +    // Returns the running node (ie. the target in this case) of the
  57.199 +    // iterator
  57.200 +    Node runningNode(const OutArcIt &e) const {
  57.201 +      return Parent::target(static_cast<const Arc&>(e));
  57.202 +    }
  57.203 +
  57.204 +    // \brief Base node of the iterator
  57.205 +    //
  57.206 +    // Returns the base node (ie. the target in this case) of the iterator
  57.207 +    Node baseNode(const InArcIt &e) const {
  57.208 +      return Parent::target(static_cast<const Arc&>(e));
  57.209 +    }
  57.210 +    // \brief Running node of the iterator
  57.211 +    //
  57.212 +    // Returns the running node (ie. the source in this case) of the
  57.213 +    // iterator
  57.214 +    Node runningNode(const InArcIt &e) const {
  57.215 +      return Parent::source(static_cast<const Arc&>(e));
  57.216 +    }
  57.217 +
  57.218 +    using Parent::first;
  57.219 +
  57.220 +    // Mappable extension
  57.221 +    
  57.222 +    template <typename _Value>
  57.223 +    class ArcMap 
  57.224 +      : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
  57.225 +      typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
  57.226 +
  57.227 +    public:
  57.228 +      explicit ArcMap(const Digraph& _g) 
  57.229 +	: Parent(_g) {}
  57.230 +      ArcMap(const Digraph& _g, const _Value& _v) 
  57.231 +	: Parent(_g, _v) {}
  57.232 +
  57.233 +      ArcMap& operator=(const ArcMap& cmap) {
  57.234 +	return operator=<ArcMap>(cmap);
  57.235 +      }
  57.236 +
  57.237 +      template <typename CMap>
  57.238 +      ArcMap& operator=(const CMap& cmap) {
  57.239 +        Parent::operator=(cmap);
  57.240 +	return *this;
  57.241 +      }
  57.242 +
  57.243 +    };
  57.244 +
  57.245 +
  57.246 +    // Alteration extension
  57.247 +
  57.248 +    Arc addArc(const Node& from, const Node& to) {
  57.249 +      Arc arc = Parent::addArc(from, to);
  57.250 +      notifier(Arc()).add(arc);
  57.251 +      return arc;
  57.252 +    }
  57.253 +    
  57.254 +    void clear() {
  57.255 +      notifier(Arc()).clear();
  57.256 +      Parent::clear();
  57.257 +    }
  57.258 +
  57.259 +    void erase(const Arc& arc) {
  57.260 +      notifier(Arc()).erase(arc);
  57.261 +      Parent::erase(arc);
  57.262 +    }
  57.263 +
  57.264 +    ArcSetExtender() {
  57.265 +      arc_notifier.setContainer(*this);
  57.266 +    }
  57.267 +
  57.268 +    ~ArcSetExtender() {
  57.269 +      arc_notifier.clear();
  57.270 +    }
  57.271 +
  57.272 +  };
  57.273 +
  57.274 +
  57.275 +  // \ingroup digraphbits
  57.276 +  //
  57.277 +  // \brief Extender for the EdgeSets
  57.278 +  template <typename Base>
  57.279 +  class EdgeSetExtender : public Base {
  57.280 +    typedef Base Parent;
  57.281 +
  57.282 +  public:
  57.283 +
  57.284 +    typedef EdgeSetExtender Graph;
  57.285 +
  57.286 +    typedef typename Parent::Node Node;
  57.287 +    typedef typename Parent::Arc Arc;
  57.288 +    typedef typename Parent::Edge Edge;
  57.289 +
  57.290 +    int maxId(Node) const {
  57.291 +      return Parent::maxNodeId();
  57.292 +    }
  57.293 +
  57.294 +    int maxId(Arc) const {
  57.295 +      return Parent::maxArcId();
  57.296 +    }
  57.297 +
  57.298 +    int maxId(Edge) const {
  57.299 +      return Parent::maxEdgeId();
  57.300 +    }
  57.301 +
  57.302 +    Node fromId(int id, Node) const {
  57.303 +      return Parent::nodeFromId(id);
  57.304 +    }
  57.305 +
  57.306 +    Arc fromId(int id, Arc) const {
  57.307 +      return Parent::arcFromId(id);
  57.308 +    }
  57.309 +
  57.310 +    Edge fromId(int id, Edge) const {
  57.311 +      return Parent::edgeFromId(id);
  57.312 +    }
  57.313 +
  57.314 +    Node oppositeNode(const Node &n, const Edge &e) const {
  57.315 +      if( n == Parent::u(e))
  57.316 +	return Parent::v(e);
  57.317 +      else if( n == Parent::v(e))
  57.318 +	return Parent::u(e);
  57.319 +      else
  57.320 +	return INVALID;
  57.321 +    }
  57.322 +
  57.323 +    Arc oppositeArc(const Arc &e) const {
  57.324 +      return Parent::direct(e, !Parent::direction(e));
  57.325 +    }
  57.326 +
  57.327 +    using Parent::direct;
  57.328 +    Arc direct(const Edge &e, const Node &s) const {
  57.329 +      return Parent::direct(e, Parent::u(e) == s);
  57.330 +    }
  57.331 +
  57.332 +    typedef AlterationNotifier<EdgeSetExtender, Arc> ArcNotifier;
  57.333 +    typedef AlterationNotifier<EdgeSetExtender, Edge> EdgeNotifier;
  57.334 +
  57.335 +
  57.336 +  protected:
  57.337 +
  57.338 +    mutable ArcNotifier arc_notifier;
  57.339 +    mutable EdgeNotifier edge_notifier;
  57.340 +
  57.341 +  public:
  57.342 +
  57.343 +    using Parent::notifier;
  57.344 +    
  57.345 +    ArcNotifier& notifier(Arc) const {
  57.346 +      return arc_notifier;
  57.347 +    }
  57.348 +
  57.349 +    EdgeNotifier& notifier(Edge) const {
  57.350 +      return edge_notifier;
  57.351 +    }
  57.352 +
  57.353 +
  57.354 +    class NodeIt : public Node { 
  57.355 +      const Graph* graph;
  57.356 +    public:
  57.357 +
  57.358 +      NodeIt() {}
  57.359 +
  57.360 +      NodeIt(Invalid i) : Node(i) { }
  57.361 +
  57.362 +      explicit NodeIt(const Graph& _graph) : graph(&_graph) {
  57.363 +	_graph.first(static_cast<Node&>(*this));
  57.364 +      }
  57.365 +
  57.366 +      NodeIt(const Graph& _graph, const Node& node) 
  57.367 +	: Node(node), graph(&_graph) {}
  57.368 +
  57.369 +      NodeIt& operator++() { 
  57.370 +	graph->next(*this);
  57.371 +	return *this; 
  57.372 +      }
  57.373 +
  57.374 +    };
  57.375 +
  57.376 +
  57.377 +    class ArcIt : public Arc { 
  57.378 +      const Graph* graph;
  57.379 +    public:
  57.380 +
  57.381 +      ArcIt() { }
  57.382 +
  57.383 +      ArcIt(Invalid i) : Arc(i) { }
  57.384 +
  57.385 +      explicit ArcIt(const Graph& _graph) : graph(&_graph) {
  57.386 +	_graph.first(static_cast<Arc&>(*this));
  57.387 +      }
  57.388 +
  57.389 +      ArcIt(const Graph& _graph, const Arc& e) : 
  57.390 +	Arc(e), graph(&_graph) { }
  57.391 +
  57.392 +      ArcIt& operator++() { 
  57.393 +	graph->next(*this);
  57.394 +	return *this; 
  57.395 +      }
  57.396 +
  57.397 +    };
  57.398 +
  57.399 +
  57.400 +    class OutArcIt : public Arc { 
  57.401 +      const Graph* graph;
  57.402 +    public:
  57.403 +
  57.404 +      OutArcIt() { }
  57.405 +
  57.406 +      OutArcIt(Invalid i) : Arc(i) { }
  57.407 +
  57.408 +      OutArcIt(const Graph& _graph, const Node& node) 
  57.409 +	: graph(&_graph) {
  57.410 +	_graph.firstOut(*this, node);
  57.411 +      }
  57.412 +
  57.413 +      OutArcIt(const Graph& _graph, const Arc& arc) 
  57.414 +	: Arc(arc), graph(&_graph) {}
  57.415 +
  57.416 +      OutArcIt& operator++() { 
  57.417 +	graph->nextOut(*this);
  57.418 +	return *this; 
  57.419 +      }
  57.420 +
  57.421 +    };
  57.422 +
  57.423 +
  57.424 +    class InArcIt : public Arc { 
  57.425 +      const Graph* graph;
  57.426 +    public:
  57.427 +
  57.428 +      InArcIt() { }
  57.429 +
  57.430 +      InArcIt(Invalid i) : Arc(i) { }
  57.431 +
  57.432 +      InArcIt(const Graph& _graph, const Node& node) 
  57.433 +	: graph(&_graph) {
  57.434 +	_graph.firstIn(*this, node);
  57.435 +      }
  57.436 +
  57.437 +      InArcIt(const Graph& _graph, const Arc& arc) : 
  57.438 +	Arc(arc), graph(&_graph) {}
  57.439 +
  57.440 +      InArcIt& operator++() { 
  57.441 +	graph->nextIn(*this);
  57.442 +	return *this; 
  57.443 +      }
  57.444 +
  57.445 +    };
  57.446 +
  57.447 +
  57.448 +    class EdgeIt : public Parent::Edge { 
  57.449 +      const Graph* graph;
  57.450 +    public:
  57.451 +
  57.452 +      EdgeIt() { }
  57.453 +
  57.454 +      EdgeIt(Invalid i) : Edge(i) { }
  57.455 +
  57.456 +      explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
  57.457 +	_graph.first(static_cast<Edge&>(*this));
  57.458 +      }
  57.459 +
  57.460 +      EdgeIt(const Graph& _graph, const Edge& e) : 
  57.461 +	Edge(e), graph(&_graph) { }
  57.462 +
  57.463 +      EdgeIt& operator++() { 
  57.464 +	graph->next(*this);
  57.465 +	return *this; 
  57.466 +      }
  57.467 +
  57.468 +    };
  57.469 +
  57.470 +    class IncEdgeIt : public Parent::Edge {
  57.471 +      friend class EdgeSetExtender;
  57.472 +      const Graph* graph;
  57.473 +      bool direction;
  57.474 +    public:
  57.475 +
  57.476 +      IncEdgeIt() { }
  57.477 +
  57.478 +      IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
  57.479 +
  57.480 +      IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
  57.481 +	_graph.firstInc(*this, direction, n);
  57.482 +      }
  57.483 +
  57.484 +      IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n)
  57.485 +	: graph(&_graph), Edge(ue) {
  57.486 +	direction = (_graph.source(ue) == n);
  57.487 +      }
  57.488 +
  57.489 +      IncEdgeIt& operator++() {
  57.490 +	graph->nextInc(*this, direction);
  57.491 +	return *this; 
  57.492 +      }
  57.493 +    };
  57.494 +
  57.495 +    // \brief Base node of the iterator
  57.496 +    //
  57.497 +    // Returns the base node (ie. the source in this case) of the iterator
  57.498 +    Node baseNode(const OutArcIt &e) const {
  57.499 +      return Parent::source(static_cast<const Arc&>(e));
  57.500 +    }
  57.501 +    // \brief Running node of the iterator
  57.502 +    //
  57.503 +    // Returns the running node (ie. the target in this case) of the
  57.504 +    // iterator
  57.505 +    Node runningNode(const OutArcIt &e) const {
  57.506 +      return Parent::target(static_cast<const Arc&>(e));
  57.507 +    }
  57.508 +
  57.509 +    // \brief Base node of the iterator
  57.510 +    //
  57.511 +    // Returns the base node (ie. the target in this case) of the iterator
  57.512 +    Node baseNode(const InArcIt &e) const {
  57.513 +      return Parent::target(static_cast<const Arc&>(e));
  57.514 +    }
  57.515 +    // \brief Running node of the iterator
  57.516 +    //
  57.517 +    // Returns the running node (ie. the source in this case) of the
  57.518 +    // iterator
  57.519 +    Node runningNode(const InArcIt &e) const {
  57.520 +      return Parent::source(static_cast<const Arc&>(e));
  57.521 +    }
  57.522 +
  57.523 +    // Base node of the iterator
  57.524 +    //
  57.525 +    // Returns the base node of the iterator
  57.526 +    Node baseNode(const IncEdgeIt &e) const {
  57.527 +      return e.direction ? u(e) : v(e);
  57.528 +    }
  57.529 +    // Running node of the iterator
  57.530 +    //
  57.531 +    // Returns the running node of the iterator
  57.532 +    Node runningNode(const IncEdgeIt &e) const {
  57.533 +      return e.direction ? v(e) : u(e);
  57.534 +    }
  57.535 +
  57.536 +
  57.537 +    template <typename _Value>
  57.538 +    class ArcMap 
  57.539 +      : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
  57.540 +      typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
  57.541 +
  57.542 +    public:
  57.543 +      explicit ArcMap(const Graph& _g) 
  57.544 +	: Parent(_g) {}
  57.545 +      ArcMap(const Graph& _g, const _Value& _v) 
  57.546 +	: Parent(_g, _v) {}
  57.547 +
  57.548 +      ArcMap& operator=(const ArcMap& cmap) {
  57.549 +	return operator=<ArcMap>(cmap);
  57.550 +      }
  57.551 +
  57.552 +      template <typename CMap>
  57.553 +      ArcMap& operator=(const CMap& cmap) {
  57.554 +        Parent::operator=(cmap);
  57.555 +	return *this;
  57.556 +      }
  57.557 +
  57.558 +    };
  57.559 +
  57.560 +
  57.561 +    template <typename _Value>
  57.562 +    class EdgeMap 
  57.563 +      : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
  57.564 +      typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
  57.565 +
  57.566 +    public:
  57.567 +      explicit EdgeMap(const Graph& _g) 
  57.568 +	: Parent(_g) {}
  57.569 +
  57.570 +      EdgeMap(const Graph& _g, const _Value& _v) 
  57.571 +	: Parent(_g, _v) {}
  57.572 +
  57.573 +      EdgeMap& operator=(const EdgeMap& cmap) {
  57.574 +	return operator=<EdgeMap>(cmap);
  57.575 +      }
  57.576 +
  57.577 +      template <typename CMap>
  57.578 +      EdgeMap& operator=(const CMap& cmap) {
  57.579 +        Parent::operator=(cmap);
  57.580 +	return *this;
  57.581 +      }
  57.582 +
  57.583 +    };
  57.584 +
  57.585 +
  57.586 +    // Alteration extension
  57.587 +
  57.588 +    Edge addEdge(const Node& from, const Node& to) {
  57.589 +      Edge edge = Parent::addEdge(from, to);
  57.590 +      notifier(Edge()).add(edge);
  57.591 +      std::vector<Arc> arcs;
  57.592 +      arcs.push_back(Parent::direct(edge, true));
  57.593 +      arcs.push_back(Parent::direct(edge, false));
  57.594 +      notifier(Arc()).add(arcs);
  57.595 +      return edge;
  57.596 +    }
  57.597 +    
  57.598 +    void clear() {
  57.599 +      notifier(Arc()).clear();
  57.600 +      notifier(Edge()).clear();
  57.601 +      Parent::clear();
  57.602 +    }
  57.603 +
  57.604 +    void erase(const Edge& edge) {
  57.605 +      std::vector<Arc> arcs;
  57.606 +      arcs.push_back(Parent::direct(edge, true));
  57.607 +      arcs.push_back(Parent::direct(edge, false));
  57.608 +      notifier(Arc()).erase(arcs);
  57.609 +      notifier(Edge()).erase(edge);
  57.610 +      Parent::erase(edge);
  57.611 +    }
  57.612 +
  57.613 +
  57.614 +    EdgeSetExtender() {
  57.615 +      arc_notifier.setContainer(*this);
  57.616 +      edge_notifier.setContainer(*this);
  57.617 +    }
  57.618 +
  57.619 +    ~EdgeSetExtender() {
  57.620 +      edge_notifier.clear();
  57.621 +      arc_notifier.clear();
  57.622 +    }
  57.623 +    
  57.624 +  };
  57.625 +
  57.626 +}
  57.627 +
  57.628 +#endif
    58.1 --- a/lemon/bits/enable_if.h	Fri Oct 16 10:21:37 2009 +0200
    58.2 +++ b/lemon/bits/enable_if.h	Thu Nov 05 15:50:01 2009 +0100
    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-2008
    58.8 + * Copyright (C) 2003-2009
    58.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   58.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   58.11   *
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/lemon/bits/graph_adaptor_extender.h	Thu Nov 05 15:50:01 2009 +0100
    59.3 @@ -0,0 +1,399 @@
    59.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    59.5 + *
    59.6 + * This file is a part of LEMON, a generic C++ optimization library.
    59.7 + *
    59.8 + * Copyright (C) 2003-2009
    59.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   59.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   59.11 + *
   59.12 + * Permission to use, modify and distribute this software is granted
   59.13 + * provided that this copyright notice appears in all copies. For
   59.14 + * precise terms see the accompanying LICENSE file.
   59.15 + *
   59.16 + * This software is provided "AS IS" with no warranty of any kind,
   59.17 + * express or implied, and with no claim as to its suitability for any
   59.18 + * purpose.
   59.19 + *
   59.20 + */
   59.21 +
   59.22 +#ifndef LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
   59.23 +#define LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
   59.24 +
   59.25 +#include <lemon/core.h>
   59.26 +#include <lemon/error.h>
   59.27 +
   59.28 +namespace lemon {
   59.29 +
   59.30 +  template <typename _Digraph>
   59.31 +  class DigraphAdaptorExtender : public _Digraph {
   59.32 +    typedef _Digraph Parent;
   59.33 +
   59.34 +  public:
   59.35 +
   59.36 +    typedef _Digraph Digraph;
   59.37 +    typedef DigraphAdaptorExtender Adaptor;
   59.38 +
   59.39 +    // Base extensions
   59.40 +
   59.41 +    typedef typename Parent::Node Node;
   59.42 +    typedef typename Parent::Arc Arc;
   59.43 +
   59.44 +    int maxId(Node) const {
   59.45 +      return Parent::maxNodeId();
   59.46 +    }
   59.47 +
   59.48 +    int maxId(Arc) const {
   59.49 +      return Parent::maxArcId();
   59.50 +    }
   59.51 +
   59.52 +    Node fromId(int id, Node) const {
   59.53 +      return Parent::nodeFromId(id);
   59.54 +    }
   59.55 +
   59.56 +    Arc fromId(int id, Arc) const {
   59.57 +      return Parent::arcFromId(id);
   59.58 +    }
   59.59 +
   59.60 +    Node oppositeNode(const Node &n, const Arc &e) const {
   59.61 +      if (n == Parent::source(e))
   59.62 +        return Parent::target(e);
   59.63 +      else if(n==Parent::target(e))
   59.64 +        return Parent::source(e);
   59.65 +      else
   59.66 +        return INVALID;
   59.67 +    }
   59.68 +
   59.69 +    class NodeIt : public Node {
   59.70 +      const Adaptor* _adaptor;
   59.71 +    public:
   59.72 +
   59.73 +      NodeIt() {}
   59.74 +
   59.75 +      NodeIt(Invalid i) : Node(i) { }
   59.76 +
   59.77 +      explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
   59.78 +        _adaptor->first(static_cast<Node&>(*this));
   59.79 +      }
   59.80 +
   59.81 +      NodeIt(const Adaptor& adaptor, const Node& node)
   59.82 +        : Node(node), _adaptor(&adaptor) {}
   59.83 +
   59.84 +      NodeIt& operator++() {
   59.85 +        _adaptor->next(*this);
   59.86 +        return *this;
   59.87 +      }
   59.88 +
   59.89 +    };
   59.90 +
   59.91 +
   59.92 +    class ArcIt : public Arc {
   59.93 +      const Adaptor* _adaptor;
   59.94 +    public:
   59.95 +
   59.96 +      ArcIt() { }
   59.97 +
   59.98 +      ArcIt(Invalid i) : Arc(i) { }
   59.99 +
  59.100 +      explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
  59.101 +        _adaptor->first(static_cast<Arc&>(*this));
  59.102 +      }
  59.103 +
  59.104 +      ArcIt(const Adaptor& adaptor, const Arc& e) :
  59.105 +        Arc(e), _adaptor(&adaptor) { }
  59.106 +
  59.107 +      ArcIt& operator++() {
  59.108 +        _adaptor->next(*this);
  59.109 +        return *this;
  59.110 +      }
  59.111 +
  59.112 +    };
  59.113 +
  59.114 +
  59.115 +    class OutArcIt : public Arc {
  59.116 +      const Adaptor* _adaptor;
  59.117 +    public:
  59.118 +
  59.119 +      OutArcIt() { }
  59.120 +
  59.121 +      OutArcIt(Invalid i) : Arc(i) { }
  59.122 +
  59.123 +      OutArcIt(const Adaptor& adaptor, const Node& node)
  59.124 +        : _adaptor(&adaptor) {
  59.125 +        _adaptor->firstOut(*this, node);
  59.126 +      }
  59.127 +
  59.128 +      OutArcIt(const Adaptor& adaptor, const Arc& arc)
  59.129 +        : Arc(arc), _adaptor(&adaptor) {}
  59.130 +
  59.131 +      OutArcIt& operator++() {
  59.132 +        _adaptor->nextOut(*this);
  59.133 +        return *this;
  59.134 +      }
  59.135 +
  59.136 +    };
  59.137 +
  59.138 +
  59.139 +    class InArcIt : public Arc {
  59.140 +      const Adaptor* _adaptor;
  59.141 +    public:
  59.142 +
  59.143 +      InArcIt() { }
  59.144 +
  59.145 +      InArcIt(Invalid i) : Arc(i) { }
  59.146 +
  59.147 +      InArcIt(const Adaptor& adaptor, const Node& node)
  59.148 +        : _adaptor(&adaptor) {
  59.149 +        _adaptor->firstIn(*this, node);
  59.150 +      }
  59.151 +
  59.152 +      InArcIt(const Adaptor& adaptor, const Arc& arc) :
  59.153 +        Arc(arc), _adaptor(&adaptor) {}
  59.154 +
  59.155 +      InArcIt& operator++() {
  59.156 +        _adaptor->nextIn(*this);
  59.157 +        return *this;
  59.158 +      }
  59.159 +
  59.160 +    };
  59.161 +
  59.162 +    Node baseNode(const OutArcIt &e) const {
  59.163 +      return Parent::source(e);
  59.164 +    }
  59.165 +    Node runningNode(const OutArcIt &e) const {
  59.166 +      return Parent::target(e);
  59.167 +    }
  59.168 +
  59.169 +    Node baseNode(const InArcIt &e) const {
  59.170 +      return Parent::target(e);
  59.171 +    }
  59.172 +    Node runningNode(const InArcIt &e) const {
  59.173 +      return Parent::source(e);
  59.174 +    }
  59.175 +
  59.176 +  };
  59.177 +
  59.178 +  template <typename _Graph>
  59.179 +  class GraphAdaptorExtender : public _Graph {
  59.180 +    typedef _Graph Parent;
  59.181 +
  59.182 +  public:
  59.183 +
  59.184 +    typedef _Graph Graph;
  59.185 +    typedef GraphAdaptorExtender Adaptor;
  59.186 +
  59.187 +    typedef typename Parent::Node Node;
  59.188 +    typedef typename Parent::Arc Arc;
  59.189 +    typedef typename Parent::Edge Edge;
  59.190 +
  59.191 +    // Graph extension
  59.192 +
  59.193 +    int maxId(Node) const {
  59.194 +      return Parent::maxNodeId();
  59.195 +    }
  59.196 +
  59.197 +    int maxId(Arc) const {
  59.198 +      return Parent::maxArcId();
  59.199 +    }
  59.200 +
  59.201 +    int maxId(Edge) const {
  59.202 +      return Parent::maxEdgeId();
  59.203 +    }
  59.204 +
  59.205 +    Node fromId(int id, Node) const {
  59.206 +      return Parent::nodeFromId(id);
  59.207 +    }
  59.208 +
  59.209 +    Arc fromId(int id, Arc) const {
  59.210 +      return Parent::arcFromId(id);
  59.211 +    }
  59.212 +
  59.213 +    Edge fromId(int id, Edge) const {
  59.214 +      return Parent::edgeFromId(id);
  59.215 +    }
  59.216 +
  59.217 +    Node oppositeNode(const Node &n, const Edge &e) const {
  59.218 +      if( n == Parent::u(e))
  59.219 +        return Parent::v(e);
  59.220 +      else if( n == Parent::v(e))
  59.221 +        return Parent::u(e);
  59.222 +      else
  59.223 +        return INVALID;
  59.224 +    }
  59.225 +
  59.226 +    Arc oppositeArc(const Arc &a) const {
  59.227 +      return Parent::direct(a, !Parent::direction(a));
  59.228 +    }
  59.229 +
  59.230 +    using Parent::direct;
  59.231 +    Arc direct(const Edge &e, const Node &s) const {
  59.232 +      return Parent::direct(e, Parent::u(e) == s);
  59.233 +    }
  59.234 +
  59.235 +
  59.236 +    class NodeIt : public Node {
  59.237 +      const Adaptor* _adaptor;
  59.238 +    public:
  59.239 +
  59.240 +      NodeIt() {}
  59.241 +
  59.242 +      NodeIt(Invalid i) : Node(i) { }
  59.243 +
  59.244 +      explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
  59.245 +        _adaptor->first(static_cast<Node&>(*this));
  59.246 +      }
  59.247 +
  59.248 +      NodeIt(const Adaptor& adaptor, const Node& node)
  59.249 +        : Node(node), _adaptor(&adaptor) {}
  59.250 +
  59.251 +      NodeIt& operator++() {
  59.252 +        _adaptor->next(*this);
  59.253 +        return *this;
  59.254 +      }
  59.255 +
  59.256 +    };
  59.257 +
  59.258 +
  59.259 +    class ArcIt : public Arc {
  59.260 +      const Adaptor* _adaptor;
  59.261 +    public:
  59.262 +
  59.263 +      ArcIt() { }
  59.264 +
  59.265 +      ArcIt(Invalid i) : Arc(i) { }
  59.266 +
  59.267 +      explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
  59.268 +        _adaptor->first(static_cast<Arc&>(*this));
  59.269 +      }
  59.270 +
  59.271 +      ArcIt(const Adaptor& adaptor, const Arc& e) :
  59.272 +        Arc(e), _adaptor(&adaptor) { }
  59.273 +
  59.274 +      ArcIt& operator++() {
  59.275 +        _adaptor->next(*this);
  59.276 +        return *this;
  59.277 +      }
  59.278 +
  59.279 +    };
  59.280 +
  59.281 +
  59.282 +    class OutArcIt : public Arc {
  59.283 +      const Adaptor* _adaptor;
  59.284 +    public:
  59.285 +
  59.286 +      OutArcIt() { }
  59.287 +
  59.288 +      OutArcIt(Invalid i) : Arc(i) { }
  59.289 +
  59.290 +      OutArcIt(const Adaptor& adaptor, const Node& node)
  59.291 +        : _adaptor(&adaptor) {
  59.292 +        _adaptor->firstOut(*this, node);
  59.293 +      }
  59.294 +
  59.295 +      OutArcIt(const Adaptor& adaptor, const Arc& arc)
  59.296 +        : Arc(arc), _adaptor(&adaptor) {}
  59.297 +
  59.298 +      OutArcIt& operator++() {
  59.299 +        _adaptor->nextOut(*this);
  59.300 +        return *this;
  59.301 +      }
  59.302 +
  59.303 +    };
  59.304 +
  59.305 +
  59.306 +    class InArcIt : public Arc {
  59.307 +      const Adaptor* _adaptor;
  59.308 +    public:
  59.309 +
  59.310 +      InArcIt() { }
  59.311 +
  59.312 +      InArcIt(Invalid i) : Arc(i) { }
  59.313 +
  59.314 +      InArcIt(const Adaptor& adaptor, const Node& node)
  59.315 +        : _adaptor(&adaptor) {
  59.316 +        _adaptor->firstIn(*this, node);
  59.317 +      }
  59.318 +
  59.319 +      InArcIt(const Adaptor& adaptor, const Arc& arc) :
  59.320 +        Arc(arc), _adaptor(&adaptor) {}
  59.321 +
  59.322 +      InArcIt& operator++() {
  59.323 +        _adaptor->nextIn(*this);
  59.324 +        return *this;
  59.325 +      }
  59.326 +
  59.327 +    };
  59.328 +
  59.329 +    class EdgeIt : public Parent::Edge {
  59.330 +      const Adaptor* _adaptor;
  59.331 +    public:
  59.332 +
  59.333 +      EdgeIt() { }
  59.334 +
  59.335 +      EdgeIt(Invalid i) : Edge(i) { }
  59.336 +
  59.337 +      explicit EdgeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
  59.338 +        _adaptor->first(static_cast<Edge&>(*this));
  59.339 +      }
  59.340 +
  59.341 +      EdgeIt(const Adaptor& adaptor, const Edge& e) :
  59.342 +        Edge(e), _adaptor(&adaptor) { }
  59.343 +
  59.344 +      EdgeIt& operator++() {
  59.345 +        _adaptor->next(*this);
  59.346 +        return *this;
  59.347 +      }
  59.348 +
  59.349 +    };
  59.350 +
  59.351 +    class IncEdgeIt : public Edge {
  59.352 +      friend class GraphAdaptorExtender;
  59.353 +      const Adaptor* _adaptor;
  59.354 +      bool direction;
  59.355 +    public:
  59.356 +
  59.357 +      IncEdgeIt() { }
  59.358 +
  59.359 +      IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
  59.360 +
  59.361 +      IncEdgeIt(const Adaptor& adaptor, const Node &n) : _adaptor(&adaptor) {
  59.362 +        _adaptor->firstInc(static_cast<Edge&>(*this), direction, n);
  59.363 +      }
  59.364 +
  59.365 +      IncEdgeIt(const Adaptor& adaptor, const Edge &e, const Node &n)
  59.366 +        : _adaptor(&adaptor), Edge(e) {
  59.367 +        direction = (_adaptor->u(e) == n);
  59.368 +      }
  59.369 +
  59.370 +      IncEdgeIt& operator++() {
  59.371 +        _adaptor->nextInc(*this, direction);
  59.372 +        return *this;
  59.373 +      }
  59.374 +    };
  59.375 +
  59.376 +    Node baseNode(const OutArcIt &a) const {
  59.377 +      return Parent::source(a);
  59.378 +    }
  59.379 +    Node runningNode(const OutArcIt &a) const {
  59.380 +      return Parent::target(a);
  59.381 +    }
  59.382 +
  59.383 +    Node baseNode(const InArcIt &a) const {
  59.384 +      return Parent::target(a);
  59.385 +    }
  59.386 +    Node runningNode(const InArcIt &a) const {
  59.387 +      return Parent::source(a);
  59.388 +    }
  59.389 +
  59.390 +    Node baseNode(const IncEdgeIt &e) const {
  59.391 +      return e.direction ? Parent::u(e) : Parent::v(e);
  59.392 +    }
  59.393 +    Node runningNode(const IncEdgeIt &e) const {
  59.394 +      return e.direction ? Parent::v(e) : Parent::u(e);
  59.395 +    }
  59.396 +
  59.397 +  };
  59.398 +
  59.399 +}
  59.400 +
  59.401 +
  59.402 +#endif
    60.1 --- a/lemon/bits/graph_extender.h	Fri Oct 16 10:21:37 2009 +0200
    60.2 +++ b/lemon/bits/graph_extender.h	Thu Nov 05 15:50:01 2009 +0100
    60.3 @@ -2,7 +2,7 @@
    60.4   *
    60.5   * This file is a part of LEMON, a generic C++ optimization library.
    60.6   *
    60.7 - * Copyright (C) 2003-2008
    60.8 + * Copyright (C) 2003-2009
    60.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   60.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   60.11   *
   60.12 @@ -29,17 +29,18 @@
   60.13  
   60.14  //\ingroup graphbits
   60.15  //\file
   60.16 -//\brief Extenders for the digraph types
   60.17 +//\brief Extenders for the graph types
   60.18  namespace lemon {
   60.19  
   60.20    // \ingroup graphbits
   60.21    //
   60.22 -  // \brief Extender for the Digraphs
   60.23 +  // \brief Extender for the digraph implementations
   60.24    template <typename Base>
   60.25    class DigraphExtender : public Base {
   60.26 +    typedef Base Parent;
   60.27 +
   60.28    public:
   60.29  
   60.30 -    typedef Base Parent;
   60.31      typedef DigraphExtender Digraph;
   60.32  
   60.33      // Base extensions
   60.34 @@ -55,11 +56,11 @@
   60.35        return Parent::maxArcId();
   60.36      }
   60.37  
   60.38 -    Node fromId(int id, Node) const {
   60.39 +    static Node fromId(int id, Node) {
   60.40        return Parent::nodeFromId(id);
   60.41      }
   60.42  
   60.43 -    Arc fromId(int id, Arc) const {
   60.44 +    static Arc fromId(int id, Arc) {
   60.45        return Parent::arcFromId(id);
   60.46      }
   60.47  
   60.48 @@ -218,10 +219,9 @@
   60.49      template <typename _Value>
   60.50      class NodeMap
   60.51        : public MapExtender<DefaultMap<Digraph, Node, _Value> > {
   60.52 -    public:
   60.53 -      typedef DigraphExtender Digraph;
   60.54        typedef MapExtender<DefaultMap<Digraph, Node, _Value> > Parent;
   60.55  
   60.56 +    public:
   60.57        explicit NodeMap(const Digraph& digraph)
   60.58          : Parent(digraph) {}
   60.59        NodeMap(const Digraph& digraph, const _Value& value)
   60.60 @@ -243,10 +243,9 @@
   60.61      template <typename _Value>
   60.62      class ArcMap
   60.63        : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
   60.64 -    public:
   60.65 -      typedef DigraphExtender Digraph;
   60.66        typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
   60.67  
   60.68 +    public:
   60.69        explicit ArcMap(const Digraph& digraph)
   60.70          : Parent(digraph) {}
   60.71        ArcMap(const Digraph& digraph, const _Value& value)
   60.72 @@ -330,9 +329,10 @@
   60.73    // \brief Extender for the Graphs
   60.74    template <typename Base>
   60.75    class GraphExtender : public Base {
   60.76 +    typedef Base Parent;
   60.77 +
   60.78    public:
   60.79  
   60.80 -    typedef Base Parent;
   60.81      typedef GraphExtender Graph;
   60.82  
   60.83      typedef True UndirectedTag;
   60.84 @@ -355,15 +355,15 @@
   60.85        return Parent::maxEdgeId();
   60.86      }
   60.87  
   60.88 -    Node fromId(int id, Node) const {
   60.89 +    static Node fromId(int id, Node) {
   60.90        return Parent::nodeFromId(id);
   60.91      }
   60.92  
   60.93 -    Arc fromId(int id, Arc) const {
   60.94 +    static Arc fromId(int id, Arc) {
   60.95        return Parent::arcFromId(id);
   60.96      }
   60.97  
   60.98 -    Edge fromId(int id, Edge) const {
   60.99 +    static Edge fromId(int id, Edge) {
  60.100        return Parent::edgeFromId(id);
  60.101      }
  60.102  
  60.103 @@ -601,11 +601,10 @@
  60.104      template <typename _Value>
  60.105      class NodeMap
  60.106        : public MapExtender<DefaultMap<Graph, Node, _Value> > {
  60.107 -    public:
  60.108 -      typedef GraphExtender Graph;
  60.109        typedef MapExtender<DefaultMap<Graph, Node, _Value> > Parent;
  60.110  
  60.111 -      NodeMap(const Graph& graph)
  60.112 +    public:
  60.113 +      explicit NodeMap(const Graph& graph)
  60.114          : Parent(graph) {}
  60.115        NodeMap(const Graph& graph, const _Value& value)
  60.116          : Parent(graph, value) {}
  60.117 @@ -626,11 +625,10 @@
  60.118      template <typename _Value>
  60.119      class ArcMap
  60.120        : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
  60.121 -    public:
  60.122 -      typedef GraphExtender Graph;
  60.123        typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
  60.124  
  60.125 -      ArcMap(const Graph& graph)
  60.126 +    public:
  60.127 +      explicit ArcMap(const Graph& graph)
  60.128          : Parent(graph) {}
  60.129        ArcMap(const Graph& graph, const _Value& value)
  60.130          : Parent(graph, value) {}
  60.131 @@ -651,11 +649,10 @@
  60.132      template <typename _Value>
  60.133      class EdgeMap
  60.134        : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
  60.135 -    public:
  60.136 -      typedef GraphExtender Graph;
  60.137        typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
  60.138  
  60.139 -      EdgeMap(const Graph& graph)
  60.140 +    public:
  60.141 +      explicit EdgeMap(const Graph& graph)
  60.142          : Parent(graph) {}
  60.143  
  60.144        EdgeMap(const Graph& graph, const _Value& value)
    61.1 --- a/lemon/bits/map_extender.h	Fri Oct 16 10:21:37 2009 +0200
    61.2 +++ b/lemon/bits/map_extender.h	Thu Nov 05 15:50:01 2009 +0100
    61.3 @@ -2,7 +2,7 @@
    61.4   *
    61.5   * This file is a part of LEMON, a generic C++ optimization library.
    61.6   *
    61.7 - * Copyright (C) 2003-2008
    61.8 + * Copyright (C) 2003-2009
    61.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   61.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   61.11   *
   61.12 @@ -36,17 +36,20 @@
   61.13    // \brief Extender for maps
   61.14    template <typename _Map>
   61.15    class MapExtender : public _Map {
   61.16 +    typedef _Map Parent;
   61.17 +    typedef typename Parent::GraphType GraphType;
   61.18 +
   61.19    public:
   61.20  
   61.21 -    typedef _Map Parent;
   61.22      typedef MapExtender Map;
   61.23 -
   61.24 -
   61.25 -    typedef typename Parent::Graph Graph;
   61.26      typedef typename Parent::Key Item;
   61.27  
   61.28      typedef typename Parent::Key Key;
   61.29      typedef typename Parent::Value Value;
   61.30 +    typedef typename Parent::Reference Reference;
   61.31 +    typedef typename Parent::ConstReference ConstReference;
   61.32 +
   61.33 +    typedef typename Parent::ReferenceMapTag ReferenceMapTag;
   61.34  
   61.35      class MapIt;
   61.36      class ConstMapIt;
   61.37 @@ -56,10 +59,10 @@
   61.38  
   61.39    public:
   61.40  
   61.41 -    MapExtender(const Graph& graph)
   61.42 +    MapExtender(const GraphType& graph)
   61.43        : Parent(graph) {}
   61.44  
   61.45 -    MapExtender(const Graph& graph, const Value& value)
   61.46 +    MapExtender(const GraphType& graph, const Value& value)
   61.47        : Parent(graph, value) {}
   61.48  
   61.49    private:
   61.50 @@ -75,9 +78,10 @@
   61.51  
   61.52    public:
   61.53      class MapIt : public Item {
   61.54 +      typedef Item Parent;
   61.55 +
   61.56      public:
   61.57  
   61.58 -      typedef Item Parent;
   61.59        typedef typename Map::Value Value;
   61.60  
   61.61        MapIt() {}
   61.62 @@ -114,10 +118,10 @@
   61.63      };
   61.64  
   61.65      class ConstMapIt : public Item {
   61.66 +      typedef Item Parent;
   61.67 +
   61.68      public:
   61.69  
   61.70 -      typedef Item Parent;
   61.71 -
   61.72        typedef typename Map::Value Value;
   61.73  
   61.74        ConstMapIt() {}
   61.75 @@ -145,10 +149,10 @@
   61.76      };
   61.77  
   61.78      class ItemIt : public Item {
   61.79 +      typedef Item Parent;
   61.80 +
   61.81      public:
   61.82  
   61.83 -      typedef Item Parent;
   61.84 -
   61.85        ItemIt() {}
   61.86  
   61.87        ItemIt(Invalid i) : Parent(i) { }
   61.88 @@ -176,17 +180,20 @@
   61.89    // \brief Extender for maps which use a subset of the items.
   61.90    template <typename _Graph, typename _Map>
   61.91    class SubMapExtender : public _Map {
   61.92 +    typedef _Map Parent;
   61.93 +    typedef _Graph GraphType;
   61.94 +
   61.95    public:
   61.96  
   61.97 -    typedef _Map Parent;
   61.98      typedef SubMapExtender Map;
   61.99 -
  61.100 -    typedef _Graph Graph;
  61.101 -
  61.102      typedef typename Parent::Key Item;
  61.103  
  61.104      typedef typename Parent::Key Key;
  61.105      typedef typename Parent::Value Value;
  61.106 +    typedef typename Parent::Reference Reference;
  61.107 +    typedef typename Parent::ConstReference ConstReference;
  61.108 +
  61.109 +    typedef typename Parent::ReferenceMapTag ReferenceMapTag;
  61.110  
  61.111      class MapIt;
  61.112      class ConstMapIt;
  61.113 @@ -196,10 +203,10 @@
  61.114  
  61.115    public:
  61.116  
  61.117 -    SubMapExtender(const Graph& _graph)
  61.118 +    SubMapExtender(const GraphType& _graph)
  61.119        : Parent(_graph), graph(_graph) {}
  61.120  
  61.121 -    SubMapExtender(const Graph& _graph, const Value& _value)
  61.122 +    SubMapExtender(const GraphType& _graph, const Value& _value)
  61.123        : Parent(_graph, _value), graph(_graph) {}
  61.124  
  61.125    private:
  61.126 @@ -219,9 +226,9 @@
  61.127  
  61.128    public:
  61.129      class MapIt : public Item {
  61.130 +      typedef Item Parent;
  61.131 +
  61.132      public:
  61.133 -
  61.134 -      typedef Item Parent;
  61.135        typedef typename Map::Value Value;
  61.136  
  61.137        MapIt() {}
  61.138 @@ -258,10 +265,10 @@
  61.139      };
  61.140  
  61.141      class ConstMapIt : public Item {
  61.142 +      typedef Item Parent;
  61.143 +
  61.144      public:
  61.145  
  61.146 -      typedef Item Parent;
  61.147 -
  61.148        typedef typename Map::Value Value;
  61.149  
  61.150        ConstMapIt() {}
  61.151 @@ -289,10 +296,10 @@
  61.152      };
  61.153  
  61.154      class ItemIt : public Item {
  61.155 +      typedef Item Parent;
  61.156 +
  61.157      public:
  61.158  
  61.159 -      typedef Item Parent;
  61.160 -
  61.161        ItemIt() {}
  61.162  
  61.163        ItemIt(Invalid i) : Parent(i) { }
  61.164 @@ -316,7 +323,7 @@
  61.165  
  61.166    private:
  61.167  
  61.168 -    const Graph& graph;
  61.169 +    const GraphType& graph;
  61.170  
  61.171    };
  61.172  
    62.1 --- a/lemon/bits/path_dump.h	Fri Oct 16 10:21:37 2009 +0200
    62.2 +++ b/lemon/bits/path_dump.h	Thu Nov 05 15:50:01 2009 +0100
    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-2008
    62.8 + * Copyright (C) 2003-2009
    62.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   62.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   62.11   *
   62.12 @@ -16,8 +16,11 @@
   62.13   *
   62.14   */
   62.15  
   62.16 -#ifndef LEMON_BITS_PRED_MAP_PATH_H
   62.17 -#define LEMON_BITS_PRED_MAP_PATH_H
   62.18 +#ifndef LEMON_BITS_PATH_DUMP_H
   62.19 +#define LEMON_BITS_PATH_DUMP_H
   62.20 +
   62.21 +#include <lemon/core.h>
   62.22 +#include <lemon/concept_check.h>
   62.23  
   62.24  namespace lemon {
   62.25  
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/lemon/bits/solver_bits.h	Thu Nov 05 15:50:01 2009 +0100
    63.3 @@ -0,0 +1,193 @@
    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-2008
    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_BITS_SOLVER_BITS_H
   63.23 +#define LEMON_BITS_SOLVER_BITS_H
   63.24 +
   63.25 +#include <vector>
   63.26 +
   63.27 +namespace lemon {
   63.28 +
   63.29 +  namespace _solver_bits {
   63.30 +
   63.31 +    class VarIndex {
   63.32 +    private:
   63.33 +      struct ItemT {
   63.34 +        int prev, next;
   63.35 +        int index;
   63.36 +      };
   63.37 +      std::vector<ItemT> items;
   63.38 +      int first_item, last_item, first_free_item;
   63.39 +
   63.40 +      std::vector<int> cross;
   63.41 +
   63.42 +    public:
   63.43 +
   63.44 +      VarIndex()
   63.45 +        : first_item(-1), last_item(-1), first_free_item(-1) {
   63.46 +      }
   63.47 +
   63.48 +      void clear() {
   63.49 +        first_item = -1;
   63.50 +        first_free_item = -1;
   63.51 +        items.clear();
   63.52 +        cross.clear();
   63.53 +      }
   63.54 +
   63.55 +      int addIndex(int idx) {
   63.56 +        int n;
   63.57 +        if (first_free_item == -1) {
   63.58 +          n = items.size();
   63.59 +          items.push_back(ItemT());
   63.60 +        } else {
   63.61 +          n = first_free_item;
   63.62 +          first_free_item = items[n].next;
   63.63 +          if (first_free_item != -1) {
   63.64 +            items[first_free_item].prev = -1;
   63.65 +          }
   63.66 +        }
   63.67 +        items[n].index = idx;
   63.68 +        if (static_cast<int>(cross.size()) <= idx) {
   63.69 +          cross.resize(idx + 1, -1);
   63.70 +        }
   63.71 +        cross[idx] = n;
   63.72 +
   63.73 +        items[n].prev = last_item;
   63.74 +        items[n].next = -1;
   63.75 +        if (last_item != -1) {
   63.76 +          items[last_item].next = n;
   63.77 +        } else {
   63.78 +          first_item = n;
   63.79 +        }
   63.80 +        last_item = n;
   63.81 +
   63.82 +        return n;
   63.83 +      }
   63.84 +
   63.85 +      int addIndex(int idx, int n) {
   63.86 +        while (n >= static_cast<int>(items.size())) {
   63.87 +          items.push_back(ItemT());
   63.88 +          items.back().prev = -1;
   63.89 +          items.back().next = first_free_item;
   63.90 +          if (first_free_item != -1) {
   63.91 +            items[first_free_item].prev = items.size() - 1;
   63.92 +          }
   63.93 +          first_free_item = items.size() - 1;
   63.94 +        }
   63.95 +        if (items[n].next != -1) {
   63.96 +          items[items[n].next].prev = items[n].prev;
   63.97 +        }
   63.98 +        if (items[n].prev != -1) {
   63.99 +          items[items[n].prev].next = items[n].next;
  63.100 +        } else {
  63.101 +          first_free_item = items[n].next;
  63.102 +        }
  63.103 +
  63.104 +        items[n].index = idx;
  63.105 +        if (static_cast<int>(cross.size()) <= idx) {
  63.106 +          cross.resize(idx + 1, -1);
  63.107 +        }
  63.108 +        cross[idx] = n;
  63.109 +
  63.110 +        items[n].prev = last_item;
  63.111 +        items[n].next = -1;
  63.112 +        if (last_item != -1) {
  63.113 +          items[last_item].next = n;
  63.114 +        } else {
  63.115 +          first_item = n;
  63.116 +        }
  63.117 +        last_item = n;
  63.118 +
  63.119 +        return n;
  63.120 +      }
  63.121 +
  63.122 +      void eraseIndex(int idx) {
  63.123 +        int n = cross[idx];
  63.124 +
  63.125 +        if (items[n].prev != -1) {
  63.126 +          items[items[n].prev].next = items[n].next;
  63.127 +        } else {
  63.128 +          first_item = items[n].next;
  63.129 +        }
  63.130 +        if (items[n].next != -1) {
  63.131 +          items[items[n].next].prev = items[n].prev;
  63.132 +        } else {
  63.133 +          last_item = items[n].prev;
  63.134 +        }
  63.135 +
  63.136 +        if (first_free_item != -1) {
  63.137 +          items[first_free_item].prev = n;
  63.138 +        }
  63.139 +        items[n].next = first_free_item;
  63.140 +        items[n].prev = -1;
  63.141 +        first_free_item = n;
  63.142 +
  63.143 +        while (!cross.empty() && cross.back() == -1) {
  63.144 +          cross.pop_back();
  63.145 +        }
  63.146 +      }
  63.147 +
  63.148 +      int maxIndex() const {
  63.149 +        return cross.size() - 1;
  63.150 +      }
  63.151 +
  63.152 +      void shiftIndices(int idx) {
  63.153 +        for (int i = idx + 1; i < static_cast<int>(cross.size()); ++i) {
  63.154 +          cross[i - 1] = cross[i];
  63.155 +          if (cross[i] != -1) {
  63.156 +            --items[cross[i]].index;
  63.157 +          }
  63.158 +        }
  63.159 +        cross.back() = -1;
  63.160 +        cross.pop_back();
  63.161 +        while (!cross.empty() && cross.back() == -1) {
  63.162 +          cross.pop_back();
  63.163 +        }
  63.164 +      }
  63.165 +
  63.166 +      void relocateIndex(int idx, int jdx) {
  63.167 +        cross[idx] = cross[jdx];
  63.168 +        items[cross[jdx]].index = idx;
  63.169 +        cross[jdx] = -1;
  63.170 +
  63.171 +        while (!cross.empty() && cross.back() == -1) {
  63.172 +          cross.pop_back();
  63.173 +        }
  63.174 +      }
  63.175 +
  63.176 +      int operator[](int idx) const {
  63.177 +        return cross[idx];
  63.178 +      }
  63.179 +
  63.180 +      int operator()(int fdx) const {
  63.181 +        return items[fdx].index;
  63.182 +      }
  63.183 +
  63.184 +      void firstItem(int& fdx) const {
  63.185 +        fdx = first_item;
  63.186 +      }
  63.187 +
  63.188 +      void nextItem(int& fdx) const {
  63.189 +        fdx = items[fdx].next;
  63.190 +      }
  63.191 +
  63.192 +    };
  63.193 +  }
  63.194 +}
  63.195 +
  63.196 +#endif
    64.1 --- a/lemon/bits/traits.h	Fri Oct 16 10:21:37 2009 +0200
    64.2 +++ b/lemon/bits/traits.h	Thu Nov 05 15:50:01 2009 +0100
    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-2008
    64.8 + * Copyright (C) 2003-2009
    64.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   64.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   64.11   *
   64.12 @@ -29,117 +29,123 @@
   64.13  
   64.14    struct InvalidType {};
   64.15  
   64.16 -  template <typename _Graph, typename _Item>
   64.17 +  template <typename GR, typename _Item>
   64.18    class ItemSetTraits {};
   64.19  
   64.20  
   64.21 -  template <typename Graph, typename Enable = void>
   64.22 +  template <typename GR, typename Enable = void>
   64.23    struct NodeNotifierIndicator {
   64.24      typedef InvalidType Type;
   64.25    };
   64.26 -  template <typename Graph>
   64.27 +  template <typename GR>
   64.28    struct NodeNotifierIndicator<
   64.29 -    Graph,
   64.30 -    typename enable_if<typename Graph::NodeNotifier::Notifier, void>::type
   64.31 +    GR,
   64.32 +    typename enable_if<typename GR::NodeNotifier::Notifier, void>::type
   64.33    > {
   64.34 -    typedef typename Graph::NodeNotifier Type;
   64.35 +    typedef typename GR::NodeNotifier Type;
   64.36    };
   64.37  
   64.38 -  template <typename _Graph>
   64.39 -  class ItemSetTraits<_Graph, typename _Graph::Node> {
   64.40 +  template <typename GR>
   64.41 +  class ItemSetTraits<GR, typename GR::Node> {
   64.42    public:
   64.43  
   64.44 -    typedef _Graph Graph;
   64.45 +    typedef GR Graph;
   64.46 +    typedef GR Digraph;
   64.47  
   64.48 -    typedef typename Graph::Node Item;
   64.49 -    typedef typename Graph::NodeIt ItemIt;
   64.50 +    typedef typename GR::Node Item;
   64.51 +    typedef typename GR::NodeIt ItemIt;
   64.52  
   64.53 -    typedef typename NodeNotifierIndicator<Graph>::Type ItemNotifier;
   64.54 +    typedef typename NodeNotifierIndicator<GR>::Type ItemNotifier;
   64.55  
   64.56 -    template <typename _Value>
   64.57 -    class Map : public Graph::template NodeMap<_Value> {
   64.58 +    template <typename V>
   64.59 +    class Map : public GR::template NodeMap<V> {
   64.60 +      typedef typename GR::template NodeMap<V> Parent;
   64.61 +
   64.62      public:
   64.63 -      typedef typename Graph::template NodeMap<_Value> Parent;
   64.64 -      typedef typename Graph::template NodeMap<_Value> Type;
   64.65 +      typedef typename GR::template NodeMap<V> Type;
   64.66        typedef typename Parent::Value Value;
   64.67  
   64.68 -      Map(const Graph& _digraph) : Parent(_digraph) {}
   64.69 -      Map(const Graph& _digraph, const Value& _value)
   64.70 +      Map(const GR& _digraph) : Parent(_digraph) {}
   64.71 +      Map(const GR& _digraph, const Value& _value)
   64.72          : Parent(_digraph, _value) {}
   64.73  
   64.74       };
   64.75  
   64.76    };
   64.77  
   64.78 -  template <typename Graph, typename Enable = void>
   64.79 +  template <typename GR, typename Enable = void>
   64.80    struct ArcNotifierIndicator {
   64.81      typedef InvalidType Type;
   64.82    };
   64.83 -  template <typename Graph>
   64.84 +  template <typename GR>
   64.85    struct ArcNotifierIndicator<
   64.86 -    Graph,
   64.87 -    typename enable_if<typename Graph::ArcNotifier::Notifier, void>::type
   64.88 +    GR,
   64.89 +    typename enable_if<typename GR::ArcNotifier::Notifier, void>::type
   64.90    > {
   64.91 -    typedef typename Graph::ArcNotifier Type;
   64.92 +    typedef typename GR::ArcNotifier Type;
   64.93    };
   64.94  
   64.95 -  template <typename _Graph>
   64.96 -  class ItemSetTraits<_Graph, typename _Graph::Arc> {
   64.97 +  template <typename GR>
   64.98 +  class ItemSetTraits<GR, typename GR::Arc> {
   64.99    public:
  64.100  
  64.101 -    typedef _Graph Graph;
  64.102 +    typedef GR Graph;
  64.103 +    typedef GR Digraph;
  64.104  
  64.105 -    typedef typename Graph::Arc Item;
  64.106 -    typedef typename Graph::ArcIt ItemIt;
  64.107 +    typedef typename GR::Arc Item;
  64.108 +    typedef typename GR::ArcIt ItemIt;
  64.109  
  64.110 -    typedef typename ArcNotifierIndicator<Graph>::Type ItemNotifier;
  64.111 +    typedef typename ArcNotifierIndicator<GR>::Type ItemNotifier;
  64.112  
  64.113 -    template <typename _Value>
  64.114 -    class Map : public Graph::template ArcMap<_Value> {
  64.115 +    template <typename V>
  64.116 +    class Map : public GR::template ArcMap<V> {
  64.117 +      typedef typename GR::template ArcMap<V> Parent;
  64.118 +
  64.119      public:
  64.120 -      typedef typename Graph::template ArcMap<_Value> Parent;
  64.121 -      typedef typename Graph::template ArcMap<_Value> Type;
  64.122 +      typedef typename GR::template ArcMap<V> Type;
  64.123        typedef typename Parent::Value Value;
  64.124  
  64.125 -      Map(const Graph& _digraph) : Parent(_digraph) {}
  64.126 -      Map(const Graph& _digraph, const Value& _value)
  64.127 +      Map(const GR& _digraph) : Parent(_digraph) {}
  64.128 +      Map(const GR& _digraph, const Value& _value)
  64.129          : Parent(_digraph, _value) {}
  64.130      };
  64.131  
  64.132    };
  64.133  
  64.134 -  template <typename Graph, typename Enable = void>
  64.135 +  template <typename GR, typename Enable = void>
  64.136    struct EdgeNotifierIndicator {
  64.137      typedef InvalidType Type;
  64.138    };
  64.139 -  template <typename Graph>
  64.140 +  template <typename GR>
  64.141    struct EdgeNotifierIndicator<
  64.142 -    Graph,
  64.143 -    typename enable_if<typename Graph::EdgeNotifier::Notifier, void>::type
  64.144 +    GR,
  64.145 +    typename enable_if<typename GR::EdgeNotifier::Notifier, void>::type
  64.146    > {
  64.147 -    typedef typename Graph::EdgeNotifier Type;
  64.148 +    typedef typename GR::EdgeNotifier Type;
  64.149    };
  64.150  
  64.151 -  template <typename _Graph>
  64.152 -  class ItemSetTraits<_Graph, typename _Graph::Edge> {
  64.153 +  template <typename GR>
  64.154 +  class ItemSetTraits<GR, typename GR::Edge> {
  64.155    public:
  64.156  
  64.157 -    typedef _Graph Graph;
  64.158 +    typedef GR Graph;
  64.159 +    typedef GR Digraph;
  64.160  
  64.161 -    typedef typename Graph::Edge Item;
  64.162 -    typedef typename Graph::EdgeIt ItemIt;
  64.163 +    typedef typename GR::Edge Item;
  64.164 +    typedef typename GR::EdgeIt ItemIt;
  64.165  
  64.166 -    typedef typename EdgeNotifierIndicator<Graph>::Type ItemNotifier;
  64.167 +    typedef typename EdgeNotifierIndicator<GR>::Type ItemNotifier;
  64.168  
  64.169 -    template <typename _Value>
  64.170 -    class Map : public Graph::template EdgeMap<_Value> {
  64.171 +    template <typename V>
  64.172 +    class Map : public GR::template EdgeMap<V> {
  64.173 +      typedef typename GR::template EdgeMap<V> Parent;
  64.174 +
  64.175      public:
  64.176 -      typedef typename Graph::template EdgeMap<_Value> Parent;
  64.177 -      typedef typename Graph::template EdgeMap<_Value> Type;
  64.178 +      typedef typename GR::template EdgeMap<V> Type;
  64.179        typedef typename Parent::Value Value;
  64.180  
  64.181 -      Map(const Graph& _digraph) : Parent(_digraph) {}
  64.182 -      Map(const Graph& _digraph, const Value& _value)
  64.183 +      Map(const GR& _digraph) : Parent(_digraph) {}
  64.184 +      Map(const GR& _digraph, const Value& _value)
  64.185          : Parent(_digraph, _value) {}
  64.186      };
  64.187  
  64.188 @@ -204,67 +210,93 @@
  64.189  
  64.190    // Indicators for the tags
  64.191  
  64.192 -  template <typename Graph, typename Enable = void>
  64.193 +  template <typename GR, typename Enable = void>
  64.194    struct NodeNumTagIndicator {
  64.195      static const bool value = false;
  64.196    };
  64.197  
  64.198 -  template <typename Graph>
  64.199 +  template <typename GR>
  64.200    struct NodeNumTagIndicator<
  64.201 -    Graph,
  64.202 -    typename enable_if<typename Graph::NodeNumTag, void>::type
  64.203 +    GR,
  64.204 +    typename enable_if<typename GR::NodeNumTag, void>::type
  64.205    > {
  64.206      static const bool value = true;
  64.207    };
  64.208  
  64.209 -  template <typename Graph, typename Enable = void>
  64.210 +  template <typename GR, typename Enable = void>
  64.211 +  struct ArcNumTagIndicator {
  64.212 +    static const bool value = false;
  64.213 +  };
  64.214 +
  64.215 +  template <typename GR>
  64.216 +  struct ArcNumTagIndicator<
  64.217 +    GR,
  64.218 +    typename enable_if<typename GR::ArcNumTag, void>::type
  64.219 +  > {
  64.220 +    static const bool value = true;
  64.221 +  };
  64.222 +
  64.223 +  template <typename GR, typename Enable = void>
  64.224    struct EdgeNumTagIndicator {
  64.225      static const bool value = false;
  64.226    };
  64.227  
  64.228 -  template <typename Graph>
  64.229 +  template <typename GR>
  64.230    struct EdgeNumTagIndicator<
  64.231 -    Graph,
  64.232 -    typename enable_if<typename Graph::EdgeNumTag, void>::type
  64.233 +    GR,
  64.234 +    typename enable_if<typename GR::EdgeNumTag, void>::type
  64.235    > {
  64.236      static const bool value = true;
  64.237    };
  64.238  
  64.239 -  template <typename Graph, typename Enable = void>
  64.240 +  template <typename GR, typename Enable = void>
  64.241 +  struct FindArcTagIndicator {
  64.242 +    static const bool value = false;
  64.243 +  };
  64.244 +
  64.245 +  template <typename GR>
  64.246 +  struct FindArcTagIndicator<
  64.247 +    GR,
  64.248 +    typename enable_if<typename GR::FindArcTag, void>::type
  64.249 +  > {
  64.250 +    static const bool value = true;
  64.251 +  };
  64.252 +
  64.253 +  template <typename GR, typename Enable = void>
  64.254    struct FindEdgeTagIndicator {
  64.255      static const bool value = false;
  64.256    };
  64.257  
  64.258 -  template <typename Graph>
  64.259 +  template <typename GR>
  64.260    struct FindEdgeTagIndicator<
  64.261 -    Graph,
  64.262 -    typename enable_if<typename Graph::FindEdgeTag, void>::type
  64.263 +    GR,
  64.264 +    typename enable_if<typename GR::FindEdgeTag, void>::type
  64.265    > {
  64.266      static const bool value = true;
  64.267    };
  64.268  
  64.269 -  template <typename Graph, typename Enable = void>
  64.270 +  template <typename GR, typename Enable = void>
  64.271    struct UndirectedTagIndicator {
  64.272      static const bool value = false;
  64.273    };
  64.274  
  64.275 -  template <typename Graph>
  64.276 +  template <typename GR>
  64.277    struct UndirectedTagIndicator<
  64.278 -    Graph,
  64.279 -    typename enable_if<typename Graph::UndirectedTag, void>::type
  64.280 +    GR,
  64.281 +    typename enable_if<typename GR::UndirectedTag, void>::type
  64.282    > {
  64.283      static const bool value = true;
  64.284    };
  64.285  
  64.286 -  template <typename Graph, typename Enable = void>
  64.287 +  template <typename GR, typename Enable = void>
  64.288    struct BuildTagIndicator {
  64.289      static const bool value = false;
  64.290    };
  64.291  
  64.292 -  template <typename Graph>
  64.293 +  template <typename GR>
  64.294    struct BuildTagIndicator<
  64.295 -    Graph,
  64.296 -    typename enable_if<typename Graph::BuildTag, void>::type
  64.297 +    GR,
  64.298 +    typename enable_if<typename GR::BuildTag, void>::type
  64.299    > {
  64.300      static const bool value = true;
  64.301    };
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/lemon/bits/variant.h	Thu Nov 05 15:50:01 2009 +0100
    65.3 @@ -0,0 +1,494 @@
    65.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    65.5 + *
    65.6 + * This file is a part of LEMON, a generic C++ optimization library.
    65.7 + *
    65.8 + * Copyright (C) 2003-2009
    65.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   65.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   65.11 + *
   65.12 + * Permission to use, modify and distribute this software is granted
   65.13 + * provided that this copyright notice appears in all copies. For
   65.14 + * precise terms see the accompanying LICENSE file.
   65.15 + *
   65.16 + * This software is provided "AS IS" with no warranty of any kind,
   65.17 + * express or implied, and with no claim as to its suitability for any
   65.18 + * purpose.
   65.19 + *
   65.20 + */
   65.21 +
   65.22 +#ifndef LEMON_BITS_VARIANT_H
   65.23 +#define LEMON_BITS_VARIANT_H
   65.24 +
   65.25 +#include <lemon/assert.h>
   65.26 +
   65.27 +// \file
   65.28 +// \brief Variant types
   65.29 +
   65.30 +namespace lemon {
   65.31 +
   65.32 +  namespace _variant_bits {
   65.33 +
   65.34 +    template <int left, int right>
   65.35 +    struct CTMax {
   65.36 +      static const int value = left < right ? right : left;
   65.37 +    };
   65.38 +
   65.39 +  }
   65.40 +
   65.41 +
   65.42 +  // \brief Simple Variant type for two types
   65.43 +  //
   65.44 +  // Simple Variant type for two types. The Variant type is a type-safe
   65.45 +  // union. C++ has strong limitations for using unions, for
   65.46 +  // example you cannot store a type with non-default constructor or
   65.47 +  // destructor in a union. This class always knowns the current
   65.48 +  // state of the variant and it cares for the proper construction
   65.49 +  // and destruction.
   65.50 +  template <typename _First, typename _Second>
   65.51 +  class BiVariant {
   65.52 +  public:
   65.53 +
   65.54 +    // \brief The \c First type.
   65.55 +    typedef _First First;
   65.56 +    // \brief The \c Second type.
   65.57 +    typedef _Second Second;
   65.58 +
   65.59 +    // \brief Constructor
   65.60 +    //
   65.61 +    // This constructor initalizes to the default value of the \c First
   65.62 +    // type.
   65.63 +    BiVariant() {
   65.64 +      flag = true;
   65.65 +      new(reinterpret_cast<First*>(data)) First();
   65.66 +    }
   65.67 +
   65.68 +    // \brief Constructor
   65.69 +    //
   65.70 +    // This constructor initalizes to the given value of the \c First
   65.71 +    // type.
   65.72 +    BiVariant(const First& f) {
   65.73 +      flag = true;
   65.74 +      new(reinterpret_cast<First*>(data)) First(f);
   65.75 +    }
   65.76 +
   65.77 +    // \brief Constructor
   65.78 +    //
   65.79 +    // This constructor initalizes to the given value of the \c
   65.80 +    // Second type.
   65.81 +    BiVariant(const Second& s) {
   65.82 +      flag = false;
   65.83 +      new(reinterpret_cast<Second*>(data)) Second(s);
   65.84 +    }
   65.85 +
   65.86 +    // \brief Copy constructor
   65.87 +    //
   65.88 +    // Copy constructor
   65.89 +    BiVariant(const BiVariant& bivariant) {
   65.90 +      flag = bivariant.flag;
   65.91 +      if (flag) {
   65.92 +        new(reinterpret_cast<First*>(data)) First(bivariant.first());
   65.93 +      } else {
   65.94 +        new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
   65.95 +      }
   65.96 +    }
   65.97 +
   65.98 +    // \brief Destrcutor
   65.99 +    //
  65.100 +    // Destructor
  65.101 +    ~BiVariant() {
  65.102 +      destroy();
  65.103 +    }
  65.104 +
  65.105 +    // \brief Set to the default value of the \c First type.
  65.106 +    //
  65.107 +    // This function sets the variant to the default value of the \c
  65.108 +    // First type.
  65.109 +    BiVariant& setFirst() {
  65.110 +      destroy();
  65.111 +      flag = true;
  65.112 +      new(reinterpret_cast<First*>(data)) First();
  65.113 +      return *this;
  65.114 +    }
  65.115 +
  65.116 +    // \brief Set to the given value of the \c First type.
  65.117 +    //
  65.118 +    // This function sets the variant to the given value of the \c
  65.119 +    // First type.
  65.120 +    BiVariant& setFirst(const First& f) {
  65.121 +      destroy();
  65.122 +      flag = true;
  65.123 +      new(reinterpret_cast<First*>(data)) First(f);
  65.124 +      return *this;
  65.125 +    }
  65.126 +
  65.127 +    // \brief Set to the default value of the \c Second type.
  65.128 +    //
  65.129 +    // This function sets the variant to the default value of the \c
  65.130 +    // Second type.
  65.131 +    BiVariant& setSecond() {
  65.132 +      destroy();
  65.133 +      flag = false;
  65.134 +      new(reinterpret_cast<Second*>(data)) Second();
  65.135 +      return *this;
  65.136 +    }
  65.137 +
  65.138 +    // \brief Set to the given value of the \c Second type.
  65.139 +    //
  65.140 +    // This function sets the variant to the given value of the \c
  65.141 +    // Second type.
  65.142 +    BiVariant& setSecond(const Second& s) {
  65.143 +      destroy();
  65.144 +      flag = false;
  65.145 +      new(reinterpret_cast<Second*>(data)) Second(s);
  65.146 +      return *this;
  65.147 +    }
  65.148 +
  65.149 +    // \brief Operator form of the \c setFirst()
  65.150 +    BiVariant& operator=(const First& f) {
  65.151 +      return setFirst(f);
  65.152 +    }
  65.153 +
  65.154 +    // \brief Operator form of the \c setSecond()
  65.155 +    BiVariant& operator=(const Second& s) {
  65.156 +      return setSecond(s);
  65.157 +    }
  65.158 +
  65.159 +    // \brief Assign operator
  65.160 +    BiVariant& operator=(const BiVariant& bivariant) {
  65.161 +      if (this == &bivariant) return *this;
  65.162 +      destroy();
  65.163 +      flag = bivariant.flag;
  65.164 +      if (flag) {
  65.165 +        new(reinterpret_cast<First*>(data)) First(bivariant.first());
  65.166 +      } else {
  65.167 +        new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
  65.168 +      }
  65.169 +      return *this;
  65.170 +    }
  65.171 +
  65.172 +    // \brief Reference to the value
  65.173 +    //
  65.174 +    // Reference to the value of the \c First type.
  65.175 +    // \pre The BiVariant should store value of \c First type.
  65.176 +    First& first() {
  65.177 +      LEMON_DEBUG(flag, "Variant wrong state");
  65.178 +      return *reinterpret_cast<First*>(data);
  65.179 +    }
  65.180 +
  65.181 +    // \brief Const reference to the value
  65.182 +    //
  65.183 +    // Const reference to the value of the \c First type.
  65.184 +    // \pre The BiVariant should store value of \c First type.
  65.185 +    const First& first() const {
  65.186 +      LEMON_DEBUG(flag, "Variant wrong state");
  65.187 +      return *reinterpret_cast<const First*>(data);
  65.188 +    }
  65.189 +
  65.190 +    // \brief Operator form of the \c first()
  65.191 +    operator First&() { return first(); }
  65.192 +    // \brief Operator form of the const \c first()
  65.193 +    operator const First&() const { return first(); }
  65.194 +
  65.195 +    // \brief Reference to the value
  65.196 +    //
  65.197 +    // Reference to the value of the \c Second type.
  65.198 +    // \pre The BiVariant should store value of \c Second type.
  65.199 +    Second& second() {
  65.200 +      LEMON_DEBUG(!flag, "Variant wrong state");
  65.201 +      return *reinterpret_cast<Second*>(data);
  65.202 +    }
  65.203 +
  65.204 +    // \brief Const reference to the value
  65.205 +    //
  65.206 +    // Const reference to the value of the \c Second type.
  65.207 +    // \pre The BiVariant should store value of \c Second type.
  65.208 +    const Second& second() const {
  65.209 +      LEMON_DEBUG(!flag, "Variant wrong state");
  65.210 +      return *reinterpret_cast<const Second*>(data);
  65.211 +    }
  65.212 +
  65.213 +    // \brief Operator form of the \c second()
  65.214 +    operator Second&() { return second(); }
  65.215 +    // \brief Operator form of the const \c second()
  65.216 +    operator const Second&() const { return second(); }
  65.217 +
  65.218 +    // \brief %True when the variant is in the first state
  65.219 +    //
  65.220 +    // %True when the variant stores value of the \c First type.
  65.221 +    bool firstState() const { return flag; }
  65.222 +
  65.223 +    // \brief %True when the variant is in the second state
  65.224 +    //
  65.225 +    // %True when the variant stores value of the \c Second type.
  65.226 +    bool secondState() const { return !flag; }
  65.227 +
  65.228 +  private:
  65.229 +
  65.230 +    void destroy() {
  65.231 +      if (flag) {
  65.232 +        reinterpret_cast<First*>(data)->~First();
  65.233 +      } else {
  65.234 +        reinterpret_cast<Second*>(data)->~Second();
  65.235 +      }
  65.236 +    }
  65.237 +
  65.238 +    char data[_variant_bits::CTMax<sizeof(First), sizeof(Second)>::value];
  65.239 +    bool flag;
  65.240 +  };
  65.241 +
  65.242 +  namespace _variant_bits {
  65.243 +
  65.244 +    template <int _idx, typename _TypeMap>
  65.245 +    struct Memory {
  65.246 +
  65.247 +      typedef typename _TypeMap::template Map<_idx>::Type Current;
  65.248 +
  65.249 +      static void destroy(int index, char* place) {
  65.250 +        if (index == _idx) {
  65.251 +          reinterpret_cast<Current*>(place)->~Current();
  65.252 +        } else {
  65.253 +          Memory<_idx - 1, _TypeMap>::destroy(index, place);
  65.254 +        }
  65.255 +      }
  65.256 +
  65.257 +      static void copy(int index, char* to, const char* from) {
  65.258 +        if (index == _idx) {
  65.259 +          new (reinterpret_cast<Current*>(to))
  65.260 +            Current(reinterpret_cast<const Current*>(from));
  65.261 +        } else {
  65.262 +          Memory<_idx - 1, _TypeMap>::copy(index, to, from);
  65.263 +        }
  65.264 +      }
  65.265 +
  65.266 +    };
  65.267 +
  65.268 +    template <typename _TypeMap>
  65.269 +    struct Memory<-1, _TypeMap> {
  65.270 +
  65.271 +      static void destroy(int, char*) {
  65.272 +        LEMON_DEBUG(false, "Variant wrong index.");
  65.273 +      }
  65.274 +
  65.275 +      static void copy(int, char*, const char*) {
  65.276 +        LEMON_DEBUG(false, "Variant wrong index.");
  65.277 +      }
  65.278 +    };
  65.279 +
  65.280 +    template <int _idx, typename _TypeMap>
  65.281 +    struct Size {
  65.282 +      static const int value =
  65.283 +      CTMax<sizeof(typename _TypeMap::template Map<_idx>::Type),
  65.284 +            Size<_idx - 1, _TypeMap>::value>::value;
  65.285 +    };
  65.286 +
  65.287 +    template <typename _TypeMap>
  65.288 +    struct Size<0, _TypeMap> {
  65.289 +      static const int value =
  65.290 +      sizeof(typename _TypeMap::template Map<0>::Type);
  65.291 +    };
  65.292 +
  65.293 +  }
  65.294 +
  65.295 +  // \brief Variant type
  65.296 +  //
  65.297 +  // Simple Variant type. The Variant type is a type-safe union.
  65.298 +  // C++ has strong limitations for using unions, for example you
  65.299 +  // cannot store type with non-default constructor or destructor in
  65.300 +  // a union. This class always knowns the current state of the
  65.301 +  // variant and it cares for the proper construction and
  65.302 +  // destruction.
  65.303 +  //
  65.304 +  // \param _num The number of the types which can be stored in the
  65.305 +  // variant type.
  65.306 +  // \param _TypeMap This class describes the types of the Variant. The
  65.307 +  // _TypeMap::Map<index>::Type should be a valid type for each index
  65.308 +  // in the range {0, 1, ..., _num - 1}. The \c VariantTypeMap is helper
  65.309 +  // class to define such type mappings up to 10 types.
  65.310 +  //
  65.311 +  // And the usage of the class:
  65.312 +  //\code
  65.313 +  // typedef Variant<3, VariantTypeMap<int, std::string, double> > MyVariant;
  65.314 +  // MyVariant var;
  65.315 +  // var.set<0>(12);
  65.316 +  // std::cout << var.get<0>() << std::endl;
  65.317 +  // var.set<1>("alpha");
  65.318 +  // std::cout << var.get<1>() << std::endl;
  65.319 +  // var.set<2>(0.75);
  65.320 +  // std::cout << var.get<2>() << std::endl;
  65.321 +  //\endcode
  65.322 +  //
  65.323 +  // The result of course:
  65.324 +  //\code
  65.325 +  // 12
  65.326 +  // alpha
  65.327 +  // 0.75
  65.328 +  //\endcode
  65.329 +  template <int _num, typename _TypeMap>
  65.330 +  class Variant {
  65.331 +  public:
  65.332 +
  65.333 +    static const int num = _num;
  65.334 +
  65.335 +    typedef _TypeMap TypeMap;
  65.336 +
  65.337 +    // \brief Constructor
  65.338 +    //
  65.339 +    // This constructor initalizes to the default value of the \c type
  65.340 +    // with 0 index.
  65.341 +    Variant() {
  65.342 +      flag = 0;
  65.343 +      new(reinterpret_cast<typename TypeMap::template Map<0>::Type*>(data))
  65.344 +        typename TypeMap::template Map<0>::Type();
  65.345 +    }
  65.346 +
  65.347 +
  65.348 +    // \brief Copy constructor
  65.349 +    //
  65.350 +    // Copy constructor
  65.351 +    Variant(const Variant& variant) {
  65.352 +      flag = variant.flag;
  65.353 +      _variant_bits::Memory<num - 1, TypeMap>::copy(flag, data, variant.data);
  65.354 +    }
  65.355 +
  65.356 +    // \brief Assign operator
  65.357 +    //
  65.358 +    // Assign operator
  65.359 +    Variant& operator=(const Variant& variant) {
  65.360 +      if (this == &variant) return *this;
  65.361 +      _variant_bits::Memory<num - 1, TypeMap>::
  65.362 +        destroy(flag, data);
  65.363 +      flag = variant.flag;
  65.364 +      _variant_bits::Memory<num - 1, TypeMap>::
  65.365 +        copy(flag, data, variant.data);
  65.366 +      return *this;
  65.367 +    }
  65.368 +
  65.369 +    // \brief Destrcutor
  65.370 +    //
  65.371 +    // Destructor
  65.372 +    ~Variant() {
  65.373 +      _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
  65.374 +    }
  65.375 +
  65.376 +    // \brief Set to the default value of the type with \c _idx index.
  65.377 +    //
  65.378 +    // This function sets the variant to the default value of the
  65.379 +    // type with \c _idx index.
  65.380 +    template <int _idx>
  65.381 +    Variant& set() {
  65.382 +      _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
  65.383 +      flag = _idx;
  65.384 +      new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
  65.385 +        typename TypeMap::template Map<_idx>::Type();
  65.386 +      return *this;
  65.387 +    }
  65.388 +
  65.389 +    // \brief Set to the given value of the type with \c _idx index.
  65.390 +    //
  65.391 +    // This function sets the variant to the given value of the type
  65.392 +    // with \c _idx index.
  65.393 +    template <int _idx>
  65.394 +    Variant& set(const typename _TypeMap::template Map<_idx>::Type& init) {
  65.395 +      _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
  65.396 +      flag = _idx;
  65.397 +      new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
  65.398 +        typename TypeMap::template Map<_idx>::Type(init);
  65.399 +      return *this;
  65.400 +    }
  65.401 +
  65.402 +    // \brief Gets the current value of the type with \c _idx index.
  65.403 +    //
  65.404 +    // Gets the current value of the type with \c _idx index.
  65.405 +    template <int _idx>
  65.406 +    const typename TypeMap::template Map<_idx>::Type& get() const {
  65.407 +      LEMON_DEBUG(_idx == flag, "Variant wrong index");
  65.408 +      return *reinterpret_cast<const typename TypeMap::
  65.409 +        template Map<_idx>::Type*>(data);
  65.410 +    }
  65.411 +
  65.412 +    // \brief Gets the current value of the type with \c _idx index.
  65.413 +    //
  65.414 +    // Gets the current value of the type with \c _idx index.
  65.415 +    template <int _idx>
  65.416 +    typename _TypeMap::template Map<_idx>::Type& get() {
  65.417 +      LEMON_DEBUG(_idx == flag, "Variant wrong index");
  65.418 +      return *reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>
  65.419 +        (data);
  65.420 +    }
  65.421 +
  65.422 +    // \brief Returns the current state of the variant.
  65.423 +    //
  65.424 +    // Returns the current state of the variant.
  65.425 +    int state() const {
  65.426 +      return flag;
  65.427 +    }
  65.428 +
  65.429 +  private:
  65.430 +
  65.431 +    char data[_variant_bits::Size<num - 1, TypeMap>::value];
  65.432 +    int flag;
  65.433 +  };
  65.434 +
  65.435 +  namespace _variant_bits {
  65.436 +
  65.437 +    template <int _index, typename _List>
  65.438 +    struct Get {
  65.439 +      typedef typename Get<_index - 1, typename _List::Next>::Type Type;
  65.440 +    };
  65.441 +
  65.442 +    template <typename _List>
  65.443 +    struct Get<0, _List> {
  65.444 +      typedef typename _List::Type Type;
  65.445 +    };
  65.446 +
  65.447 +    struct List {};
  65.448 +
  65.449 +    template <typename _Type, typename _List>
  65.450 +    struct Insert {
  65.451 +      typedef _List Next;
  65.452 +      typedef _Type Type;
  65.453 +    };
  65.454 +
  65.455 +    template <int _idx, typename _T0, typename _T1, typename _T2,
  65.456 +              typename _T3, typename _T4, typename _T5, typename _T6,
  65.457 +              typename _T7, typename _T8, typename _T9>
  65.458 +    struct Mapper {
  65.459 +      typedef List L10;
  65.460 +      typedef Insert<_T9, L10> L9;
  65.461 +      typedef Insert<_T8, L9> L8;
  65.462 +      typedef Insert<_T7, L8> L7;
  65.463 +      typedef Insert<_T6, L7> L6;
  65.464 +      typedef Insert<_T5, L6> L5;
  65.465 +      typedef Insert<_T4, L5> L4;
  65.466 +      typedef Insert<_T3, L4> L3;
  65.467 +      typedef Insert<_T2, L3> L2;
  65.468 +      typedef Insert<_T1, L2> L1;
  65.469 +      typedef Insert<_T0, L1> L0;
  65.470 +      typedef typename Get<_idx, L0>::Type Type;
  65.471 +    };
  65.472 +
  65.473 +  }
  65.474 +
  65.475 +  // \brief Helper class for Variant
  65.476 +  //
  65.477 +  // Helper class to define type mappings for Variant. This class
  65.478 +  // converts the template parameters to be mappable by integer.
  65.479 +  // \see Variant
  65.480 +  template <
  65.481 +    typename _T0,
  65.482 +    typename _T1 = void, typename _T2 = void, typename _T3 = void,
  65.483 +    typename _T4 = void, typename _T5 = void, typename _T6 = void,
  65.484 +    typename _T7 = void, typename _T8 = void, typename _T9 = void>
  65.485 +  struct VariantTypeMap {
  65.486 +    template <int _idx>
  65.487 +    struct Map {
  65.488 +      typedef typename _variant_bits::
  65.489 +      Mapper<_idx, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>::Type
  65.490 +      Type;
  65.491 +    };
  65.492 +  };
  65.493 +
  65.494 +}
  65.495 +
  65.496 +
  65.497 +#endif
    66.1 --- a/lemon/bits/vector_map.h	Fri Oct 16 10:21:37 2009 +0200
    66.2 +++ b/lemon/bits/vector_map.h	Thu Nov 05 15:50:01 2009 +0100
    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-2008
    66.8 + * Copyright (C) 2003-2009
    66.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   66.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   66.11   *
   66.12 @@ -38,9 +38,9 @@
   66.13    //
   66.14    // \brief Graph map based on the std::vector storage.
   66.15    //
   66.16 -  // The VectorMap template class is graph map structure what
   66.17 -  // automatically updates the map when a key is added to or erased from
   66.18 -  // the map. This map type uses the std::vector to store the values.
   66.19 +  // The VectorMap template class is graph map structure that automatically
   66.20 +  // updates the map when a key is added to or erased from the graph.
   66.21 +  // This map type uses std::vector to store the values.
   66.22    //
   66.23    // \tparam _Graph The graph this map is attached to.
   66.24    // \tparam _Item The item type of the graph items.
   66.25 @@ -56,7 +56,7 @@
   66.26    public:
   66.27  
   66.28      // The graph type of the map.
   66.29 -    typedef _Graph Graph;
   66.30 +    typedef _Graph GraphType;
   66.31      // The item type of the map.
   66.32      typedef _Item Item;
   66.33      // The reference map tag.
   66.34 @@ -72,20 +72,24 @@
   66.35  
   66.36      // The map type.
   66.37      typedef VectorMap Map;
   66.38 -    // The base class of the map.
   66.39 -    typedef typename Notifier::ObserverBase Parent;
   66.40  
   66.41      // The reference type of the map;
   66.42      typedef typename Container::reference Reference;
   66.43      // The const reference type of the map;
   66.44      typedef typename Container::const_reference ConstReference;
   66.45  
   66.46 +  private:
   66.47 +
   66.48 +    // The base class of the map.
   66.49 +    typedef typename Notifier::ObserverBase Parent;
   66.50 +
   66.51 +  public:
   66.52  
   66.53      // \brief Constructor to attach the new map into the notifier.
   66.54      //
   66.55      // It constructs a map and attachs it into the notifier.
   66.56      // It adds all the items of the graph to the map.
   66.57 -    VectorMap(const Graph& graph) {
   66.58 +    VectorMap(const GraphType& graph) {
   66.59        Parent::attach(graph.notifier(Item()));
   66.60        container.resize(Parent::notifier()->maxId() + 1);
   66.61      }
   66.62 @@ -94,7 +98,7 @@
   66.63      //
   66.64      // It constructs a map uses a given value to initialize the map.
   66.65      // It adds all the items of the graph to the map.
   66.66 -    VectorMap(const Graph& graph, const Value& value) {
   66.67 +    VectorMap(const GraphType& graph, const Value& value) {
   66.68        Parent::attach(graph.notifier(Item()));
   66.69        container.resize(Parent::notifier()->maxId() + 1, value);
   66.70      }
   66.71 @@ -124,7 +128,7 @@
   66.72  
   66.73      // \brief Template assign operator.
   66.74      //
   66.75 -    // The given parameter should be conform to the ReadMap
   66.76 +    // The given parameter should conform to the ReadMap
   66.77      // concecpt and could be indiced by the current item set of
   66.78      // the NodeMap. In this case the value for each item
   66.79      // is assigned by the value of the given ReadMap.
   66.80 @@ -169,7 +173,7 @@
   66.81  
   66.82      // \brief Adds a new key to the map.
   66.83      //
   66.84 -    // It adds a new key to the map. It called by the observer notifier
   66.85 +    // It adds a new key to the map. It is called by the observer notifier
   66.86      // and it overrides the add() member function of the observer base.
   66.87      virtual void add(const Key& key) {
   66.88        int id = Parent::notifier()->id(key);
   66.89 @@ -180,7 +184,7 @@
   66.90  
   66.91      // \brief Adds more new keys to the map.
   66.92      //
   66.93 -    // It adds more new keys to the map. It called by the observer notifier
   66.94 +    // It adds more new keys to the map. It is called by the observer notifier
   66.95      // and it overrides the add() member function of the observer base.
   66.96      virtual void add(const std::vector<Key>& keys) {
   66.97        int max = container.size() - 1;
   66.98 @@ -195,7 +199,7 @@
   66.99  
  66.100      // \brief Erase a key from the map.
  66.101      //
  66.102 -    // Erase a key from the map. It called by the observer notifier
  66.103 +    // Erase a key from the map. It is called by the observer notifier
  66.104      // and it overrides the erase() member function of the observer base.
  66.105      virtual void erase(const Key& key) {
  66.106        container[Parent::notifier()->id(key)] = Value();
  66.107 @@ -203,7 +207,7 @@
  66.108  
  66.109      // \brief Erase more keys from the map.
  66.110      //
  66.111 -    // Erase more keys from the map. It called by the observer notifier
  66.112 +    // It erases more keys from the map. It is called by the observer notifier
  66.113      // and it overrides the erase() member function of the observer base.
  66.114      virtual void erase(const std::vector<Key>& keys) {
  66.115        for (int i = 0; i < int(keys.size()); ++i) {
  66.116 @@ -211,9 +215,9 @@
  66.117        }
  66.118      }
  66.119  
  66.120 -    // \brief Buildes the map.
  66.121 +    // \brief Build the map.
  66.122      //
  66.123 -    // It buildes the map. It called by the observer notifier
  66.124 +    // It builds the map. It is called by the observer notifier
  66.125      // and it overrides the build() member function of the observer base.
  66.126      virtual void build() {
  66.127        int size = Parent::notifier()->maxId() + 1;
  66.128 @@ -223,7 +227,7 @@
  66.129  
  66.130      // \brief Clear the map.
  66.131      //
  66.132 -    // It erase all items from the map. It called by the observer notifier
  66.133 +    // It erases all items from the map. It is called by the observer notifier
  66.134      // and it overrides the clear() member function of the observer base.
  66.135      virtual void clear() {
  66.136        container.clear();
    67.1 --- a/lemon/bits/windows.h	Fri Oct 16 10:21:37 2009 +0200
    67.2 +++ b/lemon/bits/windows.h	Thu Nov 05 15:50:01 2009 +0100
    67.3 @@ -16,8 +16,8 @@
    67.4   *
    67.5   */
    67.6  
    67.7 -#ifndef LEMON_WINDOWS_H
    67.8 -#define LEMON_WINDOWS_H
    67.9 +#ifndef LEMON_BITS_WINDOWS_H
   67.10 +#define LEMON_BITS_WINDOWS_H
   67.11  
   67.12  #include <string>
   67.13  
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/lemon/bucket_heap.h	Thu Nov 05 15:50:01 2009 +0100
    68.3 @@ -0,0 +1,594 @@
    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-2009
    68.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   68.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   68.11 + *
   68.12 + * Permission to use, modify and distribute this software is granted
   68.13 + * provided that this copyright notice appears in all copies. For
   68.14 + * precise terms see the accompanying LICENSE file.
   68.15 + *
   68.16 + * This software is provided "AS IS" with no warranty of any kind,
   68.17 + * express or implied, and with no claim as to its suitability for any
   68.18 + * purpose.
   68.19 + *
   68.20 + */
   68.21 +
   68.22 +#ifndef LEMON_BUCKET_HEAP_H
   68.23 +#define LEMON_BUCKET_HEAP_H
   68.24 +
   68.25 +///\ingroup heaps
   68.26 +///\file
   68.27 +///\brief Bucket heap implementation.
   68.28 +
   68.29 +#include <vector>
   68.30 +#include <utility>
   68.31 +#include <functional>
   68.32 +
   68.33 +namespace lemon {
   68.34 +
   68.35 +  namespace _bucket_heap_bits {
   68.36 +
   68.37 +    template <bool MIN>
   68.38 +    struct DirectionTraits {
   68.39 +      static bool less(int left, int right) {
   68.40 +        return left < right;
   68.41 +      }
   68.42 +      static void increase(int& value) {
   68.43 +        ++value;
   68.44 +      }
   68.45 +    };
   68.46 +
   68.47 +    template <>
   68.48 +    struct DirectionTraits<false> {
   68.49 +      static bool less(int left, int right) {
   68.50 +        return left > right;
   68.51 +      }
   68.52 +      static void increase(int& value) {
   68.53 +        --value;
   68.54 +      }
   68.55 +    };
   68.56 +
   68.57 +  }
   68.58 +
   68.59 +  /// \ingroup heaps
   68.60 +  ///
   68.61 +  /// \brief Bucket heap data structure.
   68.62 +  ///
   68.63 +  /// This class implements the \e bucket \e heap data structure.
   68.64 +  /// It practically conforms to the \ref concepts::Heap "heap concept",
   68.65 +  /// but it has some limitations.
   68.66 +  ///
   68.67 +  /// The bucket heap is a very simple structure. It can store only
   68.68 +  /// \c int priorities and it maintains a list of items for each priority
   68.69 +  /// in the range <tt>[0..C)</tt>. So it should only be used when the
   68.70 +  /// priorities are small. It is not intended to use as a Dijkstra heap.
   68.71 +  ///
   68.72 +  /// \tparam IM A read-writable item map with \c int values, used
   68.73 +  /// internally to handle the cross references.
   68.74 +  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
   68.75 +  /// The default is \e min-heap. If this parameter is set to \c false,
   68.76 +  /// then the comparison is reversed, so the top(), prio() and pop()
   68.77 +  /// functions deal with the item having maximum priority instead of the
   68.78 +  /// minimum.
   68.79 +  ///
   68.80 +  /// \sa SimpleBucketHeap
   68.81 +  template <typename IM, bool MIN = true>
   68.82 +  class BucketHeap {
   68.83 +
   68.84 +  public:
   68.85 +
   68.86 +    /// Type of the item-int map.
   68.87 +    typedef IM ItemIntMap;
   68.88 +    /// Type of the priorities.
   68.89 +    typedef int Prio;
   68.90 +    /// Type of the items stored in the heap.
   68.91 +    typedef typename ItemIntMap::Key Item;
   68.92 +    /// Type of the item-priority pairs.
   68.93 +    typedef std::pair<Item,Prio> Pair;
   68.94 +
   68.95 +  private:
   68.96 +
   68.97 +    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
   68.98 +
   68.99 +  public:
  68.100 +
  68.101 +    /// \brief Type to represent the states of the items.
  68.102 +    ///
  68.103 +    /// Each item has a state associated to it. It can be "in heap",
  68.104 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
  68.105 +    /// heap's point of view, but may be useful to the user.
  68.106 +    ///
  68.107 +    /// The item-int map must be initialized in such way that it assigns
  68.108 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
  68.109 +    enum State {
  68.110 +      IN_HEAP = 0,    ///< = 0.
  68.111 +      PRE_HEAP = -1,  ///< = -1.
  68.112 +      POST_HEAP = -2  ///< = -2.
  68.113 +    };
  68.114 +
  68.115 +  public:
  68.116 +
  68.117 +    /// \brief Constructor.
  68.118 +    ///
  68.119 +    /// Constructor.
  68.120 +    /// \param map A map that assigns \c int values to the items.
  68.121 +    /// It is used internally to handle the cross references.
  68.122 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  68.123 +    explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
  68.124 +
  68.125 +    /// \brief The number of items stored in the heap.
  68.126 +    ///
  68.127 +    /// This function returns the number of items stored in the heap.
  68.128 +    int size() const { return _data.size(); }
  68.129 +
  68.130 +    /// \brief Check if the heap is empty.
  68.131 +    ///
  68.132 +    /// This function returns \c true if the heap is empty.
  68.133 +    bool empty() const { return _data.empty(); }
  68.134 +
  68.135 +    /// \brief Make the heap empty.
  68.136 +    ///
  68.137 +    /// This functon makes the heap empty.
  68.138 +    /// It does not change the cross reference map. If you want to reuse
  68.139 +    /// a heap that is not surely empty, you should first clear it and
  68.140 +    /// then you should set the cross reference map to \c PRE_HEAP
  68.141 +    /// for each item.
  68.142 +    void clear() {
  68.143 +      _data.clear(); _first.clear(); _minimum = 0;
  68.144 +    }
  68.145 +
  68.146 +  private:
  68.147 +
  68.148 +    void relocateLast(int idx) {
  68.149 +      if (idx + 1 < int(_data.size())) {
  68.150 +        _data[idx] = _data.back();
  68.151 +        if (_data[idx].prev != -1) {
  68.152 +          _data[_data[idx].prev].next = idx;
  68.153 +        } else {
  68.154 +          _first[_data[idx].value] = idx;
  68.155 +        }
  68.156 +        if (_data[idx].next != -1) {
  68.157 +          _data[_data[idx].next].prev = idx;
  68.158 +        }
  68.159 +        _iim[_data[idx].item] = idx;
  68.160 +      }
  68.161 +      _data.pop_back();
  68.162 +    }
  68.163 +
  68.164 +    void unlace(int idx) {
  68.165 +      if (_data[idx].prev != -1) {
  68.166 +        _data[_data[idx].prev].next = _data[idx].next;
  68.167 +      } else {
  68.168 +        _first[_data[idx].value] = _data[idx].next;
  68.169 +      }
  68.170 +      if (_data[idx].next != -1) {
  68.171 +        _data[_data[idx].next].prev = _data[idx].prev;
  68.172 +      }
  68.173 +    }
  68.174 +
  68.175 +    void lace(int idx) {
  68.176 +      if (int(_first.size()) <= _data[idx].value) {
  68.177 +        _first.resize(_data[idx].value + 1, -1);
  68.178 +      }
  68.179 +      _data[idx].next = _first[_data[idx].value];
  68.180 +      if (_data[idx].next != -1) {
  68.181 +        _data[_data[idx].next].prev = idx;
  68.182 +      }
  68.183 +      _first[_data[idx].value] = idx;
  68.184 +      _data[idx].prev = -1;
  68.185 +    }
  68.186 +
  68.187 +  public:
  68.188 +
  68.189 +    /// \brief Insert a pair of item and priority into the heap.
  68.190 +    ///
  68.191 +    /// This function inserts \c p.first to the heap with priority
  68.192 +    /// \c p.second.
  68.193 +    /// \param p The pair to insert.
  68.194 +    /// \pre \c p.first must not be stored in the heap.
  68.195 +    void push(const Pair& p) {
  68.196 +      push(p.first, p.second);
  68.197 +    }
  68.198 +
  68.199 +    /// \brief Insert an item into the heap with the given priority.
  68.200 +    ///
  68.201 +    /// This function inserts the given item into the heap with the
  68.202 +    /// given priority.
  68.203 +    /// \param i The item to insert.
  68.204 +    /// \param p The priority of the item.
  68.205 +    /// \pre \e i must not be stored in the heap.
  68.206 +    void push(const Item &i, const Prio &p) {
  68.207 +      int idx = _data.size();
  68.208 +      _iim[i] = idx;
  68.209 +      _data.push_back(BucketItem(i, p));
  68.210 +      lace(idx);
  68.211 +      if (Direction::less(p, _minimum)) {
  68.212 +        _minimum = p;
  68.213 +      }
  68.214 +    }
  68.215 +
  68.216 +    /// \brief Return the item having minimum priority.
  68.217 +    ///
  68.218 +    /// This function returns the item having minimum priority.
  68.219 +    /// \pre The heap must be non-empty.
  68.220 +    Item top() const {
  68.221 +      while (_first[_minimum] == -1) {
  68.222 +        Direction::increase(_minimum);
  68.223 +      }
  68.224 +      return _data[_first[_minimum]].item;
  68.225 +    }
  68.226 +
  68.227 +    /// \brief The minimum priority.
  68.228 +    ///
  68.229 +    /// This function returns the minimum priority.
  68.230 +    /// \pre The heap must be non-empty.
  68.231 +    Prio prio() const {
  68.232 +      while (_first[_minimum] == -1) {
  68.233 +        Direction::increase(_minimum);
  68.234 +      }
  68.235 +      return _minimum;
  68.236 +    }
  68.237 +
  68.238 +    /// \brief Remove the item having minimum priority.
  68.239 +    ///
  68.240 +    /// This function removes the item having minimum priority.
  68.241 +    /// \pre The heap must be non-empty.
  68.242 +    void pop() {
  68.243 +      while (_first[_minimum] == -1) {
  68.244 +        Direction::increase(_minimum);
  68.245 +      }
  68.246 +      int idx = _first[_minimum];
  68.247 +      _iim[_data[idx].item] = -2;
  68.248 +      unlace(idx);
  68.249 +      relocateLast(idx);
  68.250 +    }
  68.251 +
  68.252 +    /// \brief Remove the given item from the heap.
  68.253 +    ///
  68.254 +    /// This function removes the given item from the heap if it is
  68.255 +    /// already stored.
  68.256 +    /// \param i The item to delete.
  68.257 +    /// \pre \e i must be in the heap.
  68.258 +    void erase(const Item &i) {
  68.259 +      int idx = _iim[i];
  68.260 +      _iim[_data[idx].item] = -2;
  68.261 +      unlace(idx);
  68.262 +      relocateLast(idx);
  68.263 +    }
  68.264 +
  68.265 +    /// \brief The priority of the given item.
  68.266 +    ///
  68.267 +    /// This function returns the priority of the given item.
  68.268 +    /// \param i The item.
  68.269 +    /// \pre \e i must be in the heap.
  68.270 +    Prio operator[](const Item &i) const {
  68.271 +      int idx = _iim[i];
  68.272 +      return _data[idx].value;
  68.273 +    }
  68.274 +
  68.275 +    /// \brief Set the priority of an item or insert it, if it is
  68.276 +    /// not stored in the heap.
  68.277 +    ///
  68.278 +    /// This method sets the priority of the given item if it is
  68.279 +    /// already stored in the heap. Otherwise it inserts the given
  68.280 +    /// item into the heap with the given priority.
  68.281 +    /// \param i The item.
  68.282 +    /// \param p The priority.
  68.283 +    void set(const Item &i, const Prio &p) {
  68.284 +      int idx = _iim[i];
  68.285 +      if (idx < 0) {
  68.286 +        push(i, p);
  68.287 +      } else if (Direction::less(p, _data[idx].value)) {
  68.288 +        decrease(i, p);
  68.289 +      } else {
  68.290 +        increase(i, p);
  68.291 +      }
  68.292 +    }
  68.293 +
  68.294 +    /// \brief Decrease the priority of an item to the given value.
  68.295 +    ///
  68.296 +    /// This function decreases the priority of an item to the given value.
  68.297 +    /// \param i The item.
  68.298 +    /// \param p The priority.
  68.299 +    /// \pre \e i must be stored in the heap with priority at least \e p.
  68.300 +    void decrease(const Item &i, const Prio &p) {
  68.301 +      int idx = _iim[i];
  68.302 +      unlace(idx);
  68.303 +      _data[idx].value = p;
  68.304 +      if (Direction::less(p, _minimum)) {
  68.305 +        _minimum = p;
  68.306 +      }
  68.307 +      lace(idx);
  68.308 +    }
  68.309 +
  68.310 +    /// \brief Increase the priority of an item to the given value.
  68.311 +    ///
  68.312 +    /// This function increases the priority of an item to the given value.
  68.313 +    /// \param i The item.
  68.314 +    /// \param p The priority.
  68.315 +    /// \pre \e i must be stored in the heap with priority at most \e p.
  68.316 +    void increase(const Item &i, const Prio &p) {
  68.317 +      int idx = _iim[i];
  68.318 +      unlace(idx);
  68.319 +      _data[idx].value = p;
  68.320 +      lace(idx);
  68.321 +    }
  68.322 +
  68.323 +    /// \brief Return the state of an item.
  68.324 +    ///
  68.325 +    /// This method returns \c PRE_HEAP if the given item has never
  68.326 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  68.327 +    /// and \c POST_HEAP otherwise.
  68.328 +    /// In the latter case it is possible that the item will get back
  68.329 +    /// to the heap again.
  68.330 +    /// \param i The item.
  68.331 +    State state(const Item &i) const {
  68.332 +      int idx = _iim[i];
  68.333 +      if (idx >= 0) idx = 0;
  68.334 +      return State(idx);
  68.335 +    }
  68.336 +
  68.337 +    /// \brief Set the state of an item in the heap.
  68.338 +    ///
  68.339 +    /// This function sets the state of the given item in the heap.
  68.340 +    /// It can be used to manually clear the heap when it is important
  68.341 +    /// to achive better time complexity.
  68.342 +    /// \param i The item.
  68.343 +    /// \param st The state. It should not be \c IN_HEAP.
  68.344 +    void state(const Item& i, State st) {
  68.345 +      switch (st) {
  68.346 +      case POST_HEAP:
  68.347 +      case PRE_HEAP:
  68.348 +        if (state(i) == IN_HEAP) {
  68.349 +          erase(i);
  68.350 +        }
  68.351 +        _iim[i] = st;
  68.352 +        break;
  68.353 +      case IN_HEAP:
  68.354 +        break;
  68.355 +      }
  68.356 +    }
  68.357 +
  68.358 +  private:
  68.359 +
  68.360 +    struct BucketItem {
  68.361 +      BucketItem(const Item& _item, int _value)
  68.362 +        : item(_item), value(_value) {}
  68.363 +
  68.364 +      Item item;
  68.365 +      int value;
  68.366 +
  68.367 +      int prev, next;
  68.368 +    };
  68.369 +
  68.370 +    ItemIntMap& _iim;
  68.371 +    std::vector<int> _first;
  68.372 +    std::vector<BucketItem> _data;
  68.373 +    mutable int _minimum;
  68.374 +
  68.375 +  }; // class BucketHeap
  68.376 +
  68.377 +  /// \ingroup heaps
  68.378 +  ///
  68.379 +  /// \brief Simplified bucket heap data structure.
  68.380 +  ///
  68.381 +  /// This class implements a simplified \e bucket \e heap data
  68.382 +  /// structure. It does not provide some functionality, but it is
  68.383 +  /// faster and simpler than BucketHeap. The main difference is
  68.384 +  /// that BucketHeap stores a doubly-linked list for each key while
  68.385 +  /// this class stores only simply-linked lists. It supports erasing
  68.386 +  /// only for the item having minimum priority and it does not support
  68.387 +  /// key increasing and decreasing.
  68.388 +  ///
  68.389 +  /// Note that this implementation does not conform to the
  68.390 +  /// \ref concepts::Heap "heap concept" due to the lack of some 
  68.391 +  /// functionality.
  68.392 +  ///
  68.393 +  /// \tparam IM A read-writable item map with \c int values, used
  68.394 +  /// internally to handle the cross references.
  68.395 +  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
  68.396 +  /// The default is \e min-heap. If this parameter is set to \c false,
  68.397 +  /// then the comparison is reversed, so the top(), prio() and pop()
  68.398 +  /// functions deal with the item having maximum priority instead of the
  68.399 +  /// minimum.
  68.400 +  ///
  68.401 +  /// \sa BucketHeap
  68.402 +  template <typename IM, bool MIN = true >
  68.403 +  class SimpleBucketHeap {
  68.404 +
  68.405 +  public:
  68.406 +
  68.407 +    /// Type of the item-int map.
  68.408 +    typedef IM ItemIntMap;
  68.409 +    /// Type of the priorities.
  68.410 +    typedef int Prio;
  68.411 +    /// Type of the items stored in the heap.
  68.412 +    typedef typename ItemIntMap::Key Item;
  68.413 +    /// Type of the item-priority pairs.
  68.414 +    typedef std::pair<Item,Prio> Pair;
  68.415 +
  68.416 +  private:
  68.417 +
  68.418 +    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
  68.419 +
  68.420 +  public:
  68.421 +
  68.422 +    /// \brief Type to represent the states of the items.
  68.423 +    ///
  68.424 +    /// Each item has a state associated to it. It can be "in heap",
  68.425 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
  68.426 +    /// heap's point of view, but may be useful to the user.
  68.427 +    ///
  68.428 +    /// The item-int map must be initialized in such way that it assigns
  68.429 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
  68.430 +    enum State {
  68.431 +      IN_HEAP = 0,    ///< = 0.
  68.432 +      PRE_HEAP = -1,  ///< = -1.
  68.433 +      POST_HEAP = -2  ///< = -2.
  68.434 +    };
  68.435 +
  68.436 +  public:
  68.437 +
  68.438 +    /// \brief Constructor.
  68.439 +    ///
  68.440 +    /// Constructor.
  68.441 +    /// \param map A map that assigns \c int values to the items.
  68.442 +    /// It is used internally to handle the cross references.
  68.443 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  68.444 +    explicit SimpleBucketHeap(ItemIntMap &map)
  68.445 +      : _iim(map), _free(-1), _num(0), _minimum(0) {}
  68.446 +
  68.447 +    /// \brief The number of items stored in the heap.
  68.448 +    ///
  68.449 +    /// This function returns the number of items stored in the heap.
  68.450 +    int size() const { return _num; }
  68.451 +
  68.452 +    /// \brief Check if the heap is empty.
  68.453 +    ///
  68.454 +    /// This function returns \c true if the heap is empty.
  68.455 +    bool empty() const { return _num == 0; }
  68.456 +
  68.457 +    /// \brief Make the heap empty.
  68.458 +    ///
  68.459 +    /// This functon makes the heap empty.
  68.460 +    /// It does not change the cross reference map. If you want to reuse
  68.461 +    /// a heap that is not surely empty, you should first clear it and
  68.462 +    /// then you should set the cross reference map to \c PRE_HEAP
  68.463 +    /// for each item.
  68.464 +    void clear() {
  68.465 +      _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
  68.466 +    }
  68.467 +
  68.468 +    /// \brief Insert a pair of item and priority into the heap.
  68.469 +    ///
  68.470 +    /// This function inserts \c p.first to the heap with priority
  68.471 +    /// \c p.second.
  68.472 +    /// \param p The pair to insert.
  68.473 +    /// \pre \c p.first must not be stored in the heap.
  68.474 +    void push(const Pair& p) {
  68.475 +      push(p.first, p.second);
  68.476 +    }
  68.477 +
  68.478 +    /// \brief Insert an item into the heap with the given priority.
  68.479 +    ///
  68.480 +    /// This function inserts the given item into the heap with the
  68.481 +    /// given priority.
  68.482 +    /// \param i The item to insert.
  68.483 +    /// \param p The priority of the item.
  68.484 +    /// \pre \e i must not be stored in the heap.
  68.485 +    void push(const Item &i, const Prio &p) {
  68.486 +      int idx;
  68.487 +      if (_free == -1) {
  68.488 +        idx = _data.size();
  68.489 +        _data.push_back(BucketItem(i));
  68.490 +      } else {
  68.491 +        idx = _free;
  68.492 +        _free = _data[idx].next;
  68.493 +        _data[idx].item = i;
  68.494 +      }
  68.495 +      _iim[i] = idx;
  68.496 +      if (p >= int(_first.size())) _first.resize(p + 1, -1);
  68.497 +      _data[idx].next = _first[p];
  68.498 +      _first[p] = idx;
  68.499 +      if (Direction::less(p, _minimum)) {
  68.500 +        _minimum = p;
  68.501 +      }
  68.502 +      ++_num;
  68.503 +    }
  68.504 +
  68.505 +    /// \brief Return the item having minimum priority.
  68.506 +    ///
  68.507 +    /// This function returns the item having minimum priority.
  68.508 +    /// \pre The heap must be non-empty.
  68.509 +    Item top() const {
  68.510 +      while (_first[_minimum] == -1) {
  68.511 +        Direction::increase(_minimum);
  68.512 +      }
  68.513 +      return _data[_first[_minimum]].item;
  68.514 +    }
  68.515 +
  68.516 +    /// \brief The minimum priority.
  68.517 +    ///
  68.518 +    /// This function returns the minimum priority.
  68.519 +    /// \pre The heap must be non-empty.
  68.520 +    Prio prio() const {
  68.521 +      while (_first[_minimum] == -1) {
  68.522 +        Direction::increase(_minimum);
  68.523 +      }
  68.524 +      return _minimum;
  68.525 +    }
  68.526 +
  68.527 +    /// \brief Remove the item having minimum priority.
  68.528 +    ///
  68.529 +    /// This function removes the item having minimum priority.
  68.530 +    /// \pre The heap must be non-empty.
  68.531 +    void pop() {
  68.532 +      while (_first[_minimum] == -1) {
  68.533 +        Direction::increase(_minimum);
  68.534 +      }
  68.535 +      int idx = _first[_minimum];
  68.536 +      _iim[_data[idx].item] = -2;
  68.537 +      _first[_minimum] = _data[idx].next;
  68.538 +      _data[idx].next = _free;
  68.539 +      _free = idx;
  68.540 +      --_num;
  68.541 +    }
  68.542 +
  68.543 +    /// \brief The priority of the given item.
  68.544 +    ///
  68.545 +    /// This function returns the priority of the given item.
  68.546 +    /// \param i The item.
  68.547 +    /// \pre \e i must be in the heap.
  68.548 +    /// \warning This operator is not a constant time function because
  68.549 +    /// it scans the whole data structure to find the proper value.
  68.550 +    Prio operator[](const Item &i) const {
  68.551 +      for (int k = 0; k < int(_first.size()); ++k) {
  68.552 +        int idx = _first[k];
  68.553 +        while (idx != -1) {
  68.554 +          if (_data[idx].item == i) {
  68.555 +            return k;
  68.556 +          }
  68.557 +          idx = _data[idx].next;
  68.558 +        }
  68.559 +      }
  68.560 +      return -1;
  68.561 +    }
  68.562 +
  68.563 +    /// \brief Return the state of an item.
  68.564 +    ///
  68.565 +    /// This method returns \c PRE_HEAP if the given item has never
  68.566 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  68.567 +    /// and \c POST_HEAP otherwise.
  68.568 +    /// In the latter case it is possible that the item will get back
  68.569 +    /// to the heap again.
  68.570 +    /// \param i The item.
  68.571 +    State state(const Item &i) const {
  68.572 +      int idx = _iim[i];
  68.573 +      if (idx >= 0) idx = 0;
  68.574 +      return State(idx);
  68.575 +    }
  68.576 +
  68.577 +  private:
  68.578 +
  68.579 +    struct BucketItem {
  68.580 +      BucketItem(const Item& _item)
  68.581 +        : item(_item) {}
  68.582 +
  68.583 +      Item item;
  68.584 +      int next;
  68.585 +    };
  68.586 +
  68.587 +    ItemIntMap& _iim;
  68.588 +    std::vector<int> _first;
  68.589 +    std::vector<BucketItem> _data;
  68.590 +    int _free, _num;
  68.591 +    mutable int _minimum;
  68.592 +
  68.593 +  }; // class SimpleBucketHeap
  68.594 +
  68.595 +}
  68.596 +
  68.597 +#endif
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/lemon/cbc.cc	Thu Nov 05 15:50:01 2009 +0100
    69.3 @@ -0,0 +1,475 @@
    69.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    69.5 + *
    69.6 + * This file is a part of LEMON, a generic C++ optimization library.
    69.7 + *
    69.8 + * Copyright (C) 2003-2009
    69.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   69.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   69.11 + *
   69.12 + * Permission to use, modify and distribute this software is granted
   69.13 + * provided that this copyright notice appears in all copies. For
   69.14 + * precise terms see the accompanying LICENSE file.
   69.15 + *
   69.16 + * This software is provided "AS IS" with no warranty of any kind,
   69.17 + * express or implied, and with no claim as to its suitability for any
   69.18 + * purpose.
   69.19 + *
   69.20 + */
   69.21 +
   69.22 +///\file
   69.23 +///\brief Implementation of the CBC MIP solver interface.
   69.24 +
   69.25 +#include "cbc.h"
   69.26 +
   69.27 +#include <coin/CoinModel.hpp>
   69.28 +#include <coin/CbcModel.hpp>
   69.29 +#include <coin/OsiSolverInterface.hpp>
   69.30 +
   69.31 +#ifdef COIN_HAS_CLP
   69.32 +#include "coin/OsiClpSolverInterface.hpp"
   69.33 +#endif
   69.34 +#ifdef COIN_HAS_OSL
   69.35 +#include "coin/OsiOslSolverInterface.hpp"
   69.36 +#endif
   69.37 +
   69.38 +#include "coin/CbcCutGenerator.hpp"
   69.39 +#include "coin/CbcHeuristicLocal.hpp"
   69.40 +#include "coin/CbcHeuristicGreedy.hpp"
   69.41 +#include "coin/CbcHeuristicFPump.hpp"
   69.42 +#include "coin/CbcHeuristicRINS.hpp"
   69.43 +
   69.44 +#include "coin/CglGomory.hpp"
   69.45 +#include "coin/CglProbing.hpp"
   69.46 +#include "coin/CglKnapsackCover.hpp"
   69.47 +#include "coin/CglOddHole.hpp"
   69.48 +#include "coin/CglClique.hpp"
   69.49 +#include "coin/CglFlowCover.hpp"
   69.50 +#include "coin/CglMixedIntegerRounding.hpp"
   69.51 +
   69.52 +#include "coin/CbcHeuristic.hpp"
   69.53 +
   69.54 +namespace lemon {
   69.55 +
   69.56 +  CbcMip::CbcMip() {
   69.57 +    _prob = new CoinModel();
   69.58 +    _prob->setProblemName("LEMON");
   69.59 +    _osi_solver = 0;
   69.60 +    _cbc_model = 0;
   69.61 +    messageLevel(MESSAGE_NOTHING);
   69.62 +  }
   69.63 +
   69.64 +  CbcMip::CbcMip(const CbcMip& other) {
   69.65 +    _prob = new CoinModel(*other._prob);
   69.66 +    _prob->setProblemName("LEMON");
   69.67 +    _osi_solver = 0;
   69.68 +    _cbc_model = 0;
   69.69 +    messageLevel(MESSAGE_NOTHING);
   69.70 +  }
   69.71 +
   69.72 +  CbcMip::~CbcMip() {
   69.73 +    delete _prob;
   69.74 +    if (_osi_solver) delete _osi_solver;
   69.75 +    if (_cbc_model) delete _cbc_model;
   69.76 +  }
   69.77 +
   69.78 +  const char* CbcMip::_solverName() const { return "CbcMip"; }
   69.79 +
   69.80 +  int CbcMip::_addCol() {
   69.81 +    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0, 0, false);
   69.82 +    return _prob->numberColumns() - 1;
   69.83 +  }
   69.84 +
   69.85 +  CbcMip* CbcMip::newSolver() const {
   69.86 +    CbcMip* newlp = new CbcMip;
   69.87 +    return newlp;
   69.88 +  }
   69.89 +
   69.90 +  CbcMip* CbcMip::cloneSolver() const {
   69.91 +    CbcMip* copylp = new CbcMip(*this);
   69.92 +    return copylp;
   69.93 +  }
   69.94 +
   69.95 +  int CbcMip::_addRow() {
   69.96 +    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
   69.97 +    return _prob->numberRows() - 1;
   69.98 +  }
   69.99 +
  69.100 +  int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
  69.101 +    std::vector<int> indexes;
  69.102 +    std::vector<Value> values;
  69.103 +
  69.104 +    for(ExprIterator it = b; it != e; ++it) {
  69.105 +      indexes.push_back(it->first);
  69.106 +      values.push_back(it->second);
  69.107 +    }
  69.108 +
  69.109 +    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
  69.110 +    return _prob->numberRows() - 1;
  69.111 +  }
  69.112 +
  69.113 +  void CbcMip::_eraseCol(int i) {
  69.114 +    _prob->deleteColumn(i);
  69.115 +  }
  69.116 +
  69.117 +  void CbcMip::_eraseRow(int i) {
  69.118 +    _prob->deleteRow(i);
  69.119 +  }
  69.120 +
  69.121 +  void CbcMip::_eraseColId(int i) {
  69.122 +    cols.eraseIndex(i);
  69.123 +  }
  69.124 +
  69.125 +  void CbcMip::_eraseRowId(int i) {
  69.126 +    rows.eraseIndex(i);
  69.127 +  }
  69.128 +
  69.129 +  void CbcMip::_getColName(int c, std::string& name) const {
  69.130 +    name = _prob->getColumnName(c);
  69.131 +  }
  69.132 +
  69.133 +  void CbcMip::_setColName(int c, const std::string& name) {
  69.134 +    _prob->setColumnName(c, name.c_str());
  69.135 +  }
  69.136 +
  69.137 +  int CbcMip::_colByName(const std::string& name) const {
  69.138 +    return _prob->column(name.c_str());
  69.139 +  }
  69.140 +
  69.141 +  void CbcMip::_getRowName(int r, std::string& name) const {
  69.142 +    name = _prob->getRowName(r);
  69.143 +  }
  69.144 +
  69.145 +  void CbcMip::_setRowName(int r, const std::string& name) {
  69.146 +    _prob->setRowName(r, name.c_str());
  69.147 +  }
  69.148 +
  69.149 +  int CbcMip::_rowByName(const std::string& name) const {
  69.150 +    return _prob->row(name.c_str());
  69.151 +  }
  69.152 +
  69.153 +  void CbcMip::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
  69.154 +    for (ExprIterator it = b; it != e; ++it) {
  69.155 +      _prob->setElement(i, it->first, it->second);
  69.156 +    }
  69.157 +  }
  69.158 +
  69.159 +  void CbcMip::_getRowCoeffs(int ix, InsertIterator b) const {
  69.160 +    int length = _prob->numberRows();
  69.161 +
  69.162 +    std::vector<int> indices(length);
  69.163 +    std::vector<Value> values(length);
  69.164 +
  69.165 +    length = _prob->getRow(ix, &indices[0], &values[0]);
  69.166 +
  69.167 +    for (int i = 0; i < length; ++i) {
  69.168 +      *b = std::make_pair(indices[i], values[i]);
  69.169 +      ++b;
  69.170 +    }
  69.171 +  }
  69.172 +
  69.173 +  void CbcMip::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
  69.174 +    for (ExprIterator it = b; it != e; ++it) {
  69.175 +      _prob->setElement(it->first, ix, it->second);
  69.176 +    }
  69.177 +  }
  69.178 +
  69.179 +  void CbcMip::_getColCoeffs(int ix, InsertIterator b) const {
  69.180 +    int length = _prob->numberColumns();
  69.181 +
  69.182 +    std::vector<int> indices(length);
  69.183 +    std::vector<Value> values(length);
  69.184 +
  69.185 +    length = _prob->getColumn(ix, &indices[0], &values[0]);
  69.186 +
  69.187 +    for (int i = 0; i < length; ++i) {
  69.188 +      *b = std::make_pair(indices[i], values[i]);
  69.189 +      ++b;
  69.190 +    }
  69.191 +  }
  69.192 +
  69.193 +  void CbcMip::_setCoeff(int ix, int jx, Value value) {
  69.194 +    _prob->setElement(ix, jx, value);
  69.195 +  }
  69.196 +
  69.197 +  CbcMip::Value CbcMip::_getCoeff(int ix, int jx) const {
  69.198 +    return _prob->getElement(ix, jx);
  69.199 +  }
  69.200 +
  69.201 +
  69.202 +  void CbcMip::_setColLowerBound(int i, Value lo) {
  69.203 +    LEMON_ASSERT(lo != INF, "Invalid bound");
  69.204 +    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
  69.205 +  }
  69.206 +
  69.207 +  CbcMip::Value CbcMip::_getColLowerBound(int i) const {
  69.208 +    double val = _prob->getColumnLower(i);
  69.209 +    return val == - COIN_DBL_MAX ? - INF : val;
  69.210 +  }
  69.211 +
  69.212 +  void CbcMip::_setColUpperBound(int i, Value up) {
  69.213 +    LEMON_ASSERT(up != -INF, "Invalid bound");
  69.214 +    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
  69.215 +  }
  69.216 +
  69.217 +  CbcMip::Value CbcMip::_getColUpperBound(int i) const {
  69.218 +    double val = _prob->getColumnUpper(i);
  69.219 +    return val == COIN_DBL_MAX ? INF : val;
  69.220 +  }
  69.221 +
  69.222 +  void CbcMip::_setRowLowerBound(int i, Value lo) {
  69.223 +    LEMON_ASSERT(lo != INF, "Invalid bound");
  69.224 +    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
  69.225 +  }
  69.226 +
  69.227 +  CbcMip::Value CbcMip::_getRowLowerBound(int i) const {
  69.228 +    double val = _prob->getRowLower(i);
  69.229 +    return val == - COIN_DBL_MAX ? - INF : val;
  69.230 +  }
  69.231 +
  69.232 +  void CbcMip::_setRowUpperBound(int i, Value up) {
  69.233 +    LEMON_ASSERT(up != -INF, "Invalid bound");
  69.234 +    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
  69.235 +  }
  69.236 +
  69.237 +  CbcMip::Value CbcMip::_getRowUpperBound(int i) const {
  69.238 +    double val = _prob->getRowUpper(i);
  69.239 +    return val == COIN_DBL_MAX ? INF : val;
  69.240 +  }
  69.241 +
  69.242 +  void CbcMip::_setObjCoeffs(ExprIterator b, ExprIterator e) {
  69.243 +    int num = _prob->numberColumns();
  69.244 +    for (int i = 0; i < num; ++i) {
  69.245 +      _prob->setColumnObjective(i, 0.0);
  69.246 +    }
  69.247 +    for (ExprIterator it = b; it != e; ++it) {
  69.248 +      _prob->setColumnObjective(it->first, it->second);
  69.249 +    }
  69.250 +  }
  69.251 +
  69.252 +  void CbcMip::_getObjCoeffs(InsertIterator b) const {
  69.253 +    int num = _prob->numberColumns();
  69.254 +    for (int i = 0; i < num; ++i) {
  69.255 +      Value coef = _prob->getColumnObjective(i);
  69.256 +      if (coef != 0.0) {
  69.257 +        *b = std::make_pair(i, coef);
  69.258 +        ++b;
  69.259 +      }
  69.260 +    }
  69.261 +  }
  69.262 +
  69.263 +  void CbcMip::_setObjCoeff(int i, Value obj_coef) {
  69.264 +    _prob->setColumnObjective(i, obj_coef);
  69.265 +  }
  69.266 +
  69.267 +  CbcMip::Value CbcMip::_getObjCoeff(int i) const {
  69.268 +    return _prob->getColumnObjective(i);
  69.269 +  }
  69.270 +
  69.271 +  CbcMip::SolveExitStatus CbcMip::_solve() {
  69.272 +
  69.273 +    if (_osi_solver) {
  69.274 +      delete _osi_solver;
  69.275 +    }
  69.276 +#ifdef COIN_HAS_CLP
  69.277 +    _osi_solver = new OsiClpSolverInterface();
  69.278 +#elif COIN_HAS_OSL
  69.279 +    _osi_solver = new OsiOslSolverInterface();
  69.280 +#else
  69.281 +#error Cannot instantiate Osi solver
  69.282 +#endif
  69.283 +
  69.284 +    _osi_solver->loadFromCoinModel(*_prob);
  69.285 +
  69.286 +    if (_cbc_model) {
  69.287 +      delete _cbc_model;
  69.288 +    }
  69.289 +    _cbc_model= new CbcModel(*_osi_solver);
  69.290 +
  69.291 +    _osi_solver->messageHandler()->setLogLevel(_message_level);
  69.292 +    _cbc_model->setLogLevel(_message_level);
  69.293 +
  69.294 +    _cbc_model->initialSolve();
  69.295 +    _cbc_model->solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
  69.296 +
  69.297 +    if (!_cbc_model->isInitialSolveAbandoned() &&
  69.298 +        _cbc_model->isInitialSolveProvenOptimal() &&
  69.299 +        !_cbc_model->isInitialSolveProvenPrimalInfeasible() &&
  69.300 +        !_cbc_model->isInitialSolveProvenDualInfeasible()) {
  69.301 +
  69.302 +      CglProbing generator1;
  69.303 +      generator1.setUsingObjective(true);
  69.304 +      generator1.setMaxPass(3);
  69.305 +      generator1.setMaxProbe(100);
  69.306 +      generator1.setMaxLook(50);
  69.307 +      generator1.setRowCuts(3);
  69.308 +      _cbc_model->addCutGenerator(&generator1, -1, "Probing");
  69.309 +
  69.310 +      CglGomory generator2;
  69.311 +      generator2.setLimit(300);
  69.312 +      _cbc_model->addCutGenerator(&generator2, -1, "Gomory");
  69.313 +
  69.314 +      CglKnapsackCover generator3;
  69.315 +      _cbc_model->addCutGenerator(&generator3, -1, "Knapsack");
  69.316 +
  69.317 +      CglOddHole generator4;
  69.318 +      generator4.setMinimumViolation(0.005);
  69.319 +      generator4.setMinimumViolationPer(0.00002);
  69.320 +      generator4.setMaximumEntries(200);
  69.321 +      _cbc_model->addCutGenerator(&generator4, -1, "OddHole");
  69.322 +
  69.323 +      CglClique generator5;
  69.324 +      generator5.setStarCliqueReport(false);
  69.325 +      generator5.setRowCliqueReport(false);
  69.326 +      _cbc_model->addCutGenerator(&generator5, -1, "Clique");
  69.327 +
  69.328 +      CglMixedIntegerRounding mixedGen;
  69.329 +      _cbc_model->addCutGenerator(&mixedGen, -1, "MixedIntegerRounding");
  69.330 +
  69.331 +      CglFlowCover flowGen;
  69.332 +      _cbc_model->addCutGenerator(&flowGen, -1, "FlowCover");
  69.333 +
  69.334 +#ifdef COIN_HAS_CLP
  69.335 +      OsiClpSolverInterface* osiclp =
  69.336 +        dynamic_cast<OsiClpSolverInterface*>(_cbc_model->solver());
  69.337 +      if (osiclp->getNumRows() < 300 && osiclp->getNumCols() < 500) {
  69.338 +        osiclp->setupForRepeatedUse(2, 0);
  69.339 +      }
  69.340 +#endif
  69.341 +
  69.342 +      CbcRounding heuristic1(*_cbc_model);
  69.343 +      heuristic1.setWhen(3);
  69.344 +      _cbc_model->addHeuristic(&heuristic1);
  69.345 +
  69.346 +      CbcHeuristicLocal heuristic2(*_cbc_model);
  69.347 +      heuristic2.setWhen(3);
  69.348 +      _cbc_model->addHeuristic(&heuristic2);
  69.349 +
  69.350 +      CbcHeuristicGreedyCover heuristic3(*_cbc_model);
  69.351 +      heuristic3.setAlgorithm(11);
  69.352 +      heuristic3.setWhen(3);
  69.353 +      _cbc_model->addHeuristic(&heuristic3);
  69.354 +
  69.355 +      CbcHeuristicFPump heuristic4(*_cbc_model);
  69.356 +      heuristic4.setWhen(3);
  69.357 +      _cbc_model->addHeuristic(&heuristic4);
  69.358 +
  69.359 +      CbcHeuristicRINS heuristic5(*_cbc_model);
  69.360 +      heuristic5.setWhen(3);
  69.361 +      _cbc_model->addHeuristic(&heuristic5);
  69.362 +
  69.363 +      if (_cbc_model->getNumCols() < 500) {
  69.364 +        _cbc_model->setMaximumCutPassesAtRoot(-100);
  69.365 +      } else if (_cbc_model->getNumCols() < 5000) {
  69.366 +        _cbc_model->setMaximumCutPassesAtRoot(100);
  69.367 +      } else {
  69.368 +        _cbc_model->setMaximumCutPassesAtRoot(20);
  69.369 +      }
  69.370 +
  69.371 +      if (_cbc_model->getNumCols() < 5000) {
  69.372 +        _cbc_model->setNumberStrong(10);
  69.373 +      }
  69.374 +
  69.375 +      _cbc_model->solver()->setIntParam(OsiMaxNumIterationHotStart, 100);
  69.376 +      _cbc_model->branchAndBound();
  69.377 +    }
  69.378 +
  69.379 +    if (_cbc_model->isAbandoned()) {
  69.380 +      return UNSOLVED;
  69.381 +    } else {
  69.382 +      return SOLVED;
  69.383 +    }
  69.384 +  }
  69.385 +
  69.386 +  CbcMip::Value CbcMip::_getSol(int i) const {
  69.387 +    return _cbc_model->getColSolution()[i];
  69.388 +  }
  69.389 +
  69.390 +  CbcMip::Value CbcMip::_getSolValue() const {
  69.391 +    return _cbc_model->getObjValue();
  69.392 +  }
  69.393 +
  69.394 +  CbcMip::ProblemType CbcMip::_getType() const {
  69.395 +    if (_cbc_model->isProvenOptimal()) {
  69.396 +      return OPTIMAL;
  69.397 +    } else if (_cbc_model->isContinuousUnbounded()) {
  69.398 +      return UNBOUNDED;
  69.399 +    }
  69.400 +    return FEASIBLE;
  69.401 +  }
  69.402 +
  69.403 +  void CbcMip::_setSense(Sense sense) {
  69.404 +    switch (sense) {
  69.405 +    case MIN:
  69.406 +      _prob->setOptimizationDirection(1.0);
  69.407 +      break;
  69.408 +    case MAX:
  69.409 +      _prob->setOptimizationDirection(- 1.0);
  69.410 +      break;
  69.411 +    }
  69.412 +  }
  69.413 +
  69.414 +  CbcMip::Sense CbcMip::_getSense() const {
  69.415 +    if (_prob->optimizationDirection() > 0.0) {
  69.416 +      return MIN;
  69.417 +    } else if (_prob->optimizationDirection() < 0.0) {
  69.418 +      return MAX;
  69.419 +    } else {
  69.420 +      LEMON_ASSERT(false, "Wrong sense");
  69.421 +      return CbcMip::Sense();
  69.422 +    }
  69.423 +  }
  69.424 +
  69.425 +  void CbcMip::_setColType(int i, CbcMip::ColTypes col_type) {
  69.426 +    switch (col_type){
  69.427 +    case INTEGER:
  69.428 +      _prob->setInteger(i);
  69.429 +      break;
  69.430 +    case REAL:
  69.431 +      _prob->setContinuous(i);
  69.432 +      break;
  69.433 +    default:;
  69.434 +      LEMON_ASSERT(false, "Wrong sense");
  69.435 +    }
  69.436 +  }
  69.437 +
  69.438 +  CbcMip::ColTypes CbcMip::_getColType(int i) const {
  69.439 +    return _prob->getColumnIsInteger(i) ? INTEGER : REAL;
  69.440 +  }
  69.441 +
  69.442 +  void CbcMip::_clear() {
  69.443 +    delete _prob;
  69.444 +    if (_osi_solver) {
  69.445 +      delete _osi_solver;
  69.446 +      _osi_solver = 0;
  69.447 +    }
  69.448 +    if (_cbc_model) {
  69.449 +      delete _cbc_model;
  69.450 +      _cbc_model = 0;
  69.451 +    }
  69.452 +
  69.453 +    _prob = new CoinModel();
  69.454 +    rows.clear();
  69.455 +    cols.clear();
  69.456 +  }
  69.457 +
  69.458 +  void CbcMip::_messageLevel(MessageLevel level) {
  69.459 +    switch (level) {
  69.460 +    case MESSAGE_NOTHING:
  69.461 +      _message_level = 0;
  69.462 +      break;
  69.463 +    case MESSAGE_ERROR:
  69.464 +      _message_level = 1;
  69.465 +      break;
  69.466 +    case MESSAGE_WARNING:
  69.467 +      _message_level = 1;
  69.468 +      break;
  69.469 +    case MESSAGE_NORMAL:
  69.470 +      _message_level = 2;
  69.471 +      break;
  69.472 +    case MESSAGE_VERBOSE:
  69.473 +      _message_level = 3;
  69.474 +      break;
  69.475 +    }
  69.476 +  }
  69.477 +
  69.478 +} //END OF NAMESPACE LEMON
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/lemon/cbc.h	Thu Nov 05 15:50:01 2009 +0100
    70.3 @@ -0,0 +1,130 @@
    70.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    70.5 + *
    70.6 + * This file is a part of LEMON, a generic C++ optimization library.
    70.7 + *
    70.8 + * Copyright (C) 2003-2009
    70.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   70.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   70.11 + *
   70.12 + * Permission to use, modify and distribute this software is granted
   70.13 + * provided that this copyright notice appears in all copies. For
   70.14 + * precise terms see the accompanying LICENSE file.
   70.15 + *
   70.16 + * This software is provided "AS IS" with no warranty of any kind,
   70.17 + * express or implied, and with no claim as to its suitability for any
   70.18 + * purpose.
   70.19 + *
   70.20 + */
   70.21 +
   70.22 +// -*- C++ -*-
   70.23 +#ifndef LEMON_CBC_H
   70.24 +#define LEMON_CBC_H
   70.25 +
   70.26 +///\file
   70.27 +///\brief Header of the LEMON-CBC mip solver interface.
   70.28 +///\ingroup lp_group
   70.29 +
   70.30 +#include <lemon/lp_base.h>
   70.31 +
   70.32 +class CoinModel;
   70.33 +class OsiSolverInterface;
   70.34 +class CbcModel;
   70.35 +
   70.36 +namespace lemon {
   70.37 +
   70.38 +  /// \brief Interface for the CBC MIP solver
   70.39 +  ///
   70.40 +  /// This class implements an interface for the CBC MIP solver.
   70.41 +  ///\ingroup lp_group
   70.42 +  class CbcMip : public MipSolver {
   70.43 +  protected:
   70.44 +
   70.45 +    CoinModel *_prob;
   70.46 +    OsiSolverInterface *_osi_solver;
   70.47 +    CbcModel *_cbc_model;
   70.48 +
   70.49 +  public:
   70.50 +
   70.51 +    /// \e
   70.52 +    CbcMip();
   70.53 +    /// \e
   70.54 +    CbcMip(const CbcMip&);
   70.55 +    /// \e
   70.56 +    ~CbcMip();
   70.57 +    /// \e
   70.58 +    virtual CbcMip* newSolver() const;
   70.59 +    /// \e
   70.60 +    virtual CbcMip* cloneSolver() const;
   70.61 +
   70.62 +  protected:
   70.63 +
   70.64 +    virtual const char* _solverName() const;
   70.65 +
   70.66 +    virtual int _addCol();
   70.67 +    virtual int _addRow();
   70.68 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
   70.69 +
   70.70 +    virtual void _eraseCol(int i);
   70.71 +    virtual void _eraseRow(int i);
   70.72 +
   70.73 +    virtual void _eraseColId(int i);
   70.74 +    virtual void _eraseRowId(int i);
   70.75 +
   70.76 +    virtual void _getColName(int col, std::string& name) const;
   70.77 +    virtual void _setColName(int col, const std::string& name);
   70.78 +    virtual int _colByName(const std::string& name) const;
   70.79 +
   70.80 +    virtual void _getRowName(int row, std::string& name) const;
   70.81 +    virtual void _setRowName(int row, const std::string& name);
   70.82 +    virtual int _rowByName(const std::string& name) const;
   70.83 +
   70.84 +    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
   70.85 +    virtual void _getRowCoeffs(int i, InsertIterator b) const;
   70.86 +
   70.87 +    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
   70.88 +    virtual void _getColCoeffs(int i, InsertIterator b) const;
   70.89 +
   70.90 +    virtual void _setCoeff(int row, int col, Value value);
   70.91 +    virtual Value _getCoeff(int row, int col) const;
   70.92 +
   70.93 +    virtual void _setColLowerBound(int i, Value value);
   70.94 +    virtual Value _getColLowerBound(int i) const;
   70.95 +    virtual void _setColUpperBound(int i, Value value);
   70.96 +    virtual Value _getColUpperBound(int i) const;
   70.97 +
   70.98 +    virtual void _setRowLowerBound(int i, Value value);
   70.99 +    virtual Value _getRowLowerBound(int i) const;
  70.100 +    virtual void _setRowUpperBound(int i, Value value);
  70.101 +    virtual Value _getRowUpperBound(int i) const;
  70.102 +
  70.103 +    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
  70.104 +    virtual void _getObjCoeffs(InsertIterator b) const;
  70.105 +
  70.106 +    virtual void _setObjCoeff(int i, Value obj_coef);
  70.107 +    virtual Value _getObjCoeff(int i) const;
  70.108 +
  70.109 +    virtual void _setSense(Sense sense);
  70.110 +    virtual Sense _getSense() const;
  70.111 +
  70.112 +    virtual ColTypes _getColType(int col) const;
  70.113 +    virtual void _setColType(int col, ColTypes col_type);
  70.114 +
  70.115 +    virtual SolveExitStatus _solve();
  70.116 +    virtual ProblemType _getType() const;
  70.117 +    virtual Value _getSol(int i) const;
  70.118 +    virtual Value _getSolValue() const;
  70.119 +
  70.120 +    virtual void _clear();
  70.121 +
  70.122 +    virtual void _messageLevel(MessageLevel level);
  70.123 +    void _applyMessageLevel();
  70.124 +
  70.125 +    int _message_level;
  70.126 +
  70.127 +    
  70.128 +
  70.129 +  };
  70.130 +
  70.131 +}
  70.132 +
  70.133 +#endif
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/lemon/circulation.h	Thu Nov 05 15:50:01 2009 +0100
    71.3 @@ -0,0 +1,803 @@
    71.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    71.5 + *
    71.6 + * This file is a part of LEMON, a generic C++ optimization library.
    71.7 + *
    71.8 + * Copyright (C) 2003-2009
    71.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   71.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   71.11 + *
   71.12 + * Permission to use, modify and distribute this software is granted
   71.13 + * provided that this copyright notice appears in all copies. For
   71.14 + * precise terms see the accompanying LICENSE file.
   71.15 + *
   71.16 + * This software is provided "AS IS" with no warranty of any kind,
   71.17 + * express or implied, and with no claim as to its suitability for any
   71.18 + * purpose.
   71.19 + *
   71.20 + */
   71.21 +
   71.22 +#ifndef LEMON_CIRCULATION_H
   71.23 +#define LEMON_CIRCULATION_H
   71.24 +
   71.25 +#include <lemon/tolerance.h>
   71.26 +#include <lemon/elevator.h>
   71.27 +#include <limits>
   71.28 +
   71.29 +///\ingroup max_flow
   71.30 +///\file
   71.31 +///\brief Push-relabel algorithm for finding a feasible circulation.
   71.32 +///
   71.33 +namespace lemon {
   71.34 +
   71.35 +  /// \brief Default traits class of Circulation class.
   71.36 +  ///
   71.37 +  /// Default traits class of Circulation class.
   71.38 +  ///
   71.39 +  /// \tparam GR Type of the digraph the algorithm runs on.
   71.40 +  /// \tparam LM The type of the lower bound map.
   71.41 +  /// \tparam UM The type of the upper bound (capacity) map.
   71.42 +  /// \tparam SM The type of the supply map.
   71.43 +  template <typename GR, typename LM,
   71.44 +            typename UM, typename SM>
   71.45 +  struct CirculationDefaultTraits {
   71.46 +
   71.47 +    /// \brief The type of the digraph the algorithm runs on.
   71.48 +    typedef GR Digraph;
   71.49 +
   71.50 +    /// \brief The type of the lower bound map.
   71.51 +    ///
   71.52 +    /// The type of the map that stores the lower bounds on the arcs.
   71.53 +    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
   71.54 +    typedef LM LowerMap;
   71.55 +
   71.56 +    /// \brief The type of the upper bound (capacity) map.
   71.57 +    ///
   71.58 +    /// The type of the map that stores the upper bounds (capacities)
   71.59 +    /// on the arcs.
   71.60 +    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
   71.61 +    typedef UM UpperMap;
   71.62 +
   71.63 +    /// \brief The type of supply map.
   71.64 +    ///
   71.65 +    /// The type of the map that stores the signed supply values of the 
   71.66 +    /// nodes. 
   71.67 +    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
   71.68 +    typedef SM SupplyMap;
   71.69 +
   71.70 +    /// \brief The type of the flow and supply values.
   71.71 +    typedef typename SupplyMap::Value Value;
   71.72 +
   71.73 +    /// \brief The type of the map that stores the flow values.
   71.74 +    ///
   71.75 +    /// The type of the map that stores the flow values.
   71.76 +    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
   71.77 +    /// concept.
   71.78 +#ifdef DOXYGEN
   71.79 +    typedef GR::ArcMap<Value> FlowMap;
   71.80 +#else
   71.81 +    typedef typename Digraph::template ArcMap<Value> FlowMap;
   71.82 +#endif
   71.83 +
   71.84 +    /// \brief Instantiates a FlowMap.
   71.85 +    ///
   71.86 +    /// This function instantiates a \ref FlowMap.
   71.87 +    /// \param digraph The digraph for which we would like to define
   71.88 +    /// the flow map.
   71.89 +    static FlowMap* createFlowMap(const Digraph& digraph) {
   71.90 +      return new FlowMap(digraph);
   71.91 +    }
   71.92 +
   71.93 +    /// \brief The elevator type used by the algorithm.
   71.94 +    ///
   71.95 +    /// The elevator type used by the algorithm.
   71.96 +    ///
   71.97 +    /// \sa Elevator, LinkedElevator
   71.98 +#ifdef DOXYGEN
   71.99 +    typedef lemon::Elevator<GR, GR::Node> Elevator;
  71.100 +#else
  71.101 +    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
  71.102 +#endif
  71.103 +
  71.104 +    /// \brief Instantiates an Elevator.
  71.105 +    ///
  71.106 +    /// This function instantiates an \ref Elevator.
  71.107 +    /// \param digraph The digraph for which we would like to define
  71.108 +    /// the elevator.
  71.109 +    /// \param max_level The maximum level of the elevator.
  71.110 +    static Elevator* createElevator(const Digraph& digraph, int max_level) {
  71.111 +      return new Elevator(digraph, max_level);
  71.112 +    }
  71.113 +
  71.114 +    /// \brief The tolerance used by the algorithm
  71.115 +    ///
  71.116 +    /// The tolerance used by the algorithm to handle inexact computation.
  71.117 +    typedef lemon::Tolerance<Value> Tolerance;
  71.118 +
  71.119 +  };
  71.120 +
  71.121 +  /**
  71.122 +     \brief Push-relabel algorithm for the network circulation problem.
  71.123 +
  71.124 +     \ingroup max_flow
  71.125 +     This class implements a push-relabel algorithm for the \e network
  71.126 +     \e circulation problem.
  71.127 +     It is to find a feasible circulation when lower and upper bounds
  71.128 +     are given for the flow values on the arcs and lower bounds are
  71.129 +     given for the difference between the outgoing and incoming flow
  71.130 +     at the nodes.
  71.131 +
  71.132 +     The exact formulation of this problem is the following.
  71.133 +     Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$
  71.134 +     \f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and
  71.135 +     upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$
  71.136 +     holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
  71.137 +     denotes the signed supply values of the nodes.
  71.138 +     If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
  71.139 +     supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
  71.140 +     \f$-sup(u)\f$ demand.
  71.141 +     A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$
  71.142 +     solution of the following problem.
  71.143 +
  71.144 +     \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
  71.145 +     \geq sup(u) \quad \forall u\in V, \f]
  71.146 +     \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
  71.147 +     
  71.148 +     The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
  71.149 +     zero or negative in order to have a feasible solution (since the sum
  71.150 +     of the expressions on the left-hand side of the inequalities is zero).
  71.151 +     It means that the total demand must be greater or equal to the total
  71.152 +     supply and all the supplies have to be carried out from the supply nodes,
  71.153 +     but there could be demands that are not satisfied.
  71.154 +     If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
  71.155 +     constraints have to be satisfied with equality, i.e. all demands
  71.156 +     have to be satisfied and all supplies have to be used.
  71.157 +     
  71.158 +     If you need the opposite inequalities in the supply/demand constraints
  71.159 +     (i.e. the total demand is less than the total supply and all the demands
  71.160 +     have to be satisfied while there could be supplies that are not used),
  71.161 +     then you could easily transform the problem to the above form by reversing
  71.162 +     the direction of the arcs and taking the negative of the supply values
  71.163 +     (e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
  71.164 +
  71.165 +     This algorithm either calculates a feasible circulation, or provides
  71.166 +     a \ref barrier() "barrier", which prooves that a feasible soultion
  71.167 +     cannot exist.
  71.168 +
  71.169 +     Note that this algorithm also provides a feasible solution for the
  71.170 +     \ref min_cost_flow "minimum cost flow problem".
  71.171 +
  71.172 +     \tparam GR The type of the digraph the algorithm runs on.
  71.173 +     \tparam LM The type of the lower bound map. The default
  71.174 +     map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
  71.175 +     \tparam UM The type of the upper bound (capacity) map.
  71.176 +     The default map type is \c LM.
  71.177 +     \tparam SM The type of the supply map. The default map type is
  71.178 +     \ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>".
  71.179 +  */
  71.180 +#ifdef DOXYGEN
  71.181 +template< typename GR,
  71.182 +          typename LM,
  71.183 +          typename UM,
  71.184 +          typename SM,
  71.185 +          typename TR >
  71.186 +#else
  71.187 +template< typename GR,
  71.188 +          typename LM = typename GR::template ArcMap<int>,
  71.189 +          typename UM = LM,
  71.190 +          typename SM = typename GR::template NodeMap<typename UM::Value>,
  71.191 +          typename TR = CirculationDefaultTraits<GR, LM, UM, SM> >
  71.192 +#endif
  71.193 +  class Circulation {
  71.194 +  public:
  71.195 +
  71.196 +    ///The \ref CirculationDefaultTraits "traits class" of the algorithm.
  71.197 +    typedef TR Traits;
  71.198 +    ///The type of the digraph the algorithm runs on.
  71.199 +    typedef typename Traits::Digraph Digraph;
  71.200 +    ///The type of the flow and supply values.
  71.201 +    typedef typename Traits::Value Value;
  71.202 +
  71.203 +    ///The type of the lower bound map.
  71.204 +    typedef typename Traits::LowerMap LowerMap;
  71.205 +    ///The type of the upper bound (capacity) map.
  71.206 +    typedef typename Traits::UpperMap UpperMap;
  71.207 +    ///The type of the supply map.
  71.208 +    typedef typename Traits::SupplyMap SupplyMap;
  71.209 +    ///The type of the flow map.
  71.210 +    typedef typename Traits::FlowMap FlowMap;
  71.211 +
  71.212 +    ///The type of the elevator.
  71.213 +    typedef typename Traits::Elevator Elevator;
  71.214 +    ///The type of the tolerance.
  71.215 +    typedef typename Traits::Tolerance Tolerance;
  71.216 +
  71.217 +  private:
  71.218 +
  71.219 +    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
  71.220 +
  71.221 +    const Digraph &_g;
  71.222 +    int _node_num;
  71.223 +
  71.224 +    const LowerMap *_lo;
  71.225 +    const UpperMap *_up;
  71.226 +    const SupplyMap *_supply;
  71.227 +
  71.228 +    FlowMap *_flow;
  71.229 +    bool _local_flow;
  71.230 +
  71.231 +    Elevator* _level;
  71.232 +    bool _local_level;
  71.233 +
  71.234 +    typedef typename Digraph::template NodeMap<Value> ExcessMap;
  71.235 +    ExcessMap* _excess;
  71.236 +
  71.237 +    Tolerance _tol;
  71.238 +    int _el;
  71.239 +
  71.240 +  public:
  71.241 +
  71.242 +    typedef Circulation Create;
  71.243 +
  71.244 +    ///\name Named Template Parameters
  71.245 +
  71.246 +    ///@{
  71.247 +
  71.248 +    template <typename T>
  71.249 +    struct SetFlowMapTraits : public Traits {
  71.250 +      typedef T FlowMap;
  71.251 +      static FlowMap *createFlowMap(const Digraph&) {
  71.252 +        LEMON_ASSERT(false, "FlowMap is not initialized");
  71.253 +        return 0; // ignore warnings
  71.254 +      }
  71.255 +    };
  71.256 +
  71.257 +    /// \brief \ref named-templ-param "Named parameter" for setting
  71.258 +    /// FlowMap type
  71.259 +    ///
  71.260 +    /// \ref named-templ-param "Named parameter" for setting FlowMap
  71.261 +    /// type.
  71.262 +    template <typename T>
  71.263 +    struct SetFlowMap
  71.264 +      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
  71.265 +                           SetFlowMapTraits<T> > {
  71.266 +      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
  71.267 +                          SetFlowMapTraits<T> > Create;
  71.268 +    };
  71.269 +
  71.270 +    template <typename T>
  71.271 +    struct SetElevatorTraits : public Traits {
  71.272 +      typedef T Elevator;
  71.273 +      static Elevator *createElevator(const Digraph&, int) {
  71.274 +        LEMON_ASSERT(false, "Elevator is not initialized");
  71.275 +        return 0; // ignore warnings
  71.276 +      }
  71.277 +    };
  71.278 +
  71.279 +    /// \brief \ref named-templ-param "Named parameter" for setting
  71.280 +    /// Elevator type
  71.281 +    ///
  71.282 +    /// \ref named-templ-param "Named parameter" for setting Elevator
  71.283 +    /// type. If this named parameter is used, then an external
  71.284 +    /// elevator object must be passed to the algorithm using the
  71.285 +    /// \ref elevator(Elevator&) "elevator()" function before calling
  71.286 +    /// \ref run() or \ref init().
  71.287 +    /// \sa SetStandardElevator
  71.288 +    template <typename T>
  71.289 +    struct SetElevator
  71.290 +      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
  71.291 +                           SetElevatorTraits<T> > {
  71.292 +      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
  71.293 +                          SetElevatorTraits<T> > Create;
  71.294 +    };
  71.295 +
  71.296 +    template <typename T>
  71.297 +    struct SetStandardElevatorTraits : public Traits {
  71.298 +      typedef T Elevator;
  71.299 +      static Elevator *createElevator(const Digraph& digraph, int max_level) {
  71.300 +        return new Elevator(digraph, max_level);
  71.301 +      }
  71.302 +    };
  71.303 +
  71.304 +    /// \brief \ref named-templ-param "Named parameter" for setting
  71.305 +    /// Elevator type with automatic allocation
  71.306 +    ///
  71.307 +    /// \ref named-templ-param "Named parameter" for setting Elevator
  71.308 +    /// type with automatic allocation.
  71.309 +    /// The Elevator should have standard constructor interface to be
  71.310 +    /// able to automatically created by the algorithm (i.e. the
  71.311 +    /// digraph and the maximum level should be passed to it).
  71.312 +    /// However an external elevator object could also be passed to the
  71.313 +    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
  71.314 +    /// before calling \ref run() or \ref init().
  71.315 +    /// \sa SetElevator
  71.316 +    template <typename T>
  71.317 +    struct SetStandardElevator
  71.318 +      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
  71.319 +                       SetStandardElevatorTraits<T> > {
  71.320 +      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
  71.321 +                      SetStandardElevatorTraits<T> > Create;
  71.322 +    };
  71.323 +
  71.324 +    /// @}
  71.325 +
  71.326 +  protected:
  71.327 +
  71.328 +    Circulation() {}
  71.329 +
  71.330 +  public:
  71.331 +
  71.332 +    /// Constructor.
  71.333 +
  71.334 +    /// The constructor of the class.
  71.335 +    ///
  71.336 +    /// \param graph The digraph the algorithm runs on.
  71.337 +    /// \param lower The lower bounds for the flow values on the arcs.
  71.338 +    /// \param upper The upper bounds (capacities) for the flow values 
  71.339 +    /// on the arcs.
  71.340 +    /// \param supply The signed supply values of the nodes.
  71.341 +    Circulation(const Digraph &graph, const LowerMap &lower,
  71.342 +                const UpperMap &upper, const SupplyMap &supply)
  71.343 +      : _g(graph), _lo(&lower), _up(&upper), _supply(&supply),
  71.344 +        _flow(NULL), _local_flow(false), _level(NULL), _local_level(false),
  71.345 +        _excess(NULL) {}
  71.346 +
  71.347 +    /// Destructor.
  71.348 +    ~Circulation() {
  71.349 +      destroyStructures();
  71.350 +    }
  71.351 +
  71.352 +
  71.353 +  private:
  71.354 +
  71.355 +    bool checkBoundMaps() {
  71.356 +      for (ArcIt e(_g);e!=INVALID;++e) {
  71.357 +        if (_tol.less((*_up)[e], (*_lo)[e])) return false;
  71.358 +      }
  71.359 +      return true;
  71.360 +    }
  71.361 +
  71.362 +    void createStructures() {
  71.363 +      _node_num = _el = countNodes(_g);
  71.364 +
  71.365 +      if (!_flow) {
  71.366 +        _flow = Traits::createFlowMap(_g);
  71.367 +        _local_flow = true;
  71.368 +      }
  71.369 +      if (!_level) {
  71.370 +        _level = Traits::createElevator(_g, _node_num);
  71.371 +        _local_level = true;
  71.372 +      }
  71.373 +      if (!_excess) {
  71.374 +        _excess = new ExcessMap(_g);
  71.375 +      }
  71.376 +    }
  71.377 +
  71.378 +    void destroyStructures() {
  71.379 +      if (_local_flow) {
  71.380 +        delete _flow;
  71.381 +      }
  71.382 +      if (_local_level) {
  71.383 +        delete _level;
  71.384 +      }
  71.385 +      if (_excess) {
  71.386 +        delete _excess;
  71.387 +      }
  71.388 +    }
  71.389 +
  71.390 +  public:
  71.391 +
  71.392 +    /// Sets the lower bound map.
  71.393 +
  71.394 +    /// Sets the lower bound map.
  71.395 +    /// \return <tt>(*this)</tt>
  71.396 +    Circulation& lowerMap(const LowerMap& map) {
  71.397 +      _lo = &map;
  71.398 +      return *this;
  71.399 +    }
  71.400 +
  71.401 +    /// Sets the upper bound (capacity) map.
  71.402 +
  71.403 +    /// Sets the upper bound (capacity) map.
  71.404 +    /// \return <tt>(*this)</tt>
  71.405 +    Circulation& upperMap(const UpperMap& map) {
  71.406 +      _up = &map;
  71.407 +      return *this;
  71.408 +    }
  71.409 +
  71.410 +    /// Sets the supply map.
  71.411 +
  71.412 +    /// Sets the supply map.
  71.413 +    /// \return <tt>(*this)</tt>
  71.414 +    Circulation& supplyMap(const SupplyMap& map) {
  71.415 +      _supply = &map;
  71.416 +      return *this;
  71.417 +    }
  71.418 +
  71.419 +    /// \brief Sets the flow map.
  71.420 +    ///
  71.421 +    /// Sets the flow map.
  71.422 +    /// If you don't use this function before calling \ref run() or
  71.423 +    /// \ref init(), an instance will be allocated automatically.
  71.424 +    /// The destructor deallocates this automatically allocated map,
  71.425 +    /// of course.
  71.426 +    /// \return <tt>(*this)</tt>
  71.427 +    Circulation& flowMap(FlowMap& map) {
  71.428 +      if (_local_flow) {
  71.429 +        delete _flow;
  71.430 +        _local_flow = false;
  71.431 +      }
  71.432 +      _flow = &map;
  71.433 +      return *this;
  71.434 +    }
  71.435 +
  71.436 +    /// \brief Sets the elevator used by algorithm.
  71.437 +    ///
  71.438 +    /// Sets the elevator used by algorithm.
  71.439 +    /// If you don't use this function before calling \ref run() or
  71.440 +    /// \ref init(), an instance will be allocated automatically.
  71.441 +    /// The destructor deallocates this automatically allocated elevator,
  71.442 +    /// of course.
  71.443 +    /// \return <tt>(*this)</tt>
  71.444 +    Circulation& elevator(Elevator& elevator) {
  71.445 +      if (_local_level) {
  71.446 +        delete _level;
  71.447 +        _local_level = false;
  71.448 +      }
  71.449 +      _level = &elevator;
  71.450 +      return *this;
  71.451 +    }
  71.452 +
  71.453 +    /// \brief Returns a const reference to the elevator.
  71.454 +    ///
  71.455 +    /// Returns a const reference to the elevator.
  71.456 +    ///
  71.457 +    /// \pre Either \ref run() or \ref init() must be called before
  71.458 +    /// using this function.
  71.459 +    const Elevator& elevator() const {
  71.460 +      return *_level;
  71.461 +    }
  71.462 +
  71.463 +    /// \brief Sets the tolerance used by the algorithm.
  71.464 +    ///
  71.465 +    /// Sets the tolerance object used by the algorithm.
  71.466 +    /// \return <tt>(*this)</tt>
  71.467 +    Circulation& tolerance(const Tolerance& tolerance) {
  71.468 +      _tol = tolerance;
  71.469 +      return *this;
  71.470 +    }
  71.471 +
  71.472 +    /// \brief Returns a const reference to the tolerance.
  71.473 +    ///
  71.474 +    /// Returns a const reference to the tolerance object used by
  71.475 +    /// the algorithm.
  71.476 +    const Tolerance& tolerance() const {
  71.477 +      return _tol;
  71.478 +    }
  71.479 +
  71.480 +    /// \name Execution Control
  71.481 +    /// The simplest way to execute the algorithm is to call \ref run().\n
  71.482 +    /// If you need better control on the initial solution or the execution,
  71.483 +    /// you have to call one of the \ref init() functions first, then
  71.484 +    /// the \ref start() function.
  71.485 +
  71.486 +    ///@{
  71.487 +
  71.488 +    /// Initializes the internal data structures.
  71.489 +
  71.490 +    /// Initializes the internal data structures and sets all flow values
  71.491 +    /// to the lower bound.
  71.492 +    void init()
  71.493 +    {
  71.494 +      LEMON_DEBUG(checkBoundMaps(),
  71.495 +        "Upper bounds must be greater or equal to the lower bounds");
  71.496 +
  71.497 +      createStructures();
  71.498 +
  71.499 +      for(NodeIt n(_g);n!=INVALID;++n) {
  71.500 +        (*_excess)[n] = (*_supply)[n];
  71.501 +      }
  71.502 +
  71.503 +      for (ArcIt e(_g);e!=INVALID;++e) {
  71.504 +        _flow->set(e, (*_lo)[e]);
  71.505 +        (*_excess)[_g.target(e)] += (*_flow)[e];
  71.506 +        (*_excess)[_g.source(e)] -= (*_flow)[e];
  71.507 +      }
  71.508 +
  71.509 +      // global relabeling tested, but in general case it provides
  71.510 +      // worse performance for random digraphs
  71.511 +      _level->initStart();
  71.512 +      for(NodeIt n(_g);n!=INVALID;++n)
  71.513 +        _level->initAddItem(n);
  71.514 +      _level->initFinish();
  71.515 +      for(NodeIt n(_g);n!=INVALID;++n)
  71.516 +        if(_tol.positive((*_excess)[n]))
  71.517 +          _level->activate(n);
  71.518 +    }
  71.519 +
  71.520 +    /// Initializes the internal data structures using a greedy approach.
  71.521 +
  71.522 +    /// Initializes the internal data structures using a greedy approach
  71.523 +    /// to construct the initial solution.
  71.524 +    void greedyInit()
  71.525 +    {
  71.526 +      LEMON_DEBUG(checkBoundMaps(),
  71.527 +        "Upper bounds must be greater or equal to the lower bounds");
  71.528 +
  71.529 +      createStructures();
  71.530 +
  71.531 +      for(NodeIt n(_g);n!=INVALID;++n) {
  71.532 +        (*_excess)[n] = (*_supply)[n];
  71.533 +      }
  71.534 +
  71.535 +      for (ArcIt e(_g);e!=INVALID;++e) {
  71.536 +        if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) {
  71.537 +          _flow->set(e, (*_up)[e]);
  71.538 +          (*_excess)[_g.target(e)] += (*_up)[e];
  71.539 +          (*_excess)[_g.source(e)] -= (*_up)[e];
  71.540 +        } else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) {
  71.541 +          _flow->set(e, (*_lo)[e]);
  71.542 +          (*_excess)[_g.target(e)] += (*_lo)[e];
  71.543 +          (*_excess)[_g.source(e)] -= (*_lo)[e];
  71.544 +        } else {
  71.545 +          Value fc = -(*_excess)[_g.target(e)];
  71.546 +          _flow->set(e, fc);
  71.547 +          (*_excess)[_g.target(e)] = 0;
  71.548 +          (*_excess)[_g.source(e)] -= fc;
  71.549 +        }
  71.550 +      }
  71.551 +
  71.552 +      _level->initStart();
  71.553 +      for(NodeIt n(_g);n!=INVALID;++n)
  71.554 +        _level->initAddItem(n);
  71.555 +      _level->initFinish();
  71.556 +      for(NodeIt n(_g);n!=INVALID;++n)
  71.557 +        if(_tol.positive((*_excess)[n]))
  71.558 +          _level->activate(n);
  71.559 +    }
  71.560 +
  71.561 +    ///Executes the algorithm
  71.562 +
  71.563 +    ///This function executes the algorithm.
  71.564 +    ///
  71.565 +    ///\return \c true if a feasible circulation is found.
  71.566 +    ///
  71.567 +    ///\sa barrier()
  71.568 +    ///\sa barrierMap()
  71.569 +    bool start()
  71.570 +    {
  71.571 +
  71.572 +      Node act;
  71.573 +      Node bact=INVALID;
  71.574 +      Node last_activated=INVALID;
  71.575 +      while((act=_level->highestActive())!=INVALID) {
  71.576 +        int actlevel=(*_level)[act];
  71.577 +        int mlevel=_node_num;
  71.578 +        Value exc=(*_excess)[act];
  71.579 +
  71.580 +        for(OutArcIt e(_g,act);e!=INVALID; ++e) {
  71.581 +          Node v = _g.target(e);
  71.582 +          Value fc=(*_up)[e]-(*_flow)[e];
  71.583 +          if(!_tol.positive(fc)) continue;
  71.584 +          if((*_level)[v]<actlevel) {
  71.585 +            if(!_tol.less(fc, exc)) {
  71.586 +              _flow->set(e, (*_flow)[e] + exc);
  71.587 +              (*_excess)[v] += exc;
  71.588 +              if(!_level->active(v) && _tol.positive((*_excess)[v]))
  71.589 +                _level->activate(v);
  71.590 +              (*_excess)[act] = 0;
  71.591 +              _level->deactivate(act);
  71.592 +              goto next_l;
  71.593 +            }
  71.594 +            else {
  71.595 +              _flow->set(e, (*_up)[e]);
  71.596 +              (*_excess)[v] += fc;
  71.597 +              if(!_level->active(v) && _tol.positive((*_excess)[v]))
  71.598 +                _level->activate(v);
  71.599 +              exc-=fc;
  71.600 +            }
  71.601 +          }
  71.602 +          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
  71.603 +        }
  71.604 +        for(InArcIt e(_g,act);e!=INVALID; ++e) {
  71.605 +          Node v = _g.source(e);
  71.606 +          Value fc=(*_flow)[e]-(*_lo)[e];
  71.607 +          if(!_tol.positive(fc)) continue;
  71.608 +          if((*_level)[v]<actlevel) {
  71.609 +            if(!_tol.less(fc, exc)) {
  71.610 +              _flow->set(e, (*_flow)[e] - exc);
  71.611 +              (*_excess)[v] += exc;
  71.612 +              if(!_level->active(v) && _tol.positive((*_excess)[v]))
  71.613 +                _level->activate(v);
  71.614 +              (*_excess)[act] = 0;
  71.615 +              _level->deactivate(act);
  71.616 +              goto next_l;
  71.617 +            }
  71.618 +            else {
  71.619 +              _flow->set(e, (*_lo)[e]);
  71.620 +              (*_excess)[v] += fc;
  71.621 +              if(!_level->active(v) && _tol.positive((*_excess)[v]))
  71.622 +                _level->activate(v);
  71.623 +              exc-=fc;
  71.624 +            }
  71.625 +          }
  71.626 +          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
  71.627 +        }
  71.628 +
  71.629 +        (*_excess)[act] = exc;
  71.630 +        if(!_tol.positive(exc)) _level->deactivate(act);
  71.631 +        else if(mlevel==_node_num) {
  71.632 +          _level->liftHighestActiveToTop();
  71.633 +          _el = _node_num;
  71.634 +          return false;
  71.635 +        }
  71.636 +        else {
  71.637 +          _level->liftHighestActive(mlevel+1);
  71.638 +          if(_level->onLevel(actlevel)==0) {
  71.639 +            _el = actlevel;
  71.640 +            return false;
  71.641 +          }
  71.642 +        }
  71.643 +      next_l:
  71.644 +        ;
  71.645 +      }
  71.646 +      return true;
  71.647 +    }
  71.648 +
  71.649 +    /// Runs the algorithm.
  71.650 +
  71.651 +    /// This function runs the algorithm.
  71.652 +    ///
  71.653 +    /// \return \c true if a feasible circulation is found.
  71.654 +    ///
  71.655 +    /// \note Apart from the return value, c.run() is just a shortcut of
  71.656 +    /// the following code.
  71.657 +    /// \code
  71.658 +    ///   c.greedyInit();
  71.659 +    ///   c.start();
  71.660 +    /// \endcode
  71.661 +    bool run() {
  71.662 +      greedyInit();
  71.663 +      return start();
  71.664 +    }
  71.665 +
  71.666 +    /// @}
  71.667 +
  71.668 +    /// \name Query Functions
  71.669 +    /// The results of the circulation algorithm can be obtained using
  71.670 +    /// these functions.\n
  71.671 +    /// Either \ref run() or \ref start() should be called before
  71.672 +    /// using them.
  71.673 +
  71.674 +    ///@{
  71.675 +
  71.676 +    /// \brief Returns the flow value on the given arc.
  71.677 +    ///
  71.678 +    /// Returns the flow value on the given arc.
  71.679 +    ///
  71.680 +    /// \pre Either \ref run() or \ref init() must be called before
  71.681 +    /// using this function.
  71.682 +    Value flow(const Arc& arc) const {
  71.683 +      return (*_flow)[arc];
  71.684 +    }
  71.685 +
  71.686 +    /// \brief Returns a const reference to the flow map.
  71.687 +    ///
  71.688 +    /// Returns a const reference to the arc map storing the found flow.
  71.689 +    ///
  71.690 +    /// \pre Either \ref run() or \ref init() must be called before
  71.691 +    /// using this function.
  71.692 +    const FlowMap& flowMap() const {
  71.693 +      return *_flow;
  71.694 +    }
  71.695 +
  71.696 +    /**
  71.697 +       \brief Returns \c true if the given node is in a barrier.
  71.698 +
  71.699 +       Barrier is a set \e B of nodes for which
  71.700 +
  71.701 +       \f[ \sum_{uv\in A: u\in B} upper(uv) -
  71.702 +           \sum_{uv\in A: v\in B} lower(uv) < \sum_{v\in B} sup(v) \f]
  71.703 +
  71.704 +       holds. The existence of a set with this property prooves that a
  71.705 +       feasible circualtion cannot exist.
  71.706 +
  71.707 +       This function returns \c true if the given node is in the found
  71.708 +       barrier. If a feasible circulation is found, the function
  71.709 +       gives back \c false for every node.
  71.710 +
  71.711 +       \pre Either \ref run() or \ref init() must be called before
  71.712 +       using this function.
  71.713 +
  71.714 +       \sa barrierMap()
  71.715 +       \sa checkBarrier()
  71.716 +    */
  71.717 +    bool barrier(const Node& node) const
  71.718 +    {
  71.719 +      return (*_level)[node] >= _el;
  71.720 +    }
  71.721 +
  71.722 +    /// \brief Gives back a barrier.
  71.723 +    ///
  71.724 +    /// This function sets \c bar to the characteristic vector of the
  71.725 +    /// found barrier. \c bar should be a \ref concepts::WriteMap "writable"
  71.726 +    /// node map with \c bool (or convertible) value type.
  71.727 +    ///
  71.728 +    /// If a feasible circulation is found, the function gives back an
  71.729 +    /// empty set, so \c bar[v] will be \c false for all nodes \c v.
  71.730 +    ///
  71.731 +    /// \note This function calls \ref barrier() for each node,
  71.732 +    /// so it runs in O(n) time.
  71.733 +    ///
  71.734 +    /// \pre Either \ref run() or \ref init() must be called before
  71.735 +    /// using this function.
  71.736 +    ///
  71.737 +    /// \sa barrier()
  71.738 +    /// \sa checkBarrier()
  71.739 +    template<class BarrierMap>
  71.740 +    void barrierMap(BarrierMap &bar) const
  71.741 +    {
  71.742 +      for(NodeIt n(_g);n!=INVALID;++n)
  71.743 +        bar.set(n, (*_level)[n] >= _el);
  71.744 +    }
  71.745 +
  71.746 +    /// @}
  71.747 +
  71.748 +    /// \name Checker Functions
  71.749 +    /// The feasibility of the results can be checked using
  71.750 +    /// these functions.\n
  71.751 +    /// Either \ref run() or \ref start() should be called before
  71.752 +    /// using them.
  71.753 +
  71.754 +    ///@{
  71.755 +
  71.756 +    ///Check if the found flow is a feasible circulation
  71.757 +
  71.758 +    ///Check if the found flow is a feasible circulation,
  71.759 +    ///
  71.760 +    bool checkFlow() const {
  71.761 +      for(ArcIt e(_g);e!=INVALID;++e)
  71.762 +        if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false;
  71.763 +      for(NodeIt n(_g);n!=INVALID;++n)
  71.764 +        {
  71.765 +          Value dif=-(*_supply)[n];
  71.766 +          for(InArcIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e];
  71.767 +          for(OutArcIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e];
  71.768 +          if(_tol.negative(dif)) return false;
  71.769 +        }
  71.770 +      return true;
  71.771 +    }
  71.772 +
  71.773 +    ///Check whether or not the last execution provides a barrier
  71.774 +
  71.775 +    ///Check whether or not the last execution provides a barrier.
  71.776 +    ///\sa barrier()
  71.777 +    ///\sa barrierMap()
  71.778 +    bool checkBarrier() const
  71.779 +    {
  71.780 +      Value delta=0;
  71.781 +      Value inf_cap = std::numeric_limits<Value>::has_infinity ?
  71.782 +        std::numeric_limits<Value>::infinity() :
  71.783 +        std::numeric_limits<Value>::max();
  71.784 +      for(NodeIt n(_g);n!=INVALID;++n)
  71.785 +        if(barrier(n))
  71.786 +          delta-=(*_supply)[n];
  71.787 +      for(ArcIt e(_g);e!=INVALID;++e)
  71.788 +        {
  71.789 +          Node s=_g.source(e);
  71.790 +          Node t=_g.target(e);
  71.791 +          if(barrier(s)&&!barrier(t)) {
  71.792 +            if (_tol.less(inf_cap - (*_up)[e], delta)) return false;
  71.793 +            delta+=(*_up)[e];
  71.794 +          }
  71.795 +          else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
  71.796 +        }
  71.797 +      return _tol.negative(delta);
  71.798 +    }
  71.799 +
  71.800 +    /// @}
  71.801 +
  71.802 +  };
  71.803 +
  71.804 +}
  71.805 +
  71.806 +#endif
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/lemon/clp.cc	Thu Nov 05 15:50:01 2009 +0100
    72.3 @@ -0,0 +1,466 @@
    72.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    72.5 + *
    72.6 + * This file is a part of LEMON, a generic C++ optimization library.
    72.7 + *
    72.8 + * Copyright (C) 2003-2008
    72.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   72.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   72.11 + *
   72.12 + * Permission to use, modify and distribute this software is granted
   72.13 + * provided that this copyright notice appears in all copies. For
   72.14 + * precise terms see the accompanying LICENSE file.
   72.15 + *
   72.16 + * This software is provided "AS IS" with no warranty of any kind,
   72.17 + * express or implied, and with no claim as to its suitability for any
   72.18 + * purpose.
   72.19 + *
   72.20 + */
   72.21 +
   72.22 +#include <lemon/clp.h>
   72.23 +#include <coin/ClpSimplex.hpp>
   72.24 +
   72.25 +namespace lemon {
   72.26 +
   72.27 +  ClpLp::ClpLp() {
   72.28 +    _prob = new ClpSimplex();
   72.29 +    _init_temporals();
   72.30 +    messageLevel(MESSAGE_NOTHING);
   72.31 +  }
   72.32 +
   72.33 +  ClpLp::ClpLp(const ClpLp& other) {
   72.34 +    _prob = new ClpSimplex(*other._prob);
   72.35 +    rows = other.rows;
   72.36 +    cols = other.cols;
   72.37 +    _init_temporals();
   72.38 +    messageLevel(MESSAGE_NOTHING);
   72.39 +  }
   72.40 +
   72.41 +  ClpLp::~ClpLp() {
   72.42 +    delete _prob;
   72.43 +    _clear_temporals();
   72.44 +  }
   72.45 +
   72.46 +  void ClpLp::_init_temporals() {
   72.47 +    _primal_ray = 0;
   72.48 +    _dual_ray = 0;
   72.49 +  }
   72.50 +
   72.51 +  void ClpLp::_clear_temporals() {
   72.52 +    if (_primal_ray) {
   72.53 +      delete[] _primal_ray;
   72.54 +      _primal_ray = 0;
   72.55 +    }
   72.56 +    if (_dual_ray) {
   72.57 +      delete[] _dual_ray;
   72.58 +      _dual_ray = 0;
   72.59 +    }
   72.60 +  }
   72.61 +
   72.62 +  ClpLp* ClpLp::newSolver() const {
   72.63 +    ClpLp* newlp = new ClpLp;
   72.64 +    return newlp;
   72.65 +  }
   72.66 +
   72.67 +  ClpLp* ClpLp::cloneSolver() const {
   72.68 +    ClpLp* copylp = new ClpLp(*this);
   72.69 +    return copylp;
   72.70 +  }
   72.71 +
   72.72 +  const char* ClpLp::_solverName() const { return "ClpLp"; }
   72.73 +
   72.74 +  int ClpLp::_addCol() {
   72.75 +    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0);
   72.76 +    return _prob->numberColumns() - 1;
   72.77 +  }
   72.78 +
   72.79 +  int ClpLp::_addRow() {
   72.80 +    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
   72.81 +    return _prob->numberRows() - 1;
   72.82 +  }
   72.83 +
   72.84 +  int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
   72.85 +    std::vector<int> indexes;
   72.86 +    std::vector<Value> values;
   72.87 +
   72.88 +    for(ExprIterator it = b; it != e; ++it) {
   72.89 +      indexes.push_back(it->first);
   72.90 +      values.push_back(it->second);
   72.91 +    }
   72.92 +
   72.93 +    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
   72.94 +    return _prob->numberRows() - 1;
   72.95 +  }
   72.96 +
   72.97 +
   72.98 +  void ClpLp::_eraseCol(int c) {
   72.99 +    _col_names_ref.erase(_prob->getColumnName(c));
  72.100 +    _prob->deleteColumns(1, &c);
  72.101 +  }
  72.102 +
  72.103 +  void ClpLp::_eraseRow(int r) {
  72.104 +    _row_names_ref.erase(_prob->getRowName(r));
  72.105 +    _prob->deleteRows(1, &r);
  72.106 +  }
  72.107 +
  72.108 +  void ClpLp::_eraseColId(int i) {
  72.109 +    cols.eraseIndex(i);
  72.110 +    cols.shiftIndices(i);
  72.111 +  }
  72.112 +
  72.113 +  void ClpLp::_eraseRowId(int i) {
  72.114 +    rows.eraseIndex(i);
  72.115 +    rows.shiftIndices(i);
  72.116 +  }
  72.117 +
  72.118 +  void ClpLp::_getColName(int c, std::string& name) const {
  72.119 +    name = _prob->getColumnName(c);
  72.120 +  }
  72.121 +
  72.122 +  void ClpLp::_setColName(int c, const std::string& name) {
  72.123 +    _prob->setColumnName(c, const_cast<std::string&>(name));
  72.124 +    _col_names_ref[name] = c;
  72.125 +  }
  72.126 +
  72.127 +  int ClpLp::_colByName(const std::string& name) const {
  72.128 +    std::map<std::string, int>::const_iterator it = _col_names_ref.find(name);
  72.129 +    return it != _col_names_ref.end() ? it->second : -1;
  72.130 +  }
  72.131 +
  72.132 +  void ClpLp::_getRowName(int r, std::string& name) const {
  72.133 +    name = _prob->getRowName(r);
  72.134 +  }
  72.135 +
  72.136 +  void ClpLp::_setRowName(int r, const std::string& name) {
  72.137 +    _prob->setRowName(r, const_cast<std::string&>(name));
  72.138 +    _row_names_ref[name] = r;
  72.139 +  }
  72.140 +
  72.141 +  int ClpLp::_rowByName(const std::string& name) const {
  72.142 +    std::map<std::string, int>::const_iterator it = _row_names_ref.find(name);
  72.143 +    return it != _row_names_ref.end() ? it->second : -1;
  72.144 +  }
  72.145 +
  72.146 +
  72.147 +  void ClpLp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) {
  72.148 +    std::map<int, Value> coeffs;
  72.149 +
  72.150 +    int n = _prob->clpMatrix()->getNumCols();
  72.151 +
  72.152 +    const int* indices = _prob->clpMatrix()->getIndices();
  72.153 +    const double* elements = _prob->clpMatrix()->getElements();
  72.154 +
  72.155 +    for (int i = 0; i < n; ++i) {
  72.156 +      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
  72.157 +      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
  72.158 +
  72.159 +      const int* it = std::lower_bound(indices + begin, indices + end, ix);
  72.160 +      if (it != indices + end && *it == ix && elements[it - indices] != 0.0) {
  72.161 +        coeffs[i] = 0.0;
  72.162 +      }
  72.163 +    }
  72.164 +
  72.165 +    for (ExprIterator it = b; it != e; ++it) {
  72.166 +      coeffs[it->first] = it->second;
  72.167 +    }
  72.168 +
  72.169 +    for (std::map<int, Value>::iterator it = coeffs.begin();
  72.170 +         it != coeffs.end(); ++it) {
  72.171 +      _prob->modifyCoefficient(ix, it->first, it->second);
  72.172 +    }
  72.173 +  }
  72.174 +
  72.175 +  void ClpLp::_getRowCoeffs(int ix, InsertIterator b) const {
  72.176 +    int n = _prob->clpMatrix()->getNumCols();
  72.177 +
  72.178 +    const int* indices = _prob->clpMatrix()->getIndices();
  72.179 +    const double* elements = _prob->clpMatrix()->getElements();
  72.180 +
  72.181 +    for (int i = 0; i < n; ++i) {
  72.182 +      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
  72.183 +      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
  72.184 +
  72.185 +      const int* it = std::lower_bound(indices + begin, indices + end, ix);
  72.186 +      if (it != indices + end && *it == ix) {
  72.187 +        *b = std::make_pair(i, elements[it - indices]);
  72.188 +      }
  72.189 +    }
  72.190 +  }
  72.191 +
  72.192 +  void ClpLp::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
  72.193 +    std::map<int, Value> coeffs;
  72.194 +
  72.195 +    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
  72.196 +    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
  72.197 +
  72.198 +    const int* indices = _prob->clpMatrix()->getIndices();
  72.199 +    const double* elements = _prob->clpMatrix()->getElements();
  72.200 +
  72.201 +    for (CoinBigIndex i = begin; i != end; ++i) {
  72.202 +      if (elements[i] != 0.0) {
  72.203 +        coeffs[indices[i]] = 0.0;
  72.204 +      }
  72.205 +    }
  72.206 +    for (ExprIterator it = b; it != e; ++it) {
  72.207 +      coeffs[it->first] = it->second;
  72.208 +    }
  72.209 +    for (std::map<int, Value>::iterator it = coeffs.begin();
  72.210 +         it != coeffs.end(); ++it) {
  72.211 +      _prob->modifyCoefficient(it->first, ix, it->second);
  72.212 +    }
  72.213 +  }
  72.214 +
  72.215 +  void ClpLp::_getColCoeffs(int ix, InsertIterator b) const {
  72.216 +    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
  72.217 +    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
  72.218 +
  72.219 +    const int* indices = _prob->clpMatrix()->getIndices();
  72.220 +    const double* elements = _prob->clpMatrix()->getElements();
  72.221 +
  72.222 +    for (CoinBigIndex i = begin; i != end; ++i) {
  72.223 +      *b = std::make_pair(indices[i], elements[i]);
  72.224 +      ++b;
  72.225 +    }
  72.226 +  }
  72.227 +
  72.228 +  void ClpLp::_setCoeff(int ix, int jx, Value value) {
  72.229 +    _prob->modifyCoefficient(ix, jx, value);
  72.230 +  }
  72.231 +
  72.232 +  ClpLp::Value ClpLp::_getCoeff(int ix, int jx) const {
  72.233 +    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
  72.234 +    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
  72.235 +
  72.236 +    const int* indices = _prob->clpMatrix()->getIndices();
  72.237 +    const double* elements = _prob->clpMatrix()->getElements();
  72.238 +
  72.239 +    const int* it = std::lower_bound(indices + begin, indices + end, jx);
  72.240 +    if (it != indices + end && *it == jx) {
  72.241 +      return elements[it - indices];
  72.242 +    } else {
  72.243 +      return 0.0;
  72.244 +    }
  72.245 +  }
  72.246 +
  72.247 +  void ClpLp::_setColLowerBound(int i, Value lo) {
  72.248 +    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
  72.249 +  }
  72.250 +
  72.251 +  ClpLp::Value ClpLp::_getColLowerBound(int i) const {
  72.252 +    double val = _prob->getColLower()[i];
  72.253 +    return val == - COIN_DBL_MAX ? - INF : val;
  72.254 +  }
  72.255 +
  72.256 +  void ClpLp::_setColUpperBound(int i, Value up) {
  72.257 +    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
  72.258 +  }
  72.259 +
  72.260 +  ClpLp::Value ClpLp::_getColUpperBound(int i) const {
  72.261 +    double val = _prob->getColUpper()[i];
  72.262 +    return val == COIN_DBL_MAX ? INF : val;
  72.263 +  }
  72.264 +
  72.265 +  void ClpLp::_setRowLowerBound(int i, Value lo) {
  72.266 +    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
  72.267 +  }
  72.268 +
  72.269 +  ClpLp::Value ClpLp::_getRowLowerBound(int i) const {
  72.270 +    double val = _prob->getRowLower()[i];
  72.271 +    return val == - COIN_DBL_MAX ? - INF : val;
  72.272 +  }
  72.273 +
  72.274 +  void ClpLp::_setRowUpperBound(int i, Value up) {
  72.275 +    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
  72.276 +  }
  72.277 +
  72.278 +  ClpLp::Value ClpLp::_getRowUpperBound(int i) const {
  72.279 +    double val = _prob->getRowUpper()[i];
  72.280 +    return val == COIN_DBL_MAX ? INF : val;
  72.281 +  }
  72.282 +
  72.283 +  void ClpLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
  72.284 +    int num = _prob->clpMatrix()->getNumCols();
  72.285 +    for (int i = 0; i < num; ++i) {
  72.286 +      _prob->setObjectiveCoefficient(i, 0.0);
  72.287 +    }
  72.288 +    for (ExprIterator it = b; it != e; ++it) {
  72.289 +      _prob->setObjectiveCoefficient(it->first, it->second);
  72.290 +    }
  72.291 +  }
  72.292 +
  72.293 +  void ClpLp::_getObjCoeffs(InsertIterator b) const {
  72.294 +    int num = _prob->clpMatrix()->getNumCols();
  72.295 +    for (int i = 0; i < num; ++i) {
  72.296 +      Value coef = _prob->getObjCoefficients()[i];
  72.297 +      if (coef != 0.0) {
  72.298 +        *b = std::make_pair(i, coef);
  72.299 +        ++b;
  72.300 +      }
  72.301 +    }
  72.302 +  }
  72.303 +
  72.304 +  void ClpLp::_setObjCoeff(int i, Value obj_coef) {
  72.305 +    _prob->setObjectiveCoefficient(i, obj_coef);
  72.306 +  }
  72.307 +
  72.308 +  ClpLp::Value ClpLp::_getObjCoeff(int i) const {
  72.309 +    return _prob->getObjCoefficients()[i];
  72.310 +  }
  72.311 +
  72.312 +  ClpLp::SolveExitStatus ClpLp::_solve() {
  72.313 +    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
  72.314 +  }
  72.315 +
  72.316 +  ClpLp::SolveExitStatus ClpLp::solvePrimal() {
  72.317 +    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
  72.318 +  }
  72.319 +
  72.320 +  ClpLp::SolveExitStatus ClpLp::solveDual() {
  72.321 +    return _prob->dual() >= 0 ? SOLVED : UNSOLVED;
  72.322 +  }
  72.323 +
  72.324 +  ClpLp::SolveExitStatus ClpLp::solveBarrier() {
  72.325 +    return _prob->barrier() >= 0 ? SOLVED : UNSOLVED;
  72.326 +  }
  72.327 +
  72.328 +  ClpLp::Value ClpLp::_getPrimal(int i) const {
  72.329 +    return _prob->primalColumnSolution()[i];
  72.330 +  }
  72.331 +  ClpLp::Value ClpLp::_getPrimalValue() const {
  72.332 +    return _prob->objectiveValue();
  72.333 +  }
  72.334 +
  72.335 +  ClpLp::Value ClpLp::_getDual(int i) const {
  72.336 +    return _prob->dualRowSolution()[i];
  72.337 +  }
  72.338 +
  72.339 +  ClpLp::Value ClpLp::_getPrimalRay(int i) const {
  72.340 +    if (!_primal_ray) {
  72.341 +      _primal_ray = _prob->unboundedRay();
  72.342 +      LEMON_ASSERT(_primal_ray != 0, "Primal ray is not provided");
  72.343 +    }
  72.344 +    return _primal_ray[i];
  72.345 +  }
  72.346 +
  72.347 +  ClpLp::Value ClpLp::_getDualRay(int i) const {
  72.348 +    if (!_dual_ray) {
  72.349 +      _dual_ray = _prob->infeasibilityRay();
  72.350 +      LEMON_ASSERT(_dual_ray != 0, "Dual ray is not provided");
  72.351 +    }
  72.352 +    return _dual_ray[i];
  72.353 +  }
  72.354 +
  72.355 +  ClpLp::VarStatus ClpLp::_getColStatus(int i) const {
  72.356 +    switch (_prob->getColumnStatus(i)) {
  72.357 +    case ClpSimplex::basic:
  72.358 +      return BASIC;
  72.359 +    case ClpSimplex::isFree:
  72.360 +      return FREE;
  72.361 +    case ClpSimplex::atUpperBound:
  72.362 +      return UPPER;
  72.363 +    case ClpSimplex::atLowerBound:
  72.364 +      return LOWER;
  72.365 +    case ClpSimplex::isFixed:
  72.366 +      return FIXED;
  72.367 +    case ClpSimplex::superBasic:
  72.368 +      return FREE;
  72.369 +    default:
  72.370 +      LEMON_ASSERT(false, "Wrong column status");
  72.371 +      return VarStatus();
  72.372 +    }
  72.373 +  }
  72.374 +
  72.375 +  ClpLp::VarStatus ClpLp::_getRowStatus(int i) const {
  72.376 +    switch (_prob->getColumnStatus(i)) {
  72.377 +    case ClpSimplex::basic:
  72.378 +      return BASIC;
  72.379 +    case ClpSimplex::isFree:
  72.380 +      return FREE;
  72.381 +    case ClpSimplex::atUpperBound:
  72.382 +      return UPPER;
  72.383 +    case ClpSimplex::atLowerBound:
  72.384 +      return LOWER;
  72.385 +    case ClpSimplex::isFixed:
  72.386 +      return FIXED;
  72.387 +    case ClpSimplex::superBasic:
  72.388 +      return FREE;
  72.389 +    default:
  72.390 +      LEMON_ASSERT(false, "Wrong row status");
  72.391 +      return VarStatus();
  72.392 +    }
  72.393 +  }
  72.394 +
  72.395 +
  72.396 +  ClpLp::ProblemType ClpLp::_getPrimalType() const {
  72.397 +    if (_prob->isProvenOptimal()) {
  72.398 +      return OPTIMAL;
  72.399 +    } else if (_prob->isProvenPrimalInfeasible()) {
  72.400 +      return INFEASIBLE;
  72.401 +    } else if (_prob->isProvenDualInfeasible()) {
  72.402 +      return UNBOUNDED;
  72.403 +    } else {
  72.404 +      return UNDEFINED;
  72.405 +    }
  72.406 +  }
  72.407 +
  72.408 +  ClpLp::ProblemType ClpLp::_getDualType() const {
  72.409 +    if (_prob->isProvenOptimal()) {
  72.410 +      return OPTIMAL;
  72.411 +    } else if (_prob->isProvenDualInfeasible()) {
  72.412 +      return INFEASIBLE;
  72.413 +    } else if (_prob->isProvenPrimalInfeasible()) {
  72.414 +      return INFEASIBLE;
  72.415 +    } else {
  72.416 +      return UNDEFINED;
  72.417 +    }
  72.418 +  }
  72.419 +
  72.420 +  void ClpLp::_setSense(ClpLp::Sense sense) {
  72.421 +    switch (sense) {
  72.422 +    case MIN:
  72.423 +      _prob->setOptimizationDirection(1);
  72.424 +      break;
  72.425 +    case MAX:
  72.426 +      _prob->setOptimizationDirection(-1);
  72.427 +      break;
  72.428 +    }
  72.429 +  }
  72.430 +
  72.431 +  ClpLp::Sense ClpLp::_getSense() const {
  72.432 +    double dir = _prob->optimizationDirection();
  72.433 +    if (dir > 0.0) {
  72.434 +      return MIN;
  72.435 +    } else {
  72.436 +      return MAX;
  72.437 +    }
  72.438 +  }
  72.439 +
  72.440 +  void ClpLp::_clear() {
  72.441 +    delete _prob;
  72.442 +    _prob = new ClpSimplex();
  72.443 +    rows.clear();
  72.444 +    cols.clear();
  72.445 +    _col_names_ref.clear();
  72.446 +    _clear_temporals();
  72.447 +  }
  72.448 +
  72.449 +  void ClpLp::_messageLevel(MessageLevel level) {
  72.450 +    switch (level) {
  72.451 +    case MESSAGE_NOTHING:
  72.452 +      _prob->setLogLevel(0);
  72.453 +      break;
  72.454 +    case MESSAGE_ERROR:
  72.455 +      _prob->setLogLevel(1);
  72.456 +      break;
  72.457 +    case MESSAGE_WARNING:
  72.458 +      _prob->setLogLevel(2);
  72.459 +      break;
  72.460 +    case MESSAGE_NORMAL:
  72.461 +      _prob->setLogLevel(3);
  72.462 +      break;
  72.463 +    case MESSAGE_VERBOSE:
  72.464 +      _prob->setLogLevel(4);
  72.465 +      break;
  72.466 +    }
  72.467 +  }
  72.468 +
  72.469 +} //END OF NAMESPACE LEMON
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/lemon/clp.h	Thu Nov 05 15:50:01 2009 +0100
    73.3 @@ -0,0 +1,164 @@
    73.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    73.5 + *
    73.6 + * This file is a part of LEMON, a generic C++ optimization library.
    73.7 + *
    73.8 + * Copyright (C) 2003-2008
    73.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   73.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   73.11 + *
   73.12 + * Permission to use, modify and distribute this software is granted
   73.13 + * provided that this copyright notice appears in all copies. For
   73.14 + * precise terms see the accompanying LICENSE file.
   73.15 + *
   73.16 + * This software is provided "AS IS" with no warranty of any kind,
   73.17 + * express or implied, and with no claim as to its suitability for any
   73.18 + * purpose.
   73.19 + *
   73.20 + */
   73.21 +
   73.22 +#ifndef LEMON_CLP_H
   73.23 +#define LEMON_CLP_H
   73.24 +
   73.25 +///\file
   73.26 +///\brief Header of the LEMON-CLP lp solver interface.
   73.27 +
   73.28 +#include <vector>
   73.29 +#include <string>
   73.30 +
   73.31 +#include <lemon/lp_base.h>
   73.32 +
   73.33 +class ClpSimplex;
   73.34 +
   73.35 +namespace lemon {
   73.36 +
   73.37 +  /// \ingroup lp_group
   73.38 +  ///
   73.39 +  /// \brief Interface for the CLP solver
   73.40 +  ///
   73.41 +  /// This class implements an interface for the Clp LP solver.  The
   73.42 +  /// Clp library is an object oriented lp solver library developed at
   73.43 +  /// the IBM. The CLP is part of the COIN-OR package and it can be
   73.44 +  /// used with Common Public License.
   73.45 +  class ClpLp : public LpSolver {
   73.46 +  protected:
   73.47 +
   73.48 +    ClpSimplex* _prob;
   73.49 +
   73.50 +    std::map<std::string, int> _col_names_ref;
   73.51 +    std::map<std::string, int> _row_names_ref;
   73.52 +
   73.53 +  public:
   73.54 +
   73.55 +    /// \e
   73.56 +    ClpLp();
   73.57 +    /// \e
   73.58 +    ClpLp(const ClpLp&);
   73.59 +    /// \e
   73.60 +    ~ClpLp();
   73.61 +
   73.62 +    /// \e
   73.63 +    virtual ClpLp* newSolver() const;
   73.64 +    /// \e
   73.65 +    virtual ClpLp* cloneSolver() const;
   73.66 +
   73.67 +  protected:
   73.68 +
   73.69 +    mutable double* _primal_ray;
   73.70 +    mutable double* _dual_ray;
   73.71 +
   73.72 +    void _init_temporals();
   73.73 +    void _clear_temporals();
   73.74 +
   73.75 +  protected:
   73.76 +
   73.77 +    virtual const char* _solverName() const;
   73.78 +
   73.79 +    virtual int _addCol();
   73.80 +    virtual int _addRow();
   73.81 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
   73.82 +
   73.83 +    virtual void _eraseCol(int i);
   73.84 +    virtual void _eraseRow(int i);
   73.85 +
   73.86 +    virtual void _eraseColId(int i);
   73.87 +    virtual void _eraseRowId(int i);
   73.88 +
   73.89 +    virtual void _getColName(int col, std::string& name) const;
   73.90 +    virtual void _setColName(int col, const std::string& name);
   73.91 +    virtual int _colByName(const std::string& name) const;
   73.92 +
   73.93 +    virtual void _getRowName(int row, std::string& name) const;
   73.94 +    virtual void _setRowName(int row, const std::string& name);
   73.95 +    virtual int _rowByName(const std::string& name) const;
   73.96 +
   73.97 +    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
   73.98 +    virtual void _getRowCoeffs(int i, InsertIterator b) const;
   73.99 +
  73.100 +    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
  73.101 +    virtual void _getColCoeffs(int i, InsertIterator b) const;
  73.102 +
  73.103 +    virtual void _setCoeff(int row, int col, Value value);
  73.104 +    virtual Value _getCoeff(int row, int col) const;
  73.105 +
  73.106 +    virtual void _setColLowerBound(int i, Value value);
  73.107 +    virtual Value _getColLowerBound(int i) const;
  73.108 +    virtual void _setColUpperBound(int i, Value value);
  73.109 +    virtual Value _getColUpperBound(int i) const;
  73.110 +
  73.111 +    virtual void _setRowLowerBound(int i, Value value);
  73.112 +    virtual Value _getRowLowerBound(int i) const;
  73.113 +    virtual void _setRowUpperBound(int i, Value value);
  73.114 +    virtual Value _getRowUpperBound(int i) const;
  73.115 +
  73.116 +    virtual void _setObjCoeffs(ExprIterator, ExprIterator);
  73.117 +    virtual void _getObjCoeffs(InsertIterator) const;
  73.118 +
  73.119 +    virtual void _setObjCoeff(int i, Value obj_coef);
  73.120 +    virtual Value _getObjCoeff(int i) const;
  73.121 +
  73.122 +    virtual void _setSense(Sense sense);
  73.123 +    virtual Sense _getSense() const;
  73.124 +
  73.125 +    virtual SolveExitStatus _solve();
  73.126 +
  73.127 +    virtual Value _getPrimal(int i) const;
  73.128 +    virtual Value _getDual(int i) const;
  73.129 +
  73.130 +    virtual Value _getPrimalValue() const;
  73.131 +
  73.132 +    virtual Value _getPrimalRay(int i) const;
  73.133 +    virtual Value _getDualRay(int i) const;
  73.134 +
  73.135 +    virtual VarStatus _getColStatus(int i) const;
  73.136 +    virtual VarStatus _getRowStatus(int i) const;
  73.137 +
  73.138 +    virtual ProblemType _getPrimalType() const;
  73.139 +    virtual ProblemType _getDualType() const;
  73.140 +
  73.141 +    virtual void _clear();
  73.142 +
  73.143 +    virtual void _messageLevel(MessageLevel);
  73.144 +    
  73.145 +  public:
  73.146 +
  73.147 +    ///Solves LP with primal simplex method.
  73.148 +    SolveExitStatus solvePrimal();
  73.149 +
  73.150 +    ///Solves LP with dual simplex method.
  73.151 +    SolveExitStatus solveDual();
  73.152 +
  73.153 +    ///Solves LP with barrier method.
  73.154 +    SolveExitStatus solveBarrier();
  73.155 +
  73.156 +    ///Returns the constraint identifier understood by CLP.
  73.157 +    int clpRow(Row r) const { return rows(id(r)); }
  73.158 +
  73.159 +    ///Returns the variable identifier understood by CLP.
  73.160 +    int clpCol(Col c) const { return cols(id(c)); }
  73.161 +
  73.162 +  };
  73.163 +
  73.164 +} //END OF NAMESPACE LEMON
  73.165 +
  73.166 +#endif //LEMON_CLP_H
  73.167 +
    74.1 --- a/lemon/color.cc	Fri Oct 16 10:21:37 2009 +0200
    74.2 +++ b/lemon/color.cc	Thu Nov 05 15:50:01 2009 +0100
    74.3 @@ -2,7 +2,7 @@
    74.4   *
    74.5   * This file is a part of LEMON, a generic C++ optimization library.
    74.6   *
    74.7 - * Copyright (C) 2003-2008
    74.8 + * Copyright (C) 2003-2009
    74.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   74.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   74.11   *
    75.1 --- a/lemon/color.h	Fri Oct 16 10:21:37 2009 +0200
    75.2 +++ b/lemon/color.h	Thu Nov 05 15:50:01 2009 +0100
    75.3 @@ -2,7 +2,7 @@
    75.4   *
    75.5   * This file is a part of LEMON, a generic C++ optimization library.
    75.6   *
    75.7 - * Copyright (C) 2003-2008
    75.8 + * Copyright (C) 2003-2009
    75.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   75.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   75.11   *
    76.1 --- a/lemon/concept_check.h	Fri Oct 16 10:21:37 2009 +0200
    76.2 +++ b/lemon/concept_check.h	Thu Nov 05 15:50:01 2009 +0100
    76.3 @@ -2,7 +2,7 @@
    76.4   *
    76.5   * This file is a part of LEMON, a generic C++ optimization library.
    76.6   *
    76.7 - * Copyright (C) 2003-2008
    76.8 + * Copyright (C) 2003-2009
    76.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   76.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   76.11   *
    77.1 --- a/lemon/concepts/digraph.h	Fri Oct 16 10:21:37 2009 +0200
    77.2 +++ b/lemon/concepts/digraph.h	Thu Nov 05 15:50:01 2009 +0100
    77.3 @@ -2,7 +2,7 @@
    77.4   *
    77.5   * This file is a part of LEMON, a generic C++ optimization library.
    77.6   *
    77.7 - * Copyright (C) 2003-2008
    77.8 + * Copyright (C) 2003-2009
    77.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   77.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   77.11   *
   77.12 @@ -16,8 +16,8 @@
   77.13   *
   77.14   */
   77.15  
   77.16 -#ifndef LEMON_CONCEPT_DIGRAPH_H
   77.17 -#define LEMON_CONCEPT_DIGRAPH_H
   77.18 +#ifndef LEMON_CONCEPTS_DIGRAPH_H
   77.19 +#define LEMON_CONCEPTS_DIGRAPH_H
   77.20  
   77.21  ///\ingroup graph_concepts
   77.22  ///\file
   77.23 @@ -35,46 +35,40 @@
   77.24      ///
   77.25      /// \brief Class describing the concept of directed graphs.
   77.26      ///
   77.27 -    /// This class describes the \ref concept "concept" of the
   77.28 -    /// immutable directed digraphs.
   77.29 +    /// This class describes the common interface of all directed
   77.30 +    /// graphs (digraphs).
   77.31      ///
   77.32 -    /// Note that actual digraph implementation like @ref ListDigraph or
   77.33 -    /// @ref SmartDigraph may have several additional functionality.
   77.34 +    /// Like all concept classes, it only provides an interface
   77.35 +    /// without any sensible implementation. So any general algorithm for
   77.36 +    /// directed graphs should compile with this class, but it will not
   77.37 +    /// run properly, of course.
   77.38 +    /// An actual digraph implementation like \ref ListDigraph or
   77.39 +    /// \ref SmartDigraph may have additional functionality.
   77.40      ///
   77.41 -    /// \sa concept
   77.42 +    /// \sa Graph
   77.43      class Digraph {
   77.44      private:
   77.45 -      ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
   77.46 +      /// Diraphs are \e not copy constructible. Use DigraphCopy instead.
   77.47 +      Digraph(const Digraph &) {}
   77.48 +      /// \brief Assignment of a digraph to another one is \e not allowed.
   77.49 +      /// Use DigraphCopy instead.
   77.50 +      void operator=(const Digraph &) {}
   77.51  
   77.52 -      ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
   77.53 -      ///
   77.54 -      Digraph(const Digraph &) {};
   77.55 -      ///\brief Assignment of \ref Digraph "Digraph"s to another ones are
   77.56 -      ///\e not allowed. Use DigraphCopy() instead.
   77.57 +    public:
   77.58 +      /// Default constructor.
   77.59 +      Digraph() { }
   77.60  
   77.61 -      ///Assignment of \ref Digraph "Digraph"s to another ones are
   77.62 -      ///\e not allowed.  Use DigraphCopy() instead.
   77.63 -
   77.64 -      void operator=(const Digraph &) {}
   77.65 -    public:
   77.66 -      ///\e
   77.67 -
   77.68 -      /// Defalult constructor.
   77.69 -
   77.70 -      /// Defalult constructor.
   77.71 -      ///
   77.72 -      Digraph() { }
   77.73 -      /// Class for identifying a node of the digraph
   77.74 +      /// The node type of the digraph
   77.75  
   77.76        /// This class identifies a node of the digraph. It also serves
   77.77        /// as a base class of the node iterators,
   77.78 -      /// thus they will convert to this type.
   77.79 +      /// thus they convert to this type.
   77.80        class Node {
   77.81        public:
   77.82          /// Default constructor
   77.83  
   77.84 -        /// @warning The default constructor sets the iterator
   77.85 -        /// to an undefined value.
   77.86 +        /// Default constructor.
   77.87 +        /// \warning It sets the object to an undefined value.
   77.88          Node() { }
   77.89          /// Copy constructor.
   77.90  
   77.91 @@ -82,40 +76,39 @@
   77.92          ///
   77.93          Node(const Node&) { }
   77.94  
   77.95 -        /// Invalid constructor \& conversion.
   77.96 +        /// %Invalid constructor \& conversion.
   77.97  
   77.98 -        /// This constructor initializes the iterator to be invalid.
   77.99 +        /// Initializes the object to be invalid.
  77.100          /// \sa Invalid for more details.
  77.101          Node(Invalid) { }
  77.102          /// Equality operator
  77.103  
  77.104 +        /// Equality operator.
  77.105 +        ///
  77.106          /// Two iterators are equal if and only if they point to the
  77.107 -        /// same object or both are invalid.
  77.108 +        /// same object or both are \c INVALID.
  77.109          bool operator==(Node) const { return true; }
  77.110  
  77.111          /// Inequality operator
  77.112  
  77.113 -        /// \sa operator==(Node n)
  77.114 -        ///
  77.115 +        /// Inequality operator.
  77.116          bool operator!=(Node) const { return true; }
  77.117  
  77.118          /// Artificial ordering operator.
  77.119  
  77.120 -        /// To allow the use of digraph descriptors as key type in std::map or
  77.121 -        /// similar associative container we require this.
  77.122 +        /// Artificial ordering operator.
  77.123          ///
  77.124 -        /// \note This operator only have to define some strict ordering of
  77.125 -        /// the items; this order has nothing to do with the iteration
  77.126 -        /// ordering of the items.
  77.127 +        /// \note This operator only has to define some strict ordering of
  77.128 +        /// the nodes; this order has nothing to do with the iteration
  77.129 +        /// ordering of the nodes.
  77.130          bool operator<(Node) const { return false; }
  77.131 -
  77.132        };
  77.133  
  77.134 -      /// This iterator goes through each node.
  77.135 +      /// Iterator class for the nodes.
  77.136  
  77.137 -      /// This iterator goes through each node.
  77.138 +      /// This iterator goes through each node of the digraph.
  77.139        /// Its usage is quite simple, for example you can count the number
  77.140 -      /// of nodes in digraph \c g of type \c Digraph like this:
  77.141 +      /// of nodes in a digraph \c g of type \c %Digraph like this:
  77.142        ///\code
  77.143        /// int count=0;
  77.144        /// for (Digraph::NodeIt n(g); n!=INVALID; ++n) ++count;
  77.145 @@ -124,30 +117,28 @@
  77.146        public:
  77.147          /// Default constructor
  77.148  
  77.149 -        /// @warning The default constructor sets the iterator
  77.150 -        /// to an undefined value.
  77.151 +        /// Default constructor.
  77.152 +        /// \warning It sets the iterator to an undefined value.
  77.153          NodeIt() { }
  77.154          /// Copy constructor.
  77.155  
  77.156          /// Copy constructor.
  77.157          ///
  77.158          NodeIt(const NodeIt& n) : Node(n) { }
  77.159 -        /// Invalid constructor \& conversion.
  77.160 +        /// %Invalid constructor \& conversion.
  77.161  
  77.162 -        /// Initialize the iterator to be invalid.
  77.163 +        /// Initializes the iterator to be invalid.
  77.164          /// \sa Invalid for more details.
  77.165          NodeIt(Invalid) { }
  77.166          /// Sets the iterator to the first node.
  77.167  
  77.168 -        /// Sets the iterator to the first node of \c g.
  77.169 +        /// Sets the iterator to the first node of the given digraph.
  77.170          ///
  77.171 -        NodeIt(const Digraph&) { }
  77.172 -        /// Node -> NodeIt conversion.
  77.173 +        explicit NodeIt(const Digraph&) { }
  77.174 +        /// Sets the iterator to the given node.
  77.175  
  77.176 -        /// Sets the iterator to the node of \c the digraph pointed by
  77.177 -        /// the trivial iterator.
  77.178 -        /// This feature necessitates that each time we
  77.179 -        /// iterate the arc-set, the iteration order is the same.
  77.180 +        /// Sets the iterator to the given node of the given digraph.
  77.181 +        ///
  77.182          NodeIt(const Digraph&, const Node&) { }
  77.183          /// Next node.
  77.184  
  77.185 @@ -157,7 +148,7 @@
  77.186        };
  77.187  
  77.188  
  77.189 -      /// Class for identifying an arc of the digraph
  77.190 +      /// The arc type of the digraph
  77.191  
  77.192        /// This class identifies an arc of the digraph. It also serves
  77.193        /// as a base class of the arc iterators,
  77.194 @@ -166,207 +157,214 @@
  77.195        public:
  77.196          /// Default constructor
  77.197  
  77.198 -        /// @warning The default constructor sets the iterator
  77.199 -        /// to an undefined value.
  77.200 +        /// Default constructor.
  77.201 +        /// \warning It sets the object to an undefined value.
  77.202          Arc() { }
  77.203          /// Copy constructor.
  77.204  
  77.205          /// Copy constructor.
  77.206          ///
  77.207          Arc(const Arc&) { }
  77.208 -        /// Initialize the iterator to be invalid.
  77.209 +        /// %Invalid constructor \& conversion.
  77.210  
  77.211 -        /// Initialize the iterator to be invalid.
  77.212 -        ///
  77.213 +        /// Initializes the object to be invalid.
  77.214 +        /// \sa Invalid for more details.
  77.215          Arc(Invalid) { }
  77.216          /// Equality operator
  77.217  
  77.218 +        /// Equality operator.
  77.219 +        ///
  77.220          /// Two iterators are equal if and only if they point to the
  77.221 -        /// same object or both are invalid.
  77.222 +        /// same object or both are \c INVALID.
  77.223          bool operator==(Arc) const { return true; }
  77.224          /// Inequality operator
  77.225  
  77.226 -        /// \sa operator==(Arc n)
  77.227 -        ///
  77.228 +        /// Inequality operator.
  77.229          bool operator!=(Arc) const { return true; }
  77.230  
  77.231          /// Artificial ordering operator.
  77.232  
  77.233 -        /// To allow the use of digraph descriptors as key type in std::map or
  77.234 -        /// similar associative container we require this.
  77.235 +        /// Artificial ordering operator.
  77.236          ///
  77.237 -        /// \note This operator only have to define some strict ordering of
  77.238 -        /// the items; this order has nothing to do with the iteration
  77.239 -        /// ordering of the items.
  77.240 +        /// \note This operator only has to define some strict ordering of
  77.241 +        /// the arcs; this order has nothing to do with the iteration
  77.242 +        /// ordering of the arcs.
  77.243          bool operator<(Arc) const { return false; }
  77.244        };
  77.245  
  77.246 -      /// This iterator goes trough the outgoing arcs of a node.
  77.247 +      /// Iterator class for the outgoing arcs of a node.
  77.248  
  77.249        /// This iterator goes trough the \e outgoing arcs of a certain node
  77.250        /// of a digraph.
  77.251        /// Its usage is quite simple, for example you can count the number
  77.252        /// of outgoing arcs of a node \c n
  77.253 -      /// in digraph \c g of type \c Digraph as follows.
  77.254 +      /// in a digraph \c g of type \c %Digraph as follows.
  77.255        ///\code
  77.256        /// int count=0;
  77.257 -      /// for (Digraph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
  77.258 +      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
  77.259        ///\endcode
  77.260 -
  77.261        class OutArcIt : public Arc {
  77.262        public:
  77.263          /// Default constructor
  77.264  
  77.265 -        /// @warning The default constructor sets the iterator
  77.266 -        /// to an undefined value.
  77.267 +        /// Default constructor.
  77.268 +        /// \warning It sets the iterator to an undefined value.
  77.269          OutArcIt() { }
  77.270          /// Copy constructor.
  77.271  
  77.272          /// Copy constructor.
  77.273          ///
  77.274          OutArcIt(const OutArcIt& e) : Arc(e) { }
  77.275 -        /// Initialize the iterator to be invalid.
  77.276 +        /// %Invalid constructor \& conversion.
  77.277  
  77.278 -        /// Initialize the iterator to be invalid.
  77.279 +        /// Initializes the iterator to be invalid.
  77.280 +        /// \sa Invalid for more details.
  77.281 +        OutArcIt(Invalid) { }
  77.282 +        /// Sets the iterator to the first outgoing arc.
  77.283 +
  77.284 +        /// Sets the iterator to the first outgoing arc of the given node.
  77.285          ///
  77.286 -        OutArcIt(Invalid) { }
  77.287 -        /// This constructor sets the iterator to the first outgoing arc.
  77.288 +        OutArcIt(const Digraph&, const Node&) { }
  77.289 +        /// Sets the iterator to the given arc.
  77.290  
  77.291 -        /// This constructor sets the iterator to the first outgoing arc of
  77.292 -        /// the node.
  77.293 -        OutArcIt(const Digraph&, const Node&) { }
  77.294 -        /// Arc -> OutArcIt conversion
  77.295 -
  77.296 -        /// Sets the iterator to the value of the trivial iterator.
  77.297 -        /// This feature necessitates that each time we
  77.298 -        /// iterate the arc-set, the iteration order is the same.
  77.299 +        /// Sets the iterator to the given arc of the given digraph.
  77.300 +        ///
  77.301          OutArcIt(const Digraph&, const Arc&) { }
  77.302 -        ///Next outgoing arc
  77.303 +        /// Next outgoing arc
  77.304  
  77.305          /// Assign the iterator to the next
  77.306          /// outgoing arc of the corresponding node.
  77.307          OutArcIt& operator++() { return *this; }
  77.308        };
  77.309  
  77.310 -      /// This iterator goes trough the incoming arcs of a node.
  77.311 +      /// Iterator class for the incoming arcs of a node.
  77.312  
  77.313        /// This iterator goes trough the \e incoming arcs of a certain node
  77.314        /// of a digraph.
  77.315        /// Its usage is quite simple, for example you can count the number
  77.316 -      /// of outgoing arcs of a node \c n
  77.317 -      /// in digraph \c g of type \c Digraph as follows.
  77.318 +      /// of incoming arcs of a node \c n
  77.319 +      /// in a digraph \c g of type \c %Digraph as follows.
  77.320        ///\code
  77.321        /// int count=0;
  77.322 -      /// for(Digraph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
  77.323 +      /// for(Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
  77.324        ///\endcode
  77.325 -
  77.326        class InArcIt : public Arc {
  77.327        public:
  77.328          /// Default constructor
  77.329  
  77.330 -        /// @warning The default constructor sets the iterator
  77.331 -        /// to an undefined value.
  77.332 +        /// Default constructor.
  77.333 +        /// \warning It sets the iterator to an undefined value.
  77.334          InArcIt() { }
  77.335          /// Copy constructor.
  77.336  
  77.337          /// Copy constructor.
  77.338          ///
  77.339          InArcIt(const InArcIt& e) : Arc(e) { }
  77.340 -        /// Initialize the iterator to be invalid.
  77.341 +        /// %Invalid constructor \& conversion.
  77.342  
  77.343 -        /// Initialize the iterator to be invalid.
  77.344 +        /// Initializes the iterator to be invalid.
  77.345 +        /// \sa Invalid for more details.
  77.346 +        InArcIt(Invalid) { }
  77.347 +        /// Sets the iterator to the first incoming arc.
  77.348 +
  77.349 +        /// Sets the iterator to the first incoming arc of the given node.
  77.350          ///
  77.351 -        InArcIt(Invalid) { }
  77.352 -        /// This constructor sets the iterator to first incoming arc.
  77.353 +        InArcIt(const Digraph&, const Node&) { }
  77.354 +        /// Sets the iterator to the given arc.
  77.355  
  77.356 -        /// This constructor set the iterator to the first incoming arc of
  77.357 -        /// the node.
  77.358 -        InArcIt(const Digraph&, const Node&) { }
  77.359 -        /// Arc -> InArcIt conversion
  77.360 -
  77.361 -        /// Sets the iterator to the value of the trivial iterator \c e.
  77.362 -        /// This feature necessitates that each time we
  77.363 -        /// iterate the arc-set, the iteration order is the same.
  77.364 +        /// Sets the iterator to the given arc of the given digraph.
  77.365 +        ///
  77.366          InArcIt(const Digraph&, const Arc&) { }
  77.367          /// Next incoming arc
  77.368  
  77.369 -        /// Assign the iterator to the next inarc of the corresponding node.
  77.370 -        ///
  77.371 +        /// Assign the iterator to the next
  77.372 +        /// incoming arc of the corresponding node.
  77.373          InArcIt& operator++() { return *this; }
  77.374        };
  77.375 -      /// This iterator goes through each arc.
  77.376  
  77.377 -      /// This iterator goes through each arc of a digraph.
  77.378 +      /// Iterator class for the arcs.
  77.379 +
  77.380 +      /// This iterator goes through each arc of the digraph.
  77.381        /// Its usage is quite simple, for example you can count the number
  77.382 -      /// of arcs in a digraph \c g of type \c Digraph as follows:
  77.383 +      /// of arcs in a digraph \c g of type \c %Digraph as follows:
  77.384        ///\code
  77.385        /// int count=0;
  77.386 -      /// for(Digraph::ArcIt e(g); e!=INVALID; ++e) ++count;
  77.387 +      /// for(Digraph::ArcIt a(g); a!=INVALID; ++a) ++count;
  77.388        ///\endcode
  77.389        class ArcIt : public Arc {
  77.390        public:
  77.391          /// Default constructor
  77.392  
  77.393 -        /// @warning The default constructor sets the iterator
  77.394 -        /// to an undefined value.
  77.395 +        /// Default constructor.
  77.396 +        /// \warning It sets the iterator to an undefined value.
  77.397          ArcIt() { }
  77.398          /// Copy constructor.
  77.399  
  77.400          /// Copy constructor.
  77.401          ///
  77.402          ArcIt(const ArcIt& e) : Arc(e) { }
  77.403 -        /// Initialize the iterator to be invalid.
  77.404 +        /// %Invalid constructor \& conversion.
  77.405  
  77.406 -        /// Initialize the iterator to be invalid.
  77.407 +        /// Initializes the iterator to be invalid.
  77.408 +        /// \sa Invalid for more details.
  77.409 +        ArcIt(Invalid) { }
  77.410 +        /// Sets the iterator to the first arc.
  77.411 +
  77.412 +        /// Sets the iterator to the first arc of the given digraph.
  77.413          ///
  77.414 -        ArcIt(Invalid) { }
  77.415 -        /// This constructor sets the iterator to the first arc.
  77.416 +        explicit ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
  77.417 +        /// Sets the iterator to the given arc.
  77.418  
  77.419 -        /// This constructor sets the iterator to the first arc of \c g.
  77.420 -        ///@param g the digraph
  77.421 -        ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
  77.422 -        /// Arc -> ArcIt conversion
  77.423 -
  77.424 -        /// Sets the iterator to the value of the trivial iterator \c e.
  77.425 -        /// This feature necessitates that each time we
  77.426 -        /// iterate the arc-set, the iteration order is the same.
  77.427 +        /// Sets the iterator to the given arc of the given digraph.
  77.428 +        ///
  77.429          ArcIt(const Digraph&, const Arc&) { }
  77.430 -        ///Next arc
  77.431 +        /// Next arc
  77.432  
  77.433          /// Assign the iterator to the next arc.
  77.434 +        ///
  77.435          ArcIt& operator++() { return *this; }
  77.436        };
  77.437 -      ///Gives back the target node of an arc.
  77.438  
  77.439 -      ///Gives back the target node of an arc.
  77.440 +      /// \brief The source node of the arc.
  77.441        ///
  77.442 -      Node target(Arc) const { return INVALID; }
  77.443 -      ///Gives back the source node of an arc.
  77.444 -
  77.445 -      ///Gives back the source node of an arc.
  77.446 -      ///
  77.447 +      /// Returns the source node of the given arc.
  77.448        Node source(Arc) const { return INVALID; }
  77.449  
  77.450 -      /// \brief Returns the ID of the node.
  77.451 +      /// \brief The target node of the arc.
  77.452 +      ///
  77.453 +      /// Returns the target node of the given arc.
  77.454 +      Node target(Arc) const { return INVALID; }
  77.455 +
  77.456 +      /// \brief The ID of the node.
  77.457 +      ///
  77.458 +      /// Returns the ID of the given node.
  77.459        int id(Node) const { return -1; }
  77.460  
  77.461 -      /// \brief Returns the ID of the arc.
  77.462 +      /// \brief The ID of the arc.
  77.463 +      ///
  77.464 +      /// Returns the ID of the given arc.
  77.465        int id(Arc) const { return -1; }
  77.466  
  77.467 -      /// \brief Returns the node with the given ID.
  77.468 +      /// \brief The node with the given ID.
  77.469        ///
  77.470 -      /// \pre The argument should be a valid node ID in the graph.
  77.471 +      /// Returns the node with the given ID.
  77.472 +      /// \pre The argument should be a valid node ID in the digraph.
  77.473        Node nodeFromId(int) const { return INVALID; }
  77.474  
  77.475 -      /// \brief Returns the arc with the given ID.
  77.476 +      /// \brief The arc with the given ID.
  77.477        ///
  77.478 -      /// \pre The argument should be a valid arc ID in the graph.
  77.479 +      /// Returns the arc with the given ID.
  77.480 +      /// \pre The argument should be a valid arc ID in the digraph.
  77.481        Arc arcFromId(int) const { return INVALID; }
  77.482  
  77.483 -      /// \brief Returns an upper bound on the node IDs.
  77.484 +      /// \brief An upper bound on the node IDs.
  77.485 +      ///
  77.486 +      /// Returns an upper bound on the node IDs.
  77.487        int maxNodeId() const { return -1; }
  77.488  
  77.489 -      /// \brief Returns an upper bound on the arc IDs.
  77.490 +      /// \brief An upper bound on the arc IDs.
  77.491 +      ///
  77.492 +      /// Returns an upper bound on the arc IDs.
  77.493        int maxArcId() const { return -1; }
  77.494  
  77.495        void first(Node&) const {}
  77.496 @@ -392,51 +390,52 @@
  77.497        // Dummy parameter.
  77.498        int maxId(Arc) const { return -1; }
  77.499  
  77.500 +      /// \brief The opposite node on the arc.
  77.501 +      ///
  77.502 +      /// Returns the opposite node on the given arc.
  77.503 +      Node oppositeNode(Node, Arc) const { return INVALID; }
  77.504 +
  77.505        /// \brief The base node of the iterator.
  77.506        ///
  77.507 -      /// Gives back the base node of the iterator.
  77.508 -      /// It is always the target of the pointed arc.
  77.509 -      Node baseNode(const InArcIt&) const { return INVALID; }
  77.510 +      /// Returns the base node of the given outgoing arc iterator
  77.511 +      /// (i.e. the source node of the corresponding arc).
  77.512 +      Node baseNode(OutArcIt) const { return INVALID; }
  77.513  
  77.514        /// \brief The running node of the iterator.
  77.515        ///
  77.516 -      /// Gives back the running node of the iterator.
  77.517 -      /// It is always the source of the pointed arc.
  77.518 -      Node runningNode(const InArcIt&) const { return INVALID; }
  77.519 +      /// Returns the running node of the given outgoing arc iterator
  77.520 +      /// (i.e. the target node of the corresponding arc).
  77.521 +      Node runningNode(OutArcIt) const { return INVALID; }
  77.522  
  77.523        /// \brief The base node of the iterator.
  77.524        ///
  77.525 -      /// Gives back the base node of the iterator.
  77.526 -      /// It is always the source of the pointed arc.
  77.527 -      Node baseNode(const OutArcIt&) const { return INVALID; }
  77.528 +      /// Returns the base node of the given incomming arc iterator
  77.529 +      /// (i.e. the target node of the corresponding arc).
  77.530 +      Node baseNode(InArcIt) const { return INVALID; }
  77.531  
  77.532        /// \brief The running node of the iterator.
  77.533        ///
  77.534 -      /// Gives back the running node of the iterator.
  77.535 -      /// It is always the target of the pointed arc.
  77.536 -      Node runningNode(const OutArcIt&) const { return INVALID; }
  77.537 +      /// Returns the running node of the given incomming arc iterator
  77.538 +      /// (i.e. the source node of the corresponding arc).
  77.539 +      Node runningNode(InArcIt) const { return INVALID; }
  77.540  
  77.541 -      /// \brief The opposite node on the given arc.
  77.542 +      /// \brief Standard graph map type for the nodes.
  77.543        ///
  77.544 -      /// Gives back the opposite node on the given arc.
  77.545 -      Node oppositeNode(const Node&, const Arc&) const { return INVALID; }
  77.546 -
  77.547 -      /// \brief Read write map of the nodes to type \c T.
  77.548 -      ///
  77.549 -      /// ReadWrite map of the nodes to type \c T.
  77.550 -      /// \sa Reference
  77.551 +      /// Standard graph map type for the nodes.
  77.552 +      /// It conforms to the ReferenceMap concept.
  77.553        template<class T>
  77.554 -      class NodeMap : public ReadWriteMap< Node, T > {
  77.555 +      class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
  77.556        public:
  77.557  
  77.558 -        ///\e
  77.559 -        NodeMap(const Digraph&) { }
  77.560 -        ///\e
  77.561 +        /// Constructor
  77.562 +        explicit NodeMap(const Digraph&) { }
  77.563 +        /// Constructor with given initial value
  77.564          NodeMap(const Digraph&, T) { }
  77.565  
  77.566        private:
  77.567          ///Copy constructor
  77.568 -        NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
  77.569 +        NodeMap(const NodeMap& nm) : 
  77.570 +          ReferenceMap<Node, T, T&, const T&>(nm) { }
  77.571          ///Assignment operator
  77.572          template <typename CMap>
  77.573          NodeMap& operator=(const CMap&) {
  77.574 @@ -445,21 +444,23 @@
  77.575          }
  77.576        };
  77.577  
  77.578 -      /// \brief Read write map of the arcs to type \c T.
  77.579 +      /// \brief Standard graph map type for the arcs.
  77.580        ///
  77.581 -      /// Reference map of the arcs to type \c T.
  77.582 -      /// \sa Reference
  77.583 +      /// Standard graph map type for the arcs.
  77.584 +      /// It conforms to the ReferenceMap concept.
  77.585        template<class T>
  77.586 -      class ArcMap : public ReadWriteMap<Arc,T> {
  77.587 +      class ArcMap : public ReferenceMap<Arc, T, T&, const T&> {
  77.588        public:
  77.589  
  77.590 -        ///\e
  77.591 -        ArcMap(const Digraph&) { }
  77.592 -        ///\e
  77.593 +        /// Constructor
  77.594 +        explicit ArcMap(const Digraph&) { }
  77.595 +        /// Constructor with given initial value
  77.596          ArcMap(const Digraph&, T) { }
  77.597 +
  77.598        private:
  77.599          ///Copy constructor
  77.600 -        ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { }
  77.601 +        ArcMap(const ArcMap& em) :
  77.602 +          ReferenceMap<Arc, T, T&, const T&>(em) { }
  77.603          ///Assignment operator
  77.604          template <typename CMap>
  77.605          ArcMap& operator=(const CMap&) {
  77.606 @@ -471,6 +472,7 @@
  77.607        template <typename _Digraph>
  77.608        struct Constraints {
  77.609          void constraints() {
  77.610 +          checkConcept<BaseDigraphComponent, _Digraph>();
  77.611            checkConcept<IterableDigraphComponent<>, _Digraph>();
  77.612            checkConcept<IDableDigraphComponent<>, _Digraph>();
  77.613            checkConcept<MappableDigraphComponent<>, _Digraph>();
  77.614 @@ -484,4 +486,4 @@
  77.615  
  77.616  
  77.617  
  77.618 -#endif // LEMON_CONCEPT_DIGRAPH_H
  77.619 +#endif
    78.1 --- a/lemon/concepts/graph.h	Fri Oct 16 10:21:37 2009 +0200
    78.2 +++ b/lemon/concepts/graph.h	Thu Nov 05 15:50:01 2009 +0100
    78.3 @@ -2,7 +2,7 @@
    78.4   *
    78.5   * This file is a part of LEMON, a generic C++ optimization library.
    78.6   *
    78.7 - * Copyright (C) 2003-2008
    78.8 + * Copyright (C) 2003-2009
    78.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   78.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   78.11   *
   78.12 @@ -18,13 +18,14 @@
   78.13  
   78.14  ///\ingroup graph_concepts
   78.15  ///\file
   78.16 -///\brief The concept of Undirected Graphs.
   78.17 +///\brief The concept of undirected graphs.
   78.18  
   78.19 -#ifndef LEMON_CONCEPT_GRAPH_H
   78.20 -#define LEMON_CONCEPT_GRAPH_H
   78.21 +#ifndef LEMON_CONCEPTS_GRAPH_H
   78.22 +#define LEMON_CONCEPTS_GRAPH_H
   78.23  
   78.24  #include <lemon/concepts/graph_components.h>
   78.25 -#include <lemon/concepts/graph.h>
   78.26 +#include <lemon/concepts/maps.h>
   78.27 +#include <lemon/concept_check.h>
   78.28  #include <lemon/core.h>
   78.29  
   78.30  namespace lemon {
   78.31 @@ -32,63 +33,74 @@
   78.32  
   78.33      /// \ingroup graph_concepts
   78.34      ///
   78.35 -    /// \brief Class describing the concept of Undirected Graphs.
   78.36 +    /// \brief Class describing the concept of undirected graphs.
   78.37      ///
   78.38 -    /// This class describes the common interface of all Undirected
   78.39 -    /// Graphs.
   78.40 +    /// This class describes the common interface of all undirected
   78.41 +    /// graphs.
   78.42      ///
   78.43 -    /// As all concept describing classes it provides only interface
   78.44 -    /// without any sensible implementation. So any algorithm for
   78.45 -    /// undirected graph should compile with this class, but it will not
   78.46 +    /// Like all concept classes, it only provides an interface
   78.47 +    /// without any sensible implementation. So any general algorithm for
   78.48 +    /// undirected graphs should compile with this class, but it will not
   78.49      /// run properly, of course.
   78.50 +    /// An actual graph implementation like \ref ListGraph or
   78.51 +    /// \ref SmartGraph may have additional functionality.    
   78.52      ///
   78.53 -    /// The LEMON undirected graphs also fulfill the concept of
   78.54 -    /// directed graphs (\ref lemon::concepts::Digraph "Digraph
   78.55 -    /// Concept"). Each edges can be seen as two opposite
   78.56 -    /// directed arc and consequently the undirected graph can be
   78.57 -    /// seen as the direceted graph of these directed arcs. The
   78.58 -    /// Graph has the Edge inner class for the edges and
   78.59 -    /// the Arc type for the directed arcs. The Arc type is
   78.60 -    /// convertible to Edge or inherited from it so from a directed
   78.61 -    /// arc we can get the represented edge.
   78.62 +    /// The undirected graphs also fulfill the concept of \ref Digraph
   78.63 +    /// "directed graphs", since each edge can also be regarded as two
   78.64 +    /// oppositely directed arcs.
   78.65 +    /// Undirected graphs provide an Edge type for the undirected edges and
   78.66 +    /// an Arc type for the directed arcs. The Arc type is convertible to
   78.67 +    /// Edge or inherited from it, i.e. the corresponding edge can be
   78.68 +    /// obtained from an arc.
   78.69 +    /// EdgeIt and EdgeMap classes can be used for the edges, while ArcIt
   78.70 +    /// and ArcMap classes can be used for the arcs (just like in digraphs).
   78.71 +    /// Both InArcIt and OutArcIt iterates on the same edges but with
   78.72 +    /// opposite direction. IncEdgeIt also iterates on the same edges
   78.73 +    /// as OutArcIt and InArcIt, but it is not convertible to Arc,
   78.74 +    /// only to Edge.
   78.75      ///
   78.76 -    /// In the sense of the LEMON each edge has a default
   78.77 -    /// direction (it should be in every computer implementation,
   78.78 -    /// because the order of edge's nodes defines an
   78.79 -    /// orientation). With the default orientation we can define that
   78.80 -    /// the directed arc is forward or backward directed. With the \c
   78.81 -    /// direction() and \c direct() function we can get the direction
   78.82 -    /// of the directed arc and we can direct an edge.
   78.83 +    /// In LEMON, each undirected edge has an inherent orientation.
   78.84 +    /// Thus it can defined if an arc is forward or backward oriented in
   78.85 +    /// an undirected graph with respect to this default oriantation of
   78.86 +    /// the represented edge.
   78.87 +    /// With the direction() and direct() functions the direction
   78.88 +    /// of an arc can be obtained and set, respectively.
   78.89      ///
   78.90 -    /// The EdgeIt is an iterator for the edges. We can use
   78.91 -    /// the EdgeMap to map values for the edges. The InArcIt and
   78.92 -    /// OutArcIt iterates on the same edges but with opposite
   78.93 -    /// direction. The IncEdgeIt iterates also on the same edges
   78.94 -    /// as the OutArcIt and InArcIt but it is not convertible to Arc just
   78.95 -    /// to Edge.
   78.96 +    /// Only nodes and edges can be added to or removed from an undirected
   78.97 +    /// graph and the corresponding arcs are added or removed automatically.
   78.98 +    ///
   78.99 +    /// \sa Digraph
  78.100      class Graph {
  78.101 +    private:
  78.102 +      /// Graphs are \e not copy constructible. Use DigraphCopy instead.
  78.103 +      Graph(const Graph&) {}
  78.104 +      /// \brief Assignment of a graph to another one is \e not allowed.
  78.105 +      /// Use DigraphCopy instead.
  78.106 +      void operator=(const Graph&) {}
  78.107 +
  78.108      public:
  78.109 -      /// \brief The undirected graph should be tagged by the
  78.110 -      /// UndirectedTag.
  78.111 +      /// Default constructor.
  78.112 +      Graph() {}
  78.113 +
  78.114 +      /// \brief Undirected graphs should be tagged with \c UndirectedTag.
  78.115        ///
  78.116 -      /// The undirected graph should be tagged by the UndirectedTag. This
  78.117 -      /// tag helps the enable_if technics to make compile time
  78.118 +      /// Undirected graphs should be tagged with \c UndirectedTag.
  78.119 +      /// 
  78.120 +      /// This tag helps the \c enable_if technics to make compile time
  78.121        /// specializations for undirected graphs.
  78.122        typedef True UndirectedTag;
  78.123  
  78.124 -      /// \brief The base type of node iterators,
  78.125 -      /// or in other words, the trivial node iterator.
  78.126 -      ///
  78.127 -      /// This is the base type of each node iterator,
  78.128 -      /// thus each kind of node iterator converts to this.
  78.129 -      /// More precisely each kind of node iterator should be inherited
  78.130 -      /// from the trivial node iterator.
  78.131 +      /// The node type of the graph
  78.132 +
  78.133 +      /// This class identifies a node of the graph. It also serves
  78.134 +      /// as a base class of the node iterators,
  78.135 +      /// thus they convert to this type.
  78.136        class Node {
  78.137        public:
  78.138          /// Default constructor
  78.139  
  78.140 -        /// @warning The default constructor sets the iterator
  78.141 -        /// to an undefined value.
  78.142 +        /// Default constructor.
  78.143 +        /// \warning It sets the object to an undefined value.
  78.144          Node() { }
  78.145          /// Copy constructor.
  78.146  
  78.147 @@ -96,40 +108,40 @@
  78.148          ///
  78.149          Node(const Node&) { }
  78.150  
  78.151 -        /// Invalid constructor \& conversion.
  78.152 +        /// %Invalid constructor \& conversion.
  78.153  
  78.154 -        /// This constructor initializes the iterator to be invalid.
  78.155 +        /// Initializes the object to be invalid.
  78.156          /// \sa Invalid for more details.
  78.157          Node(Invalid) { }
  78.158          /// Equality operator
  78.159  
  78.160 +        /// Equality operator.
  78.161 +        ///
  78.162          /// Two iterators are equal if and only if they point to the
  78.163 -        /// same object or both are invalid.
  78.164 +        /// same object or both are \c INVALID.
  78.165          bool operator==(Node) const { return true; }
  78.166  
  78.167          /// Inequality operator
  78.168  
  78.169 -        /// \sa operator==(Node n)
  78.170 -        ///
  78.171 +        /// Inequality operator.
  78.172          bool operator!=(Node) const { return true; }
  78.173  
  78.174          /// Artificial ordering operator.
  78.175  
  78.176 -        /// To allow the use of graph descriptors as key type in std::map or
  78.177 -        /// similar associative container we require this.
  78.178 +        /// Artificial ordering operator.
  78.179          ///
  78.180 -        /// \note This operator only have to define some strict ordering of
  78.181 +        /// \note This operator only has to define some strict ordering of
  78.182          /// the items; this order has nothing to do with the iteration
  78.183          /// ordering of the items.
  78.184          bool operator<(Node) const { return false; }
  78.185  
  78.186        };
  78.187  
  78.188 -      /// This iterator goes through each node.
  78.189 +      /// Iterator class for the nodes.
  78.190  
  78.191 -      /// This iterator goes through each node.
  78.192 +      /// This iterator goes through each node of the graph.
  78.193        /// Its usage is quite simple, for example you can count the number
  78.194 -      /// of nodes in graph \c g of type \c Graph like this:
  78.195 +      /// of nodes in a graph \c g of type \c %Graph like this:
  78.196        ///\code
  78.197        /// int count=0;
  78.198        /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
  78.199 @@ -138,30 +150,28 @@
  78.200        public:
  78.201          /// Default constructor
  78.202  
  78.203 -        /// @warning The default constructor sets the iterator
  78.204 -        /// to an undefined value.
  78.205 +        /// Default constructor.
  78.206 +        /// \warning It sets the iterator to an undefined value.
  78.207          NodeIt() { }
  78.208          /// Copy constructor.
  78.209  
  78.210          /// Copy constructor.
  78.211          ///
  78.212          NodeIt(const NodeIt& n) : Node(n) { }
  78.213 -        /// Invalid constructor \& conversion.
  78.214 +        /// %Invalid constructor \& conversion.
  78.215  
  78.216 -        /// Initialize the iterator to be invalid.
  78.217 +        /// Initializes the iterator to be invalid.
  78.218          /// \sa Invalid for more details.
  78.219          NodeIt(Invalid) { }
  78.220          /// Sets the iterator to the first node.
  78.221  
  78.222 -        /// Sets the iterator to the first node of \c g.
  78.223 +        /// Sets the iterator to the first node of the given digraph.
  78.224          ///
  78.225 -        NodeIt(const Graph&) { }
  78.226 -        /// Node -> NodeIt conversion.
  78.227 +        explicit NodeIt(const Graph&) { }
  78.228 +        /// Sets the iterator to the given node.
  78.229  
  78.230 -        /// Sets the iterator to the node of \c the graph pointed by
  78.231 -        /// the trivial iterator.
  78.232 -        /// This feature necessitates that each time we
  78.233 -        /// iterate the arc-set, the iteration order is the same.
  78.234 +        /// Sets the iterator to the given node of the given digraph.
  78.235 +        ///
  78.236          NodeIt(const Graph&, const Node&) { }
  78.237          /// Next node.
  78.238  
  78.239 @@ -171,54 +181,55 @@
  78.240        };
  78.241  
  78.242  
  78.243 -      /// The base type of the edge iterators.
  78.244 +      /// The edge type of the graph
  78.245  
  78.246 -      /// The base type of the edge iterators.
  78.247 -      ///
  78.248 +      /// This class identifies an edge of the graph. It also serves
  78.249 +      /// as a base class of the edge iterators,
  78.250 +      /// thus they will convert to this type.
  78.251        class Edge {
  78.252        public:
  78.253          /// Default constructor
  78.254  
  78.255 -        /// @warning The default constructor sets the iterator
  78.256 -        /// to an undefined value.
  78.257 +        /// Default constructor.
  78.258 +        /// \warning It sets the object to an undefined value.
  78.259          Edge() { }
  78.260          /// Copy constructor.
  78.261  
  78.262          /// Copy constructor.
  78.263          ///
  78.264          Edge(const Edge&) { }
  78.265 -        /// Initialize the iterator to be invalid.
  78.266 +        /// %Invalid constructor \& conversion.
  78.267  
  78.268 -        /// Initialize the iterator to be invalid.
  78.269 -        ///
  78.270 +        /// Initializes the object to be invalid.
  78.271 +        /// \sa Invalid for more details.
  78.272          Edge(Invalid) { }
  78.273          /// Equality operator
  78.274  
  78.275 +        /// Equality operator.
  78.276 +        ///
  78.277          /// Two iterators are equal if and only if they point to the
  78.278 -        /// same object or both are invalid.
  78.279 +        /// same object or both are \c INVALID.
  78.280          bool operator==(Edge) const { return true; }
  78.281          /// Inequality operator
  78.282  
  78.283 -        /// \sa operator==(Edge n)
  78.284 -        ///
  78.285 +        /// Inequality operator.
  78.286          bool operator!=(Edge) const { return true; }
  78.287  
  78.288          /// Artificial ordering operator.
  78.289  
  78.290 -        /// To allow the use of graph descriptors as key type in std::map or
  78.291 -        /// similar associative container we require this.
  78.292 +        /// Artificial ordering operator.
  78.293          ///
  78.294 -        /// \note This operator only have to define some strict ordering of
  78.295 -        /// the items; this order has nothing to do with the iteration
  78.296 -        /// ordering of the items.
  78.297 +        /// \note This operator only has to define some strict ordering of
  78.298 +        /// the edges; this order has nothing to do with the iteration
  78.299 +        /// ordering of the edges.
  78.300          bool operator<(Edge) const { return false; }
  78.301        };
  78.302  
  78.303 -      /// This iterator goes through each edge.
  78.304 +      /// Iterator class for the edges.
  78.305  
  78.306 -      /// This iterator goes through each edge of a graph.
  78.307 +      /// This iterator goes through each edge of the graph.
  78.308        /// Its usage is quite simple, for example you can count the number
  78.309 -      /// of edges in a graph \c g of type \c Graph as follows:
  78.310 +      /// of edges in a graph \c g of type \c %Graph as follows:
  78.311        ///\code
  78.312        /// int count=0;
  78.313        /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
  78.314 @@ -227,294 +238,291 @@
  78.315        public:
  78.316          /// Default constructor
  78.317  
  78.318 -        /// @warning The default constructor sets the iterator
  78.319 -        /// to an undefined value.
  78.320 +        /// Default constructor.
  78.321 +        /// \warning It sets the iterator to an undefined value.
  78.322          EdgeIt() { }
  78.323          /// Copy constructor.
  78.324  
  78.325          /// Copy constructor.
  78.326          ///
  78.327          EdgeIt(const EdgeIt& e) : Edge(e) { }
  78.328 -        /// Initialize the iterator to be invalid.
  78.329 +        /// %Invalid constructor \& conversion.
  78.330  
  78.331 -        /// Initialize the iterator to be invalid.
  78.332 +        /// Initializes the iterator to be invalid.
  78.333 +        /// \sa Invalid for more details.
  78.334 +        EdgeIt(Invalid) { }
  78.335 +        /// Sets the iterator to the first edge.
  78.336 +
  78.337 +        /// Sets the iterator to the first edge of the given graph.
  78.338          ///
  78.339 -        EdgeIt(Invalid) { }
  78.340 -        /// This constructor sets the iterator to the first edge.
  78.341 +        explicit EdgeIt(const Graph&) { }
  78.342 +        /// Sets the iterator to the given edge.
  78.343  
  78.344 -        /// This constructor sets the iterator to the first edge.
  78.345 -        EdgeIt(const Graph&) { }
  78.346 -        /// Edge -> EdgeIt conversion
  78.347 -
  78.348 -        /// Sets the iterator to the value of the trivial iterator.
  78.349 -        /// This feature necessitates that each time we
  78.350 -        /// iterate the edge-set, the iteration order is the
  78.351 -        /// same.
  78.352 +        /// Sets the iterator to the given edge of the given graph.
  78.353 +        ///
  78.354          EdgeIt(const Graph&, const Edge&) { }
  78.355          /// Next edge
  78.356  
  78.357          /// Assign the iterator to the next edge.
  78.358 +        ///
  78.359          EdgeIt& operator++() { return *this; }
  78.360        };
  78.361  
  78.362 -      /// \brief This iterator goes trough the incident undirected
  78.363 -      /// arcs of a node.
  78.364 -      ///
  78.365 -      /// This iterator goes trough the incident edges
  78.366 -      /// of a certain node of a graph. You should assume that the
  78.367 -      /// loop arcs will be iterated twice.
  78.368 -      ///
  78.369 +      /// Iterator class for the incident edges of a node.
  78.370 +
  78.371 +      /// This iterator goes trough the incident undirected edges
  78.372 +      /// of a certain node of a graph.
  78.373        /// Its usage is quite simple, for example you can compute the
  78.374 -      /// degree (i.e. count the number of incident arcs of a node \c n
  78.375 -      /// in graph \c g of type \c Graph as follows.
  78.376 +      /// degree (i.e. the number of incident edges) of a node \c n
  78.377 +      /// in a graph \c g of type \c %Graph as follows.
  78.378        ///
  78.379        ///\code
  78.380        /// int count=0;
  78.381        /// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
  78.382        ///\endcode
  78.383 +      ///
  78.384 +      /// \warning Loop edges will be iterated twice.
  78.385        class IncEdgeIt : public Edge {
  78.386        public:
  78.387          /// Default constructor
  78.388  
  78.389 -        /// @warning The default constructor sets the iterator
  78.390 -        /// to an undefined value.
  78.391 +        /// Default constructor.
  78.392 +        /// \warning It sets the iterator to an undefined value.
  78.393          IncEdgeIt() { }
  78.394          /// Copy constructor.
  78.395  
  78.396          /// Copy constructor.
  78.397          ///
  78.398          IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
  78.399 -        /// Initialize the iterator to be invalid.
  78.400 +        /// %Invalid constructor \& conversion.
  78.401  
  78.402 -        /// Initialize the iterator to be invalid.
  78.403 +        /// Initializes the iterator to be invalid.
  78.404 +        /// \sa Invalid for more details.
  78.405 +        IncEdgeIt(Invalid) { }
  78.406 +        /// Sets the iterator to the first incident edge.
  78.407 +
  78.408 +        /// Sets the iterator to the first incident edge of the given node.
  78.409          ///
  78.410 -        IncEdgeIt(Invalid) { }
  78.411 -        /// This constructor sets the iterator to first incident arc.
  78.412 +        IncEdgeIt(const Graph&, const Node&) { }
  78.413 +        /// Sets the iterator to the given edge.
  78.414  
  78.415 -        /// This constructor set the iterator to the first incident arc of
  78.416 -        /// the node.
  78.417 -        IncEdgeIt(const Graph&, const Node&) { }
  78.418 -        /// Edge -> IncEdgeIt conversion
  78.419 +        /// Sets the iterator to the given edge of the given graph.
  78.420 +        ///
  78.421 +        IncEdgeIt(const Graph&, const Edge&) { }
  78.422 +        /// Next incident edge
  78.423  
  78.424 -        /// Sets the iterator to the value of the trivial iterator \c e.
  78.425 -        /// This feature necessitates that each time we
  78.426 -        /// iterate the arc-set, the iteration order is the same.
  78.427 -        IncEdgeIt(const Graph&, const Edge&) { }
  78.428 -        /// Next incident arc
  78.429 -
  78.430 -        /// Assign the iterator to the next incident arc
  78.431 +        /// Assign the iterator to the next incident edge
  78.432          /// of the corresponding node.
  78.433          IncEdgeIt& operator++() { return *this; }
  78.434        };
  78.435  
  78.436 -      /// The directed arc type.
  78.437 +      /// The arc type of the graph
  78.438  
  78.439 -      /// The directed arc type. It can be converted to the
  78.440 -      /// edge or it should be inherited from the undirected
  78.441 -      /// arc.
  78.442 -      class Arc : public Edge {
  78.443 +      /// This class identifies a directed arc of the graph. It also serves
  78.444 +      /// as a base class of the arc iterators,
  78.445 +      /// thus they will convert to this type.
  78.446 +      class Arc {
  78.447        public:
  78.448          /// Default constructor
  78.449  
  78.450 -        /// @warning The default constructor sets the iterator
  78.451 -        /// to an undefined value.
  78.452 +        /// Default constructor.
  78.453 +        /// \warning It sets the object to an undefined value.
  78.454          Arc() { }
  78.455          /// Copy constructor.
  78.456  
  78.457          /// Copy constructor.
  78.458          ///
  78.459 -        Arc(const Arc& e) : Edge(e) { }
  78.460 -        /// Initialize the iterator to be invalid.
  78.461 +        Arc(const Arc&) { }
  78.462 +        /// %Invalid constructor \& conversion.
  78.463  
  78.464 -        /// Initialize the iterator to be invalid.
  78.465 -        ///
  78.466 +        /// Initializes the object to be invalid.
  78.467 +        /// \sa Invalid for more details.
  78.468          Arc(Invalid) { }
  78.469          /// Equality operator
  78.470  
  78.471 +        /// Equality operator.
  78.472 +        ///
  78.473          /// Two iterators are equal if and only if they point to the
  78.474 -        /// same object or both are invalid.
  78.475 +        /// same object or both are \c INVALID.
  78.476          bool operator==(Arc) const { return true; }
  78.477          /// Inequality operator
  78.478  
  78.479 -        /// \sa operator==(Arc n)
  78.480 -        ///
  78.481 +        /// Inequality operator.
  78.482          bool operator!=(Arc) const { return true; }
  78.483  
  78.484          /// Artificial ordering operator.
  78.485  
  78.486 -        /// To allow the use of graph descriptors as key type in std::map or
  78.487 -        /// similar associative container we require this.
  78.488 +        /// Artificial ordering operator.
  78.489          ///
  78.490 -        /// \note This operator only have to define some strict ordering of
  78.491 -        /// the items; this order has nothing to do with the iteration
  78.492 -        /// ordering of the items.
  78.493 +        /// \note This operator only has to define some strict ordering of
  78.494 +        /// the arcs; this order has nothing to do with the iteration
  78.495 +        /// ordering of the arcs.
  78.496          bool operator<(Arc) const { return false; }
  78.497  
  78.498 +        /// Converison to \c Edge
  78.499 +        
  78.500 +        /// Converison to \c Edge.
  78.501 +        ///
  78.502 +        operator Edge() const { return Edge(); }
  78.503        };
  78.504 -      /// This iterator goes through each directed arc.
  78.505  
  78.506 -      /// This iterator goes through each arc of a graph.
  78.507 +      /// Iterator class for the arcs.
  78.508 +
  78.509 +      /// This iterator goes through each directed arc of the graph.
  78.510        /// Its usage is quite simple, for example you can count the number
  78.511 -      /// of arcs in a graph \c g of type \c Graph as follows:
  78.512 +      /// of arcs in a graph \c g of type \c %Graph as follows:
  78.513        ///\code
  78.514        /// int count=0;
  78.515 -      /// for(Graph::ArcIt e(g); e!=INVALID; ++e) ++count;
  78.516 +      /// for(Graph::ArcIt a(g); a!=INVALID; ++a) ++count;
  78.517        ///\endcode
  78.518        class ArcIt : public Arc {
  78.519        public:
  78.520          /// Default constructor
  78.521  
  78.522 -        /// @warning The default constructor sets the iterator
  78.523 -        /// to an undefined value.
  78.524 +        /// Default constructor.
  78.525 +        /// \warning It sets the iterator to an undefined value.
  78.526          ArcIt() { }
  78.527          /// Copy constructor.
  78.528  
  78.529          /// Copy constructor.
  78.530          ///
  78.531          ArcIt(const ArcIt& e) : Arc(e) { }
  78.532 -        /// Initialize the iterator to be invalid.
  78.533 +        /// %Invalid constructor \& conversion.
  78.534  
  78.535 -        /// Initialize the iterator to be invalid.
  78.536 +        /// Initializes the iterator to be invalid.
  78.537 +        /// \sa Invalid for more details.
  78.538 +        ArcIt(Invalid) { }
  78.539 +        /// Sets the iterator to the first arc.
  78.540 +
  78.541 +        /// Sets the iterator to the first arc of the given graph.
  78.542          ///
  78.543 -        ArcIt(Invalid) { }
  78.544 -        /// This constructor sets the iterator to the first arc.
  78.545 +        explicit ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
  78.546 +        /// Sets the iterator to the given arc.
  78.547  
  78.548 -        /// This constructor sets the iterator to the first arc of \c g.
  78.549 -        ///@param g the graph
  78.550 -        ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
  78.551 -        /// Arc -> ArcIt conversion
  78.552 -
  78.553 -        /// Sets the iterator to the value of the trivial iterator \c e.
  78.554 -        /// This feature necessitates that each time we
  78.555 -        /// iterate the arc-set, the iteration order is the same.
  78.556 +        /// Sets the iterator to the given arc of the given graph.
  78.557 +        ///
  78.558          ArcIt(const Graph&, const Arc&) { }
  78.559 -        ///Next arc
  78.560 +        /// Next arc
  78.561  
  78.562          /// Assign the iterator to the next arc.
  78.563 +        ///
  78.564          ArcIt& operator++() { return *this; }
  78.565        };
  78.566  
  78.567 -      /// This iterator goes trough the outgoing directed arcs of a node.
  78.568 +      /// Iterator class for the outgoing arcs of a node.
  78.569  
  78.570 -      /// This iterator goes trough the \e outgoing arcs of a certain node
  78.571 -      /// of a graph.
  78.572 +      /// This iterator goes trough the \e outgoing directed arcs of a
  78.573 +      /// certain node of a graph.
  78.574        /// Its usage is quite simple, for example you can count the number
  78.575        /// of outgoing arcs of a node \c n
  78.576 -      /// in graph \c g of type \c Graph as follows.
  78.577 +      /// in a graph \c g of type \c %Graph as follows.
  78.578        ///\code
  78.579        /// int count=0;
  78.580 -      /// for (Graph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
  78.581 +      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
  78.582        ///\endcode
  78.583 -
  78.584        class OutArcIt : public Arc {
  78.585        public:
  78.586          /// Default constructor
  78.587  
  78.588 -        /// @warning The default constructor sets the iterator
  78.589 -        /// to an undefined value.
  78.590 +        /// Default constructor.
  78.591 +        /// \warning It sets the iterator to an undefined value.
  78.592          OutArcIt() { }
  78.593          /// Copy constructor.
  78.594  
  78.595          /// Copy constructor.
  78.596          ///
  78.597          OutArcIt(const OutArcIt& e) : Arc(e) { }
  78.598 -        /// Initialize the iterator to be invalid.
  78.599 +        /// %Invalid constructor \& conversion.
  78.600  
  78.601 -        /// Initialize the iterator to be invalid.
  78.602 +        /// Initializes the iterator to be invalid.
  78.603 +        /// \sa Invalid for more details.
  78.604 +        OutArcIt(Invalid) { }
  78.605 +        /// Sets the iterator to the first outgoing arc.
  78.606 +
  78.607 +        /// Sets the iterator to the first outgoing arc of the given node.
  78.608          ///
  78.609 -        OutArcIt(Invalid) { }
  78.610 -        /// This constructor sets the iterator to the first outgoing arc.
  78.611 -
  78.612 -        /// This constructor sets the iterator to the first outgoing arc of
  78.613 -        /// the node.
  78.614 -        ///@param n the node
  78.615 -        ///@param g the graph
  78.616          OutArcIt(const Graph& n, const Node& g) {
  78.617            ignore_unused_variable_warning(n);
  78.618            ignore_unused_variable_warning(g);
  78.619          }
  78.620 -        /// Arc -> OutArcIt conversion
  78.621 +        /// Sets the iterator to the given arc.
  78.622  
  78.623 -        /// Sets the iterator to the value of the trivial iterator.
  78.624 -        /// This feature necessitates that each time we
  78.625 -        /// iterate the arc-set, the iteration order is the same.
  78.626 +        /// Sets the iterator to the given arc of the given graph.
  78.627 +        ///
  78.628          OutArcIt(const Graph&, const Arc&) { }
  78.629 -        ///Next outgoing arc
  78.630 +        /// Next outgoing arc
  78.631  
  78.632          /// Assign the iterator to the next
  78.633          /// outgoing arc of the corresponding node.
  78.634          OutArcIt& operator++() { return *this; }
  78.635        };
  78.636  
  78.637 -      /// This iterator goes trough the incoming directed arcs of a node.
  78.638 +      /// Iterator class for the incoming arcs of a node.
  78.639  
  78.640 -      /// This iterator goes trough the \e incoming arcs of a certain node
  78.641 -      /// of a graph.
  78.642 +      /// This iterator goes trough the \e incoming directed arcs of a
  78.643 +      /// certain node of a graph.
  78.644        /// Its usage is quite simple, for example you can count the number
  78.645 -      /// of outgoing arcs of a node \c n
  78.646 -      /// in graph \c g of type \c Graph as follows.
  78.647 +      /// of incoming arcs of a node \c n
  78.648 +      /// in a graph \c g of type \c %Graph as follows.
  78.649        ///\code
  78.650        /// int count=0;
  78.651 -      /// for(Graph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
  78.652 +      /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
  78.653        ///\endcode
  78.654 -
  78.655        class InArcIt : public Arc {
  78.656        public:
  78.657          /// Default constructor
  78.658  
  78.659 -        /// @warning The default constructor sets the iterator
  78.660 -        /// to an undefined value.
  78.661 +        /// Default constructor.
  78.662 +        /// \warning It sets the iterator to an undefined value.
  78.663          InArcIt() { }
  78.664          /// Copy constructor.
  78.665  
  78.666          /// Copy constructor.
  78.667          ///
  78.668          InArcIt(const InArcIt& e) : Arc(e) { }
  78.669 -        /// Initialize the iterator to be invalid.
  78.670 +        /// %Invalid constructor \& conversion.
  78.671  
  78.672 -        /// Initialize the iterator to be invalid.
  78.673 +        /// Initializes the iterator to be invalid.
  78.674 +        /// \sa Invalid for more details.
  78.675 +        InArcIt(Invalid) { }
  78.676 +        /// Sets the iterator to the first incoming arc.
  78.677 +
  78.678 +        /// Sets the iterator to the first incoming arc of the given node.
  78.679          ///
  78.680 -        InArcIt(Invalid) { }
  78.681 -        /// This constructor sets the iterator to first incoming arc.
  78.682 -
  78.683 -        /// This constructor set the iterator to the first incoming arc of
  78.684 -        /// the node.
  78.685 -        ///@param n the node
  78.686 -        ///@param g the graph
  78.687          InArcIt(const Graph& g, const Node& n) {
  78.688            ignore_unused_variable_warning(n);
  78.689            ignore_unused_variable_warning(g);
  78.690          }
  78.691 -        /// Arc -> InArcIt conversion
  78.692 +        /// Sets the iterator to the given arc.
  78.693  
  78.694 -        /// Sets the iterator to the value of the trivial iterator \c e.
  78.695 -        /// This feature necessitates that each time we
  78.696 -        /// iterate the arc-set, the iteration order is the same.
  78.697 +        /// Sets the iterator to the given arc of the given graph.
  78.698 +        ///
  78.699          InArcIt(const Graph&, const Arc&) { }
  78.700          /// Next incoming arc
  78.701  
  78.702 -        /// Assign the iterator to the next inarc of the corresponding node.
  78.703 -        ///
  78.704 +        /// Assign the iterator to the next
  78.705 +        /// incoming arc of the corresponding node.
  78.706          InArcIt& operator++() { return *this; }
  78.707        };
  78.708  
  78.709 -      /// \brief Read write map of the nodes to type \c T.
  78.710 +      /// \brief Standard graph map type for the nodes.
  78.711        ///
  78.712 -      /// ReadWrite map of the nodes to type \c T.
  78.713 -      /// \sa Reference
  78.714 +      /// Standard graph map type for the nodes.
  78.715 +      /// It conforms to the ReferenceMap concept.
  78.716        template<class T>
  78.717 -      class NodeMap : public ReadWriteMap< Node, T >
  78.718 +      class NodeMap : public ReferenceMap<Node, T, T&, const T&>
  78.719        {
  78.720        public:
  78.721  
  78.722 -        ///\e
  78.723 -        NodeMap(const Graph&) { }
  78.724 -        ///\e
  78.725 +        /// Constructor
  78.726 +        explicit NodeMap(const Graph&) { }
  78.727 +        /// Constructor with given initial value
  78.728          NodeMap(const Graph&, T) { }
  78.729  
  78.730        private:
  78.731          ///Copy constructor
  78.732 -        NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
  78.733 +        NodeMap(const NodeMap& nm) :
  78.734 +          ReferenceMap<Node, T, T&, const T&>(nm) { }
  78.735          ///Assignment operator
  78.736          template <typename CMap>
  78.737          NodeMap& operator=(const CMap&) {
  78.738 @@ -523,22 +531,24 @@
  78.739          }
  78.740        };
  78.741  
  78.742 -      /// \brief Read write map of the directed arcs to type \c T.
  78.743 +      /// \brief Standard graph map type for the arcs.
  78.744        ///
  78.745 -      /// Reference map of the directed arcs to type \c T.
  78.746 -      /// \sa Reference
  78.747 +      /// Standard graph map type for the arcs.
  78.748 +      /// It conforms to the ReferenceMap concept.
  78.749        template<class T>
  78.750 -      class ArcMap : public ReadWriteMap<Arc,T>
  78.751 +      class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
  78.752        {
  78.753        public:
  78.754  
  78.755 -        ///\e
  78.756 -        ArcMap(const Graph&) { }
  78.757 -        ///\e
  78.758 +        /// Constructor
  78.759 +        explicit ArcMap(const Graph&) { }
  78.760 +        /// Constructor with given initial value
  78.761          ArcMap(const Graph&, T) { }
  78.762 +
  78.763        private:
  78.764          ///Copy constructor
  78.765 -        ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { }
  78.766 +        ArcMap(const ArcMap& em) :
  78.767 +          ReferenceMap<Arc, T, T&, const T&>(em) { }
  78.768          ///Assignment operator
  78.769          template <typename CMap>
  78.770          ArcMap& operator=(const CMap&) {
  78.771 @@ -547,22 +557,24 @@
  78.772          }
  78.773        };
  78.774  
  78.775 -      /// Read write map of the edges to type \c T.
  78.776 -
  78.777 -      /// Reference map of the arcs to type \c T.
  78.778 -      /// \sa Reference
  78.779 +      /// \brief Standard graph map type for the edges.
  78.780 +      ///
  78.781 +      /// Standard graph map type for the edges.
  78.782 +      /// It conforms to the ReferenceMap concept.
  78.783        template<class T>
  78.784 -      class EdgeMap : public ReadWriteMap<Edge,T>
  78.785 +      class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
  78.786        {
  78.787        public:
  78.788  
  78.789 -        ///\e
  78.790 -        EdgeMap(const Graph&) { }
  78.791 -        ///\e
  78.792 +        /// Constructor
  78.793 +        explicit EdgeMap(const Graph&) { }
  78.794 +        /// Constructor with given initial value
  78.795          EdgeMap(const Graph&, T) { }
  78.796 +
  78.797        private:
  78.798          ///Copy constructor
  78.799 -        EdgeMap(const EdgeMap& em) : ReadWriteMap<Edge,T>(em) {}
  78.800 +        EdgeMap(const EdgeMap& em) :
  78.801 +          ReferenceMap<Edge, T, T&, const T&>(em) {}
  78.802          ///Assignment operator
  78.803          template <typename CMap>
  78.804          EdgeMap& operator=(const CMap&) {
  78.805 @@ -571,95 +583,124 @@
  78.806          }
  78.807        };
  78.808  
  78.809 -      /// \brief Direct the given edge.
  78.810 +      /// \brief The first node of the edge.
  78.811        ///
  78.812 -      /// Direct the given edge. The returned arc source
  78.813 -      /// will be the given node.
  78.814 -      Arc direct(const Edge&, const Node&) const {
  78.815 +      /// Returns the first node of the given edge.
  78.816 +      ///
  78.817 +      /// Edges don't have source and target nodes, however methods
  78.818 +      /// u() and v() are used to query the two end-nodes of an edge.
  78.819 +      /// The orientation of an edge that arises this way is called
  78.820 +      /// the inherent direction, it is used to define the default
  78.821 +      /// direction for the corresponding arcs.
  78.822 +      /// \sa v()
  78.823 +      /// \sa direction()
  78.824 +      Node u(Edge) const { return INVALID; }
  78.825 +
  78.826 +      /// \brief The second node of the edge.
  78.827 +      ///
  78.828 +      /// Returns the second node of the given edge.
  78.829 +      ///
  78.830 +      /// Edges don't have source and target nodes, however methods
  78.831 +      /// u() and v() are used to query the two end-nodes of an edge.
  78.832 +      /// The orientation of an edge that arises this way is called
  78.833 +      /// the inherent direction, it is used to define the default
  78.834 +      /// direction for the corresponding arcs.
  78.835 +      /// \sa u()
  78.836 +      /// \sa direction()
  78.837 +      Node v(Edge) const { return INVALID; }
  78.838 +
  78.839 +      /// \brief The source node of the arc.
  78.840 +      ///
  78.841 +      /// Returns the source node of the given arc.
  78.842 +      Node source(Arc) const { return INVALID; }
  78.843 +
  78.844 +      /// \brief The target node of the arc.
  78.845 +      ///
  78.846 +      /// Returns the target node of the given arc.
  78.847 +      Node target(Arc) const { return INVALID; }
  78.848 +
  78.849 +      /// \brief The ID of the node.
  78.850 +      ///
  78.851 +      /// Returns the ID of the given node.
  78.852 +      int id(Node) const { return -1; }
  78.853 +
  78.854 +      /// \brief The ID of the edge.
  78.855 +      ///
  78.856 +      /// Returns the ID of the given edge.
  78.857 +      int id(Edge) const { return -1; }
  78.858 +
  78.859 +      /// \brief The ID of the arc.
  78.860 +      ///
  78.861 +      /// Returns the ID of the given arc.
  78.862 +      int id(Arc) const { return -1; }
  78.863 +
  78.864 +      /// \brief The node with the given ID.
  78.865 +      ///
  78.866 +      /// Returns the node with the given ID.
  78.867 +      /// \pre The argument should be a valid node ID in the graph.
  78.868 +      Node nodeFromId(int) const { return INVALID; }
  78.869 +
  78.870 +      /// \brief The edge with the given ID.
  78.871 +      ///
  78.872 +      /// Returns the edge with the given ID.
  78.873 +      /// \pre The argument should be a valid edge ID in the graph.
  78.874 +      Edge edgeFromId(int) const { return INVALID; }
  78.875 +
  78.876 +      /// \brief The arc with the given ID.
  78.877 +      ///
  78.878 +      /// Returns the arc with the given ID.
  78.879 +      /// \pre The argument should be a valid arc ID in the graph.
  78.880 +      Arc arcFromId(int) const { return INVALID; }
  78.881 +
  78.882 +      /// \brief An upper bound on the node IDs.
  78.883 +      ///
  78.884 +      /// Returns an upper bound on the node IDs.
  78.885 +      int maxNodeId() const { return -1; }
  78.886 +
  78.887 +      /// \brief An upper bound on the edge IDs.
  78.888 +      ///
  78.889 +      /// Returns an upper bound on the edge IDs.
  78.890 +      int maxEdgeId() const { return -1; }
  78.891 +
  78.892 +      /// \brief An upper bound on the arc IDs.
  78.893 +      ///
  78.894 +      /// Returns an upper bound on the arc IDs.
  78.895 +      int maxArcId() const { return -1; }
  78.896 +
  78.897 +      /// \brief The direction of the arc.
  78.898 +      ///
  78.899 +      /// Returns \c true if the direction of the given arc is the same as
  78.900 +      /// the inherent orientation of the represented edge.
  78.901 +      bool direction(Arc) const { return true; }
  78.902 +
  78.903 +      /// \brief Direct the edge.
  78.904 +      ///
  78.905 +      /// Direct the given edge. The returned arc
  78.906 +      /// represents the given edge and its direction comes
  78.907 +      /// from the bool parameter. If it is \c true, then the direction
  78.908 +      /// of the arc is the same as the inherent orientation of the edge.
  78.909 +      Arc direct(Edge, bool) const {
  78.910          return INVALID;
  78.911        }
  78.912  
  78.913 -      /// \brief Direct the given edge.
  78.914 +      /// \brief Direct the edge.
  78.915        ///
  78.916 -      /// Direct the given edge. The returned arc
  78.917 -      /// represents the given edge and the direction comes
  78.918 -      /// from the bool parameter. The source of the edge and
  78.919 -      /// the directed arc is the same when the given bool is true.
  78.920 -      Arc direct(const Edge&, bool) const {
  78.921 +      /// Direct the given edge. The returned arc represents the given
  78.922 +      /// edge and its source node is the given node.
  78.923 +      Arc direct(Edge, Node) const {
  78.924          return INVALID;
  78.925        }
  78.926  
  78.927 -      /// \brief Returns true if the arc has default orientation.
  78.928 +      /// \brief The oppositely directed arc.
  78.929        ///
  78.930 -      /// Returns whether the given directed arc is same orientation as
  78.931 -      /// the corresponding edge's default orientation.
  78.932 -      bool direction(Arc) const { return true; }
  78.933 -
  78.934 -      /// \brief Returns the opposite directed arc.
  78.935 -      ///
  78.936 -      /// Returns the opposite directed arc.
  78.937 +      /// Returns the oppositely directed arc representing the same edge.
  78.938        Arc oppositeArc(Arc) const { return INVALID; }
  78.939  
  78.940 -      /// \brief Opposite node on an arc
  78.941 +      /// \brief The opposite node on the edge.
  78.942        ///
  78.943 -      /// \return the opposite of the given Node on the given Edge
  78.944 +      /// Returns the opposite node on the given edge.
  78.945        Node oppositeNode(Node, Edge) const { return INVALID; }
  78.946  
  78.947 -      /// \brief First node of the edge.
  78.948 -      ///
  78.949 -      /// \return the first node of the given Edge.
  78.950 -      ///
  78.951 -      /// Naturally edges don't have direction and thus
  78.952 -      /// don't have source and target node. But we use these two methods
  78.953 -      /// to query the two nodes of the arc. The direction of the arc
  78.954 -      /// which arises this way is called the inherent direction of the
  78.955 -      /// edge, and is used to define the "default" direction
  78.956 -      /// of the directed versions of the arcs.
  78.957 -      /// \sa direction
  78.958 -      Node u(Edge) const { return INVALID; }
  78.959 -
  78.960 -      /// \brief Second node of the edge.
  78.961 -      Node v(Edge) const { return INVALID; }
  78.962 -
  78.963 -      /// \brief Source node of the directed arc.
  78.964 -      Node source(Arc) const { return INVALID; }
  78.965 -
  78.966 -      /// \brief Target node of the directed arc.
  78.967 -      Node target(Arc) const { return INVALID; }
  78.968 -
  78.969 -      /// \brief Returns the id of the node.
  78.970 -      int id(Node) const { return -1; }
  78.971 -
  78.972 -      /// \brief Returns the id of the edge.
  78.973 -      int id(Edge) const { return -1; }
  78.974 -
  78.975 -      /// \brief Returns the id of the arc.
  78.976 -      int id(Arc) const { return -1; }
  78.977 -
  78.978 -      /// \brief Returns the node with the given id.
  78.979 -      ///
  78.980 -      /// \pre The argument should be a valid node id in the graph.
  78.981 -      Node nodeFromId(int) const { return INVALID; }
  78.982 -
  78.983 -      /// \brief Returns the edge with the given id.
  78.984 -      ///
  78.985 -      /// \pre The argument should be a valid edge id in the graph.
  78.986 -      Edge edgeFromId(int) const { return INVALID; }
  78.987 -
  78.988 -      /// \brief Returns the arc with the given id.
  78.989 -      ///
  78.990 -      /// \pre The argument should be a valid arc id in the graph.
  78.991 -      Arc arcFromId(int) const { return INVALID; }
  78.992 -
  78.993 -      /// \brief Returns an upper bound on the node IDs.
  78.994 -      int maxNodeId() const { return -1; }
  78.995 -
  78.996 -      /// \brief Returns an upper bound on the edge IDs.
  78.997 -      int maxEdgeId() const { return -1; }
  78.998 -
  78.999 -      /// \brief Returns an upper bound on the arc IDs.
 78.1000 -      int maxArcId() const { return -1; }
 78.1001 -
 78.1002        void first(Node&) const {}
 78.1003        void next(Node&) const {}
 78.1004  
 78.1005 @@ -692,51 +733,44 @@
 78.1006        // Dummy parameter.
 78.1007        int maxId(Arc) const { return -1; }
 78.1008  
 78.1009 -      /// \brief Base node of the iterator
 78.1010 +      /// \brief The base node of the iterator.
 78.1011        ///
 78.1012 -      /// Returns the base node (the source in this case) of the iterator
 78.1013 -      Node baseNode(OutArcIt e) const {
 78.1014 -        return source(e);
 78.1015 -      }
 78.1016 -      /// \brief Running node of the iterator
 78.1017 +      /// Returns the base node of the given incident edge iterator.
 78.1018 +      Node baseNode(IncEdgeIt) const { return INVALID; }
 78.1019 +
 78.1020 +      /// \brief The running node of the iterator.
 78.1021        ///
 78.1022 -      /// Returns the running node (the target in this case) of the
 78.1023 -      /// iterator
 78.1024 -      Node runningNode(OutArcIt e) const {
 78.1025 -        return target(e);
 78.1026 -      }
 78.1027 +      /// Returns the running node of the given incident edge iterator.
 78.1028 +      Node runningNode(IncEdgeIt) const { return INVALID; }
 78.1029  
 78.1030 -      /// \brief Base node of the iterator
 78.1031 +      /// \brief The base node of the iterator.
 78.1032        ///
 78.1033 -      /// Returns the base node (the target in this case) of the iterator
 78.1034 -      Node baseNode(InArcIt e) const {
 78.1035 -        return target(e);
 78.1036 -      }
 78.1037 -      /// \brief Running node of the iterator
 78.1038 +      /// Returns the base node of the given outgoing arc iterator
 78.1039 +      /// (i.e. the source node of the corresponding arc).
 78.1040 +      Node baseNode(OutArcIt) const { return INVALID; }
 78.1041 +
 78.1042 +      /// \brief The running node of the iterator.
 78.1043        ///
 78.1044 -      /// Returns the running node (the source in this case) of the
 78.1045 -      /// iterator
 78.1046 -      Node runningNode(InArcIt e) const {
 78.1047 -        return source(e);
 78.1048 -      }
 78.1049 +      /// Returns the running node of the given outgoing arc iterator
 78.1050 +      /// (i.e. the target node of the corresponding arc).
 78.1051 +      Node runningNode(OutArcIt) const { return INVALID; }
 78.1052  
 78.1053 -      /// \brief Base node of the iterator
 78.1054 +      /// \brief The base node of the iterator.
 78.1055        ///
 78.1056 -      /// Returns the base node of the iterator
 78.1057 -      Node baseNode(IncEdgeIt) const {
 78.1058 -        return INVALID;
 78.1059 -      }
 78.1060 +      /// Returns the base node of the given incomming arc iterator
 78.1061 +      /// (i.e. the target node of the corresponding arc).
 78.1062 +      Node baseNode(InArcIt) const { return INVALID; }
 78.1063  
 78.1064 -      /// \brief Running node of the iterator
 78.1065 +      /// \brief The running node of the iterator.
 78.1066        ///
 78.1067 -      /// Returns the running node of the iterator
 78.1068 -      Node runningNode(IncEdgeIt) const {
 78.1069 -        return INVALID;
 78.1070 -      }
 78.1071 +      /// Returns the running node of the given incomming arc iterator
 78.1072 +      /// (i.e. the source node of the corresponding arc).
 78.1073 +      Node runningNode(InArcIt) const { return INVALID; }
 78.1074  
 78.1075        template <typename _Graph>
 78.1076        struct Constraints {
 78.1077          void constraints() {
 78.1078 +          checkConcept<BaseGraphComponent, _Graph>();
 78.1079            checkConcept<IterableGraphComponent<>, _Graph>();
 78.1080            checkConcept<IDableGraphComponent<>, _Graph>();
 78.1081            checkConcept<MappableGraphComponent<>, _Graph>();
    79.1 --- a/lemon/concepts/graph_components.h	Fri Oct 16 10:21:37 2009 +0200
    79.2 +++ b/lemon/concepts/graph_components.h	Thu Nov 05 15:50:01 2009 +0100
    79.3 @@ -2,7 +2,7 @@
    79.4   *
    79.5   * This file is a part of LEMON, a generic C++ optimization library.
    79.6   *
    79.7 - * Copyright (C) 2003-2008
    79.8 + * Copyright (C) 2003-2009
    79.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   79.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   79.11   *
   79.12 @@ -20,9 +20,8 @@
   79.13  ///\file
   79.14  ///\brief The concept of graph components.
   79.15  
   79.16 -
   79.17 -#ifndef LEMON_CONCEPT_GRAPH_COMPONENTS_H
   79.18 -#define LEMON_CONCEPT_GRAPH_COMPONENTS_H
   79.19 +#ifndef LEMON_CONCEPTS_GRAPH_COMPONENTS_H
   79.20 +#define LEMON_CONCEPTS_GRAPH_COMPONENTS_H
   79.21  
   79.22  #include <lemon/core.h>
   79.23  #include <lemon/concepts/maps.h>
   79.24 @@ -32,75 +31,83 @@
   79.25  namespace lemon {
   79.26    namespace concepts {
   79.27  
   79.28 -    /// \brief Skeleton class for graph Node and Arc types
   79.29 +    /// \brief Concept class for \c Node, \c Arc and \c Edge types.
   79.30      ///
   79.31 -    /// This class describes the interface of Node and Arc (and Edge
   79.32 -    /// in undirected graphs) subtypes of graph types.
   79.33 +    /// This class describes the concept of \c Node, \c Arc and \c Edge
   79.34 +    /// subtypes of digraph and graph types.
   79.35      ///
   79.36      /// \note This class is a template class so that we can use it to
   79.37 -    /// create graph skeleton classes. The reason for this is than Node
   79.38 -    /// and Arc types should \em not derive from the same base class.
   79.39 -    /// For Node you should instantiate it with character 'n' and for Arc
   79.40 -    /// with 'a'.
   79.41 -
   79.42 +    /// create graph skeleton classes. The reason for this is that \c Node
   79.43 +    /// and \c Arc (or \c Edge) types should \e not derive from the same 
   79.44 +    /// base class. For \c Node you should instantiate it with character
   79.45 +    /// \c 'n', for \c Arc with \c 'a' and for \c Edge with \c 'e'.
   79.46  #ifndef DOXYGEN
   79.47 -    template <char _selector = '0'>
   79.48 +    template <char sel = '0'>
   79.49  #endif
   79.50      class GraphItem {
   79.51      public:
   79.52        /// \brief Default constructor.
   79.53        ///
   79.54 +      /// Default constructor.
   79.55        /// \warning The default constructor is not required to set
   79.56        /// the item to some well-defined value. So you should consider it
   79.57        /// as uninitialized.
   79.58        GraphItem() {}
   79.59 +
   79.60        /// \brief Copy constructor.
   79.61        ///
   79.62        /// Copy constructor.
   79.63 +      GraphItem(const GraphItem &) {}
   79.64 +
   79.65 +      /// \brief Constructor for conversion from \c INVALID.
   79.66        ///
   79.67 -      GraphItem(const GraphItem &) {}
   79.68 -      /// \brief Invalid constructor \& conversion.
   79.69 -      ///
   79.70 -      /// This constructor initializes the item to be invalid.
   79.71 +      /// Constructor for conversion from \c INVALID.
   79.72 +      /// It initializes the item to be invalid.
   79.73        /// \sa Invalid for more details.
   79.74        GraphItem(Invalid) {}
   79.75 -      /// \brief Assign operator for nodes.
   79.76 +
   79.77 +      /// \brief Assignment operator.
   79.78        ///
   79.79 -      /// The nodes are assignable.
   79.80 +      /// Assignment operator for the item.
   79.81 +      GraphItem& operator=(const GraphItem&) { return *this; }
   79.82 +
   79.83 +      /// \brief Assignment operator for INVALID.
   79.84        ///
   79.85 -      GraphItem& operator=(GraphItem const&) { return *this; }
   79.86 +      /// This operator makes the item invalid.
   79.87 +      GraphItem& operator=(Invalid) { return *this; }
   79.88 +
   79.89        /// \brief Equality operator.
   79.90        ///
   79.91 -      /// Two iterators are equal if and only if they represents the
   79.92 -      /// same node in the graph or both are invalid.
   79.93 -      bool operator==(GraphItem) const { return false; }
   79.94 +      /// Equality operator.
   79.95 +      bool operator==(const GraphItem&) const { return false; }
   79.96 +
   79.97        /// \brief Inequality operator.
   79.98        ///
   79.99 -      /// \sa operator==(const Node& n)
  79.100 +      /// Inequality operator.
  79.101 +      bool operator!=(const GraphItem&) const { return false; }
  79.102 +
  79.103 +      /// \brief Ordering operator.
  79.104        ///
  79.105 -      bool operator!=(GraphItem) const { return false; }
  79.106 -
  79.107 -      /// \brief Artificial ordering operator.
  79.108 +      /// This operator defines an ordering of the items.
  79.109 +      /// It makes possible to use graph item types as key types in 
  79.110 +      /// associative containers (e.g. \c std::map).
  79.111        ///
  79.112 -      /// To allow the use of graph descriptors as key type in std::map or
  79.113 -      /// similar associative container we require this.
  79.114 -      ///
  79.115 -      /// \note This operator only have to define some strict ordering of
  79.116 +      /// \note This operator only has to define some strict ordering of
  79.117        /// the items; this order has nothing to do with the iteration
  79.118        /// ordering of the items.
  79.119 -      bool operator<(GraphItem) const { return false; }
  79.120 +      bool operator<(const GraphItem&) const { return false; }
  79.121  
  79.122        template<typename _GraphItem>
  79.123        struct Constraints {
  79.124          void constraints() {
  79.125            _GraphItem i1;
  79.126 +          i1=INVALID;
  79.127            _GraphItem i2 = i1;
  79.128            _GraphItem i3 = INVALID;
  79.129  
  79.130            i1 = i2 = i3;
  79.131  
  79.132            bool b;
  79.133 -          //          b = (ia == ib) && (ia != ib) && (ia < ib);
  79.134            b = (ia == ib) && (ia != ib);
  79.135            b = (ia == INVALID) && (ib != INVALID);
  79.136            b = (ia < ib);
  79.137 @@ -111,13 +118,12 @@
  79.138        };
  79.139      };
  79.140  
  79.141 -    /// \brief An empty base directed graph class.
  79.142 +    /// \brief Base skeleton class for directed graphs.
  79.143      ///
  79.144 -    /// This class provides the minimal set of features needed for a
  79.145 -    /// directed graph structure. All digraph concepts have to be
  79.146 -    /// conform to this base directed graph. It just provides types
  79.147 -    /// for nodes and arcs and functions to get the source and the
  79.148 -    /// target of the arcs.
  79.149 +    /// This class describes the base interface of directed graph types.
  79.150 +    /// All digraph %concepts have to conform to this class.
  79.151 +    /// It just provides types for nodes and arcs and functions 
  79.152 +    /// to get the source and the target nodes of arcs.
  79.153      class BaseDigraphComponent {
  79.154      public:
  79.155  
  79.156 @@ -125,31 +131,27 @@
  79.157  
  79.158        /// \brief Node class of the digraph.
  79.159        ///
  79.160 -      /// This class represents the Nodes of the digraph.
  79.161 -      ///
  79.162 +      /// This class represents the nodes of the digraph.
  79.163        typedef GraphItem<'n'> Node;
  79.164  
  79.165        /// \brief Arc class of the digraph.
  79.166        ///
  79.167 -      /// This class represents the Arcs of the digraph.
  79.168 +      /// This class represents the arcs of the digraph.
  79.169 +      typedef GraphItem<'a'> Arc;
  79.170 +
  79.171 +      /// \brief Return the source node of an arc.
  79.172        ///
  79.173 -      typedef GraphItem<'e'> Arc;
  79.174 +      /// This function returns the source node of an arc.
  79.175 +      Node source(const Arc&) const { return INVALID; }
  79.176  
  79.177 -      /// \brief Gives back the target node of an arc.
  79.178 +      /// \brief Return the target node of an arc.
  79.179        ///
  79.180 -      /// Gives back the target node of an arc.
  79.181 +      /// This function returns the target node of an arc.
  79.182 +      Node target(const Arc&) const { return INVALID; }
  79.183 +
  79.184 +      /// \brief Return the opposite node on the given arc.
  79.185        ///
  79.186 -      Node target(const Arc&) const { return INVALID;}
  79.187 -
  79.188 -      /// \brief Gives back the source node of an arc.
  79.189 -      ///
  79.190 -      /// Gives back the source node of an arc.
  79.191 -      ///
  79.192 -      Node source(const Arc&) const { return INVALID;}
  79.193 -
  79.194 -      /// \brief Gives back the opposite node on the given arc.
  79.195 -      ///
  79.196 -      /// Gives back the opposite node on the given arc.
  79.197 +      /// This function returns the opposite node on the given arc.
  79.198        Node oppositeNode(const Node&, const Arc&) const {
  79.199          return INVALID;
  79.200        }
  79.201 @@ -175,91 +177,92 @@
  79.202        };
  79.203      };
  79.204  
  79.205 -    /// \brief An empty base undirected graph class.
  79.206 +    /// \brief Base skeleton class for undirected graphs.
  79.207      ///
  79.208 -    /// This class provides the minimal set of features needed for an
  79.209 -    /// undirected graph structure. All undirected graph concepts have
  79.210 -    /// to be conform to this base graph. It just provides types for
  79.211 -    /// nodes, arcs and edges and functions to get the
  79.212 -    /// source and the target of the arcs and edges,
  79.213 -    /// conversion from arcs to edges and function to get
  79.214 -    /// both direction of the edges.
  79.215 +    /// This class describes the base interface of undirected graph types.
  79.216 +    /// All graph %concepts have to conform to this class.
  79.217 +    /// It extends the interface of \ref BaseDigraphComponent with an
  79.218 +    /// \c Edge type and functions to get the end nodes of edges,
  79.219 +    /// to convert from arcs to edges and to get both direction of edges.
  79.220      class BaseGraphComponent : public BaseDigraphComponent {
  79.221      public:
  79.222 +
  79.223 +      typedef BaseGraphComponent Graph;
  79.224 +
  79.225        typedef BaseDigraphComponent::Node Node;
  79.226        typedef BaseDigraphComponent::Arc Arc;
  79.227 -      /// \brief Undirected arc class of the graph.
  79.228 +
  79.229 +      /// \brief Undirected edge class of the graph.
  79.230        ///
  79.231 -      /// This class represents the edges of the graph.
  79.232 -      /// The undirected graphs can be used as a directed graph which
  79.233 -      /// for each arc contains the opposite arc too so the graph is
  79.234 -      /// bidirected. The edge represents two opposite
  79.235 -      /// directed arcs.
  79.236 -      class Edge : public GraphItem<'u'> {
  79.237 +      /// This class represents the undirected edges of the graph.
  79.238 +      /// Undirected graphs can be used as directed graphs, each edge is
  79.239 +      /// represented by two opposite directed arcs.
  79.240 +      class Edge : public GraphItem<'e'> {
  79.241 +        typedef GraphItem<'e'> Parent;
  79.242 +
  79.243        public:
  79.244 -        typedef GraphItem<'u'> Parent;
  79.245          /// \brief Default constructor.
  79.246          ///
  79.247 +        /// Default constructor.
  79.248          /// \warning The default constructor is not required to set
  79.249          /// the item to some well-defined value. So you should consider it
  79.250          /// as uninitialized.
  79.251          Edge() {}
  79.252 +
  79.253          /// \brief Copy constructor.
  79.254          ///
  79.255          /// Copy constructor.
  79.256 +        Edge(const Edge &) : Parent() {}
  79.257 +
  79.258 +        /// \brief Constructor for conversion from \c INVALID.
  79.259          ///
  79.260 -        Edge(const Edge &) : Parent() {}
  79.261 -        /// \brief Invalid constructor \& conversion.
  79.262 -        ///
  79.263 -        /// This constructor initializes the item to be invalid.
  79.264 +        /// Constructor for conversion from \c INVALID.
  79.265 +        /// It initializes the item to be invalid.
  79.266          /// \sa Invalid for more details.
  79.267          Edge(Invalid) {}
  79.268 -        /// \brief Converter from arc to edge.
  79.269 +
  79.270 +        /// \brief Constructor for conversion from an arc.
  79.271          ///
  79.272 +        /// Constructor for conversion from an arc.
  79.273          /// Besides the core graph item functionality each arc should
  79.274          /// be convertible to the represented edge.
  79.275          Edge(const Arc&) {}
  79.276 -        /// \brief Assign arc to edge.
  79.277 -        ///
  79.278 -        /// Besides the core graph item functionality each arc should
  79.279 -        /// be convertible to the represented edge.
  79.280 -        Edge& operator=(const Arc&) { return *this; }
  79.281 -      };
  79.282 +     };
  79.283  
  79.284 -      /// \brief Returns the direction of the arc.
  79.285 +      /// \brief Return one end node of an edge.
  79.286 +      ///
  79.287 +      /// This function returns one end node of an edge.
  79.288 +      Node u(const Edge&) const { return INVALID; }
  79.289 +
  79.290 +      /// \brief Return the other end node of an edge.
  79.291 +      ///
  79.292 +      /// This function returns the other end node of an edge.
  79.293 +      Node v(const Edge&) const { return INVALID; }
  79.294 +
  79.295 +      /// \brief Return a directed arc related to an edge.
  79.296 +      ///
  79.297 +      /// This function returns a directed arc from its direction and the
  79.298 +      /// represented edge.
  79.299 +      Arc direct(const Edge&, bool) const { return INVALID; }
  79.300 +
  79.301 +      /// \brief Return a directed arc related to an edge.
  79.302 +      ///
  79.303 +      /// This function returns a directed arc from its source node and the
  79.304 +      /// represented edge.
  79.305 +      Arc direct(const Edge&, const Node&) const { return INVALID; }
  79.306 +
  79.307 +      /// \brief Return the direction of the arc.
  79.308        ///
  79.309        /// Returns the direction of the arc. Each arc represents an
  79.310        /// edge with a direction. It gives back the
  79.311        /// direction.
  79.312        bool direction(const Arc&) const { return true; }
  79.313  
  79.314 -      /// \brief Returns the directed arc.
  79.315 +      /// \brief Return the opposite arc.
  79.316        ///
  79.317 -      /// Returns the directed arc from its direction and the
  79.318 -      /// represented edge.
  79.319 -      Arc direct(const Edge&, bool) const { return INVALID;}
  79.320 -
  79.321 -      /// \brief Returns the directed arc.
  79.322 -      ///
  79.323 -      /// Returns the directed arc from its source and the
  79.324 -      /// represented edge.
  79.325 -      Arc direct(const Edge&, const Node&) const { return INVALID;}
  79.326 -
  79.327 -      /// \brief Returns the opposite arc.
  79.328 -      ///
  79.329 -      /// Returns the opposite arc. It is the arc representing the
  79.330 -      /// same edge and has opposite direction.
  79.331 -      Arc oppositeArc(const Arc&) const { return INVALID;}
  79.332 -
  79.333 -      /// \brief Gives back one ending of an edge.
  79.334 -      ///
  79.335 -      /// Gives back one ending of an edge.
  79.336 -      Node u(const Edge&) const { return INVALID;}
  79.337 -
  79.338 -      /// \brief Gives back the other ending of an edge.
  79.339 -      ///
  79.340 -      /// Gives back the other ending of an edge.
  79.341 -      Node v(const Edge&) const { return INVALID;}
  79.342 +      /// This function returns the opposite arc, i.e. the arc representing
  79.343 +      /// the same edge and has opposite direction.
  79.344 +      Arc oppositeArc(const Arc&) const { return INVALID; }
  79.345  
  79.346        template <typename _Graph>
  79.347        struct Constraints {
  79.348 @@ -269,7 +272,7 @@
  79.349  
  79.350          void constraints() {
  79.351            checkConcept<BaseDigraphComponent, _Graph>();
  79.352 -          checkConcept<GraphItem<'u'>, Edge>();
  79.353 +          checkConcept<GraphItem<'e'>, Edge>();
  79.354            {
  79.355              Node n;
  79.356              Edge ue(INVALID);
  79.357 @@ -277,6 +280,7 @@
  79.358              n = graph.u(ue);
  79.359              n = graph.v(ue);
  79.360              e = graph.direct(ue, true);
  79.361 +            e = graph.direct(ue, false);
  79.362              e = graph.direct(ue, n);
  79.363              e = graph.oppositeArc(e);
  79.364              ue = e;
  79.365 @@ -290,59 +294,57 @@
  79.366  
  79.367      };
  79.368  
  79.369 -    /// \brief An empty idable base digraph class.
  79.370 +    /// \brief Skeleton class for \e idable directed graphs.
  79.371      ///
  79.372 -    /// This class provides beside the core digraph features
  79.373 -    /// core id functions for the digraph structure.
  79.374 -    /// The most of the base digraphs should be conform to this concept.
  79.375 -    /// The id's are unique and immutable.
  79.376 -    template <typename _Base = BaseDigraphComponent>
  79.377 -    class IDableDigraphComponent : public _Base {
  79.378 +    /// This class describes the interface of \e idable directed graphs.
  79.379 +    /// It extends \ref BaseDigraphComponent with the core ID functions.
  79.380 +    /// The ids of the items must be unique and immutable.
  79.381 +    /// This concept is part of the Digraph concept.
  79.382 +    template <typename BAS = BaseDigraphComponent>
  79.383 +    class IDableDigraphComponent : public BAS {
  79.384      public:
  79.385  
  79.386 -      typedef _Base Base;
  79.387 +      typedef BAS Base;
  79.388        typedef typename Base::Node Node;
  79.389        typedef typename Base::Arc Arc;
  79.390  
  79.391 -      /// \brief Gives back an unique integer id for the Node.
  79.392 +      /// \brief Return a unique integer id for the given node.
  79.393        ///
  79.394 -      /// Gives back an unique integer id for the Node.
  79.395 +      /// This function returns a unique integer id for the given node.
  79.396 +      int id(const Node&) const { return -1; }
  79.397 +
  79.398 +      /// \brief Return the node by its unique id.
  79.399        ///
  79.400 -      int id(const Node&) const { return -1;}
  79.401 +      /// This function returns the node by its unique id.
  79.402 +      /// If the digraph does not contain a node with the given id,
  79.403 +      /// then the result of the function is undefined.
  79.404 +      Node nodeFromId(int) const { return INVALID; }
  79.405  
  79.406 -      /// \brief Gives back the node by the unique id.
  79.407 +      /// \brief Return a unique integer id for the given arc.
  79.408        ///
  79.409 -      /// Gives back the node by the unique id.
  79.410 -      /// If the digraph does not contain node with the given id
  79.411 -      /// then the result of the function is undetermined.
  79.412 -      Node nodeFromId(int) const { return INVALID;}
  79.413 +      /// This function returns a unique integer id for the given arc.
  79.414 +      int id(const Arc&) const { return -1; }
  79.415  
  79.416 -      /// \brief Gives back an unique integer id for the Arc.
  79.417 +      /// \brief Return the arc by its unique id.
  79.418        ///
  79.419 -      /// Gives back an unique integer id for the Arc.
  79.420 +      /// This function returns the arc by its unique id.
  79.421 +      /// If the digraph does not contain an arc with the given id,
  79.422 +      /// then the result of the function is undefined.
  79.423 +      Arc arcFromId(int) const { return INVALID; }
  79.424 +
  79.425 +      /// \brief Return an integer greater or equal to the maximum
  79.426 +      /// node id.
  79.427        ///
  79.428 -      int id(const Arc&) const { return -1;}
  79.429 +      /// This function returns an integer greater or equal to the
  79.430 +      /// maximum node id.
  79.431 +      int maxNodeId() const { return -1; }
  79.432  
  79.433 -      /// \brief Gives back the arc by the unique id.
  79.434 +      /// \brief Return an integer greater or equal to the maximum
  79.435 +      /// arc id.
  79.436        ///
  79.437 -      /// Gives back the arc by the unique id.
  79.438 -      /// If the digraph does not contain arc with the given id
  79.439 -      /// then the result of the function is undetermined.
  79.440 -      Arc arcFromId(int) const { return INVALID;}
  79.441 -
  79.442 -      /// \brief Gives back an integer greater or equal to the maximum
  79.443 -      /// Node id.
  79.444 -      ///
  79.445 -      /// Gives back an integer greater or equal to the maximum Node
  79.446 -      /// id.
  79.447 -      int maxNodeId() const { return -1;}
  79.448 -
  79.449 -      /// \brief Gives back an integer greater or equal to the maximum
  79.450 -      /// Arc id.
  79.451 -      ///
  79.452 -      /// Gives back an integer greater or equal to the maximum Arc
  79.453 -      /// id.
  79.454 -      int maxArcId() const { return -1;}
  79.455 +      /// This function returns an integer greater or equal to the
  79.456 +      /// maximum arc id.
  79.457 +      int maxArcId() const { return -1; }
  79.458  
  79.459        template <typename _Digraph>
  79.460        struct Constraints {
  79.461 @@ -350,10 +352,12 @@
  79.462          void constraints() {
  79.463            checkConcept<Base, _Digraph >();
  79.464            typename _Digraph::Node node;
  79.465 +          node=INVALID;
  79.466            int nid = digraph.id(node);
  79.467            nid = digraph.id(node);
  79.468            node = digraph.nodeFromId(nid);
  79.469            typename _Digraph::Arc arc;
  79.470 +          arc=INVALID;
  79.471            int eid = digraph.id(arc);
  79.472            eid = digraph.id(arc);
  79.473            arc = digraph.arcFromId(eid);
  79.474 @@ -368,46 +372,45 @@
  79.475        };
  79.476      };
  79.477  
  79.478 -    /// \brief An empty idable base undirected graph class.
  79.479 +    /// \brief Skeleton class for \e idable undirected graphs.
  79.480      ///
  79.481 -    /// This class provides beside the core undirected graph features
  79.482 -    /// core id functions for the undirected graph structure.  The
  79.483 -    /// most of the base undirected graphs should be conform to this
  79.484 -    /// concept.  The id's are unique and immutable.
  79.485 -    template <typename _Base = BaseGraphComponent>
  79.486 -    class IDableGraphComponent : public IDableDigraphComponent<_Base> {
  79.487 +    /// This class describes the interface of \e idable undirected
  79.488 +    /// graphs. It extends \ref IDableDigraphComponent with the core ID
  79.489 +    /// functions of undirected graphs.
  79.490 +    /// The ids of the items must be unique and immutable.
  79.491 +    /// This concept is part of the Graph concept.
  79.492 +    template <typename BAS = BaseGraphComponent>
  79.493 +    class IDableGraphComponent : public IDableDigraphComponent<BAS> {
  79.494      public:
  79.495  
  79.496 -      typedef _Base Base;
  79.497 +      typedef BAS Base;
  79.498        typedef typename Base::Edge Edge;
  79.499  
  79.500 -      using IDableDigraphComponent<_Base>::id;
  79.501 +      using IDableDigraphComponent<Base>::id;
  79.502  
  79.503 -      /// \brief Gives back an unique integer id for the Edge.
  79.504 +      /// \brief Return a unique integer id for the given edge.
  79.505        ///
  79.506 -      /// Gives back an unique integer id for the Edge.
  79.507 +      /// This function returns a unique integer id for the given edge.
  79.508 +      int id(const Edge&) const { return -1; }
  79.509 +
  79.510 +      /// \brief Return the edge by its unique id.
  79.511        ///
  79.512 -      int id(const Edge&) const { return -1;}
  79.513 +      /// This function returns the edge by its unique id.
  79.514 +      /// If the graph does not contain an edge with the given id,
  79.515 +      /// then the result of the function is undefined.
  79.516 +      Edge edgeFromId(int) const { return INVALID; }
  79.517  
  79.518 -      /// \brief Gives back the edge by the unique id.
  79.519 +      /// \brief Return an integer greater or equal to the maximum
  79.520 +      /// edge id.
  79.521        ///
  79.522 -      /// Gives back the edge by the unique id.  If the
  79.523 -      /// graph does not contain arc with the given id then the
  79.524 -      /// result of the function is undetermined.
  79.525 -      Edge edgeFromId(int) const { return INVALID;}
  79.526 -
  79.527 -      /// \brief Gives back an integer greater or equal to the maximum
  79.528 -      /// Edge id.
  79.529 -      ///
  79.530 -      /// Gives back an integer greater or equal to the maximum Edge
  79.531 -      /// id.
  79.532 -      int maxEdgeId() const { return -1;}
  79.533 +      /// This function returns an integer greater or equal to the
  79.534 +      /// maximum edge id.
  79.535 +      int maxEdgeId() const { return -1; }
  79.536  
  79.537        template <typename _Graph>
  79.538        struct Constraints {
  79.539  
  79.540          void constraints() {
  79.541 -          checkConcept<Base, _Graph >();
  79.542            checkConcept<IDableDigraphComponent<Base>, _Graph >();
  79.543            typename _Graph::Edge edge;
  79.544            int ueid = graph.id(edge);
  79.545 @@ -421,231 +424,243 @@
  79.546        };
  79.547      };
  79.548  
  79.549 -    /// \brief Skeleton class for graph NodeIt and ArcIt
  79.550 +    /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types.
  79.551      ///
  79.552 -    /// Skeleton class for graph NodeIt and ArcIt.
  79.553 -    ///
  79.554 -    template <typename _Graph, typename _Item>
  79.555 -    class GraphItemIt : public _Item {
  79.556 +    /// This class describes the concept of \c NodeIt, \c ArcIt and 
  79.557 +    /// \c EdgeIt subtypes of digraph and graph types.
  79.558 +    template <typename GR, typename Item>
  79.559 +    class GraphItemIt : public Item {
  79.560      public:
  79.561        /// \brief Default constructor.
  79.562        ///
  79.563 -      /// @warning The default constructor sets the iterator
  79.564 -      /// to an undefined value.
  79.565 +      /// Default constructor.
  79.566 +      /// \warning The default constructor is not required to set
  79.567 +      /// the iterator to some well-defined value. So you should consider it
  79.568 +      /// as uninitialized.
  79.569        GraphItemIt() {}
  79.570 +
  79.571        /// \brief Copy constructor.
  79.572        ///
  79.573        /// Copy constructor.
  79.574 +      GraphItemIt(const GraphItemIt& it) : Item(it) {}
  79.575 +
  79.576 +      /// \brief Constructor that sets the iterator to the first item.
  79.577        ///
  79.578 -      GraphItemIt(const GraphItemIt& ) {}
  79.579 -      /// \brief Sets the iterator to the first item.
  79.580 +      /// Constructor that sets the iterator to the first item.
  79.581 +      explicit GraphItemIt(const GR&) {}
  79.582 +
  79.583 +      /// \brief Constructor for conversion from \c INVALID.
  79.584        ///
  79.585 -      /// Sets the iterator to the first item of \c the graph.
  79.586 -      ///
  79.587 -      explicit GraphItemIt(const _Graph&) {}
  79.588 -      /// \brief Invalid constructor \& conversion.
  79.589 -      ///
  79.590 -      /// This constructor initializes the item to be invalid.
  79.591 +      /// Constructor for conversion from \c INVALID.
  79.592 +      /// It initializes the iterator to be invalid.
  79.593        /// \sa Invalid for more details.
  79.594        GraphItemIt(Invalid) {}
  79.595 -      /// \brief Assign operator for items.
  79.596 +
  79.597 +      /// \brief Assignment operator.
  79.598        ///
  79.599 -      /// The items are assignable.
  79.600 +      /// Assignment operator for the iterator.
  79.601 +      GraphItemIt& operator=(const GraphItemIt&) { return *this; }
  79.602 +
  79.603 +      /// \brief Increment the iterator.
  79.604        ///
  79.605 -      GraphItemIt& operator=(const GraphItemIt&) { return *this; }
  79.606 -      /// \brief Next item.
  79.607 -      ///
  79.608 -      /// Assign the iterator to the next item.
  79.609 -      ///
  79.610 +      /// This operator increments the iterator, i.e. assigns it to the
  79.611 +      /// next item.
  79.612        GraphItemIt& operator++() { return *this; }
  79.613 + 
  79.614        /// \brief Equality operator
  79.615        ///
  79.616 +      /// Equality operator.
  79.617        /// Two iterators are equal if and only if they point to the
  79.618        /// same object or both are invalid.
  79.619        bool operator==(const GraphItemIt&) const { return true;}
  79.620 +
  79.621        /// \brief Inequality operator
  79.622        ///
  79.623 -      /// \sa operator==(Node n)
  79.624 -      ///
  79.625 +      /// Inequality operator.
  79.626 +      /// Two iterators are equal if and only if they point to the
  79.627 +      /// same object or both are invalid.
  79.628        bool operator!=(const GraphItemIt&) const { return true;}
  79.629  
  79.630        template<typename _GraphItemIt>
  79.631        struct Constraints {
  79.632          void constraints() {
  79.633 +          checkConcept<GraphItem<>, _GraphItemIt>();
  79.634            _GraphItemIt it1(g);
  79.635            _GraphItemIt it2;
  79.636 +          _GraphItemIt it3 = it1;
  79.637 +          _GraphItemIt it4 = INVALID;
  79.638  
  79.639            it2 = ++it1;
  79.640            ++it2 = it1;
  79.641            ++(++it1);
  79.642  
  79.643 -          _Item bi = it1;
  79.644 +          Item bi = it1;
  79.645            bi = it2;
  79.646          }
  79.647 -        _Graph& g;
  79.648 +        const GR& g;
  79.649        };
  79.650      };
  79.651  
  79.652 -    /// \brief Skeleton class for graph InArcIt and OutArcIt
  79.653 +    /// \brief Concept class for \c InArcIt, \c OutArcIt and 
  79.654 +    /// \c IncEdgeIt types.
  79.655      ///
  79.656 -    /// \note Because InArcIt and OutArcIt may not inherit from the same
  79.657 -    /// base class, the _selector is a additional template parameter. For
  79.658 -    /// InArcIt you should instantiate it with character 'i' and for
  79.659 -    /// OutArcIt with 'o'.
  79.660 -    template <typename _Graph,
  79.661 -              typename _Item = typename _Graph::Arc,
  79.662 -              typename _Base = typename _Graph::Node,
  79.663 -              char _selector = '0'>
  79.664 -    class GraphIncIt : public _Item {
  79.665 +    /// This class describes the concept of \c InArcIt, \c OutArcIt 
  79.666 +    /// and \c IncEdgeIt subtypes of digraph and graph types.
  79.667 +    ///
  79.668 +    /// \note Since these iterator classes do not inherit from the same
  79.669 +    /// base class, there is an additional template parameter (selector)
  79.670 +    /// \c sel. For \c InArcIt you should instantiate it with character 
  79.671 +    /// \c 'i', for \c OutArcIt with \c 'o' and for \c IncEdgeIt with \c 'e'.
  79.672 +    template <typename GR,
  79.673 +              typename Item = typename GR::Arc,
  79.674 +              typename Base = typename GR::Node,
  79.675 +              char sel = '0'>
  79.676 +    class GraphIncIt : public Item {
  79.677      public:
  79.678        /// \brief Default constructor.
  79.679        ///
  79.680 -      /// @warning The default constructor sets the iterator
  79.681 -      /// to an undefined value.
  79.682 +      /// Default constructor.
  79.683 +      /// \warning The default constructor is not required to set
  79.684 +      /// the iterator to some well-defined value. So you should consider it
  79.685 +      /// as uninitialized.
  79.686        GraphIncIt() {}
  79.687 +
  79.688        /// \brief Copy constructor.
  79.689        ///
  79.690        /// Copy constructor.
  79.691 +      GraphIncIt(const GraphIncIt& it) : Item(it) {}
  79.692 +
  79.693 +      /// \brief Constructor that sets the iterator to the first 
  79.694 +      /// incoming or outgoing arc.
  79.695        ///
  79.696 -      GraphIncIt(GraphIncIt const& gi) : _Item(gi) {}
  79.697 -      /// \brief Sets the iterator to the first arc incoming into or outgoing
  79.698 -      /// from the node.
  79.699 +      /// Constructor that sets the iterator to the first arc 
  79.700 +      /// incoming to or outgoing from the given node.
  79.701 +      explicit GraphIncIt(const GR&, const Base&) {}
  79.702 +
  79.703 +      /// \brief Constructor for conversion from \c INVALID.
  79.704        ///
  79.705 -      /// Sets the iterator to the first arc incoming into or outgoing
  79.706 -      /// from the node.
  79.707 -      ///
  79.708 -      explicit GraphIncIt(const _Graph&, const _Base&) {}
  79.709 -      /// \brief Invalid constructor \& conversion.
  79.710 -      ///
  79.711 -      /// This constructor initializes the item to be invalid.
  79.712 +      /// Constructor for conversion from \c INVALID.
  79.713 +      /// It initializes the iterator to be invalid.
  79.714        /// \sa Invalid for more details.
  79.715        GraphIncIt(Invalid) {}
  79.716 -      /// \brief Assign operator for iterators.
  79.717 +
  79.718 +      /// \brief Assignment operator.
  79.719        ///
  79.720 -      /// The iterators are assignable.
  79.721 +      /// Assignment operator for the iterator.
  79.722 +      GraphIncIt& operator=(const GraphIncIt&) { return *this; }
  79.723 +
  79.724 +      /// \brief Increment the iterator.
  79.725        ///
  79.726 -      GraphIncIt& operator=(GraphIncIt const&) { return *this; }
  79.727 -      /// \brief Next item.
  79.728 -      ///
  79.729 -      /// Assign the iterator to the next item.
  79.730 -      ///
  79.731 +      /// This operator increments the iterator, i.e. assigns it to the
  79.732 +      /// next arc incoming to or outgoing from the given node.
  79.733        GraphIncIt& operator++() { return *this; }
  79.734  
  79.735        /// \brief Equality operator
  79.736        ///
  79.737 +      /// Equality operator.
  79.738        /// Two iterators are equal if and only if they point to the
  79.739        /// same object or both are invalid.
  79.740        bool operator==(const GraphIncIt&) const { return true;}
  79.741  
  79.742        /// \brief Inequality operator
  79.743        ///
  79.744 -      /// \sa operator==(Node n)
  79.745 -      ///
  79.746 +      /// Inequality operator.
  79.747 +      /// Two iterators are equal if and only if they point to the
  79.748 +      /// same object or both are invalid.
  79.749        bool operator!=(const GraphIncIt&) const { return true;}
  79.750  
  79.751        template <typename _GraphIncIt>
  79.752        struct Constraints {
  79.753          void constraints() {
  79.754 -          checkConcept<GraphItem<_selector>, _GraphIncIt>();
  79.755 +          checkConcept<GraphItem<sel>, _GraphIncIt>();
  79.756            _GraphIncIt it1(graph, node);
  79.757            _GraphIncIt it2;
  79.758 +          _GraphIncIt it3 = it1;
  79.759 +          _GraphIncIt it4 = INVALID;
  79.760  
  79.761            it2 = ++it1;
  79.762            ++it2 = it1;
  79.763            ++(++it1);
  79.764 -          _Item e = it1;
  79.765 +          Item e = it1;
  79.766            e = it2;
  79.767 -
  79.768          }
  79.769 -
  79.770 -        _Item arc;
  79.771 -        _Base node;
  79.772 -        _Graph graph;
  79.773 -        _GraphIncIt it;
  79.774 +        const Base& node;
  79.775 +        const GR& graph;
  79.776        };
  79.777      };
  79.778  
  79.779 -
  79.780 -    /// \brief An empty iterable digraph class.
  79.781 +    /// \brief Skeleton class for iterable directed graphs.
  79.782      ///
  79.783 -    /// This class provides beside the core digraph features
  79.784 -    /// iterator based iterable interface for the digraph structure.
  79.785 +    /// This class describes the interface of iterable directed
  79.786 +    /// graphs. It extends \ref BaseDigraphComponent with the core
  79.787 +    /// iterable interface.
  79.788      /// This concept is part of the Digraph concept.
  79.789 -    template <typename _Base = BaseDigraphComponent>
  79.790 -    class IterableDigraphComponent : public _Base {
  79.791 +    template <typename BAS = BaseDigraphComponent>
  79.792 +    class IterableDigraphComponent : public BAS {
  79.793  
  79.794      public:
  79.795  
  79.796 -      typedef _Base Base;
  79.797 +      typedef BAS Base;
  79.798        typedef typename Base::Node Node;
  79.799        typedef typename Base::Arc Arc;
  79.800  
  79.801        typedef IterableDigraphComponent Digraph;
  79.802  
  79.803 -      /// \name Base iteration
  79.804 +      /// \name Base Iteration
  79.805        ///
  79.806 -      /// This interface provides functions for iteration on digraph items
  79.807 +      /// This interface provides functions for iteration on digraph items.
  79.808        ///
  79.809        /// @{
  79.810  
  79.811 -      /// \brief Gives back the first node in the iterating order.
  79.812 +      /// \brief Return the first node.
  79.813        ///
  79.814 -      /// Gives back the first node in the iterating order.
  79.815 -      ///
  79.816 +      /// This function gives back the first node in the iteration order.
  79.817        void first(Node&) const {}
  79.818  
  79.819 -      /// \brief Gives back the next node in the iterating order.
  79.820 +      /// \brief Return the next node.
  79.821        ///
  79.822 -      /// Gives back the next node in the iterating order.
  79.823 -      ///
  79.824 +      /// This function gives back the next node in the iteration order.
  79.825        void next(Node&) const {}
  79.826  
  79.827 -      /// \brief Gives back the first arc in the iterating order.
  79.828 +      /// \brief Return the first arc.
  79.829        ///
  79.830 -      /// Gives back the first arc in the iterating order.
  79.831 -      ///
  79.832 +      /// This function gives back the first arc in the iteration order.
  79.833        void first(Arc&) const {}
  79.834  
  79.835 -      /// \brief Gives back the next arc in the iterating order.
  79.836 +      /// \brief Return the next arc.
  79.837        ///
  79.838 -      /// Gives back the next arc in the iterating order.
  79.839 -      ///
  79.840 +      /// This function gives back the next arc in the iteration order.
  79.841        void next(Arc&) const {}
  79.842  
  79.843 -
  79.844 -      /// \brief Gives back the first of the arcs point to the given
  79.845 -      /// node.
  79.846 +      /// \brief Return the first arc incomming to the given node.
  79.847        ///
  79.848 -      /// Gives back the first of the arcs point to the given node.
  79.849 -      ///
  79.850 +      /// This function gives back the first arc incomming to the
  79.851 +      /// given node.
  79.852        void firstIn(Arc&, const Node&) const {}
  79.853  
  79.854 -      /// \brief Gives back the next of the arcs points to the given
  79.855 -      /// node.
  79.856 +      /// \brief Return the next arc incomming to the given node.
  79.857        ///
  79.858 -      /// Gives back the next of the arcs points to the given node.
  79.859 -      ///
  79.860 +      /// This function gives back the next arc incomming to the
  79.861 +      /// given node.
  79.862        void nextIn(Arc&) const {}
  79.863  
  79.864 -      /// \brief Gives back the first of the arcs start from the
  79.865 +      /// \brief Return the first arc outgoing form the given node.
  79.866 +      ///
  79.867 +      /// This function gives back the first arc outgoing form the
  79.868        /// given node.
  79.869 -      ///
  79.870 -      /// Gives back the first of the arcs start from the given node.
  79.871 -      ///
  79.872        void firstOut(Arc&, const Node&) const {}
  79.873  
  79.874 -      /// \brief Gives back the next of the arcs start from the given
  79.875 -      /// node.
  79.876 +      /// \brief Return the next arc outgoing form the given node.
  79.877        ///
  79.878 -      /// Gives back the next of the arcs start from the given node.
  79.879 -      ///
  79.880 +      /// This function gives back the next arc outgoing form the
  79.881 +      /// given node.
  79.882        void nextOut(Arc&) const {}
  79.883  
  79.884        /// @}
  79.885  
  79.886 -      /// \name Class based iteration
  79.887 +      /// \name Class Based Iteration
  79.888        ///
  79.889 -      /// This interface provides functions for iteration on digraph items
  79.890 +      /// This interface provides iterator classes for digraph items.
  79.891        ///
  79.892        /// @{
  79.893  
  79.894 @@ -655,15 +670,15 @@
  79.895        ///
  79.896        typedef GraphItemIt<Digraph, Node> NodeIt;
  79.897  
  79.898 -      /// \brief This iterator goes through each node.
  79.899 +      /// \brief This iterator goes through each arc.
  79.900        ///
  79.901 -      /// This iterator goes through each node.
  79.902 +      /// This iterator goes through each arc.
  79.903        ///
  79.904        typedef GraphItemIt<Digraph, Arc> ArcIt;
  79.905  
  79.906        /// \brief This iterator goes trough the incoming arcs of a node.
  79.907        ///
  79.908 -      /// This iterator goes trough the \e inccoming arcs of a certain node
  79.909 +      /// This iterator goes trough the \e incoming arcs of a certain node
  79.910        /// of a digraph.
  79.911        typedef GraphIncIt<Digraph, Arc, Node, 'i'> InArcIt;
  79.912  
  79.913 @@ -675,26 +690,26 @@
  79.914  
  79.915        /// \brief The base node of the iterator.
  79.916        ///
  79.917 -      /// Gives back the base node of the iterator.
  79.918 -      /// It is always the target of the pointed arc.
  79.919 +      /// This function gives back the base node of the iterator.
  79.920 +      /// It is always the target node of the pointed arc.
  79.921        Node baseNode(const InArcIt&) const { return INVALID; }
  79.922  
  79.923        /// \brief The running node of the iterator.
  79.924        ///
  79.925 -      /// Gives back the running node of the iterator.
  79.926 -      /// It is always the source of the pointed arc.
  79.927 +      /// This function gives back the running node of the iterator.
  79.928 +      /// It is always the source node of the pointed arc.
  79.929        Node runningNode(const InArcIt&) const { return INVALID; }
  79.930  
  79.931        /// \brief The base node of the iterator.
  79.932        ///
  79.933 -      /// Gives back the base node of the iterator.
  79.934 -      /// It is always the source of the pointed arc.
  79.935 +      /// This function gives back the base node of the iterator.
  79.936 +      /// It is always the source node of the pointed arc.
  79.937        Node baseNode(const OutArcIt&) const { return INVALID; }
  79.938  
  79.939        /// \brief The running node of the iterator.
  79.940        ///
  79.941 -      /// Gives back the running node of the iterator.
  79.942 -      /// It is always the target of the pointed arc.
  79.943 +      /// This function gives back the running node of the iterator.
  79.944 +      /// It is always the target node of the pointed arc.
  79.945        Node runningNode(const OutArcIt&) const { return INVALID; }
  79.946  
  79.947        /// @}
  79.948 @@ -736,31 +751,31 @@
  79.949                typename _Digraph::Node, 'o'>, typename _Digraph::OutArcIt>();
  79.950  
  79.951              typename _Digraph::Node n;
  79.952 -            typename _Digraph::InArcIt ieit(INVALID);
  79.953 -            typename _Digraph::OutArcIt oeit(INVALID);
  79.954 -            n = digraph.baseNode(ieit);
  79.955 -            n = digraph.runningNode(ieit);
  79.956 -            n = digraph.baseNode(oeit);
  79.957 -            n = digraph.runningNode(oeit);
  79.958 +            const typename _Digraph::InArcIt iait(INVALID);
  79.959 +            const typename _Digraph::OutArcIt oait(INVALID);
  79.960 +            n = digraph.baseNode(iait);
  79.961 +            n = digraph.runningNode(iait);
  79.962 +            n = digraph.baseNode(oait);
  79.963 +            n = digraph.runningNode(oait);
  79.964              ignore_unused_variable_warning(n);
  79.965            }
  79.966          }
  79.967  
  79.968          const _Digraph& digraph;
  79.969 -
  79.970        };
  79.971      };
  79.972  
  79.973 -    /// \brief An empty iterable undirected graph class.
  79.974 +    /// \brief Skeleton class for iterable undirected graphs.
  79.975      ///
  79.976 -    /// This class provides beside the core graph features iterator
  79.977 -    /// based iterable interface for the undirected graph structure.
  79.978 +    /// This class describes the interface of iterable undirected
  79.979 +    /// graphs. It extends \ref IterableDigraphComponent with the core
  79.980 +    /// iterable interface of undirected graphs.
  79.981      /// This concept is part of the Graph concept.
  79.982 -    template <typename _Base = BaseGraphComponent>
  79.983 -    class IterableGraphComponent : public IterableDigraphComponent<_Base> {
  79.984 +    template <typename BAS = BaseGraphComponent>
  79.985 +    class IterableGraphComponent : public IterableDigraphComponent<BAS> {
  79.986      public:
  79.987  
  79.988 -      typedef _Base Base;
  79.989 +      typedef BAS Base;
  79.990        typedef typename Base::Node Node;
  79.991        typedef typename Base::Arc Arc;
  79.992        typedef typename Base::Edge Edge;
  79.993 @@ -768,75 +783,71 @@
  79.994  
  79.995        typedef IterableGraphComponent Graph;
  79.996  
  79.997 -      /// \name Base iteration
  79.998 +      /// \name Base Iteration
  79.999        ///
 79.1000 -      /// This interface provides functions for iteration on graph items
 79.1001 +      /// This interface provides functions for iteration on edges.
 79.1002 +      ///
 79.1003        /// @{
 79.1004  
 79.1005 -      using IterableDigraphComponent<_Base>::first;
 79.1006 -      using IterableDigraphComponent<_Base>::next;
 79.1007 +      using IterableDigraphComponent<Base>::first;
 79.1008 +      using IterableDigraphComponent<Base>::next;
 79.1009  
 79.1010 -      /// \brief Gives back the first edge in the iterating
 79.1011 -      /// order.
 79.1012 +      /// \brief Return the first edge.
 79.1013        ///
 79.1014 -      /// Gives back the first edge in the iterating order.
 79.1015 -      ///
 79.1016 +      /// This function gives back the first edge in the iteration order.
 79.1017        void first(Edge&) const {}
 79.1018  
 79.1019 -      /// \brief Gives back the next edge in the iterating
 79.1020 -      /// order.
 79.1021 +      /// \brief Return the next edge.
 79.1022        ///
 79.1023 -      /// Gives back the next edge in the iterating order.
 79.1024 -      ///
 79.1025 +      /// This function gives back the next edge in the iteration order.
 79.1026        void next(Edge&) const {}
 79.1027  
 79.1028 -
 79.1029 -      /// \brief Gives back the first of the edges from the
 79.1030 +      /// \brief Return the first edge incident to the given node.
 79.1031 +      ///
 79.1032 +      /// This function gives back the first edge incident to the given 
 79.1033 +      /// node. The bool parameter gives back the direction for which the
 79.1034 +      /// source node of the directed arc representing the edge is the 
 79.1035        /// given node.
 79.1036 -      ///
 79.1037 -      /// Gives back the first of the edges from the given
 79.1038 -      /// node. The bool parameter gives back that direction which
 79.1039 -      /// gives a good direction of the edge so the source of the
 79.1040 -      /// directed arc is the given node.
 79.1041        void firstInc(Edge&, bool&, const Node&) const {}
 79.1042  
 79.1043        /// \brief Gives back the next of the edges from the
 79.1044        /// given node.
 79.1045        ///
 79.1046 -      /// Gives back the next of the edges from the given
 79.1047 -      /// node. The bool parameter should be used as the \c firstInc()
 79.1048 -      /// use it.
 79.1049 +      /// This function gives back the next edge incident to the given 
 79.1050 +      /// node. The bool parameter should be used as \c firstInc() use it.
 79.1051        void nextInc(Edge&, bool&) const {}
 79.1052  
 79.1053 -      using IterableDigraphComponent<_Base>::baseNode;
 79.1054 -      using IterableDigraphComponent<_Base>::runningNode;
 79.1055 +      using IterableDigraphComponent<Base>::baseNode;
 79.1056 +      using IterableDigraphComponent<Base>::runningNode;
 79.1057  
 79.1058        /// @}
 79.1059  
 79.1060 -      /// \name Class based iteration
 79.1061 +      /// \name Class Based Iteration
 79.1062        ///
 79.1063 -      /// This interface provides functions for iteration on graph items
 79.1064 +      /// This interface provides iterator classes for edges.
 79.1065        ///
 79.1066        /// @{
 79.1067  
 79.1068 -      /// \brief This iterator goes through each node.
 79.1069 +      /// \brief This iterator goes through each edge.
 79.1070        ///
 79.1071 -      /// This iterator goes through each node.
 79.1072 +      /// This iterator goes through each edge.
 79.1073        typedef GraphItemIt<Graph, Edge> EdgeIt;
 79.1074 -      /// \brief This iterator goes trough the incident arcs of a
 79.1075 +
 79.1076 +      /// \brief This iterator goes trough the incident edges of a
 79.1077        /// node.
 79.1078        ///
 79.1079 -      /// This iterator goes trough the incident arcs of a certain
 79.1080 +      /// This iterator goes trough the incident edges of a certain
 79.1081        /// node of a graph.
 79.1082 -      typedef GraphIncIt<Graph, Edge, Node, 'u'> IncEdgeIt;
 79.1083 +      typedef GraphIncIt<Graph, Edge, Node, 'e'> IncEdgeIt;
 79.1084 +
 79.1085        /// \brief The base node of the iterator.
 79.1086        ///
 79.1087 -      /// Gives back the base node of the iterator.
 79.1088 +      /// This function gives back the base node of the iterator.
 79.1089        Node baseNode(const IncEdgeIt&) const { return INVALID; }
 79.1090  
 79.1091        /// \brief The running node of the iterator.
 79.1092        ///
 79.1093 -      /// Gives back the running node of the iterator.
 79.1094 +      /// This function gives back the running node of the iterator.
 79.1095        Node runningNode(const IncEdgeIt&) const { return INVALID; }
 79.1096  
 79.1097        /// @}
 79.1098 @@ -865,54 +876,54 @@
 79.1099              checkConcept<GraphItemIt<_Graph, typename _Graph::Edge>,
 79.1100                typename _Graph::EdgeIt >();
 79.1101              checkConcept<GraphIncIt<_Graph, typename _Graph::Edge,
 79.1102 -              typename _Graph::Node, 'u'>, typename _Graph::IncEdgeIt>();
 79.1103 +              typename _Graph::Node, 'e'>, typename _Graph::IncEdgeIt>();
 79.1104  
 79.1105              typename _Graph::Node n;
 79.1106 -            typename _Graph::IncEdgeIt ueit(INVALID);
 79.1107 -            n = graph.baseNode(ueit);
 79.1108 -            n = graph.runningNode(ueit);
 79.1109 +            const typename _Graph::IncEdgeIt ieit(INVALID);
 79.1110 +            n = graph.baseNode(ieit);
 79.1111 +            n = graph.runningNode(ieit);
 79.1112            }
 79.1113          }
 79.1114  
 79.1115          const _Graph& graph;
 79.1116 -
 79.1117        };
 79.1118      };
 79.1119  
 79.1120 -    /// \brief An empty alteration notifier digraph class.
 79.1121 +    /// \brief Skeleton class for alterable directed graphs.
 79.1122      ///
 79.1123 -    /// This class provides beside the core digraph features alteration
 79.1124 -    /// notifier interface for the digraph structure.  This implements
 79.1125 +    /// This class describes the interface of alterable directed
 79.1126 +    /// graphs. It extends \ref BaseDigraphComponent with the alteration
 79.1127 +    /// notifier interface. It implements
 79.1128      /// an observer-notifier pattern for each digraph item. More
 79.1129      /// obsevers can be registered into the notifier and whenever an
 79.1130 -    /// alteration occured in the digraph all the observers will
 79.1131 +    /// alteration occured in the digraph all the observers will be
 79.1132      /// notified about it.
 79.1133 -    template <typename _Base = BaseDigraphComponent>
 79.1134 -    class AlterableDigraphComponent : public _Base {
 79.1135 +    template <typename BAS = BaseDigraphComponent>
 79.1136 +    class AlterableDigraphComponent : public BAS {
 79.1137      public:
 79.1138  
 79.1139 -      typedef _Base Base;
 79.1140 +      typedef BAS Base;
 79.1141        typedef typename Base::Node Node;
 79.1142        typedef typename Base::Arc Arc;
 79.1143  
 79.1144  
 79.1145 -      /// The node observer registry.
 79.1146 +      /// Node alteration notifier class.
 79.1147        typedef AlterationNotifier<AlterableDigraphComponent, Node>
 79.1148        NodeNotifier;
 79.1149 -      /// The arc observer registry.
 79.1150 +      /// Arc alteration notifier class.
 79.1151        typedef AlterationNotifier<AlterableDigraphComponent, Arc>
 79.1152        ArcNotifier;
 79.1153  
 79.1154 -      /// \brief Gives back the node alteration notifier.
 79.1155 +      /// \brief Return the node alteration notifier.
 79.1156        ///
 79.1157 -      /// Gives back the node alteration notifier.
 79.1158 +      /// This function gives back the node alteration notifier.
 79.1159        NodeNotifier& notifier(Node) const {
 79.1160 -        return NodeNotifier();
 79.1161 +         return NodeNotifier();
 79.1162        }
 79.1163  
 79.1164 -      /// \brief Gives back the arc alteration notifier.
 79.1165 +      /// \brief Return the arc alteration notifier.
 79.1166        ///
 79.1167 -      /// Gives back the arc alteration notifier.
 79.1168 +      /// This function gives back the arc alteration notifier.
 79.1169        ArcNotifier& notifier(Arc) const {
 79.1170          return ArcNotifier();
 79.1171        }
 79.1172 @@ -932,34 +943,33 @@
 79.1173          }
 79.1174  
 79.1175          const _Digraph& digraph;
 79.1176 -
 79.1177        };
 79.1178 -
 79.1179      };
 79.1180  
 79.1181 -    /// \brief An empty alteration notifier undirected graph class.
 79.1182 +    /// \brief Skeleton class for alterable undirected graphs.
 79.1183      ///
 79.1184 -    /// This class provides beside the core graph features alteration
 79.1185 -    /// notifier interface for the graph structure.  This implements
 79.1186 -    /// an observer-notifier pattern for each graph item. More
 79.1187 +    /// This class describes the interface of alterable undirected
 79.1188 +    /// graphs. It extends \ref AlterableDigraphComponent with the alteration
 79.1189 +    /// notifier interface of undirected graphs. It implements
 79.1190 +    /// an observer-notifier pattern for the edges. More
 79.1191      /// obsevers can be registered into the notifier and whenever an
 79.1192 -    /// alteration occured in the graph all the observers will
 79.1193 +    /// alteration occured in the graph all the observers will be
 79.1194      /// notified about it.
 79.1195 -    template <typename _Base = BaseGraphComponent>
 79.1196 -    class AlterableGraphComponent : public AlterableDigraphComponent<_Base> {
 79.1197 +    template <typename BAS = BaseGraphComponent>
 79.1198 +    class AlterableGraphComponent : public AlterableDigraphComponent<BAS> {
 79.1199      public:
 79.1200  
 79.1201 -      typedef _Base Base;
 79.1202 +      typedef BAS Base;
 79.1203        typedef typename Base::Edge Edge;
 79.1204  
 79.1205  
 79.1206 -      /// The arc observer registry.
 79.1207 +      /// Edge alteration notifier class.
 79.1208        typedef AlterationNotifier<AlterableGraphComponent, Edge>
 79.1209        EdgeNotifier;
 79.1210  
 79.1211 -      /// \brief Gives back the arc alteration notifier.
 79.1212 +      /// \brief Return the edge alteration notifier.
 79.1213        ///
 79.1214 -      /// Gives back the arc alteration notifier.
 79.1215 +      /// This function gives back the edge alteration notifier.
 79.1216        EdgeNotifier& notifier(Edge) const {
 79.1217          return EdgeNotifier();
 79.1218        }
 79.1219 @@ -967,44 +977,48 @@
 79.1220        template <typename _Graph>
 79.1221        struct Constraints {
 79.1222          void constraints() {
 79.1223 -          checkConcept<AlterableGraphComponent<Base>, _Graph>();
 79.1224 +          checkConcept<AlterableDigraphComponent<Base>, _Graph>();
 79.1225            typename _Graph::EdgeNotifier& uen
 79.1226              = graph.notifier(typename _Graph::Edge());
 79.1227            ignore_unused_variable_warning(uen);
 79.1228          }
 79.1229  
 79.1230          const _Graph& graph;
 79.1231 -
 79.1232        };
 79.1233 -
 79.1234      };
 79.1235  
 79.1236 -    /// \brief Class describing the concept of graph maps
 79.1237 +    /// \brief Concept class for standard graph maps.
 79.1238      ///
 79.1239 -    /// This class describes the common interface of the graph maps
 79.1240 -    /// (NodeMap, ArcMap), that is maps that can be used to
 79.1241 -    /// associate data to graph descriptors (nodes or arcs).
 79.1242 -    template <typename _Graph, typename _Item, typename _Value>
 79.1243 -    class GraphMap : public ReadWriteMap<_Item, _Value> {
 79.1244 +    /// This class describes the concept of standard graph maps, i.e.
 79.1245 +    /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and 
 79.1246 +    /// graph types, which can be used for associating data to graph items.
 79.1247 +    /// The standard graph maps must conform to the ReferenceMap concept.
 79.1248 +    template <typename GR, typename K, typename V>
 79.1249 +    class GraphMap : public ReferenceMap<K, V, V&, const V&> {
 79.1250 +      typedef ReferenceMap<K, V, V&, const V&> Parent;
 79.1251 +
 79.1252      public:
 79.1253  
 79.1254 -      typedef ReadWriteMap<_Item, _Value> Parent;
 79.1255 +      /// The key type of the map.
 79.1256 +      typedef K Key;
 79.1257 +      /// The value type of the map.
 79.1258 +      typedef V Value;
 79.1259 +      /// The reference type of the map.
 79.1260 +      typedef Value& Reference;
 79.1261 +      /// The const reference type of the map.
 79.1262 +      typedef const Value& ConstReference;
 79.1263  
 79.1264 -      /// The graph type of the map.
 79.1265 -      typedef _Graph Graph;
 79.1266 -      /// The key type of the map.
 79.1267 -      typedef _Item Key;
 79.1268 -      /// The value type of the map.
 79.1269 -      typedef _Value Value;
 79.1270 +      // The reference map tag.
 79.1271 +      typedef True ReferenceMapTag;
 79.1272  
 79.1273        /// \brief Construct a new map.
 79.1274        ///
 79.1275        /// Construct a new map for the graph.
 79.1276 -      explicit GraphMap(const Graph&) {}
 79.1277 +      explicit GraphMap(const GR&) {}
 79.1278        /// \brief Construct a new map with default value.
 79.1279        ///
 79.1280 -      /// Construct a new map for the graph and initalise the values.
 79.1281 -      GraphMap(const Graph&, const Value&) {}
 79.1282 +      /// Construct a new map for the graph and initalize the values.
 79.1283 +      GraphMap(const GR&, const Value&) {}
 79.1284  
 79.1285      private:
 79.1286        /// \brief Copy constructor.
 79.1287 @@ -1012,9 +1026,9 @@
 79.1288        /// Copy Constructor.
 79.1289        GraphMap(const GraphMap&) : Parent() {}
 79.1290  
 79.1291 -      /// \brief Assign operator.
 79.1292 +      /// \brief Assignment operator.
 79.1293        ///
 79.1294 -      /// Assign operator. It does not mofify the underlying graph,
 79.1295 +      /// Assignment operator. It does not mofify the underlying graph,
 79.1296        /// it just iterates on the current item set and set the  map
 79.1297        /// with the value returned by the assigned map.
 79.1298        template <typename CMap>
 79.1299 @@ -1027,53 +1041,55 @@
 79.1300        template<typename _Map>
 79.1301        struct Constraints {
 79.1302          void constraints() {
 79.1303 -          checkConcept<ReadWriteMap<Key, Value>, _Map >();
 79.1304 -          // Construction with a graph parameter
 79.1305 -          _Map a(g);
 79.1306 -          // Constructor with a graph and a default value parameter
 79.1307 -          _Map a2(g,t);
 79.1308 -          // Copy constructor.
 79.1309 -          // _Map b(c);
 79.1310 +          checkConcept
 79.1311 +            <ReferenceMap<Key, Value, Value&, const Value&>, _Map>();
 79.1312 +          _Map m1(g);
 79.1313 +          _Map m2(g,t);
 79.1314 +          
 79.1315 +          // Copy constructor
 79.1316 +          // _Map m3(m);
 79.1317  
 79.1318 +          // Assignment operator
 79.1319            // ReadMap<Key, Value> cmap;
 79.1320 -          // b = cmap;
 79.1321 +          // m3 = cmap;
 79.1322  
 79.1323 -          ignore_unused_variable_warning(a);
 79.1324 -          ignore_unused_variable_warning(a2);
 79.1325 -          // ignore_unused_variable_warning(b);
 79.1326 +          ignore_unused_variable_warning(m1);
 79.1327 +          ignore_unused_variable_warning(m2);
 79.1328 +          // ignore_unused_variable_warning(m3);
 79.1329          }
 79.1330  
 79.1331 -        const _Map &c;
 79.1332 -        const Graph &g;
 79.1333 +        const _Map &m;
 79.1334 +        const GR &g;
 79.1335          const typename GraphMap::Value &t;
 79.1336        };
 79.1337  
 79.1338      };
 79.1339  
 79.1340 -    /// \brief An empty mappable digraph class.
 79.1341 +    /// \brief Skeleton class for mappable directed graphs.
 79.1342      ///
 79.1343 -    /// This class provides beside the core digraph features
 79.1344 -    /// map interface for the digraph structure.
 79.1345 +    /// This class describes the interface of mappable directed graphs.
 79.1346 +    /// It extends \ref BaseDigraphComponent with the standard digraph 
 79.1347 +    /// map classes, namely \c NodeMap and \c ArcMap.
 79.1348      /// This concept is part of the Digraph concept.
 79.1349 -    template <typename _Base = BaseDigraphComponent>
 79.1350 -    class MappableDigraphComponent : public _Base  {
 79.1351 +    template <typename BAS = BaseDigraphComponent>
 79.1352 +    class MappableDigraphComponent : public BAS  {
 79.1353      public:
 79.1354  
 79.1355 -      typedef _Base Base;
 79.1356 +      typedef BAS Base;
 79.1357        typedef typename Base::Node Node;
 79.1358        typedef typename Base::Arc Arc;
 79.1359  
 79.1360        typedef MappableDigraphComponent Digraph;
 79.1361  
 79.1362 -      /// \brief ReadWrite map of the nodes.
 79.1363 +      /// \brief Standard graph map for the nodes.
 79.1364        ///
 79.1365 -      /// ReadWrite map of the nodes.
 79.1366 -      ///
 79.1367 -      template <typename _Value>
 79.1368 -      class NodeMap : public GraphMap<Digraph, Node, _Value> {
 79.1369 +      /// Standard graph map for the nodes.
 79.1370 +      /// It conforms to the ReferenceMap concept.
 79.1371 +      template <typename V>
 79.1372 +      class NodeMap : public GraphMap<MappableDigraphComponent, Node, V> {
 79.1373 +        typedef GraphMap<MappableDigraphComponent, Node, V> Parent;
 79.1374 +
 79.1375        public:
 79.1376 -        typedef GraphMap<MappableDigraphComponent, Node, _Value> Parent;
 79.1377 -
 79.1378          /// \brief Construct a new map.
 79.1379          ///
 79.1380          /// Construct a new map for the digraph.
 79.1381 @@ -1082,8 +1098,8 @@
 79.1382  
 79.1383          /// \brief Construct a new map with default value.
 79.1384          ///
 79.1385 -        /// Construct a new map for the digraph and initalise the values.
 79.1386 -        NodeMap(const MappableDigraphComponent& digraph, const _Value& value)
 79.1387 +        /// Construct a new map for the digraph and initalize the values.
 79.1388 +        NodeMap(const MappableDigraphComponent& digraph, const V& value)
 79.1389            : Parent(digraph, value) {}
 79.1390  
 79.1391        private:
 79.1392 @@ -1092,26 +1108,26 @@
 79.1393          /// Copy Constructor.
 79.1394          NodeMap(const NodeMap& nm) : Parent(nm) {}
 79.1395  
 79.1396 -        /// \brief Assign operator.
 79.1397 +        /// \brief Assignment operator.
 79.1398          ///
 79.1399 -        /// Assign operator.
 79.1400 +        /// Assignment operator.
 79.1401          template <typename CMap>
 79.1402          NodeMap& operator=(const CMap&) {
 79.1403 -          checkConcept<ReadMap<Node, _Value>, CMap>();
 79.1404 +          checkConcept<ReadMap<Node, V>, CMap>();
 79.1405            return *this;
 79.1406          }
 79.1407  
 79.1408        };
 79.1409  
 79.1410 -      /// \brief ReadWrite map of the arcs.
 79.1411 +      /// \brief Standard graph map for the arcs.
 79.1412        ///
 79.1413 -      /// ReadWrite map of the arcs.
 79.1414 -      ///
 79.1415 -      template <typename _Value>
 79.1416 -      class ArcMap : public GraphMap<Digraph, Arc, _Value> {
 79.1417 +      /// Standard graph map for the arcs.
 79.1418 +      /// It conforms to the ReferenceMap concept.
 79.1419 +      template <typename V>
 79.1420 +      class ArcMap : public GraphMap<MappableDigraphComponent, Arc, V> {
 79.1421 +        typedef GraphMap<MappableDigraphComponent, Arc, V> Parent;
 79.1422 +
 79.1423        public:
 79.1424 -        typedef GraphMap<MappableDigraphComponent, Arc, _Value> Parent;
 79.1425 -
 79.1426          /// \brief Construct a new map.
 79.1427          ///
 79.1428          /// Construct a new map for the digraph.
 79.1429 @@ -1120,8 +1136,8 @@
 79.1430  
 79.1431          /// \brief Construct a new map with default value.
 79.1432          ///
 79.1433 -        /// Construct a new map for the digraph and initalise the values.
 79.1434 -        ArcMap(const MappableDigraphComponent& digraph, const _Value& value)
 79.1435 +        /// Construct a new map for the digraph and initalize the values.
 79.1436 +        ArcMap(const MappableDigraphComponent& digraph, const V& value)
 79.1437            : Parent(digraph, value) {}
 79.1438  
 79.1439        private:
 79.1440 @@ -1130,12 +1146,12 @@
 79.1441          /// Copy Constructor.
 79.1442          ArcMap(const ArcMap& nm) : Parent(nm) {}
 79.1443  
 79.1444 -        /// \brief Assign operator.
 79.1445 +        /// \brief Assignment operator.
 79.1446          ///
 79.1447 -        /// Assign operator.
 79.1448 +        /// Assignment operator.
 79.1449          template <typename CMap>
 79.1450          ArcMap& operator=(const CMap&) {
 79.1451 -          checkConcept<ReadMap<Arc, _Value>, CMap>();
 79.1452 +          checkConcept<ReadMap<Arc, V>, CMap>();
 79.1453            return *this;
 79.1454          }
 79.1455  
 79.1456 @@ -1182,33 +1198,34 @@
 79.1457            }
 79.1458          }
 79.1459  
 79.1460 -        _Digraph& digraph;
 79.1461 +        const _Digraph& digraph;
 79.1462        };
 79.1463      };
 79.1464  
 79.1465 -    /// \brief An empty mappable base bipartite graph class.
 79.1466 +    /// \brief Skeleton class for mappable undirected graphs.
 79.1467      ///
 79.1468 -    /// This class provides beside the core graph features
 79.1469 -    /// map interface for the graph structure.
 79.1470 +    /// This class describes the interface of mappable undirected graphs.
 79.1471 +    /// It extends \ref MappableDigraphComponent with the standard graph 
 79.1472 +    /// map class for edges (\c EdgeMap).
 79.1473      /// This concept is part of the Graph concept.
 79.1474 -    template <typename _Base = BaseGraphComponent>
 79.1475 -    class MappableGraphComponent : public MappableDigraphComponent<_Base>  {
 79.1476 +    template <typename BAS = BaseGraphComponent>
 79.1477 +    class MappableGraphComponent : public MappableDigraphComponent<BAS>  {
 79.1478      public:
 79.1479  
 79.1480 -      typedef _Base Base;
 79.1481 +      typedef BAS Base;
 79.1482        typedef typename Base::Edge Edge;
 79.1483  
 79.1484        typedef MappableGraphComponent Graph;
 79.1485  
 79.1486 -      /// \brief ReadWrite map of the edges.
 79.1487 +      /// \brief Standard graph map for the edges.
 79.1488        ///
 79.1489 -      /// ReadWrite map of the edges.
 79.1490 -      ///
 79.1491 -      template <typename _Value>
 79.1492 -      class EdgeMap : public GraphMap<Graph, Edge, _Value> {
 79.1493 +      /// Standard graph map for the edges.
 79.1494 +      /// It conforms to the ReferenceMap concept.
 79.1495 +      template <typename V>
 79.1496 +      class EdgeMap : public GraphMap<MappableGraphComponent, Edge, V> {
 79.1497 +        typedef GraphMap<MappableGraphComponent, Edge, V> Parent;
 79.1498 +
 79.1499        public:
 79.1500 -        typedef GraphMap<MappableGraphComponent, Edge, _Value> Parent;
 79.1501 -
 79.1502          /// \brief Construct a new map.
 79.1503          ///
 79.1504          /// Construct a new map for the graph.
 79.1505 @@ -1217,8 +1234,8 @@
 79.1506  
 79.1507          /// \brief Construct a new map with default value.
 79.1508          ///
 79.1509 -        /// Construct a new map for the graph and initalise the values.
 79.1510 -        EdgeMap(const MappableGraphComponent& graph, const _Value& value)
 79.1511 +        /// Construct a new map for the graph and initalize the values.
 79.1512 +        EdgeMap(const MappableGraphComponent& graph, const V& value)
 79.1513            : Parent(graph, value) {}
 79.1514  
 79.1515        private:
 79.1516 @@ -1227,12 +1244,12 @@
 79.1517          /// Copy Constructor.
 79.1518          EdgeMap(const EdgeMap& nm) : Parent(nm) {}
 79.1519  
 79.1520 -        /// \brief Assign operator.
 79.1521 +        /// \brief Assignment operator.
 79.1522          ///
 79.1523 -        /// Assign operator.
 79.1524 +        /// Assignment operator.
 79.1525          template <typename CMap>
 79.1526          EdgeMap& operator=(const CMap&) {
 79.1527 -          checkConcept<ReadMap<Edge, _Value>, CMap>();
 79.1528 +          checkConcept<ReadMap<Edge, V>, CMap>();
 79.1529            return *this;
 79.1530          }
 79.1531  
 79.1532 @@ -1249,7 +1266,7 @@
 79.1533          };
 79.1534  
 79.1535          void constraints() {
 79.1536 -          checkConcept<MappableGraphComponent<Base>, _Graph>();
 79.1537 +          checkConcept<MappableDigraphComponent<Base>, _Graph>();
 79.1538  
 79.1539            { // int map test
 79.1540              typedef typename _Graph::template EdgeMap<int> IntEdgeMap;
 79.1541 @@ -1266,35 +1283,35 @@
 79.1542            }
 79.1543          }
 79.1544  
 79.1545 -        _Graph& graph;
 79.1546 +        const _Graph& graph;
 79.1547        };
 79.1548      };
 79.1549  
 79.1550 -    /// \brief An empty extendable digraph class.
 79.1551 +    /// \brief Skeleton class for extendable directed graphs.
 79.1552      ///
 79.1553 -    /// This class provides beside the core digraph features digraph
 79.1554 -    /// extendable interface for the digraph structure.  The main
 79.1555 -    /// difference between the base and this interface is that the
 79.1556 -    /// digraph alterations should handled already on this level.
 79.1557 -    template <typename _Base = BaseDigraphComponent>
 79.1558 -    class ExtendableDigraphComponent : public _Base {
 79.1559 +    /// This class describes the interface of extendable directed graphs.
 79.1560 +    /// It extends \ref BaseDigraphComponent with functions for adding 
 79.1561 +    /// nodes and arcs to the digraph.
 79.1562 +    /// This concept requires \ref AlterableDigraphComponent.
 79.1563 +    template <typename BAS = BaseDigraphComponent>
 79.1564 +    class ExtendableDigraphComponent : public BAS {
 79.1565      public:
 79.1566 -      typedef _Base Base;
 79.1567 +      typedef BAS Base;
 79.1568  
 79.1569 -      typedef typename _Base::Node Node;
 79.1570 -      typedef typename _Base::Arc Arc;
 79.1571 +      typedef typename Base::Node Node;
 79.1572 +      typedef typename Base::Arc Arc;
 79.1573  
 79.1574 -      /// \brief Adds a new node to the digraph.
 79.1575 +      /// \brief Add a new node to the digraph.
 79.1576        ///
 79.1577 -      /// Adds a new node to the digraph.
 79.1578 -      ///
 79.1579 +      /// This function adds a new node to the digraph.
 79.1580        Node addNode() {
 79.1581          return INVALID;
 79.1582        }
 79.1583  
 79.1584 -      /// \brief Adds a new arc connects the given two nodes.
 79.1585 +      /// \brief Add a new arc connecting the given two nodes.
 79.1586        ///
 79.1587 -      /// Adds a new arc connects the the given two nodes.
 79.1588 +      /// This function adds a new arc connecting the given two nodes
 79.1589 +      /// of the digraph.
 79.1590        Arc addArc(const Node&, const Node&) {
 79.1591          return INVALID;
 79.1592        }
 79.1593 @@ -1314,33 +1331,32 @@
 79.1594        };
 79.1595      };
 79.1596  
 79.1597 -    /// \brief An empty extendable base undirected graph class.
 79.1598 +    /// \brief Skeleton class for extendable undirected graphs.
 79.1599      ///
 79.1600 -    /// This class provides beside the core undirected graph features
 79.1601 -    /// core undircted graph extend interface for the graph structure.
 79.1602 -    /// The main difference between the base and this interface is
 79.1603 -    /// that the graph alterations should handled already on this
 79.1604 -    /// level.
 79.1605 -    template <typename _Base = BaseGraphComponent>
 79.1606 -    class ExtendableGraphComponent : public _Base {
 79.1607 +    /// This class describes the interface of extendable undirected graphs.
 79.1608 +    /// It extends \ref BaseGraphComponent with functions for adding 
 79.1609 +    /// nodes and edges to the graph.
 79.1610 +    /// This concept requires \ref AlterableGraphComponent.
 79.1611 +    template <typename BAS = BaseGraphComponent>
 79.1612 +    class ExtendableGraphComponent : public BAS {
 79.1613      public:
 79.1614  
 79.1615 -      typedef _Base Base;
 79.1616 -      typedef typename _Base::Node Node;
 79.1617 -      typedef typename _Base::Edge Edge;
 79.1618 +      typedef BAS Base;
 79.1619 +      typedef typename Base::Node Node;
 79.1620 +      typedef typename Base::Edge Edge;
 79.1621  
 79.1622 -      /// \brief Adds a new node to the graph.
 79.1623 +      /// \brief Add a new node to the digraph.
 79.1624        ///
 79.1625 -      /// Adds a new node to the graph.
 79.1626 -      ///
 79.1627 +      /// This function adds a new node to the digraph.
 79.1628        Node addNode() {
 79.1629          return INVALID;
 79.1630        }
 79.1631  
 79.1632 -      /// \brief Adds a new arc connects the given two nodes.
 79.1633 +      /// \brief Add a new edge connecting the given two nodes.
 79.1634        ///
 79.1635 -      /// Adds a new arc connects the the given two nodes.
 79.1636 -      Edge addArc(const Node&, const Node&) {
 79.1637 +      /// This function adds a new edge connecting the given two nodes
 79.1638 +      /// of the graph.
 79.1639 +      Edge addEdge(const Node&, const Node&) {
 79.1640          return INVALID;
 79.1641        }
 79.1642  
 79.1643 @@ -1359,39 +1375,38 @@
 79.1644        };
 79.1645      };
 79.1646  
 79.1647 -    /// \brief An empty erasable digraph class.
 79.1648 +    /// \brief Skeleton class for erasable directed graphs.
 79.1649      ///
 79.1650 -    /// This class provides beside the core digraph features core erase
 79.1651 -    /// functions for the digraph structure. The main difference between
 79.1652 -    /// the base and this interface is that the digraph alterations
 79.1653 -    /// should handled already on this level.
 79.1654 -    template <typename _Base = BaseDigraphComponent>
 79.1655 -    class ErasableDigraphComponent : public _Base {
 79.1656 +    /// This class describes the interface of erasable directed graphs.
 79.1657 +    /// It extends \ref BaseDigraphComponent with functions for removing 
 79.1658 +    /// nodes and arcs from the digraph.
 79.1659 +    /// This concept requires \ref AlterableDigraphComponent.
 79.1660 +    template <typename BAS = BaseDigraphComponent>
 79.1661 +    class ErasableDigraphComponent : public BAS {
 79.1662      public:
 79.1663  
 79.1664 -      typedef _Base Base;
 79.1665 +      typedef BAS Base;
 79.1666        typedef typename Base::Node Node;
 79.1667        typedef typename Base::Arc Arc;
 79.1668  
 79.1669        /// \brief Erase a node from the digraph.
 79.1670        ///
 79.1671 -      /// Erase a node from the digraph. This function should
 79.1672 -      /// erase all arcs connecting to the node.
 79.1673 +      /// This function erases the given node from the digraph and all arcs 
 79.1674 +      /// connected to the node.
 79.1675        void erase(const Node&) {}
 79.1676  
 79.1677        /// \brief Erase an arc from the digraph.
 79.1678        ///
 79.1679 -      /// Erase an arc from the digraph.
 79.1680 -      ///
 79.1681 +      /// This function erases the given arc from the digraph.
 79.1682        void erase(const Arc&) {}
 79.1683  
 79.1684        template <typename _Digraph>
 79.1685        struct Constraints {
 79.1686          void constraints() {
 79.1687            checkConcept<Base, _Digraph>();
 79.1688 -          typename _Digraph::Node node;
 79.1689 +          const typename _Digraph::Node node(INVALID);
 79.1690            digraph.erase(node);
 79.1691 -          typename _Digraph::Arc arc;
 79.1692 +          const typename _Digraph::Arc arc(INVALID);
 79.1693            digraph.erase(arc);
 79.1694          }
 79.1695  
 79.1696 @@ -1399,39 +1414,38 @@
 79.1697        };
 79.1698      };
 79.1699  
 79.1700 -    /// \brief An empty erasable base undirected graph class.
 79.1701 +    /// \brief Skeleton class for erasable undirected graphs.
 79.1702      ///
 79.1703 -    /// This class provides beside the core undirected graph features
 79.1704 -    /// core erase functions for the undirceted graph structure. The
 79.1705 -    /// main difference between the base and this interface is that
 79.1706 -    /// the graph alterations should handled already on this level.
 79.1707 -    template <typename _Base = BaseGraphComponent>
 79.1708 -    class ErasableGraphComponent : public _Base {
 79.1709 +    /// This class describes the interface of erasable undirected graphs.
 79.1710 +    /// It extends \ref BaseGraphComponent with functions for removing 
 79.1711 +    /// nodes and edges from the graph.
 79.1712 +    /// This concept requires \ref AlterableGraphComponent.
 79.1713 +    template <typename BAS = BaseGraphComponent>
 79.1714 +    class ErasableGraphComponent : public BAS {
 79.1715      public:
 79.1716  
 79.1717 -      typedef _Base Base;
 79.1718 +      typedef BAS Base;
 79.1719        typedef typename Base::Node Node;
 79.1720        typedef typename Base::Edge Edge;
 79.1721  
 79.1722        /// \brief Erase a node from the graph.
 79.1723        ///
 79.1724 -      /// Erase a node from the graph. This function should erase
 79.1725 -      /// arcs connecting to the node.
 79.1726 +      /// This function erases the given node from the graph and all edges
 79.1727 +      /// connected to the node.
 79.1728        void erase(const Node&) {}
 79.1729  
 79.1730 -      /// \brief Erase an arc from the graph.
 79.1731 +      /// \brief Erase an edge from the digraph.
 79.1732        ///
 79.1733 -      /// Erase an arc from the graph.
 79.1734 -      ///
 79.1735 +      /// This function erases the given edge from the digraph.
 79.1736        void erase(const Edge&) {}
 79.1737  
 79.1738        template <typename _Graph>
 79.1739        struct Constraints {
 79.1740          void constraints() {
 79.1741            checkConcept<Base, _Graph>();
 79.1742 -          typename _Graph::Node node;
 79.1743 +          const typename _Graph::Node node(INVALID);
 79.1744            graph.erase(node);
 79.1745 -          typename _Graph::Edge edge;
 79.1746 +          const typename _Graph::Edge edge(INVALID);
 79.1747            graph.erase(edge);
 79.1748          }
 79.1749  
 79.1750 @@ -1439,22 +1453,21 @@
 79.1751        };
 79.1752      };
 79.1753  
 79.1754 -    /// \brief An empty clearable base digraph class.
 79.1755 +    /// \brief Skeleton class for clearable directed graphs.
 79.1756      ///
 79.1757 -    /// This class provides beside the core digraph features core clear
 79.1758 -    /// functions for the digraph structure. The main difference between
 79.1759 -    /// the base and this interface is that the digraph alterations
 79.1760 -    /// should handled already on this level.
 79.1761 -    template <typename _Base = BaseDigraphComponent>
 79.1762 -    class ClearableDigraphComponent : public _Base {
 79.1763 +    /// This class describes the interface of clearable directed graphs.
 79.1764 +    /// It extends \ref BaseDigraphComponent with a function for clearing
 79.1765 +    /// the digraph.
 79.1766 +    /// This concept requires \ref AlterableDigraphComponent.
 79.1767 +    template <typename BAS = BaseDigraphComponent>
 79.1768 +    class ClearableDigraphComponent : public BAS {
 79.1769      public:
 79.1770  
 79.1771 -      typedef _Base Base;
 79.1772 +      typedef BAS Base;
 79.1773  
 79.1774        /// \brief Erase all nodes and arcs from the digraph.
 79.1775        ///
 79.1776 -      /// Erase all nodes and arcs from the digraph.
 79.1777 -      ///
 79.1778 +      /// This function erases all nodes and arcs from the digraph.
 79.1779        void clear() {}
 79.1780  
 79.1781        template <typename _Digraph>
 79.1782 @@ -1464,29 +1477,35 @@
 79.1783            digraph.clear();
 79.1784          }
 79.1785  
 79.1786 -        _Digraph digraph;
 79.1787 +        _Digraph& digraph;
 79.1788        };
 79.1789      };
 79.1790  
 79.1791 -    /// \brief An empty clearable base undirected graph class.
 79.1792 +    /// \brief Skeleton class for clearable undirected graphs.
 79.1793      ///
 79.1794 -    /// This class provides beside the core undirected graph features
 79.1795 -    /// core clear functions for the undirected graph structure. The
 79.1796 -    /// main difference between the base and this interface is that
 79.1797 -    /// the graph alterations should handled already on this level.
 79.1798 -    template <typename _Base = BaseGraphComponent>
 79.1799 -    class ClearableGraphComponent : public ClearableDigraphComponent<_Base> {
 79.1800 +    /// This class describes the interface of clearable undirected graphs.
 79.1801 +    /// It extends \ref BaseGraphComponent with a function for clearing
 79.1802 +    /// the graph.
 79.1803 +    /// This concept requires \ref AlterableGraphComponent.
 79.1804 +    template <typename BAS = BaseGraphComponent>
 79.1805 +    class ClearableGraphComponent : public ClearableDigraphComponent<BAS> {
 79.1806      public:
 79.1807  
 79.1808 -      typedef _Base Base;
 79.1809 +      typedef BAS Base;
 79.1810 +
 79.1811 +      /// \brief Erase all nodes and edges from the graph.
 79.1812 +      ///
 79.1813 +      /// This function erases all nodes and edges from the graph.
 79.1814 +      void clear() {}
 79.1815  
 79.1816        template <typename _Graph>
 79.1817        struct Constraints {
 79.1818          void constraints() {
 79.1819 -          checkConcept<ClearableGraphComponent<Base>, _Graph>();
 79.1820 +          checkConcept<Base, _Graph>();
 79.1821 +          graph.clear();
 79.1822          }
 79.1823  
 79.1824 -        _Graph graph;
 79.1825 +        _Graph& graph;
 79.1826        };
 79.1827      };
 79.1828  
    80.1 --- a/lemon/concepts/heap.h	Fri Oct 16 10:21:37 2009 +0200
    80.2 +++ b/lemon/concepts/heap.h	Thu Nov 05 15:50:01 2009 +0100
    80.3 @@ -2,7 +2,7 @@
    80.4   *
    80.5   * This file is a part of LEMON, a generic C++ optimization library.
    80.6   *
    80.7 - * Copyright (C) 2003-2008
    80.8 + * Copyright (C) 2003-2009
    80.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   80.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   80.11   *
   80.12 @@ -16,14 +16,15 @@
   80.13   *
   80.14   */
   80.15  
   80.16 +#ifndef LEMON_CONCEPTS_HEAP_H
   80.17 +#define LEMON_CONCEPTS_HEAP_H
   80.18 +
   80.19  ///\ingroup concept
   80.20  ///\file
   80.21  ///\brief The concept of heaps.
   80.22  
   80.23 -#ifndef LEMON_CONCEPT_HEAP_H
   80.24 -#define LEMON_CONCEPT_HEAP_H
   80.25 -
   80.26  #include <lemon/core.h>
   80.27 +#include <lemon/concept_check.h>
   80.28  
   80.29  namespace lemon {
   80.30  
   80.31 @@ -34,123 +35,160 @@
   80.32  
   80.33      /// \brief The heap concept.
   80.34      ///
   80.35 -    /// Concept class describing the main interface of heaps.
   80.36 -    template <typename Priority, typename ItemIntMap>
   80.37 +    /// This concept class describes the main interface of heaps.
   80.38 +    /// The various \ref heaps "heap structures" are efficient
   80.39 +    /// implementations of the abstract data type \e priority \e queue.
   80.40 +    /// They store items with specified values called \e priorities
   80.41 +    /// in such a way that finding and removing the item with minimum
   80.42 +    /// priority are efficient. The basic operations are adding and
   80.43 +    /// erasing items, changing the priority of an item, etc.
   80.44 +    ///
   80.45 +    /// Heaps are crucial in several algorithms, such as Dijkstra and Prim.
   80.46 +    /// Any class that conforms to this concept can be used easily in such
   80.47 +    /// algorithms.
   80.48 +    ///
   80.49 +    /// \tparam PR Type of the priorities of the items.
   80.50 +    /// \tparam IM A read-writable item map with \c int values, used
   80.51 +    /// internally to handle the cross references.
   80.52 +    /// \tparam CMP A functor class for comparing the priorities.
   80.53 +    /// The default is \c std::less<PR>.
   80.54 +#ifdef DOXYGEN
   80.55 +    template <typename PR, typename IM, typename CMP>
   80.56 +#else
   80.57 +    template <typename PR, typename IM, typename CMP = std::less<PR> >
   80.58 +#endif
   80.59      class Heap {
   80.60      public:
   80.61  
   80.62 +      /// Type of the item-int map.
   80.63 +      typedef IM ItemIntMap;
   80.64 +      /// Type of the priorities.
   80.65 +      typedef PR Prio;
   80.66        /// Type of the items stored in the heap.
   80.67        typedef typename ItemIntMap::Key Item;
   80.68  
   80.69 -      /// Type of the priorities.
   80.70 -      typedef Priority Prio;
   80.71 -
   80.72        /// \brief Type to represent the states of the items.
   80.73        ///
   80.74        /// Each item has a state associated to it. It can be "in heap",
   80.75 -      /// "pre heap" or "post heap". The later two are indifferent
   80.76 -      /// from the point of view of the heap, but may be useful for
   80.77 -      /// the user.
   80.78 +      /// "pre-heap" or "post-heap". The latter two are indifferent from the
   80.79 +      /// heap's point of view, but may be useful to the user.
   80.80        ///
   80.81 -      /// The \c ItemIntMap must be initialized in such a way, that it
   80.82 -      /// assigns \c PRE_HEAP (<tt>-1</tt>) to every item.
   80.83 +      /// The item-int map must be initialized in such way that it assigns
   80.84 +      /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
   80.85        enum State {
   80.86 -        IN_HEAP = 0,
   80.87 -        PRE_HEAP = -1,
   80.88 -        POST_HEAP = -2
   80.89 +        IN_HEAP = 0,    ///< = 0. The "in heap" state constant.
   80.90 +        PRE_HEAP = -1,  ///< = -1. The "pre-heap" state constant.
   80.91 +        POST_HEAP = -2  ///< = -2. The "post-heap" state constant.
   80.92        };
   80.93  
   80.94 -      /// \brief The constructor.
   80.95 +      /// \brief Constructor.
   80.96        ///
   80.97 -      /// The constructor.
   80.98 +      /// Constructor.
   80.99        /// \param map A map that assigns \c int values to keys of type
  80.100        /// \c Item. It is used internally by the heap implementations to
  80.101        /// handle the cross references. The assigned value must be
  80.102 -      /// \c PRE_HEAP (<tt>-1</tt>) for every item.
  80.103 +      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
  80.104        explicit Heap(ItemIntMap &map) {}
  80.105  
  80.106 +      /// \brief Constructor.
  80.107 +      ///
  80.108 +      /// Constructor.
  80.109 +      /// \param map A map that assigns \c int values to keys of type
  80.110 +      /// \c Item. It is used internally by the heap implementations to
  80.111 +      /// handle the cross references. The assigned value must be
  80.112 +      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
  80.113 +      /// \param comp The function object used for comparing the priorities.
  80.114 +      explicit Heap(ItemIntMap &map, const CMP &comp) {}
  80.115 +
  80.116        /// \brief The number of items stored in the heap.
  80.117        ///
  80.118 -      /// Returns the number of items stored in the heap.
  80.119 +      /// This function returns the number of items stored in the heap.
  80.120        int size() const { return 0; }
  80.121  
  80.122 -      /// \brief Checks if the heap is empty.
  80.123 +      /// \brief Check if the heap is empty.
  80.124        ///
  80.125 -      /// Returns \c true if the heap is empty.
  80.126 +      /// This function returns \c true if the heap is empty.
  80.127        bool empty() const { return false; }
  80.128  
  80.129 -      /// \brief Makes the heap empty.
  80.130 +      /// \brief Make the heap empty.
  80.131        ///
  80.132 -      /// Makes the heap empty.
  80.133 -      void clear();
  80.134 +      /// This functon makes the heap empty.
  80.135 +      /// It does not change the cross reference map. If you want to reuse
  80.136 +      /// a heap that is not surely empty, you should first clear it and
  80.137 +      /// then you should set the cross reference map to \c PRE_HEAP
  80.138 +      /// for each item.
  80.139 +      void clear() {}
  80.140  
  80.141 -      /// \brief Inserts an item into the heap with the given priority.
  80.142 +      /// \brief Insert an item into the heap with the given priority.
  80.143        ///
  80.144 -      /// Inserts the given item into the heap with the given priority.
  80.145 +      /// This function inserts the given item into the heap with the
  80.146 +      /// given priority.
  80.147        /// \param i The item to insert.
  80.148        /// \param p The priority of the item.
  80.149 +      /// \pre \e i must not be stored in the heap.
  80.150        void push(const Item &i, const Prio &p) {}
  80.151  
  80.152 -      /// \brief Returns the item having minimum priority.
  80.153 +      /// \brief Return the item having minimum priority.
  80.154        ///
  80.155 -      /// Returns the item having minimum priority.
  80.156 +      /// This function returns the item having minimum priority.
  80.157        /// \pre The heap must be non-empty.
  80.158        Item top() const {}
  80.159  
  80.160        /// \brief The minimum priority.
  80.161        ///
  80.162 -      /// Returns the minimum priority.
  80.163 +      /// This function returns the minimum priority.
  80.164        /// \pre The heap must be non-empty.
  80.165        Prio prio() const {}
  80.166  
  80.167 -      /// \brief Removes the item having minimum priority.
  80.168 +      /// \brief Remove the item having minimum priority.
  80.169        ///
  80.170 -      /// Removes the item having minimum priority.
  80.171 +      /// This function removes the item having minimum priority.
  80.172        /// \pre The heap must be non-empty.
  80.173        void pop() {}
  80.174  
  80.175 -      /// \brief Removes an item from the heap.
  80.176 +      /// \brief Remove the given item from the heap.
  80.177        ///
  80.178 -      /// Removes the given item from the heap if it is already stored.
  80.179 +      /// This function removes the given item from the heap if it is
  80.180 +      /// already stored.
  80.181        /// \param i The item to delete.
  80.182 +      /// \pre \e i must be in the heap.
  80.183        void erase(const Item &i) {}
  80.184  
  80.185 -      /// \brief The priority of an item.
  80.186 +      /// \brief The priority of the given item.
  80.187        ///
  80.188 -      /// Returns the priority of the given item.
  80.189 -      /// \pre \c i must be in the heap.
  80.190 +      /// This function returns the priority of the given item.
  80.191        /// \param i The item.
  80.192 +      /// \pre \e i must be in the heap.
  80.193        Prio operator[](const Item &i) const {}
  80.194  
  80.195 -      /// \brief Sets the priority of an item or inserts it, if it is
  80.196 +      /// \brief Set the priority of an item or insert it, if it is
  80.197        /// not stored in the heap.
  80.198        ///
  80.199        /// This method sets the priority of the given item if it is
  80.200 -      /// already stored in the heap.
  80.201 -      /// Otherwise it inserts the given item with the given priority.
  80.202 +      /// already stored in the heap. Otherwise it inserts the given
  80.203 +      /// item into the heap with the given priority.
  80.204        ///
  80.205        /// \param i The item.
  80.206        /// \param p The priority.
  80.207        void set(const Item &i, const Prio &p) {}
  80.208  
  80.209 -      /// \brief Decreases the priority of an item to the given value.
  80.210 +      /// \brief Decrease the priority of an item to the given value.
  80.211        ///
  80.212 -      /// Decreases the priority of an item to the given value.
  80.213 -      /// \pre \c i must be stored in the heap with priority at least \c p.
  80.214 +      /// This function decreases the priority of an item to the given value.
  80.215        /// \param i The item.
  80.216        /// \param p The priority.
  80.217 +      /// \pre \e i must be stored in the heap with priority at least \e p.
  80.218        void decrease(const Item &i, const Prio &p) {}
  80.219  
  80.220 -      /// \brief Increases the priority of an item to the given value.
  80.221 +      /// \brief Increase the priority of an item to the given value.
  80.222        ///
  80.223 -      /// Increases the priority of an item to the given value.
  80.224 -      /// \pre \c i must be stored in the heap with priority at most \c p.
  80.225 +      /// This function increases the priority of an item to the given value.
  80.226        /// \param i The item.
  80.227        /// \param p The priority.
  80.228 +      /// \pre \e i must be stored in the heap with priority at most \e p.
  80.229        void increase(const Item &i, const Prio &p) {}
  80.230  
  80.231 -      /// \brief Returns if an item is in, has already been in, or has
  80.232 -      /// never been in the heap.
  80.233 +      /// \brief Return the state of an item.
  80.234        ///
  80.235        /// This method returns \c PRE_HEAP if the given item has never
  80.236        /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  80.237 @@ -160,11 +198,11 @@
  80.238        /// \param i The item.
  80.239        State state(const Item &i) const {}
  80.240  
  80.241 -      /// \brief Sets the state of an item in the heap.
  80.242 +      /// \brief Set the state of an item in the heap.
  80.243        ///
  80.244 -      /// Sets the state of the given item in the heap. It can be used
  80.245 -      /// to manually clear the heap when it is important to achive the
  80.246 -      /// better time complexity.
  80.247 +      /// This function sets the state of the given item in the heap.
  80.248 +      /// It can be used to manually clear the heap when it is important
  80.249 +      /// to achive better time complexity.
  80.250        /// \param i The item.
  80.251        /// \param st The state. It should not be \c IN_HEAP.
  80.252        void state(const Item& i, State st) {}
  80.253 @@ -242,4 +280,4 @@
  80.254      /// @}
  80.255    } // namespace lemon
  80.256  }
  80.257 -#endif // LEMON_CONCEPT_PATH_H
  80.258 +#endif
    81.1 --- a/lemon/concepts/maps.h	Fri Oct 16 10:21:37 2009 +0200
    81.2 +++ b/lemon/concepts/maps.h	Thu Nov 05 15:50:01 2009 +0100
    81.3 @@ -2,7 +2,7 @@
    81.4   *
    81.5   * This file is a part of LEMON, a generic C++ optimization library.
    81.6   *
    81.7 - * Copyright (C) 2003-2008
    81.8 + * Copyright (C) 2003-2009
    81.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   81.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   81.11   *
   81.12 @@ -16,8 +16,8 @@
   81.13   *
   81.14   */
   81.15  
   81.16 -#ifndef LEMON_CONCEPT_MAPS_H
   81.17 -#define LEMON_CONCEPT_MAPS_H
   81.18 +#ifndef LEMON_CONCEPTS_MAPS_H
   81.19 +#define LEMON_CONCEPTS_MAPS_H
   81.20  
   81.21  #include <lemon/core.h>
   81.22  #include <lemon/concept_check.h>
   81.23 @@ -182,7 +182,8 @@
   81.24  
   81.25        template<typename _ReferenceMap>
   81.26        struct Constraints {
   81.27 -        void constraints() {
   81.28 +        typename enable_if<typename _ReferenceMap::ReferenceMapTag, void>::type
   81.29 +        constraints() {
   81.30            checkConcept<ReadWriteMap<K, T>, _ReferenceMap >();
   81.31            ref = m[key];
   81.32            m[key] = val;
   81.33 @@ -213,4 +214,4 @@
   81.34  
   81.35  } //namespace lemon
   81.36  
   81.37 -#endif // LEMON_CONCEPT_MAPS_H
   81.38 +#endif
    82.1 --- a/lemon/concepts/path.h	Fri Oct 16 10:21:37 2009 +0200
    82.2 +++ b/lemon/concepts/path.h	Thu Nov 05 15:50:01 2009 +0100
    82.3 @@ -2,7 +2,7 @@
    82.4   *
    82.5   * This file is a part of LEMON, a generic C++ optimization library.
    82.6   *
    82.7 - * Copyright (C) 2003-2008
    82.8 + * Copyright (C) 2003-2009
    82.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   82.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   82.11   *
   82.12 @@ -21,8 +21,8 @@
   82.13  ///\brief Classes for representing paths in digraphs.
   82.14  ///
   82.15  
   82.16 -#ifndef LEMON_CONCEPT_PATH_H
   82.17 -#define LEMON_CONCEPT_PATH_H
   82.18 +#ifndef LEMON_CONCEPTS_PATH_H
   82.19 +#define LEMON_CONCEPTS_PATH_H
   82.20  
   82.21  #include <lemon/core.h>
   82.22  #include <lemon/concept_check.h>
   82.23 @@ -38,19 +38,19 @@
   82.24      ///
   82.25      /// A skeleton structure for representing directed paths in a
   82.26      /// digraph.
   82.27 -    /// \tparam _Digraph The digraph type in which the path is.
   82.28 +    /// \tparam GR The digraph type in which the path is.
   82.29      ///
   82.30      /// In a sense, the path can be treated as a list of arcs. The
   82.31      /// lemon path type stores just this list. As a consequence it
   82.32      /// cannot enumerate the nodes in the path and the zero length
   82.33      /// paths cannot store the source.
   82.34      ///
   82.35 -    template <typename _Digraph>
   82.36 +    template <typename GR>
   82.37      class Path {
   82.38      public:
   82.39  
   82.40        /// Type of the underlying digraph.
   82.41 -      typedef _Digraph Digraph;
   82.42 +      typedef GR Digraph;
   82.43        /// Arc type of the underlying digraph.
   82.44        typedef typename Digraph::Arc Arc;
   82.45  
   82.46 @@ -205,18 +205,17 @@
   82.47      /// LEMON such algorithms gives back a path dumper what can
   82.48      /// assigned to a real path and the dumpers can be implemented as
   82.49      /// an adaptor class to the predecessor map.
   82.50 -
   82.51 -    /// \tparam _Digraph  The digraph type in which the path is.
   82.52 +    ///
   82.53 +    /// \tparam GR The digraph type in which the path is.
   82.54      ///
   82.55      /// The paths can be constructed from any path type by a
   82.56      /// template constructor or a template assignment operator.
   82.57 -    ///
   82.58 -    template <typename _Digraph>
   82.59 +    template <typename GR>
   82.60      class PathDumper {
   82.61      public:
   82.62  
   82.63        /// Type of the underlying digraph.
   82.64 -      typedef _Digraph Digraph;
   82.65 +      typedef GR Digraph;
   82.66        /// Arc type of the underlying digraph.
   82.67        typedef typename Digraph::Arc Arc;
   82.68  
   82.69 @@ -305,4 +304,4 @@
   82.70  
   82.71  } // namespace lemon
   82.72  
   82.73 -#endif // LEMON_CONCEPT_PATH_H
   82.74 +#endif
    83.1 --- a/lemon/config.h.cmake	Fri Oct 16 10:21:37 2009 +0200
    83.2 +++ b/lemon/config.h.cmake	Thu Nov 05 15:50:01 2009 +0100
    83.3 @@ -1,1 +1,8 @@
    83.4 +#define LEMON_VERSION "@PROJECT_VERSION@"
    83.5  #cmakedefine LEMON_HAVE_LONG_LONG 1
    83.6 +#cmakedefine LEMON_HAVE_LP 1
    83.7 +#cmakedefine LEMON_HAVE_MIP 1
    83.8 +#cmakedefine LEMON_HAVE_GLPK 1
    83.9 +#cmakedefine LEMON_HAVE_CPLEX 1
   83.10 +#cmakedefine LEMON_HAVE_CLP 1
   83.11 +#cmakedefine LEMON_HAVE_CBC 1
    84.1 --- a/lemon/config.h.in	Fri Oct 16 10:21:37 2009 +0200
    84.2 +++ b/lemon/config.h.in	Thu Nov 05 15:50:01 2009 +0100
    84.3 @@ -1,8 +1,26 @@
    84.4 +/* The version string */
    84.5 +#undef LEMON_VERSION
    84.6 +
    84.7 +/* Define to 1 if you have long long */
    84.8 +#undef LEMON_HAVE_LONG_LONG
    84.9 +
   84.10 +/* Define to 1 if you have any LP solver. */
   84.11 +#undef LEMON_HAVE_LP
   84.12 +
   84.13 +/* Define to 1 if you have any MIP solver. */
   84.14 +#undef LEMON_HAVE_MIP
   84.15 +
   84.16  /* Define to 1 if you have CPLEX. */
   84.17  #undef LEMON_HAVE_CPLEX
   84.18  
   84.19  /* Define to 1 if you have GLPK. */
   84.20  #undef LEMON_HAVE_GLPK
   84.21  
   84.22 -/* Define to 1 if you have long long */
   84.23 -#undef LEMON_HAVE_LONG_LONG
   84.24 +/* Define to 1 if you have SOPLEX */
   84.25 +#undef LEMON_HAVE_SOPLEX
   84.26 +
   84.27 +/* Define to 1 if you have CLP */
   84.28 +#undef LEMON_HAVE_CLP
   84.29 +
   84.30 +/* Define to 1 if you have CBC */
   84.31 +#undef LEMON_HAVE_CBC
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/lemon/connectivity.h	Thu Nov 05 15:50:01 2009 +0100
    85.3 @@ -0,0 +1,1665 @@
    85.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    85.5 + *
    85.6 + * This file is a part of LEMON, a generic C++ optimization library.
    85.7 + *
    85.8 + * Copyright (C) 2003-2009
    85.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   85.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   85.11 + *
   85.12 + * Permission to use, modify and distribute this software is granted
   85.13 + * provided that this copyright notice appears in all copies. For
   85.14 + * precise terms see the accompanying LICENSE file.
   85.15 + *
   85.16 + * This software is provided "AS IS" with no warranty of any kind,
   85.17 + * express or implied, and with no claim as to its suitability for any
   85.18 + * purpose.
   85.19 + *
   85.20 + */
   85.21 +
   85.22 +#ifndef LEMON_CONNECTIVITY_H
   85.23 +#define LEMON_CONNECTIVITY_H
   85.24 +
   85.25 +#include <lemon/dfs.h>
   85.26 +#include <lemon/bfs.h>
   85.27 +#include <lemon/core.h>
   85.28 +#include <lemon/maps.h>
   85.29 +#include <lemon/adaptors.h>
   85.30 +
   85.31 +#include <lemon/concepts/digraph.h>
   85.32 +#include <lemon/concepts/graph.h>
   85.33 +#include <lemon/concept_check.h>
   85.34 +
   85.35 +#include <stack>
   85.36 +#include <functional>
   85.37 +
   85.38 +/// \ingroup graph_properties
   85.39 +/// \file
   85.40 +/// \brief Connectivity algorithms
   85.41 +///
   85.42 +/// Connectivity algorithms
   85.43 +
   85.44 +namespace lemon {
   85.45 +
   85.46 +  /// \ingroup graph_properties
   85.47 +  ///
   85.48 +  /// \brief Check whether an undirected graph is connected.
   85.49 +  ///
   85.50 +  /// This function checks whether the given undirected graph is connected,
   85.51 +  /// i.e. there is a path between any two nodes in the graph.
   85.52 +  ///
   85.53 +  /// \return \c true if the graph is connected.
   85.54 +  /// \note By definition, the empty graph is connected.
   85.55 +  ///
   85.56 +  /// \see countConnectedComponents(), connectedComponents()
   85.57 +  /// \see stronglyConnected()
   85.58 +  template <typename Graph>
   85.59 +  bool connected(const Graph& graph) {
   85.60 +    checkConcept<concepts::Graph, Graph>();
   85.61 +    typedef typename Graph::NodeIt NodeIt;
   85.62 +    if (NodeIt(graph) == INVALID) return true;
   85.63 +    Dfs<Graph> dfs(graph);
   85.64 +    dfs.run(NodeIt(graph));
   85.65 +    for (NodeIt it(graph); it != INVALID; ++it) {
   85.66 +      if (!dfs.reached(it)) {
   85.67 +        return false;
   85.68 +      }
   85.69 +    }
   85.70 +    return true;
   85.71 +  }
   85.72 +
   85.73 +  /// \ingroup graph_properties
   85.74 +  ///
   85.75 +  /// \brief Count the number of connected components of an undirected graph
   85.76 +  ///
   85.77 +  /// This function counts the number of connected components of the given
   85.78 +  /// undirected graph.
   85.79 +  ///
   85.80 +  /// The connected components are the classes of an equivalence relation
   85.81 +  /// on the nodes of an undirected graph. Two nodes are in the same class
   85.82 +  /// if they are connected with a path.
   85.83 +  ///
   85.84 +  /// \return The number of connected components.
   85.85 +  /// \note By definition, the empty graph consists
   85.86 +  /// of zero connected components.
   85.87 +  ///
   85.88 +  /// \see connected(), connectedComponents()
   85.89 +  template <typename Graph>
   85.90 +  int countConnectedComponents(const Graph &graph) {
   85.91 +    checkConcept<concepts::Graph, Graph>();
   85.92 +    typedef typename Graph::Node Node;
   85.93 +    typedef typename Graph::Arc Arc;
   85.94 +
   85.95 +    typedef NullMap<Node, Arc> PredMap;
   85.96 +    typedef NullMap<Node, int> DistMap;
   85.97 +
   85.98 +    int compNum = 0;
   85.99 +    typename Bfs<Graph>::
  85.100 +      template SetPredMap<PredMap>::
  85.101 +      template SetDistMap<DistMap>::
  85.102 +      Create bfs(graph);
  85.103 +
  85.104 +    PredMap predMap;
  85.105 +    bfs.predMap(predMap);
  85.106 +
  85.107 +    DistMap distMap;
  85.108 +    bfs.distMap(distMap);
  85.109 +
  85.110 +    bfs.init();
  85.111 +    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
  85.112 +      if (!bfs.reached(n)) {
  85.113 +        bfs.addSource(n);
  85.114 +        bfs.start();
  85.115 +        ++compNum;
  85.116 +      }
  85.117 +    }
  85.118 +    return compNum;
  85.119 +  }
  85.120 +
  85.121 +  /// \ingroup graph_properties
  85.122 +  ///
  85.123 +  /// \brief Find the connected components of an undirected graph
  85.124 +  ///
  85.125 +  /// This function finds the connected components of the given undirected
  85.126 +  /// graph.
  85.127 +  ///
  85.128 +  /// The connected components are the classes of an equivalence relation
  85.129 +  /// on the nodes of an undirected graph. Two nodes are in the same class
  85.130 +  /// if they are connected with a path.
  85.131 +  ///
  85.132 +  /// \image html connected_components.png
  85.133 +  /// \image latex connected_components.eps "Connected components" width=\textwidth
  85.134 +  ///
  85.135 +  /// \param graph The undirected graph.
  85.136 +  /// \retval compMap A writable node map. The values will be set from 0 to
  85.137 +  /// the number of the connected components minus one. Each value of the map
  85.138 +  /// will be set exactly once, and the values of a certain component will be
  85.139 +  /// set continuously.
  85.140 +  /// \return The number of connected components.
  85.141 +  /// \note By definition, the empty graph consists
  85.142 +  /// of zero connected components.
  85.143 +  ///
  85.144 +  /// \see connected(), countConnectedComponents()
  85.145 +  template <class Graph, class NodeMap>
  85.146 +  int connectedComponents(const Graph &graph, NodeMap &compMap) {
  85.147 +    checkConcept<concepts::Graph, Graph>();
  85.148 +    typedef typename Graph::Node Node;
  85.149 +    typedef typename Graph::Arc Arc;
  85.150 +    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
  85.151 +
  85.152 +    typedef NullMap<Node, Arc> PredMap;
  85.153 +    typedef NullMap<Node, int> DistMap;
  85.154 +
  85.155 +    int compNum = 0;
  85.156 +    typename Bfs<Graph>::
  85.157 +      template SetPredMap<PredMap>::
  85.158 +      template SetDistMap<DistMap>::
  85.159 +      Create bfs(graph);
  85.160 +
  85.161 +    PredMap predMap;
  85.162 +    bfs.predMap(predMap);
  85.163 +
  85.164 +    DistMap distMap;
  85.165 +    bfs.distMap(distMap);
  85.166 +
  85.167 +    bfs.init();
  85.168 +    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
  85.169 +      if(!bfs.reached(n)) {
  85.170 +        bfs.addSource(n);
  85.171 +        while (!bfs.emptyQueue()) {
  85.172 +          compMap.set(bfs.nextNode(), compNum);
  85.173 +          bfs.processNextNode();
  85.174 +        }
  85.175 +        ++compNum;
  85.176 +      }
  85.177 +    }
  85.178 +    return compNum;
  85.179 +  }
  85.180 +
  85.181 +  namespace _connectivity_bits {
  85.182 +
  85.183 +    template <typename Digraph, typename Iterator >
  85.184 +    struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
  85.185 +    public:
  85.186 +      typedef typename Digraph::Node Node;
  85.187 +      LeaveOrderVisitor(Iterator it) : _it(it) {}
  85.188 +
  85.189 +      void leave(const Node& node) {
  85.190 +        *(_it++) = node;
  85.191 +      }
  85.192 +
  85.193 +    private:
  85.194 +      Iterator _it;
  85.195 +    };
  85.196 +
  85.197 +    template <typename Digraph, typename Map>
  85.198 +    struct FillMapVisitor : public DfsVisitor<Digraph> {
  85.199 +    public:
  85.200 +      typedef typename Digraph::Node Node;
  85.201 +      typedef typename Map::Value Value;
  85.202 +
  85.203 +      FillMapVisitor(Map& map, Value& value)
  85.204 +        : _map(map), _value(value) {}
  85.205 +
  85.206 +      void reach(const Node& node) {
  85.207 +        _map.set(node, _value);
  85.208 +      }
  85.209 +    private:
  85.210 +      Map& _map;
  85.211 +      Value& _value;
  85.212 +    };
  85.213 +
  85.214 +    template <typename Digraph, typename ArcMap>
  85.215 +    struct StronglyConnectedCutArcsVisitor : public DfsVisitor<Digraph> {
  85.216 +    public:
  85.217 +      typedef typename Digraph::Node Node;
  85.218 +      typedef typename Digraph::Arc Arc;
  85.219 +
  85.220 +      StronglyConnectedCutArcsVisitor(const Digraph& digraph,
  85.221 +                                      ArcMap& cutMap,
  85.222 +                                      int& cutNum)
  85.223 +        : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
  85.224 +          _compMap(digraph, -1), _num(-1) {
  85.225 +      }
  85.226 +
  85.227 +      void start(const Node&) {
  85.228 +        ++_num;
  85.229 +      }
  85.230 +
  85.231 +      void reach(const Node& node) {
  85.232 +        _compMap.set(node, _num);
  85.233 +      }
  85.234 +
  85.235 +      void examine(const Arc& arc) {
  85.236 +         if (_compMap[_digraph.source(arc)] !=
  85.237 +             _compMap[_digraph.target(arc)]) {
  85.238 +           _cutMap.set(arc, true);
  85.239 +           ++_cutNum;
  85.240 +         }
  85.241 +      }
  85.242 +    private:
  85.243 +      const Digraph& _digraph;
  85.244 +      ArcMap& _cutMap;
  85.245 +      int& _cutNum;
  85.246 +
  85.247 +      typename Digraph::template NodeMap<int> _compMap;
  85.248 +      int _num;
  85.249 +    };
  85.250 +
  85.251 +  }
  85.252 +
  85.253 +
  85.254 +  /// \ingroup graph_properties
  85.255 +  ///
  85.256 +  /// \brief Check whether a directed graph is strongly connected.
  85.257 +  ///
  85.258 +  /// This function checks whether the given directed graph is strongly
  85.259 +  /// connected, i.e. any two nodes of the digraph are
  85.260 +  /// connected with directed paths in both direction.
  85.261 +  ///
  85.262 +  /// \return \c true if the digraph is strongly connected.
  85.263 +  /// \note By definition, the empty digraph is strongly connected.
  85.264 +  /// 
  85.265 +  /// \see countStronglyConnectedComponents(), stronglyConnectedComponents()
  85.266 +  /// \see connected()
  85.267 +  template <typename Digraph>
  85.268 +  bool stronglyConnected(const Digraph& digraph) {
  85.269 +    checkConcept<concepts::Digraph, Digraph>();
  85.270 +
  85.271 +    typedef typename Digraph::Node Node;
  85.272 +    typedef typename Digraph::NodeIt NodeIt;
  85.273 +
  85.274 +    typename Digraph::Node source = NodeIt(digraph);
  85.275 +    if (source == INVALID) return true;
  85.276 +
  85.277 +    using namespace _connectivity_bits;
  85.278 +
  85.279 +    typedef DfsVisitor<Digraph> Visitor;
  85.280 +    Visitor visitor;
  85.281 +
  85.282 +    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
  85.283 +    dfs.init();
  85.284 +    dfs.addSource(source);
  85.285 +    dfs.start();
  85.286 +
  85.287 +    for (NodeIt it(digraph); it != INVALID; ++it) {
  85.288 +      if (!dfs.reached(it)) {
  85.289 +        return false;
  85.290 +      }
  85.291 +    }
  85.292 +
  85.293 +    typedef ReverseDigraph<const Digraph> RDigraph;
  85.294 +    typedef typename RDigraph::NodeIt RNodeIt;
  85.295 +    RDigraph rdigraph(digraph);
  85.296 +
  85.297 +    typedef DfsVisitor<RDigraph> RVisitor;
  85.298 +    RVisitor rvisitor;
  85.299 +
  85.300 +    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
  85.301 +    rdfs.init();
  85.302 +    rdfs.addSource(source);
  85.303 +    rdfs.start();
  85.304 +
  85.305 +    for (RNodeIt it(rdigraph); it != INVALID; ++it) {
  85.306 +      if (!rdfs.reached(it)) {
  85.307 +        return false;
  85.308 +      }
  85.309 +    }
  85.310 +
  85.311 +    return true;
  85.312 +  }
  85.313 +
  85.314 +  /// \ingroup graph_properties
  85.315 +  ///
  85.316 +  /// \brief Count the number of strongly connected components of a 
  85.317 +  /// directed graph
  85.318 +  ///
  85.319 +  /// This function counts the number of strongly connected components of
  85.320 +  /// the given directed graph.
  85.321 +  ///
  85.322 +  /// The strongly connected components are the classes of an
  85.323 +  /// equivalence relation on the nodes of a digraph. Two nodes are in
  85.324 +  /// the same class if they are connected with directed paths in both
  85.325 +  /// direction.
  85.326 +  ///
  85.327 +  /// \return The number of strongly connected components.
  85.328 +  /// \note By definition, the empty digraph has zero
  85.329 +  /// strongly connected components.
  85.330 +  ///
  85.331 +  /// \see stronglyConnected(), stronglyConnectedComponents()
  85.332 +  template <typename Digraph>
  85.333 +  int countStronglyConnectedComponents(const Digraph& digraph) {
  85.334 +    checkConcept<concepts::Digraph, Digraph>();
  85.335 +
  85.336 +    using namespace _connectivity_bits;
  85.337 +
  85.338 +    typedef typename Digraph::Node Node;
  85.339 +    typedef typename Digraph::Arc Arc;
  85.340 +    typedef typename Digraph::NodeIt NodeIt;
  85.341 +    typedef typename Digraph::ArcIt ArcIt;
  85.342 +
  85.343 +    typedef std::vector<Node> Container;
  85.344 +    typedef typename Container::iterator Iterator;
  85.345 +
  85.346 +    Container nodes(countNodes(digraph));
  85.347 +    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
  85.348 +    Visitor visitor(nodes.begin());
  85.349 +
  85.350 +    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
  85.351 +    dfs.init();
  85.352 +    for (NodeIt it(digraph); it != INVALID; ++it) {
  85.353 +      if (!dfs.reached(it)) {
  85.354 +        dfs.addSource(it);
  85.355 +        dfs.start();
  85.356 +      }
  85.357 +    }
  85.358 +
  85.359 +    typedef typename Container::reverse_iterator RIterator;
  85.360 +    typedef ReverseDigraph<const Digraph> RDigraph;
  85.361 +
  85.362 +    RDigraph rdigraph(digraph);
  85.363 +
  85.364 +    typedef DfsVisitor<Digraph> RVisitor;
  85.365 +    RVisitor rvisitor;
  85.366 +
  85.367 +    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
  85.368 +
  85.369 +    int compNum = 0;
  85.370 +
  85.371 +    rdfs.init();
  85.372 +    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
  85.373 +      if (!rdfs.reached(*it)) {
  85.374 +        rdfs.addSource(*it);
  85.375 +        rdfs.start();
  85.376 +        ++compNum;
  85.377 +      }
  85.378 +    }
  85.379 +    return compNum;
  85.380 +  }
  85.381 +
  85.382 +  /// \ingroup graph_properties
  85.383 +  ///
  85.384 +  /// \brief Find the strongly connected components of a directed graph
  85.385 +  ///
  85.386 +  /// This function finds the strongly connected components of the given
  85.387 +  /// directed graph. In addition, the numbering of the components will
  85.388 +  /// satisfy that there is no arc going from a higher numbered component
  85.389 +  /// to a lower one (i.e. it provides a topological order of the components).
  85.390 +  ///
  85.391 +  /// The strongly connected components are the classes of an
  85.392 +  /// equivalence relation on the nodes of a digraph. Two nodes are in
  85.393 +  /// the same class if they are connected with directed paths in both
  85.394 +  /// direction.
  85.395 +  ///
  85.396 +  /// \image html strongly_connected_components.png
  85.397 +  /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
  85.398 +  ///
  85.399 +  /// \param digraph The digraph.
  85.400 +  /// \retval compMap A writable node map. The values will be set from 0 to
  85.401 +  /// the number of the strongly connected components minus one. Each value
  85.402 +  /// of the map will be set exactly once, and the values of a certain
  85.403 +  /// component will be set continuously.
  85.404 +  /// \return The number of strongly connected components.
  85.405 +  /// \note By definition, the empty digraph has zero
  85.406 +  /// strongly connected components.
  85.407 +  ///
  85.408 +  /// \see stronglyConnected(), countStronglyConnectedComponents()
  85.409 +  template <typename Digraph, typename NodeMap>
  85.410 +  int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
  85.411 +    checkConcept<concepts::Digraph, Digraph>();
  85.412 +    typedef typename Digraph::Node Node;
  85.413 +    typedef typename Digraph::NodeIt NodeIt;
  85.414 +    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
  85.415 +
  85.416 +    using namespace _connectivity_bits;
  85.417 +
  85.418 +    typedef std::vector<Node> Container;
  85.419 +    typedef typename Container::iterator Iterator;
  85.420 +
  85.421 +    Container nodes(countNodes(digraph));
  85.422 +    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
  85.423 +    Visitor visitor(nodes.begin());
  85.424 +
  85.425 +    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
  85.426 +    dfs.init();
  85.427 +    for (NodeIt it(digraph); it != INVALID; ++it) {
  85.428 +      if (!dfs.reached(it)) {
  85.429 +        dfs.addSource(it);
  85.430 +        dfs.start();
  85.431 +      }
  85.432 +    }
  85.433 +
  85.434 +    typedef typename Container::reverse_iterator RIterator;
  85.435 +    typedef ReverseDigraph<const Digraph> RDigraph;
  85.436 +
  85.437 +    RDigraph rdigraph(digraph);
  85.438 +
  85.439 +    int compNum = 0;
  85.440 +
  85.441 +    typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
  85.442 +    RVisitor rvisitor(compMap, compNum);
  85.443 +
  85.444 +    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
  85.445 +
  85.446 +    rdfs.init();
  85.447 +    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
  85.448 +      if (!rdfs.reached(*it)) {
  85.449 +        rdfs.addSource(*it);
  85.450 +        rdfs.start();
  85.451 +        ++compNum;
  85.452 +      }
  85.453 +    }
  85.454 +    return compNum;
  85.455 +  }
  85.456 +
  85.457 +  /// \ingroup graph_properties
  85.458 +  ///
  85.459 +  /// \brief Find the cut arcs of the strongly connected components.
  85.460 +  ///
  85.461 +  /// This function finds the cut arcs of the strongly connected components
  85.462 +  /// of the given digraph.
  85.463 +  ///
  85.464 +  /// The strongly connected components are the classes of an
  85.465 +  /// equivalence relation on the nodes of a digraph. Two nodes are in
  85.466 +  /// the same class if they are connected with directed paths in both
  85.467 +  /// direction.
  85.468 +  /// The strongly connected components are separated by the cut arcs.
  85.469 +  ///
  85.470 +  /// \param digraph The digraph.
  85.471 +  /// \retval cutMap A writable arc map. The values will be set to \c true
  85.472 +  /// for the cut arcs (exactly once for each cut arc), and will not be
  85.473 +  /// changed for other arcs.
  85.474 +  /// \return The number of cut arcs.
  85.475 +  ///
  85.476 +  /// \see stronglyConnected(), stronglyConnectedComponents()
  85.477 +  template <typename Digraph, typename ArcMap>
  85.478 +  int stronglyConnectedCutArcs(const Digraph& digraph, ArcMap& cutMap) {
  85.479 +    checkConcept<concepts::Digraph, Digraph>();
  85.480 +    typedef typename Digraph::Node Node;
  85.481 +    typedef typename Digraph::Arc Arc;
  85.482 +    typedef typename Digraph::NodeIt NodeIt;
  85.483 +    checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
  85.484 +
  85.485 +    using namespace _connectivity_bits;
  85.486 +
  85.487 +    typedef std::vector<Node> Container;
  85.488 +    typedef typename Container::iterator Iterator;
  85.489 +
  85.490 +    Container nodes(countNodes(digraph));
  85.491 +    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
  85.492 +    Visitor visitor(nodes.begin());
  85.493 +
  85.494 +    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
  85.495 +    dfs.init();
  85.496 +    for (NodeIt it(digraph); it != INVALID; ++it) {
  85.497 +      if (!dfs.reached(it)) {
  85.498 +        dfs.addSource(it);
  85.499 +        dfs.start();
  85.500 +      }
  85.501 +    }
  85.502 +
  85.503 +    typedef typename Container::reverse_iterator RIterator;
  85.504 +    typedef ReverseDigraph<const Digraph> RDigraph;
  85.505 +
  85.506 +    RDigraph rdigraph(digraph);
  85.507 +
  85.508 +    int cutNum = 0;
  85.509 +
  85.510 +    typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
  85.511 +    RVisitor rvisitor(rdigraph, cutMap, cutNum);
  85.512 +
  85.513 +    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
  85.514 +
  85.515 +    rdfs.init();
  85.516 +    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
  85.517 +      if (!rdfs.reached(*it)) {
  85.518 +        rdfs.addSource(*it);
  85.519 +        rdfs.start();
  85.520 +      }
  85.521 +    }
  85.522 +    return cutNum;
  85.523 +  }
  85.524 +
  85.525 +  namespace _connectivity_bits {
  85.526 +
  85.527 +    template <typename Digraph>
  85.528 +    class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
  85.529 +    public:
  85.530 +      typedef typename Digraph::Node Node;
  85.531 +      typedef typename Digraph::Arc Arc;
  85.532 +      typedef typename Digraph::Edge Edge;
  85.533 +
  85.534 +      CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
  85.535 +        : _graph(graph), _compNum(compNum),
  85.536 +          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
  85.537 +
  85.538 +      void start(const Node& node) {
  85.539 +        _predMap.set(node, INVALID);
  85.540 +      }
  85.541 +
  85.542 +      void reach(const Node& node) {
  85.543 +        _numMap.set(node, _num);
  85.544 +        _retMap.set(node, _num);
  85.545 +        ++_num;
  85.546 +      }
  85.547 +
  85.548 +      void discover(const Arc& edge) {
  85.549 +        _predMap.set(_graph.target(edge), _graph.source(edge));
  85.550 +      }
  85.551 +
  85.552 +      void examine(const Arc& edge) {
  85.553 +        if (_graph.source(edge) == _graph.target(edge) &&
  85.554 +            _graph.direction(edge)) {
  85.555 +          ++_compNum;
  85.556 +          return;
  85.557 +        }
  85.558 +        if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
  85.559 +          return;
  85.560 +        }
  85.561 +        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
  85.562 +          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
  85.563 +        }
  85.564 +      }
  85.565 +
  85.566 +      void backtrack(const Arc& edge) {
  85.567 +        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
  85.568 +          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
  85.569 +        }
  85.570 +        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
  85.571 +          ++_compNum;
  85.572 +        }
  85.573 +      }
  85.574 +
  85.575 +    private:
  85.576 +      const Digraph& _graph;
  85.577 +      int& _compNum;
  85.578 +
  85.579 +      typename Digraph::template NodeMap<int> _numMap;
  85.580 +      typename Digraph::template NodeMap<int> _retMap;
  85.581 +      typename Digraph::template NodeMap<Node> _predMap;
  85.582 +      int _num;
  85.583 +    };
  85.584 +
  85.585 +    template <typename Digraph, typename ArcMap>
  85.586 +    class BiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
  85.587 +    public:
  85.588 +      typedef typename Digraph::Node Node;
  85.589 +      typedef typename Digraph::Arc Arc;
  85.590 +      typedef typename Digraph::Edge Edge;
  85.591 +
  85.592 +      BiNodeConnectedComponentsVisitor(const Digraph& graph,
  85.593 +                                       ArcMap& compMap, int &compNum)
  85.594 +        : _graph(graph), _compMap(compMap), _compNum(compNum),
  85.595 +          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
  85.596 +
  85.597 +      void start(const Node& node) {
  85.598 +        _predMap.set(node, INVALID);
  85.599 +      }
  85.600 +
  85.601 +      void reach(const Node& node) {
  85.602 +        _numMap.set(node, _num);
  85.603 +        _retMap.set(node, _num);
  85.604 +        ++_num;
  85.605 +      }
  85.606 +
  85.607 +      void discover(const Arc& edge) {
  85.608 +        Node target = _graph.target(edge);
  85.609 +        _predMap.set(target, edge);
  85.610 +        _edgeStack.push(edge);
  85.611 +      }
  85.612 +
  85.613 +      void examine(const Arc& edge) {
  85.614 +        Node source = _graph.source(edge);
  85.615 +        Node target = _graph.target(edge);
  85.616 +        if (source == target && _graph.direction(edge)) {
  85.617 +          _compMap.set(edge, _compNum);
  85.618 +          ++_compNum;
  85.619 +          return;
  85.620 +        }
  85.621 +        if (_numMap[target] < _numMap[source]) {
  85.622 +          if (_predMap[source] != _graph.oppositeArc(edge)) {
  85.623 +            _edgeStack.push(edge);
  85.624 +          }
  85.625 +        }
  85.626 +        if (_predMap[source] != INVALID &&
  85.627 +            target == _graph.source(_predMap[source])) {
  85.628 +          return;
  85.629 +        }
  85.630 +        if (_retMap[source] > _numMap[target]) {
  85.631 +          _retMap.set(source, _numMap[target]);
  85.632 +        }
  85.633 +      }
  85.634 +
  85.635 +      void backtrack(const Arc& edge) {
  85.636 +        Node source = _graph.source(edge);
  85.637 +        Node target = _graph.target(edge);
  85.638 +        if (_retMap[source] > _retMap[target]) {
  85.639 +          _retMap.set(source, _retMap[target]);
  85.640 +        }
  85.641 +        if (_numMap[source] <= _retMap[target]) {
  85.642 +          while (_edgeStack.top() != edge) {
  85.643 +            _compMap.set(_edgeStack.top(), _compNum);
  85.644 +            _edgeStack.pop();
  85.645 +          }
  85.646 +          _compMap.set(edge, _compNum);
  85.647 +          _edgeStack.pop();
  85.648 +          ++_compNum;
  85.649 +        }
  85.650 +      }
  85.651 +
  85.652 +    private:
  85.653 +      const Digraph& _graph;
  85.654 +      ArcMap& _compMap;
  85.655 +      int& _compNum;
  85.656 +
  85.657 +      typename Digraph::template NodeMap<int> _numMap;
  85.658 +      typename Digraph::template NodeMap<int> _retMap;
  85.659 +      typename Digraph::template NodeMap<Arc> _predMap;
  85.660 +      std::stack<Edge> _edgeStack;
  85.661 +      int _num;
  85.662 +    };
  85.663 +
  85.664 +
  85.665 +    template <typename Digraph, typename NodeMap>
  85.666 +    class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Digraph> {
  85.667 +    public:
  85.668 +      typedef typename Digraph::Node Node;
  85.669 +      typedef typename Digraph::Arc Arc;
  85.670 +      typedef typename Digraph::Edge Edge;
  85.671 +
  85.672 +      BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap,
  85.673 +                                     int& cutNum)
  85.674 +        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
  85.675 +          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
  85.676 +
  85.677 +      void start(const Node& node) {
  85.678 +        _predMap.set(node, INVALID);
  85.679 +        rootCut = false;
  85.680 +      }
  85.681 +
  85.682 +      void reach(const Node& node) {
  85.683 +        _numMap.set(node, _num);
  85.684 +        _retMap.set(node, _num);
  85.685 +        ++_num;
  85.686 +      }
  85.687 +
  85.688 +      void discover(const Arc& edge) {
  85.689 +        _predMap.set(_graph.target(edge), _graph.source(edge));
  85.690 +      }
  85.691 +
  85.692 +      void examine(const Arc& edge) {
  85.693 +        if (_graph.source(edge) == _graph.target(edge) &&
  85.694 +            _graph.direction(edge)) {
  85.695 +          if (!_cutMap[_graph.source(edge)]) {
  85.696 +            _cutMap.set(_graph.source(edge), true);
  85.697 +            ++_cutNum;
  85.698 +          }
  85.699 +          return;
  85.700 +        }
  85.701 +        if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
  85.702 +        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
  85.703 +          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
  85.704 +        }
  85.705 +      }
  85.706 +
  85.707 +      void backtrack(const Arc& edge) {
  85.708 +        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
  85.709 +          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
  85.710 +        }
  85.711 +        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
  85.712 +          if (_predMap[_graph.source(edge)] != INVALID) {
  85.713 +            if (!_cutMap[_graph.source(edge)]) {
  85.714 +              _cutMap.set(_graph.source(edge), true);
  85.715 +              ++_cutNum;
  85.716 +            }
  85.717 +          } else if (rootCut) {
  85.718 +            if (!_cutMap[_graph.source(edge)]) {
  85.719 +              _cutMap.set(_graph.source(edge), true);
  85.720 +              ++_cutNum;
  85.721 +            }
  85.722 +          } else {
  85.723 +            rootCut = true;
  85.724 +          }
  85.725 +        }
  85.726 +      }
  85.727 +
  85.728 +    private:
  85.729 +      const Digraph& _graph;
  85.730 +      NodeMap& _cutMap;
  85.731 +      int& _cutNum;
  85.732 +
  85.733 +      typename Digraph::template NodeMap<int> _numMap;
  85.734 +      typename Digraph::template NodeMap<int> _retMap;
  85.735 +      typename Digraph::template NodeMap<Node> _predMap;
  85.736 +      std::stack<Edge> _edgeStack;
  85.737 +      int _num;
  85.738 +      bool rootCut;
  85.739 +    };
  85.740 +
  85.741 +  }
  85.742 +
  85.743 +  template <typename Graph>
  85.744 +  int countBiNodeConnectedComponents(const Graph& graph);
  85.745 +
  85.746 +  /// \ingroup graph_properties
  85.747 +  ///
  85.748 +  /// \brief Check whether an undirected graph is bi-node-connected.
  85.749 +  ///
  85.750 +  /// This function checks whether the given undirected graph is 
  85.751 +  /// bi-node-connected, i.e. any two edges are on same circle.
  85.752 +  ///
  85.753 +  /// \return \c true if the graph bi-node-connected.
  85.754 +  /// \note By definition, the empty graph is bi-node-connected.
  85.755 +  ///
  85.756 +  /// \see countBiNodeConnectedComponents(), biNodeConnectedComponents()
  85.757 +  template <typename Graph>
  85.758 +  bool biNodeConnected(const Graph& graph) {
  85.759 +    return countBiNodeConnectedComponents(graph) <= 1;
  85.760 +  }
  85.761 +
  85.762 +  /// \ingroup graph_properties
  85.763 +  ///
  85.764 +  /// \brief Count the number of bi-node-connected components of an 
  85.765 +  /// undirected graph.
  85.766 +  ///
  85.767 +  /// This function counts the number of bi-node-connected components of
  85.768 +  /// the given undirected graph.
  85.769 +  ///
  85.770 +  /// The bi-node-connected components are the classes of an equivalence
  85.771 +  /// relation on the edges of a undirected graph. Two edges are in the
  85.772 +  /// same class if they are on same circle.
  85.773 +  ///
  85.774 +  /// \return The number of bi-node-connected components.
  85.775 +  ///
  85.776 +  /// \see biNodeConnected(), biNodeConnectedComponents()
  85.777 +  template <typename Graph>
  85.778 +  int countBiNodeConnectedComponents(const Graph& graph) {
  85.779 +    checkConcept<concepts::Graph, Graph>();
  85.780 +    typedef typename Graph::NodeIt NodeIt;
  85.781 +
  85.782 +    using namespace _connectivity_bits;
  85.783 +
  85.784 +    typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
  85.785 +
  85.786 +    int compNum = 0;
  85.787 +    Visitor visitor(graph, compNum);
  85.788 +
  85.789 +    DfsVisit<Graph, Visitor> dfs(graph, visitor);
  85.790 +    dfs.init();
  85.791 +
  85.792 +    for (NodeIt it(graph); it != INVALID; ++it) {
  85.793 +      if (!dfs.reached(it)) {
  85.794 +        dfs.addSource(it);
  85.795 +        dfs.start();
  85.796 +      }
  85.797 +    }
  85.798 +    return compNum;
  85.799 +  }
  85.800 +
  85.801 +  /// \ingroup graph_properties
  85.802 +  ///
  85.803 +  /// \brief Find the bi-node-connected components of an undirected graph.
  85.804 +  ///
  85.805 +  /// This function finds the bi-node-connected components of the given
  85.806 +  /// undirected graph.
  85.807 +  ///
  85.808 +  /// The bi-node-connected components are the classes of an equivalence
  85.809 +  /// relation on the edges of a undirected graph. Two edges are in the
  85.810 +  /// same class if they are on same circle.
  85.811 +  ///
  85.812 +  /// \image html node_biconnected_components.png
  85.813 +  /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
  85.814 +  ///
  85.815 +  /// \param graph The undirected graph.
  85.816 +  /// \retval compMap A writable edge map. The values will be set from 0
  85.817 +  /// to the number of the bi-node-connected components minus one. Each
  85.818 +  /// value of the map will be set exactly once, and the values of a 
  85.819 +  /// certain component will be set continuously.
  85.820 +  /// \return The number of bi-node-connected components.
  85.821 +  ///
  85.822 +  /// \see biNodeConnected(), countBiNodeConnectedComponents()
  85.823 +  template <typename Graph, typename EdgeMap>
  85.824 +  int biNodeConnectedComponents(const Graph& graph,
  85.825 +                                EdgeMap& compMap) {
  85.826 +    checkConcept<concepts::Graph, Graph>();
  85.827 +    typedef typename Graph::NodeIt NodeIt;
  85.828 +    typedef typename Graph::Edge Edge;
  85.829 +    checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
  85.830 +
  85.831 +    using namespace _connectivity_bits;
  85.832 +
  85.833 +    typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
  85.834 +
  85.835 +    int compNum = 0;
  85.836 +    Visitor visitor(graph, compMap, compNum);
  85.837 +
  85.838 +    DfsVisit<Graph, Visitor> dfs(graph, visitor);
  85.839 +    dfs.init();
  85.840 +
  85.841 +    for (NodeIt it(graph); it != INVALID; ++it) {
  85.842 +      if (!dfs.reached(it)) {
  85.843 +        dfs.addSource(it);
  85.844 +        dfs.start();
  85.845 +      }
  85.846 +    }
  85.847 +    return compNum;
  85.848 +  }
  85.849 +
  85.850 +  /// \ingroup graph_properties
  85.851 +  ///
  85.852 +  /// \brief Find the bi-node-connected cut nodes in an undirected graph.
  85.853 +  ///
  85.854 +  /// This function finds the bi-node-connected cut nodes in the given
  85.855 +  /// undirected graph.
  85.856 +  ///
  85.857 +  /// The bi-node-connected components are the classes of an equivalence
  85.858 +  /// relation on the edges of a undirected graph. Two edges are in the
  85.859 +  /// same class if they are on same circle.
  85.860 +  /// The bi-node-connected components are separted by the cut nodes of
  85.861 +  /// the components.
  85.862 +  ///
  85.863 +  /// \param graph The undirected graph.
  85.864 +  /// \retval cutMap A writable node map. The values will be set to 
  85.865 +  /// \c true for the nodes that separate two or more components
  85.866 +  /// (exactly once for each cut node), and will not be changed for
  85.867 +  /// other nodes.
  85.868 +  /// \return The number of the cut nodes.
  85.869 +  ///
  85.870 +  /// \see biNodeConnected(), biNodeConnectedComponents()
  85.871 +  template <typename Graph, typename NodeMap>
  85.872 +  int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
  85.873 +    checkConcept<concepts::Graph, Graph>();
  85.874 +    typedef typename Graph::Node Node;
  85.875 +    typedef typename Graph::NodeIt NodeIt;
  85.876 +    checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
  85.877 +
  85.878 +    using namespace _connectivity_bits;
  85.879 +
  85.880 +    typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
  85.881 +
  85.882 +    int cutNum = 0;
  85.883 +    Visitor visitor(graph, cutMap, cutNum);
  85.884 +
  85.885 +    DfsVisit<Graph, Visitor> dfs(graph, visitor);
  85.886 +    dfs.init();
  85.887 +
  85.888 +    for (NodeIt it(graph); it != INVALID; ++it) {
  85.889 +      if (!dfs.reached(it)) {
  85.890 +        dfs.addSource(it);
  85.891 +        dfs.start();
  85.892 +      }
  85.893 +    }
  85.894 +    return cutNum;
  85.895 +  }
  85.896 +
  85.897 +  namespace _connectivity_bits {
  85.898 +
  85.899 +    template <typename Digraph>
  85.900 +    class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
  85.901 +    public:
  85.902 +      typedef typename Digraph::Node Node;
  85.903 +      typedef typename Digraph::Arc Arc;
  85.904 +      typedef typename Digraph::Edge Edge;
  85.905 +
  85.906 +      CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
  85.907 +        : _graph(graph), _compNum(compNum),
  85.908 +          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
  85.909 +
  85.910 +      void start(const Node& node) {
  85.911 +        _predMap.set(node, INVALID);
  85.912 +      }
  85.913 +
  85.914 +      void reach(const Node& node) {
  85.915 +        _numMap.set(node, _num);
  85.916 +        _retMap.set(node, _num);
  85.917 +        ++_num;
  85.918 +      }
  85.919 +
  85.920 +      void leave(const Node& node) {
  85.921 +        if (_numMap[node] <= _retMap[node]) {
  85.922 +          ++_compNum;
  85.923 +        }
  85.924 +      }
  85.925 +
  85.926 +      void discover(const Arc& edge) {
  85.927 +        _predMap.set(_graph.target(edge), edge);
  85.928 +      }
  85.929 +
  85.930 +      void examine(const Arc& edge) {
  85.931 +        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
  85.932 +          return;
  85.933 +        }
  85.934 +        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
  85.935 +          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
  85.936 +        }
  85.937 +      }
  85.938 +
  85.939 +      void backtrack(const Arc& edge) {
  85.940 +        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
  85.941 +          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
  85.942 +        }
  85.943 +      }
  85.944 +
  85.945 +    private:
  85.946 +      const Digraph& _graph;
  85.947 +      int& _compNum;
  85.948 +
  85.949 +      typename Digraph::template NodeMap<int> _numMap;
  85.950 +      typename Digraph::template NodeMap<int> _retMap;
  85.951 +      typename Digraph::template NodeMap<Arc> _predMap;
  85.952 +      int _num;
  85.953 +    };
  85.954 +
  85.955 +    template <typename Digraph, typename NodeMap>
  85.956 +    class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
  85.957 +    public:
  85.958 +      typedef typename Digraph::Node Node;
  85.959 +      typedef typename Digraph::Arc Arc;
  85.960 +      typedef typename Digraph::Edge Edge;
  85.961 +
  85.962 +      BiEdgeConnectedComponentsVisitor(const Digraph& graph,
  85.963 +                                       NodeMap& compMap, int &compNum)
  85.964 +        : _graph(graph), _compMap(compMap), _compNum(compNum),
  85.965 +          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
  85.966 +
  85.967 +      void start(const Node& node) {
  85.968 +        _predMap.set(node, INVALID);
  85.969 +      }
  85.970 +
  85.971 +      void reach(const Node& node) {
  85.972 +        _numMap.set(node, _num);
  85.973 +        _retMap.set(node, _num);
  85.974 +        _nodeStack.push(node);
  85.975 +        ++_num;
  85.976 +      }
  85.977 +
  85.978 +      void leave(const Node& node) {
  85.979 +        if (_numMap[node] <= _retMap[node]) {
  85.980 +          while (_nodeStack.top() != node) {
  85.981 +            _compMap.set(_nodeStack.top(), _compNum);
  85.982 +            _nodeStack.pop();
  85.983 +          }
  85.984 +          _compMap.set(node, _compNum);
  85.985 +          _nodeStack.pop();
  85.986 +          ++_compNum;
  85.987 +        }
  85.988 +      }
  85.989 +
  85.990 +      void discover(const Arc& edge) {
  85.991 +        _predMap.set(_graph.target(edge), edge);
  85.992 +      }
  85.993 +
  85.994 +      void examine(const Arc& edge) {
  85.995 +        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
  85.996 +          return;
  85.997 +        }
  85.998 +        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
  85.999 +          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
 85.1000 +        }
 85.1001 +      }
 85.1002 +
 85.1003 +      void backtrack(const Arc& edge) {
 85.1004 +        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
 85.1005 +          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
 85.1006 +        }
 85.1007 +      }
 85.1008 +
 85.1009 +    private:
 85.1010 +      const Digraph& _graph;
 85.1011 +      NodeMap& _compMap;
 85.1012 +      int& _compNum;
 85.1013 +
 85.1014 +      typename Digraph::template NodeMap<int> _numMap;
 85.1015 +      typename Digraph::template NodeMap<int> _retMap;
 85.1016 +      typename Digraph::template NodeMap<Arc> _predMap;
 85.1017 +      std::stack<Node> _nodeStack;
 85.1018 +      int _num;
 85.1019 +    };
 85.1020 +
 85.1021 +
 85.1022 +    template <typename Digraph, typename ArcMap>
 85.1023 +    class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
 85.1024 +    public:
 85.1025 +      typedef typename Digraph::Node Node;
 85.1026 +      typedef typename Digraph::Arc Arc;
 85.1027 +      typedef typename Digraph::Edge Edge;
 85.1028 +
 85.1029 +      BiEdgeConnectedCutEdgesVisitor(const Digraph& graph,
 85.1030 +                                     ArcMap& cutMap, int &cutNum)
 85.1031 +        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
 85.1032 +          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
 85.1033 +
 85.1034 +      void start(const Node& node) {
 85.1035 +        _predMap[node] = INVALID;
 85.1036 +      }
 85.1037 +
 85.1038 +      void reach(const Node& node) {
 85.1039 +        _numMap.set(node, _num);
 85.1040 +        _retMap.set(node, _num);
 85.1041 +        ++_num;
 85.1042 +      }
 85.1043 +
 85.1044 +      void leave(const Node& node) {
 85.1045 +        if (_numMap[node] <= _retMap[node]) {
 85.1046 +          if (_predMap[node] != INVALID) {
 85.1047 +            _cutMap.set(_predMap[node], true);
 85.1048 +            ++_cutNum;
 85.1049 +          }
 85.1050 +        }
 85.1051 +      }
 85.1052 +
 85.1053 +      void discover(const Arc& edge) {
 85.1054 +        _predMap.set(_graph.target(edge), edge);
 85.1055 +      }
 85.1056 +
 85.1057 +      void examine(const Arc& edge) {
 85.1058 +        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
 85.1059 +          return;
 85.1060 +        }
 85.1061 +        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
 85.1062 +          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
 85.1063 +        }
 85.1064 +      }
 85.1065 +
 85.1066 +      void backtrack(const Arc& edge) {
 85.1067 +        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
 85.1068 +          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
 85.1069 +        }
 85.1070 +      }
 85.1071 +
 85.1072 +    private:
 85.1073 +      const Digraph& _graph;
 85.1074 +      ArcMap& _cutMap;
 85.1075 +      int& _cutNum;
 85.1076 +
 85.1077 +      typename Digraph::template NodeMap<int> _numMap;
 85.1078 +      typename Digraph::template NodeMap<int> _retMap;
 85.1079 +      typename Digraph::template NodeMap<Arc> _predMap;
 85.1080 +      int _num;
 85.1081 +    };
 85.1082 +  }
 85.1083 +
 85.1084 +  template <typename Graph>
 85.1085 +  int countBiEdgeConnectedComponents(const Graph& graph);
 85.1086 +
 85.1087 +  /// \ingroup graph_properties
 85.1088 +  ///
 85.1089 +  /// \brief Check whether an undirected graph is bi-edge-connected.
 85.1090 +  ///
 85.1091 +  /// This function checks whether the given undirected graph is 
 85.1092 +  /// bi-edge-connected, i.e. any two nodes are connected with at least
 85.1093 +  /// two edge-disjoint paths.
 85.1094 +  ///
 85.1095 +  /// \return \c true if the graph is bi-edge-connected.
 85.1096 +  /// \note By definition, the empty graph is bi-edge-connected.
 85.1097 +  ///
 85.1098 +  /// \see countBiEdgeConnectedComponents(), biEdgeConnectedComponents()
 85.1099 +  template <typename Graph>
 85.1100 +  bool biEdgeConnected(const Graph& graph) {
 85.1101 +    return countBiEdgeConnectedComponents(graph) <= 1;
 85.1102 +  }
 85.1103 +
 85.1104 +  /// \ingroup graph_properties
 85.1105 +  ///
 85.1106 +  /// \brief Count the number of bi-edge-connected components of an
 85.1107 +  /// undirected graph.
 85.1108 +  ///
 85.1109 +  /// This function counts the number of bi-edge-connected components of
 85.1110 +  /// the given undirected graph.
 85.1111 +  ///
 85.1112 +  /// The bi-edge-connected components are the classes of an equivalence
 85.1113 +  /// relation on the nodes of an undirected graph. Two nodes are in the
 85.1114 +  /// same class if they are connected with at least two edge-disjoint
 85.1115 +  /// paths.
 85.1116 +  ///
 85.1117 +  /// \return The number of bi-edge-connected components.
 85.1118 +  ///
 85.1119 +  /// \see biEdgeConnected(), biEdgeConnectedComponents()
 85.1120 +  template <typename Graph>
 85.1121 +  int countBiEdgeConnectedComponents(const Graph& graph) {
 85.1122 +    checkConcept<concepts::Graph, Graph>();
 85.1123 +    typedef typename Graph::NodeIt NodeIt;
 85.1124 +
 85.1125 +    using namespace _connectivity_bits;
 85.1126 +
 85.1127 +    typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
 85.1128 +
 85.1129 +    int compNum = 0;
 85.1130 +    Visitor visitor(graph, compNum);
 85.1131 +
 85.1132 +    DfsVisit<Graph, Visitor> dfs(graph, visitor);
 85.1133 +    dfs.init();
 85.1134 +
 85.1135 +    for (NodeIt it(graph); it != INVALID; ++it) {
 85.1136 +      if (!dfs.reached(it)) {
 85.1137 +        dfs.addSource(it);
 85.1138 +        dfs.start();
 85.1139 +      }
 85.1140 +    }
 85.1141 +    return compNum;
 85.1142 +  }
 85.1143 +
 85.1144 +  /// \ingroup graph_properties
 85.1145 +  ///
 85.1146 +  /// \brief Find the bi-edge-connected components of an undirected graph.
 85.1147 +  ///
 85.1148 +  /// This function finds the bi-edge-connected components of the given
 85.1149 +  /// undirected graph.
 85.1150 +  ///
 85.1151 +  /// The bi-edge-connected components are the classes of an equivalence
 85.1152 +  /// relation on the nodes of an undirected graph. Two nodes are in the
 85.1153 +  /// same class if they are connected with at least two edge-disjoint
 85.1154 +  /// paths.
 85.1155 +  ///
 85.1156 +  /// \image html edge_biconnected_components.png
 85.1157 +  /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
 85.1158 +  ///
 85.1159 +  /// \param graph The undirected graph.
 85.1160 +  /// \retval compMap A writable node map. The values will be set from 0 to
 85.1161 +  /// the number of the bi-edge-connected components minus one. Each value
 85.1162 +  /// of the map will be set exactly once, and the values of a certain
 85.1163 +  /// component will be set continuously.
 85.1164 +  /// \return The number of bi-edge-connected components.
 85.1165 +  ///
 85.1166 +  /// \see biEdgeConnected(), countBiEdgeConnectedComponents()
 85.1167 +  template <typename Graph, typename NodeMap>
 85.1168 +  int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
 85.1169 +    checkConcept<concepts::Graph, Graph>();
 85.1170 +    typedef typename Graph::NodeIt NodeIt;
 85.1171 +    typedef typename Graph::Node Node;
 85.1172 +    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
 85.1173 +
 85.1174 +    using namespace _connectivity_bits;
 85.1175 +
 85.1176 +    typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
 85.1177 +
 85.1178 +    int compNum = 0;
 85.1179 +    Visitor visitor(graph, compMap, compNum);
 85.1180 +
 85.1181 +    DfsVisit<Graph, Visitor> dfs(graph, visitor);
 85.1182 +    dfs.init();
 85.1183 +
 85.1184 +    for (NodeIt it(graph); it != INVALID; ++it) {
 85.1185 +      if (!dfs.reached(it)) {
 85.1186 +        dfs.addSource(it);
 85.1187 +        dfs.start();
 85.1188 +      }
 85.1189 +    }
 85.1190 +    return compNum;
 85.1191 +  }
 85.1192 +
 85.1193 +  /// \ingroup graph_properties
 85.1194 +  ///
 85.1195 +  /// \brief Find the bi-edge-connected cut edges in an undirected graph.
 85.1196 +  ///
 85.1197 +  /// This function finds the bi-edge-connected cut edges in the given
 85.1198 +  /// undirected graph. 
 85.1199 +  ///
 85.1200 +  /// The bi-edge-connected components are the classes of an equivalence
 85.1201 +  /// relation on the nodes of an undirected graph. Two nodes are in the
 85.1202 +  /// same class if they are connected with at least two edge-disjoint
 85.1203 +  /// paths.
 85.1204 +  /// The bi-edge-connected components are separted by the cut edges of
 85.1205 +  /// the components.
 85.1206 +  ///
 85.1207 +  /// \param graph The undirected graph.
 85.1208 +  /// \retval cutMap A writable edge map. The values will be set to \c true
 85.1209 +  /// for the cut edges (exactly once for each cut edge), and will not be
 85.1210 +  /// changed for other edges.
 85.1211 +  /// \return The number of cut edges.
 85.1212 +  ///
 85.1213 +  /// \see biEdgeConnected(), biEdgeConnectedComponents()
 85.1214 +  template <typename Graph, typename EdgeMap>
 85.1215 +  int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
 85.1216 +    checkConcept<concepts::Graph, Graph>();
 85.1217 +    typedef typename Graph::NodeIt NodeIt;
 85.1218 +    typedef typename Graph::Edge Edge;
 85.1219 +    checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
 85.1220 +
 85.1221 +    using namespace _connectivity_bits;
 85.1222 +
 85.1223 +    typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
 85.1224 +
 85.1225 +    int cutNum = 0;
 85.1226 +    Visitor visitor(graph, cutMap, cutNum);
 85.1227 +
 85.1228 +    DfsVisit<Graph, Visitor> dfs(graph, visitor);
 85.1229 +    dfs.init();
 85.1230 +
 85.1231 +    for (NodeIt it(graph); it != INVALID; ++it) {
 85.1232 +      if (!dfs.reached(it)) {
 85.1233 +        dfs.addSource(it);
 85.1234 +        dfs.start();
 85.1235 +      }
 85.1236 +    }
 85.1237 +    return cutNum;
 85.1238 +  }
 85.1239 +
 85.1240 +
 85.1241 +  namespace _connectivity_bits {
 85.1242 +
 85.1243 +    template <typename Digraph, typename IntNodeMap>
 85.1244 +    class TopologicalSortVisitor : public DfsVisitor<Digraph> {
 85.1245 +    public:
 85.1246 +      typedef typename Digraph::Node Node;
 85.1247 +      typedef typename Digraph::Arc edge;
 85.1248 +
 85.1249 +      TopologicalSortVisitor(IntNodeMap& order, int num)
 85.1250 +        : _order(order), _num(num) {}
 85.1251 +
 85.1252 +      void leave(const Node& node) {
 85.1253 +        _order.set(node, --_num);
 85.1254 +      }
 85.1255 +
 85.1256 +    private:
 85.1257 +      IntNodeMap& _order;
 85.1258 +      int _num;
 85.1259 +    };
 85.1260 +
 85.1261 +  }
 85.1262 +
 85.1263 +  /// \ingroup graph_properties
 85.1264 +  ///
 85.1265 +  /// \brief Check whether a digraph is DAG.
 85.1266 +  ///
 85.1267 +  /// This function checks whether the given digraph is DAG, i.e.
 85.1268 +  /// \e Directed \e Acyclic \e Graph.
 85.1269 +  /// \return \c true if there is no directed cycle in the digraph.
 85.1270 +  /// \see acyclic()
 85.1271 +  template <typename Digraph>
 85.1272 +  bool dag(const Digraph& digraph) {
 85.1273 +
 85.1274 +    checkConcept<concepts::Digraph, Digraph>();
 85.1275 +
 85.1276 +    typedef typename Digraph::Node Node;
 85.1277 +    typedef typename Digraph::NodeIt NodeIt;
 85.1278 +    typedef typename Digraph::Arc Arc;
 85.1279 +
 85.1280 +    typedef typename Digraph::template NodeMap<bool> ProcessedMap;
 85.1281 +
 85.1282 +    typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
 85.1283 +      Create dfs(digraph);
 85.1284 +
 85.1285 +    ProcessedMap processed(digraph);
 85.1286 +    dfs.processedMap(processed);
 85.1287 +
 85.1288 +    dfs.init();
 85.1289 +    for (NodeIt it(digraph); it != INVALID; ++it) {
 85.1290 +      if (!dfs.reached(it)) {
 85.1291 +        dfs.addSource(it);
 85.1292 +        while (!dfs.emptyQueue()) {
 85.1293 +          Arc arc = dfs.nextArc();
 85.1294 +          Node target = digraph.target(arc);
 85.1295 +          if (dfs.reached(target) && !processed[target]) {
 85.1296 +            return false;
 85.1297 +          }
 85.1298 +          dfs.processNextArc();
 85.1299 +        }
 85.1300 +      }
 85.1301 +    }
 85.1302 +    return true;
 85.1303 +  }
 85.1304 +
 85.1305 +  /// \ingroup graph_properties
 85.1306 +  ///
 85.1307 +  /// \brief Sort the nodes of a DAG into topolgical order.
 85.1308 +  ///
 85.1309 +  /// This function sorts the nodes of the given acyclic digraph (DAG)
 85.1310 +  /// into topolgical order.
 85.1311 +  ///
 85.1312 +  /// \param digraph The digraph, which must be DAG.
 85.1313 +  /// \retval order A writable node map. The values will be set from 0 to
 85.1314 +  /// the number of the nodes in the digraph minus one. Each value of the
 85.1315 +  /// map will be set exactly once, and the values will be set descending
 85.1316 +  /// order.
 85.1317 +  ///
 85.1318 +  /// \see dag(), checkedTopologicalSort()
 85.1319 +  template <typename Digraph, typename NodeMap>
 85.1320 +  void topologicalSort(const Digraph& digraph, NodeMap& order) {
 85.1321 +    using namespace _connectivity_bits;
 85.1322 +
 85.1323 +    checkConcept<concepts::Digraph, Digraph>();
 85.1324 +    checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
 85.1325 +
 85.1326 +    typedef typename Digraph::Node Node;
 85.1327 +    typedef typename Digraph::NodeIt NodeIt;
 85.1328 +    typedef typename Digraph::Arc Arc;
 85.1329 +
 85.1330 +    TopologicalSortVisitor<Digraph, NodeMap>
 85.1331 +      visitor(order, countNodes(digraph));
 85.1332 +
 85.1333 +    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
 85.1334 +      dfs(digraph, visitor);
 85.1335 +
 85.1336 +    dfs.init();
 85.1337 +    for (NodeIt it(digraph); it != INVALID; ++it) {
 85.1338 +      if (!dfs.reached(it)) {
 85.1339 +        dfs.addSource(it);
 85.1340 +        dfs.start();
 85.1341 +      }
 85.1342 +    }
 85.1343 +  }
 85.1344 +
 85.1345 +  /// \ingroup graph_properties
 85.1346 +  ///
 85.1347 +  /// \brief Sort the nodes of a DAG into topolgical order.
 85.1348 +  ///
 85.1349 +  /// This function sorts the nodes of the given acyclic digraph (DAG)
 85.1350 +  /// into topolgical order and also checks whether the given digraph
 85.1351 +  /// is DAG.
 85.1352 +  ///
 85.1353 +  /// \param digraph The digraph.
 85.1354 +  /// \retval order A readable and writable node map. The values will be
 85.1355 +  /// set from 0 to the number of the nodes in the digraph minus one. 
 85.1356 +  /// Each value of the map will be set exactly once, and the values will
 85.1357 +  /// be set descending order.
 85.1358 +  /// \return \c false if the digraph is not DAG.
 85.1359 +  ///
 85.1360 +  /// \see dag(), topologicalSort()
 85.1361 +  template <typename Digraph, typename NodeMap>
 85.1362 +  bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
 85.1363 +    using namespace _connectivity_bits;
 85.1364 +
 85.1365 +    checkConcept<concepts::Digraph, Digraph>();
 85.1366 +    checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
 85.1367 +      NodeMap>();
 85.1368 +
 85.1369 +    typedef typename Digraph::Node Node;
 85.1370 +    typedef typename Digraph::NodeIt NodeIt;
 85.1371 +    typedef typename Digraph::Arc Arc;
 85.1372 +
 85.1373 +    for (NodeIt it(digraph); it != INVALID; ++it) {
 85.1374 +      order.set(it, -1);
 85.1375 +    }
 85.1376 +
 85.1377 +    TopologicalSortVisitor<Digraph, NodeMap>
 85.1378 +      visitor(order, countNodes(digraph));
 85.1379 +
 85.1380 +    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
 85.1381 +      dfs(digraph, visitor);
 85.1382 +
 85.1383 +    dfs.init();
 85.1384 +    for (NodeIt it(digraph); it != INVALID; ++it) {
 85.1385 +      if (!dfs.reached(it)) {
 85.1386 +        dfs.addSource(it);
 85.1387 +        while (!dfs.emptyQueue()) {
 85.1388 +           Arc arc = dfs.nextArc();
 85.1389 +           Node target = digraph.target(arc);
 85.1390 +           if (dfs.reached(target) && order[target] == -1) {
 85.1391 +             return false;
 85.1392 +           }
 85.1393 +           dfs.processNextArc();
 85.1394 +         }
 85.1395 +      }
 85.1396 +    }
 85.1397 +    return true;
 85.1398 +  }
 85.1399 +
 85.1400 +  /// \ingroup graph_properties
 85.1401 +  ///
 85.1402 +  /// \brief Check whether an undirected graph is acyclic.
 85.1403 +  ///
 85.1404 +  /// This function checks whether the given undirected graph is acyclic.
 85.1405 +  /// \return \c true if there is no cycle in the graph.
 85.1406 +  /// \see dag()
 85.1407 +  template <typename Graph>
 85.1408 +  bool acyclic(const Graph& graph) {
 85.1409 +    checkConcept<concepts::Graph, Graph>();
 85.1410 +    typedef typename Graph::Node Node;
 85.1411 +    typedef typename Graph::NodeIt NodeIt;
 85.1412 +    typedef typename Graph::Arc Arc;
 85.1413 +    Dfs<Graph> dfs(graph);
 85.1414 +    dfs.init();
 85.1415 +    for (NodeIt it(graph); it != INVALID; ++it) {
 85.1416 +      if (!dfs.reached(it)) {
 85.1417 +        dfs.addSource(it);
 85.1418 +        while (!dfs.emptyQueue()) {
 85.1419 +          Arc arc = dfs.nextArc();
 85.1420 +          Node source = graph.source(arc);
 85.1421 +          Node target = graph.target(arc);
 85.1422 +          if (dfs.reached(target) &&
 85.1423 +              dfs.predArc(source) != graph.oppositeArc(arc)) {
 85.1424 +            return false;
 85.1425 +          }
 85.1426 +          dfs.processNextArc();
 85.1427 +        }
 85.1428 +      }
 85.1429 +    }
 85.1430 +    return true;
 85.1431 +  }
 85.1432 +
 85.1433 +  /// \ingroup graph_properties
 85.1434 +  ///
 85.1435 +  /// \brief Check whether an undirected graph is tree.
 85.1436 +  ///
 85.1437 +  /// This function checks whether the given undirected graph is tree.
 85.1438 +  /// \return \c true if the graph is acyclic and connected.
 85.1439 +  /// \see acyclic(), connected()
 85.1440 +  template <typename Graph>
 85.1441 +  bool tree(const Graph& graph) {
 85.1442 +    checkConcept<concepts::Graph, Graph>();
 85.1443 +    typedef typename Graph::Node Node;
 85.1444 +    typedef typename Graph::NodeIt NodeIt;
 85.1445 +    typedef typename Graph::Arc Arc;
 85.1446 +    if (NodeIt(graph) == INVALID) return true;
 85.1447 +    Dfs<Graph> dfs(graph);
 85.1448 +    dfs.init();
 85.1449 +    dfs.addSource(NodeIt(graph));
 85.1450 +    while (!dfs.emptyQueue()) {
 85.1451 +      Arc arc = dfs.nextArc();
 85.1452 +      Node source = graph.source(arc);
 85.1453 +      Node target = graph.target(arc);
 85.1454 +      if (dfs.reached(target) &&
 85.1455 +          dfs.predArc(source) != graph.oppositeArc(arc)) {
 85.1456 +        return false;
 85.1457 +      }
 85.1458 +      dfs.processNextArc();
 85.1459 +    }
 85.1460 +    for (NodeIt it(graph); it != INVALID; ++it) {
 85.1461 +      if (!dfs.reached(it)) {
 85.1462 +        return false;
 85.1463 +      }
 85.1464 +    }
 85.1465 +    return true;
 85.1466 +  }
 85.1467 +
 85.1468 +  namespace _connectivity_bits {
 85.1469 +
 85.1470 +    template <typename Digraph>
 85.1471 +    class BipartiteVisitor : public BfsVisitor<Digraph> {
 85.1472 +    public:
 85.1473 +      typedef typename Digraph::Arc Arc;
 85.1474 +      typedef typename Digraph::Node Node;
 85.1475 +
 85.1476 +      BipartiteVisitor(const Digraph& graph, bool& bipartite)
 85.1477 +        : _graph(graph), _part(graph), _bipartite(bipartite) {}
 85.1478 +
 85.1479 +      void start(const Node& node) {
 85.1480 +        _part[node] = true;
 85.1481 +      }
 85.1482 +      void discover(const Arc& edge) {
 85.1483 +        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
 85.1484 +      }
 85.1485 +      void examine(const Arc& edge) {
 85.1486 +        _bipartite = _bipartite &&
 85.1487 +          _part[_graph.target(edge)] != _part[_graph.source(edge)];
 85.1488 +      }
 85.1489 +
 85.1490 +    private:
 85.1491 +
 85.1492 +      const Digraph& _graph;
 85.1493 +      typename Digraph::template NodeMap<bool> _part;
 85.1494 +      bool& _bipartite;
 85.1495 +    };
 85.1496 +
 85.1497 +    template <typename Digraph, typename PartMap>
 85.1498 +    class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
 85.1499 +    public:
 85.1500 +      typedef typename Digraph::Arc Arc;
 85.1501 +      typedef typename Digraph::Node Node;
 85.1502 +
 85.1503 +      BipartitePartitionsVisitor(const Digraph& graph,
 85.1504 +                                 PartMap& part, bool& bipartite)
 85.1505 +        : _graph(graph), _part(part), _bipartite(bipartite) {}
 85.1506 +
 85.1507 +      void start(const Node& node) {
 85.1508 +        _part.set(node, true);
 85.1509 +      }
 85.1510 +      void discover(const Arc& edge) {
 85.1511 +        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
 85.1512 +      }
 85.1513 +      void examine(const Arc& edge) {
 85.1514 +        _bipartite = _bipartite &&
 85.1515 +          _part[_graph.target(edge)] != _part[_graph.source(edge)];
 85.1516 +      }
 85.1517 +
 85.1518 +    private:
 85.1519 +
 85.1520 +      const Digraph& _graph;
 85.1521 +      PartMap& _part;
 85.1522 +      bool& _bipartite;
 85.1523 +    };
 85.1524 +  }
 85.1525 +
 85.1526 +  /// \ingroup graph_properties
 85.1527 +  ///
 85.1528 +  /// \brief Check whether an undirected graph is bipartite.
 85.1529 +  ///
 85.1530 +  /// The function checks whether the given undirected graph is bipartite.
 85.1531 +  /// \return \c true if the graph is bipartite.
 85.1532 +  ///
 85.1533 +  /// \see bipartitePartitions()
 85.1534 +  template<typename Graph>
 85.1535 +  bool bipartite(const Graph &graph){
 85.1536 +    using namespace _connectivity_bits;
 85.1537 +
 85.1538 +    checkConcept<concepts::Graph, Graph>();
 85.1539 +
 85.1540 +    typedef typename Graph::NodeIt NodeIt;
 85.1541 +    typedef typename Graph::ArcIt ArcIt;
 85.1542 +
 85.1543 +    bool bipartite = true;
 85.1544 +
 85.1545 +    BipartiteVisitor<Graph>
 85.1546 +      visitor(graph, bipartite);
 85.1547 +    BfsVisit<Graph, BipartiteVisitor<Graph> >
 85.1548 +      bfs(graph, visitor);
 85.1549 +    bfs.init();
 85.1550 +    for(NodeIt it(graph); it != INVALID; ++it) {
 85.1551 +      if(!bfs.reached(it)){
 85.1552 +        bfs.addSource(it);
 85.1553 +        while (!bfs.emptyQueue()) {
 85.1554 +          bfs.processNextNode();
 85.1555 +          if (!bipartite) return false;
 85.1556 +        }
 85.1557 +      }
 85.1558 +    }
 85.1559 +    return true;
 85.1560 +  }
 85.1561 +
 85.1562 +  /// \ingroup graph_properties
 85.1563 +  ///
 85.1564 +  /// \brief Find the bipartite partitions of an undirected graph.
 85.1565 +  ///
 85.1566 +  /// This function checks whether the given undirected graph is bipartite
 85.1567 +  /// and gives back the bipartite partitions.
 85.1568 +  ///
 85.1569 +  /// \image html bipartite_partitions.png
 85.1570 +  /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
 85.1571 +  ///
 85.1572 +  /// \param graph The undirected graph.
 85.1573 +  /// \retval partMap A writable node map of \c bool (or convertible) value
 85.1574 +  /// type. The values will be set to \c true for one component and
 85.1575 +  /// \c false for the other one.
 85.1576 +  /// \return \c true if the graph is bipartite, \c false otherwise.
 85.1577 +  ///
 85.1578 +  /// \see bipartite()
 85.1579 +  template<typename Graph, typename NodeMap>
 85.1580 +  bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
 85.1581 +    using namespace _connectivity_bits;
 85.1582 +
 85.1583 +    checkConcept<concepts::Graph, Graph>();
 85.1584 +    checkConcept<concepts::WriteMap<typename Graph::Node, bool>, NodeMap>();
 85.1585 +
 85.1586 +    typedef typename Graph::Node Node;
 85.1587 +    typedef typename Graph::NodeIt NodeIt;
 85.1588 +    typedef typename Graph::ArcIt ArcIt;
 85.1589 +
 85.1590 +    bool bipartite = true;
 85.1591 +
 85.1592 +    BipartitePartitionsVisitor<Graph, NodeMap>
 85.1593 +      visitor(graph, partMap, bipartite);
 85.1594 +    BfsVisit<Graph, BipartitePartitionsVisitor<Graph, NodeMap> >
 85.1595 +      bfs(graph, visitor);
 85.1596 +    bfs.init();
 85.1597 +    for(NodeIt it(graph); it != INVALID; ++it) {
 85.1598 +      if(!bfs.reached(it)){
 85.1599 +        bfs.addSource(it);
 85.1600 +        while (!bfs.emptyQueue()) {
 85.1601 +          bfs.processNextNode();
 85.1602 +          if (!bipartite) return false;
 85.1603 +        }
 85.1604 +      }
 85.1605 +    }
 85.1606 +    return true;
 85.1607 +  }
 85.1608 +
 85.1609 +  /// \ingroup graph_properties
 85.1610 +  ///
 85.1611 +  /// \brief Check whether the given graph contains no loop arcs/edges.
 85.1612 +  ///
 85.1613 +  /// This function returns \c true if there are no loop arcs/edges in
 85.1614 +  /// the given graph. It works for both directed and undirected graphs.
 85.1615 +  template <typename Graph>
 85.1616 +  bool loopFree(const Graph& graph) {
 85.1617 +    for (typename Graph::ArcIt it(graph); it != INVALID; ++it) {
 85.1618 +      if (graph.source(it) == graph.target(it)) return false;
 85.1619 +    }
 85.1620 +    return true;
 85.1621 +  }
 85.1622 +
 85.1623 +  /// \ingroup graph_properties
 85.1624 +  ///
 85.1625 +  /// \brief Check whether the given graph contains no parallel arcs/edges.
 85.1626 +  ///
 85.1627 +  /// This function returns \c true if there are no parallel arcs/edges in
 85.1628 +  /// the given graph. It works for both directed and undirected graphs.
 85.1629 +  template <typename Graph>
 85.1630 +  bool parallelFree(const Graph& graph) {
 85.1631 +    typename Graph::template NodeMap<int> reached(graph, 0);
 85.1632 +    int cnt = 1;
 85.1633 +    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
 85.1634 +      for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
 85.1635 +        if (reached[graph.target(a)] == cnt) return false;
 85.1636 +        reached[graph.target(a)] = cnt;
 85.1637 +      }
 85.1638 +      ++cnt;
 85.1639 +    }
 85.1640 +    return true;
 85.1641 +  }
 85.1642 +
 85.1643 +  /// \ingroup graph_properties
 85.1644 +  ///
 85.1645 +  /// \brief Check whether the given graph is simple.
 85.1646 +  ///
 85.1647 +  /// This function returns \c true if the given graph is simple, i.e.
 85.1648 +  /// it contains no loop arcs/edges and no parallel arcs/edges.
 85.1649 +  /// The function works for both directed and undirected graphs.
 85.1650 +  /// \see loopFree(), parallelFree()
 85.1651 +  template <typename Graph>
 85.1652 +  bool simpleGraph(const Graph& graph) {
 85.1653 +    typename Graph::template NodeMap<int> reached(graph, 0);
 85.1654 +    int cnt = 1;
 85.1655 +    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
 85.1656 +      reached[n] = cnt;
 85.1657 +      for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
 85.1658 +        if (reached[graph.target(a)] == cnt) return false;
 85.1659 +        reached[graph.target(a)] = cnt;
 85.1660 +      }
 85.1661 +      ++cnt;
 85.1662 +    }
 85.1663 +    return true;
 85.1664 +  }
 85.1665 +
 85.1666 +} //namespace lemon
 85.1667 +
 85.1668 +#endif //LEMON_CONNECTIVITY_H
    86.1 --- a/lemon/core.h	Fri Oct 16 10:21:37 2009 +0200
    86.2 +++ b/lemon/core.h	Thu Nov 05 15:50:01 2009 +0100
    86.3 @@ -2,7 +2,7 @@
    86.4   *
    86.5   * This file is a part of LEMON, a generic C++ optimization library.
    86.6   *
    86.7 - * Copyright (C) 2003-2008
    86.8 + * Copyright (C) 2003-2009
    86.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   86.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   86.11   *
   86.12 @@ -27,6 +27,16 @@
   86.13  #include <lemon/bits/traits.h>
   86.14  #include <lemon/assert.h>
   86.15  
   86.16 +// Disable the following warnings when compiling with MSVC:
   86.17 +// C4250: 'class1' : inherits 'class2::member' via dominance
   86.18 +// C4355: 'this' : used in base member initializer list
   86.19 +// C4503: 'function' : decorated name length exceeded, name was truncated
   86.20 +// C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
   86.21 +// C4996: 'function': was declared deprecated
   86.22 +#ifdef _MSC_VER
   86.23 +#pragma warning( disable : 4250 4355 4503 4800 4996 )
   86.24 +#endif
   86.25 +
   86.26  ///\file
   86.27  ///\brief LEMON core utilities.
   86.28  ///
   86.29 @@ -1034,28 +1044,27 @@
   86.30    ///
   86.31    ///\sa findArc()
   86.32    ///\sa ArcLookUp, AllArcLookUp, DynArcLookUp
   86.33 -  template <typename _Graph>
   86.34 -  class ConArcIt : public _Graph::Arc {
   86.35 +  template <typename GR>
   86.36 +  class ConArcIt : public GR::Arc {
   86.37 +    typedef typename GR::Arc Parent;
   86.38 +
   86.39    public:
   86.40  
   86.41 -    typedef _Graph Graph;
   86.42 -    typedef typename Graph::Arc Parent;
   86.43 -
   86.44 -    typedef typename Graph::Arc Arc;
   86.45 -    typedef typename Graph::Node Node;
   86.46 +    typedef typename GR::Arc Arc;
   86.47 +    typedef typename GR::Node Node;
   86.48  
   86.49      /// \brief Constructor.
   86.50      ///
   86.51      /// Construct a new ConArcIt iterating on the arcs that
   86.52      /// connects nodes \c u and \c v.
   86.53 -    ConArcIt(const Graph& g, Node u, Node v) : _graph(g) {
   86.54 +    ConArcIt(const GR& g, Node u, Node v) : _graph(g) {
   86.55        Parent::operator=(findArc(_graph, u, v));
   86.56      }
   86.57  
   86.58      /// \brief Constructor.
   86.59      ///
   86.60      /// Construct a new ConArcIt that continues the iterating from arc \c a.
   86.61 -    ConArcIt(const Graph& g, Arc a) : Parent(a), _graph(g) {}
   86.62 +    ConArcIt(const GR& g, Arc a) : Parent(a), _graph(g) {}
   86.63  
   86.64      /// \brief Increment operator.
   86.65      ///
   86.66 @@ -1066,7 +1075,7 @@
   86.67        return *this;
   86.68      }
   86.69    private:
   86.70 -    const Graph& _graph;
   86.71 +    const GR& _graph;
   86.72    };
   86.73  
   86.74    namespace _core_bits {
   86.75 @@ -1157,28 +1166,27 @@
   86.76    ///\endcode
   86.77    ///
   86.78    ///\sa findEdge()
   86.79 -  template <typename _Graph>
   86.80 -  class ConEdgeIt : public _Graph::Edge {
   86.81 +  template <typename GR>
   86.82 +  class ConEdgeIt : public GR::Edge {
   86.83 +    typedef typename GR::Edge Parent;
   86.84 +
   86.85    public:
   86.86  
   86.87 -    typedef _Graph Graph;
   86.88 -    typedef typename Graph::Edge Parent;
   86.89 -
   86.90 -    typedef typename Graph::Edge Edge;
   86.91 -    typedef typename Graph::Node Node;
   86.92 +    typedef typename GR::Edge Edge;
   86.93 +    typedef typename GR::Node Node;
   86.94  
   86.95      /// \brief Constructor.
   86.96      ///
   86.97      /// Construct a new ConEdgeIt iterating on the edges that
   86.98      /// connects nodes \c u and \c v.
   86.99 -    ConEdgeIt(const Graph& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
  86.100 +    ConEdgeIt(const GR& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
  86.101        Parent::operator=(findEdge(_graph, _u, _v));
  86.102      }
  86.103  
  86.104      /// \brief Constructor.
  86.105      ///
  86.106      /// Construct a new ConEdgeIt that continues iterating from edge \c e.
  86.107 -    ConEdgeIt(const Graph& g, Edge e) : Parent(e), _graph(g) {}
  86.108 +    ConEdgeIt(const GR& g, Edge e) : Parent(e), _graph(g) {}
  86.109  
  86.110      /// \brief Increment operator.
  86.111      ///
  86.112 @@ -1188,7 +1196,7 @@
  86.113        return *this;
  86.114      }
  86.115    private:
  86.116 -    const Graph& _graph;
  86.117 +    const GR& _graph;
  86.118      Node _u, _v;
  86.119    };
  86.120  
  86.121 @@ -1211,29 +1219,32 @@
  86.122    ///optimal time bound in a constant factor for any distribution of
  86.123    ///queries.
  86.124    ///
  86.125 -  ///\tparam G The type of the underlying digraph.
  86.126 +  ///\tparam GR The type of the underlying digraph.
  86.127    ///
  86.128    ///\sa ArcLookUp
  86.129    ///\sa AllArcLookUp
  86.130 -  template<class G>
  86.131 +  template <typename GR>
  86.132    class DynArcLookUp
  86.133 -    : protected ItemSetTraits<G, typename G::Arc>::ItemNotifier::ObserverBase
  86.134 +    : protected ItemSetTraits<GR, typename GR::Arc>::ItemNotifier::ObserverBase
  86.135    {
  86.136 -  public:
  86.137 -    typedef typename ItemSetTraits<G, typename G::Arc>
  86.138 +    typedef typename ItemSetTraits<GR, typename GR::Arc>
  86.139      ::ItemNotifier::ObserverBase Parent;
  86.140  
  86.141 -    TEMPLATE_DIGRAPH_TYPEDEFS(G);
  86.142 -    typedef G Digraph;
  86.143 +    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
  86.144 +
  86.145 +  public:
  86.146 +
  86.147 +    /// The Digraph type
  86.148 +    typedef GR Digraph;
  86.149  
  86.150    protected:
  86.151  
  86.152 -    class AutoNodeMap : public ItemSetTraits<G, Node>::template Map<Arc>::Type {
  86.153 +    class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type {
  86.154 +      typedef typename ItemSetTraits<GR, Node>::template Map<Arc>::Type Parent;
  86.155 +
  86.156      public:
  86.157  
  86.158 -      typedef typename ItemSetTraits<G, Node>::template Map<Arc>::Type Parent;
  86.159 -
  86.160 -      AutoNodeMap(const G& digraph) : Parent(digraph, INVALID) {}
  86.161 +      AutoNodeMap(const GR& digraph) : Parent(digraph, INVALID) {}
  86.162  
  86.163        virtual void add(const Node& node) {
  86.164          Parent::add(node);
  86.165 @@ -1257,12 +1268,6 @@
  86.166        }
  86.167      };
  86.168  
  86.169 -    const Digraph &_g;
  86.170 -    AutoNodeMap _head;
  86.171 -    typename Digraph::template ArcMap<Arc> _parent;
  86.172 -    typename Digraph::template ArcMap<Arc> _left;
  86.173 -    typename Digraph::template ArcMap<Arc> _right;
  86.174 -
  86.175      class ArcLess {
  86.176        const Digraph &g;
  86.177      public:
  86.178 @@ -1273,6 +1278,14 @@
  86.179        }
  86.180      };
  86.181  
  86.182 +  protected: 
  86.183 +
  86.184 +    const Digraph &_g;
  86.185 +    AutoNodeMap _head;
  86.186 +    typename Digraph::template ArcMap<Arc> _parent;
  86.187 +    typename Digraph::template ArcMap<Arc> _left;
  86.188 +    typename Digraph::template ArcMap<Arc> _right;
  86.189 +
  86.190    public:
  86.191  
  86.192      ///Constructor
  86.193 @@ -1315,27 +1328,27 @@
  86.194  
  86.195      virtual void clear() {
  86.196        for(NodeIt n(_g);n!=INVALID;++n) {
  86.197 -        _head.set(n, INVALID);
  86.198 +        _head[n] = INVALID;
  86.199        }
  86.200      }
  86.201  
  86.202      void insert(Arc arc) {
  86.203        Node s = _g.source(arc);
  86.204        Node t = _g.target(arc);
  86.205 -      _left.set(arc, INVALID);
  86.206 -      _right.set(arc, INVALID);
  86.207 +      _left[arc] = INVALID;
  86.208 +      _right[arc] = INVALID;
  86.209  
  86.210        Arc e = _head[s];
  86.211        if (e == INVALID) {
  86.212 -        _head.set(s, arc);
  86.213 -        _parent.set(arc, INVALID);
  86.214 +        _head[s] = arc;
  86.215 +        _parent[arc] = INVALID;
  86.216          return;
  86.217        }
  86.218        while (true) {
  86.219          if (t < _g.target(e)) {
  86.220            if (_left[e] == INVALID) {
  86.221 -            _left.set(e, arc);
  86.222 -            _parent.set(arc, e);
  86.223 +            _left[e] = arc;
  86.224 +            _parent[arc] = e;
  86.225              splay(arc);
  86.226              return;
  86.227            } else {
  86.228 @@ -1343,8 +1356,8 @@
  86.229            }
  86.230          } else {
  86.231            if (_right[e] == INVALID) {
  86.232 -            _right.set(e, arc);
  86.233 -            _parent.set(arc, e);
  86.234 +            _right[e] = arc;
  86.235 +            _parent[arc] = e;
  86.236              splay(arc);
  86.237              return;
  86.238            } else {
  86.239 @@ -1357,27 +1370,27 @@
  86.240      void remove(Arc arc) {
  86.241        if (_left[arc] == INVALID) {
  86.242          if (_right[arc] != INVALID) {
  86.243 -          _parent.set(_right[arc], _parent[arc]);
  86.244 +          _parent[_right[arc]] = _parent[arc];
  86.245          }
  86.246          if (_parent[arc] != INVALID) {
  86.247            if (_left[_parent[arc]] == arc) {
  86.248 -            _left.set(_parent[arc], _right[arc]);
  86.249 +            _left[_parent[arc]] = _right[arc];
  86.250            } else {
  86.251 -            _right.set(_parent[arc], _right[arc]);
  86.252 +            _right[_parent[arc]] = _right[arc];
  86.253            }
  86.254          } else {
  86.255 -          _head.set(_g.source(arc), _right[arc]);
  86.256 +          _head[_g.source(arc)] = _right[arc];
  86.257          }
  86.258        } else if (_right[arc] == INVALID) {
  86.259 -        _parent.set(_left[arc], _parent[arc]);
  86.260 +        _parent[_left[arc]] = _parent[arc];
  86.261          if (_parent[arc] != INVALID) {
  86.262            if (_left[_parent[arc]] == arc) {
  86.263 -            _left.set(_parent[arc], _left[arc]);
  86.264 +            _left[_parent[arc]] = _left[arc];
  86.265            } else {
  86.266 -            _right.set(_parent[arc], _left[arc]);
  86.267 +            _right[_parent[arc]] = _left[arc];
  86.268            }
  86.269          } else {
  86.270 -          _head.set(_g.source(arc), _left[arc]);
  86.271 +          _head[_g.source(arc)] = _left[arc];
  86.272          }
  86.273        } else {
  86.274          Arc e = _left[arc];
  86.275 @@ -1387,38 +1400,38 @@
  86.276              e = _right[e];
  86.277            }
  86.278            Arc s = _parent[e];
  86.279 -          _right.set(_parent[e], _left[e]);
  86.280 +          _right[_parent[e]] = _left[e];
  86.281            if (_left[e] != INVALID) {
  86.282 -            _parent.set(_left[e], _parent[e]);
  86.283 +            _parent[_left[e]] = _parent[e];
  86.284            }
  86.285  
  86.286 -          _left.set(e, _left[arc]);
  86.287 -          _parent.set(_left[arc], e);
  86.288 -          _right.set(e, _right[arc]);
  86.289 -          _parent.set(_right[arc], e);
  86.290 +          _left[e] = _left[arc];
  86.291 +          _parent[_left[arc]] = e;
  86.292 +          _right[e] = _right[arc];
  86.293 +          _parent[_right[arc]] = e;
  86.294  
  86.295 -          _parent.set(e, _parent[arc]);
  86.296 +          _parent[e] = _parent[arc];
  86.297            if (_parent[arc] != INVALID) {
  86.298              if (_left[_parent[arc]] == arc) {
  86.299 -              _left.set(_parent[arc], e);
  86.300 +              _left[_parent[arc]] = e;
  86.301              } else {
  86.302 -              _right.set(_parent[arc], e);
  86.303 +              _right[_parent[arc]] = e;
  86.304              }
  86.305            }
  86.306            splay(s);
  86.307          } else {
  86.308 -          _right.set(e, _right[arc]);
  86.309 -          _parent.set(_right[arc], e);
  86.310 -          _parent.set(e, _parent[arc]);
  86.311 +          _right[e] = _right[arc];
  86.312 +          _parent[_right[arc]] = e;
  86.313 +          _parent[e] = _parent[arc];
  86.314  
  86.315            if (_parent[arc] != INVALID) {
  86.316              if (_left[_parent[arc]] == arc) {
  86.317 -              _left.set(_parent[arc], e);
  86.318 +              _left[_parent[arc]] = e;
  86.319              } else {
  86.320 -              _right.set(_parent[arc], e);
  86.321 +              _right[_parent[arc]] = e;
  86.322              }
  86.323            } else {
  86.324 -            _head.set(_g.source(arc), e);
  86.325 +            _head[_g.source(arc)] = e;
  86.326            }
  86.327          }
  86.328        }
  86.329 @@ -1430,17 +1443,17 @@
  86.330        Arc me=v[m];
  86.331        if (a < m) {
  86.332          Arc left = refreshRec(v,a,m-1);
  86.333 -        _left.set(me, left);
  86.334 -        _parent.set(left, me);
  86.335 +        _left[me] = left;
  86.336 +        _parent[left] = me;
  86.337        } else {
  86.338 -        _left.set(me, INVALID);
  86.339 +        _left[me] = INVALID;
  86.340        }
  86.341        if (m < b) {
  86.342          Arc right = refreshRec(v,m+1,b);
  86.343 -        _right.set(me, right);
  86.344 -        _parent.set(right, me);
  86.345 +        _right[me] = right;
  86.346 +        _parent[right] = me;
  86.347        } else {
  86.348 -        _right.set(me, INVALID);
  86.349 +        _right[me] = INVALID;
  86.350        }
  86.351        return me;
  86.352      }
  86.353 @@ -1452,46 +1465,46 @@
  86.354          if (!v.empty()) {
  86.355            std::sort(v.begin(),v.end(),ArcLess(_g));
  86.356            Arc head = refreshRec(v,0,v.size()-1);
  86.357 -          _head.set(n, head);
  86.358 -          _parent.set(head, INVALID);
  86.359 +          _head[n] = head;
  86.360 +          _parent[head] = INVALID;
  86.361          }
  86.362 -        else _head.set(n, INVALID);
  86.363 +        else _head[n] = INVALID;
  86.364        }
  86.365      }
  86.366  
  86.367      void zig(Arc v) {
  86.368        Arc w = _parent[v];
  86.369 -      _parent.set(v, _parent[w]);
  86.370 -      _parent.set(w, v);
  86.371 -      _left.set(w, _right[v]);
  86.372 -      _right.set(v, w);
  86.373 +      _parent[v] = _parent[w];
  86.374 +      _parent[w] = v;
  86.375 +      _left[w] = _right[v];
  86.376 +      _right[v] = w;
  86.377        if (_parent[v] != INVALID) {
  86.378          if (_right[_parent[v]] == w) {
  86.379 -          _right.set(_parent[v], v);
  86.380 +          _right[_parent[v]] = v;
  86.381          } else {
  86.382 -          _left.set(_parent[v], v);
  86.383 +          _left[_parent[v]] = v;
  86.384          }
  86.385        }
  86.386        if (_left[w] != INVALID){
  86.387 -        _parent.set(_left[w], w);
  86.388 +        _parent[_left[w]] = w;
  86.389        }
  86.390      }
  86.391  
  86.392      void zag(Arc v) {
  86.393        Arc w = _parent[v];
  86.394 -      _parent.set(v, _parent[w]);
  86.395 -      _parent.set(w, v);
  86.396 -      _right.set(w, _left[v]);
  86.397 -      _left.set(v, w);
  86.398 +      _parent[v] = _parent[w];
  86.399 +      _parent[w] = v;
  86.400 +      _right[w] = _left[v];
  86.401 +      _left[v] = w;
  86.402        if (_parent[v] != INVALID){
  86.403          if (_left[_parent[v]] == w) {
  86.404 -          _left.set(_parent[v], v);
  86.405 +          _left[_parent[v]] = v;
  86.406          } else {
  86.407 -          _right.set(_parent[v], v);
  86.408 +          _right[_parent[v]] = v;
  86.409          }
  86.410        }
  86.411        if (_right[w] != INVALID){
  86.412 -        _parent.set(_right[w], w);
  86.413 +        _parent[_right[w]] = w;
  86.414        }
  86.415      }
  86.416  
  86.417 @@ -1623,16 +1636,19 @@
  86.418    ///digraph changes. This is a time consuming (superlinearly proportional
  86.419    ///(<em>O</em>(<em>m</em> log<em>m</em>)) to the number of arcs).
  86.420    ///
  86.421 -  ///\tparam G The type of the underlying digraph.
  86.422 +  ///\tparam GR The type of the underlying digraph.
  86.423    ///
  86.424    ///\sa DynArcLookUp
  86.425    ///\sa AllArcLookUp
  86.426 -  template<class G>
  86.427 +  template<class GR>
  86.428    class ArcLookUp
  86.429    {
  86.430 +    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
  86.431 +
  86.432    public:
  86.433 -    TEMPLATE_DIGRAPH_TYPEDEFS(G);
  86.434 -    typedef G Digraph;
  86.435 +
  86.436 +    /// The Digraph type
  86.437 +    typedef GR Digraph;
  86.438  
  86.439    protected:
  86.440      const Digraph &_g;
  86.441 @@ -1733,22 +1749,21 @@
  86.442    ///digraph changes. This is a time consuming (superlinearly proportional
  86.443    ///(<em>O</em>(<em>m</em> log<em>m</em>)) to the number of arcs).
  86.444    ///
  86.445 -  ///\tparam G The type of the underlying digraph.
  86.446 +  ///\tparam GR The type of the underlying digraph.
  86.447    ///
  86.448    ///\sa DynArcLookUp
  86.449    ///\sa ArcLookUp
  86.450 -  template<class G>
  86.451 -  class AllArcLookUp : public ArcLookUp<G>
  86.452 +  template<class GR>
  86.453 +  class AllArcLookUp : public ArcLookUp<GR>
  86.454    {
  86.455 -    using ArcLookUp<G>::_g;
  86.456 -    using ArcLookUp<G>::_right;
  86.457 -    using ArcLookUp<G>::_left;
  86.458 -    using ArcLookUp<G>::_head;
  86.459 +    using ArcLookUp<GR>::_g;
  86.460 +    using ArcLookUp<GR>::_right;
  86.461 +    using ArcLookUp<GR>::_left;
  86.462 +    using ArcLookUp<GR>::_head;
  86.463  
  86.464 -    TEMPLATE_DIGRAPH_TYPEDEFS(G);
  86.465 -    typedef G Digraph;
  86.466 +    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
  86.467  
  86.468 -    typename Digraph::template ArcMap<Arc> _next;
  86.469 +    typename GR::template ArcMap<Arc> _next;
  86.470  
  86.471      Arc refreshNext(Arc head,Arc next=INVALID)
  86.472      {
  86.473 @@ -1767,13 +1782,17 @@
  86.474      }
  86.475  
  86.476    public:
  86.477 +
  86.478 +    /// The Digraph type
  86.479 +    typedef GR Digraph;
  86.480 +
  86.481      ///Constructor
  86.482  
  86.483      ///Constructor.
  86.484      ///
  86.485      ///It builds up the search database, which remains valid until the digraph
  86.486      ///changes.
  86.487 -    AllArcLookUp(const Digraph &g) : ArcLookUp<G>(g), _next(g) {refreshNext();}
  86.488 +    AllArcLookUp(const Digraph &g) : ArcLookUp<GR>(g), _next(g) {refreshNext();}
  86.489  
  86.490      ///Refresh the data structure at a node.
  86.491  
  86.492 @@ -1783,7 +1802,7 @@
  86.493      ///the number of the outgoing arcs of \c n.
  86.494      void refresh(Node n)
  86.495      {
  86.496 -      ArcLookUp<G>::refresh(n);
  86.497 +      ArcLookUp<GR>::refresh(n);
  86.498        refreshNext(_head[n]);
  86.499      }
  86.500  
  86.501 @@ -1830,7 +1849,7 @@
  86.502  #ifdef DOXYGEN
  86.503      Arc operator()(Node s, Node t, Arc prev=INVALID) const {}
  86.504  #else
  86.505 -    using ArcLookUp<G>::operator() ;
  86.506 +    using ArcLookUp<GR>::operator() ;
  86.507      Arc operator()(Node s, Node t, Arc prev) const
  86.508      {
  86.509        return prev==INVALID?(*this)(s,t):_next[prev];
    87.1 --- a/lemon/counter.h	Fri Oct 16 10:21:37 2009 +0200
    87.2 +++ b/lemon/counter.h	Thu Nov 05 15:50:01 2009 +0100
    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-2008
    87.8 + * Copyright (C) 2003-2009
    87.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   87.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   87.11   *
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/lemon/cplex.cc	Thu Nov 05 15:50:01 2009 +0100
    88.3 @@ -0,0 +1,984 @@
    88.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    88.5 + *
    88.6 + * This file is a part of LEMON, a generic C++ optimization library.
    88.7 + *
    88.8 + * Copyright (C) 2003-2009
    88.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   88.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   88.11 + *
   88.12 + * Permission to use, modify and distribute this software is granted
   88.13 + * provided that this copyright notice appears in all copies. For
   88.14 + * precise terms see the accompanying LICENSE file.
   88.15 + *
   88.16 + * This software is provided "AS IS" with no warranty of any kind,
   88.17 + * express or implied, and with no claim as to its suitability for any
   88.18 + * purpose.
   88.19 + *
   88.20 + */
   88.21 +
   88.22 +#include <iostream>
   88.23 +#include <vector>
   88.24 +#include <cstring>
   88.25 +
   88.26 +#include <lemon/cplex.h>
   88.27 +
   88.28 +extern "C" {
   88.29 +#include <ilcplex/cplex.h>
   88.30 +}
   88.31 +
   88.32 +
   88.33 +///\file
   88.34 +///\brief Implementation of the LEMON-CPLEX lp solver interface.
   88.35 +namespace lemon {
   88.36 +
   88.37 +  CplexEnv::LicenseError::LicenseError(int status) {
   88.38 +    if (!CPXgeterrorstring(0, status, _message)) {
   88.39 +      std::strcpy(_message, "Cplex unknown error");
   88.40 +    }
   88.41 +  }
   88.42 +
   88.43 +  CplexEnv::CplexEnv() {
   88.44 +    int status;
   88.45 +    _cnt = new int;
   88.46 +    _env = CPXopenCPLEX(&status);
   88.47 +    if (_env == 0) {
   88.48 +      delete _cnt;
   88.49 +      _cnt = 0;
   88.50 +      throw LicenseError(status);
   88.51 +    }
   88.52 +  }
   88.53 +
   88.54 +  CplexEnv::CplexEnv(const CplexEnv& other) {
   88.55 +    _env = other._env;
   88.56 +    _cnt = other._cnt;
   88.57 +    ++(*_cnt);
   88.58 +  }
   88.59 +
   88.60 +  CplexEnv& CplexEnv::operator=(const CplexEnv& other) {
   88.61 +    _env = other._env;
   88.62 +    _cnt = other._cnt;
   88.63 +    ++(*_cnt);
   88.64 +    return *this;
   88.65 +  }
   88.66 +
   88.67 +  CplexEnv::~CplexEnv() {
   88.68 +    --(*_cnt);
   88.69 +    if (*_cnt == 0) {
   88.70 +      delete _cnt;
   88.71 +      CPXcloseCPLEX(&_env);
   88.72 +    }
   88.73 +  }
   88.74 +
   88.75 +  CplexBase::CplexBase() : LpBase() {
   88.76 +    int status;
   88.77 +    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
   88.78 +    messageLevel(MESSAGE_NOTHING);
   88.79 +  }
   88.80 +
   88.81 +  CplexBase::CplexBase(const CplexEnv& env)
   88.82 +    : LpBase(), _env(env) {
   88.83 +    int status;
   88.84 +    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
   88.85 +    messageLevel(MESSAGE_NOTHING);
   88.86 +  }
   88.87 +
   88.88 +  CplexBase::CplexBase(const CplexBase& cplex)
   88.89 +    : LpBase() {
   88.90 +    int status;
   88.91 +    _prob = CPXcloneprob(cplexEnv(), cplex._prob, &status);
   88.92 +    rows = cplex.rows;
   88.93 +    cols = cplex.cols;
   88.94 +    messageLevel(MESSAGE_NOTHING);
   88.95 +  }
   88.96 +
   88.97 +  CplexBase::~CplexBase() {
   88.98 +    CPXfreeprob(cplexEnv(),&_prob);
   88.99 +  }
  88.100 +
  88.101 +  int CplexBase::_addCol() {
  88.102 +    int i = CPXgetnumcols(cplexEnv(), _prob);
  88.103 +    double lb = -INF, ub = INF;
  88.104 +    CPXnewcols(cplexEnv(), _prob, 1, 0, &lb, &ub, 0, 0);
  88.105 +    return i;
  88.106 +  }
  88.107 +
  88.108 +
  88.109 +  int CplexBase::_addRow() {
  88.110 +    int i = CPXgetnumrows(cplexEnv(), _prob);
  88.111 +    const double ub = INF;
  88.112 +    const char s = 'L';
  88.113 +    CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
  88.114 +    return i;
  88.115 +  }
  88.116 +
  88.117 +  int CplexBase::_addRow(Value lb, ExprIterator b, 
  88.118 +                         ExprIterator e, Value ub) {
  88.119 +    int i = CPXgetnumrows(cplexEnv(), _prob);
  88.120 +    if (lb == -INF) {
  88.121 +      const char s = 'L';
  88.122 +      CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
  88.123 +    } else if (ub == INF) {
  88.124 +      const char s = 'G';
  88.125 +      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
  88.126 +    } else if (lb == ub){
  88.127 +      const char s = 'E';
  88.128 +      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
  88.129 +    } else {
  88.130 +      const char s = 'R';
  88.131 +      double len = ub - lb;
  88.132 +      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0);
  88.133 +    }
  88.134 +
  88.135 +    std::vector<int> indices;
  88.136 +    std::vector<int> rowlist;
  88.137 +    std::vector<Value> values;
  88.138 +
  88.139 +    for(ExprIterator it=b; it!=e; ++it) {
  88.140 +      indices.push_back(it->first);
  88.141 +      values.push_back(it->second);
  88.142 +      rowlist.push_back(i);
  88.143 +    }
  88.144 +
  88.145 +    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
  88.146 +                   &rowlist.front(), &indices.front(), &values.front());
  88.147 +
  88.148 +    return i;
  88.149 +  }
  88.150 +
  88.151 +  void CplexBase::_eraseCol(int i) {
  88.152 +    CPXdelcols(cplexEnv(), _prob, i, i);
  88.153 +  }
  88.154 +
  88.155 +  void CplexBase::_eraseRow(int i) {
  88.156 +    CPXdelrows(cplexEnv(), _prob, i, i);
  88.157 +  }
  88.158 +
  88.159 +  void CplexBase::_eraseColId(int i) {
  88.160 +    cols.eraseIndex(i);
  88.161 +    cols.shiftIndices(i);
  88.162 +  }
  88.163 +  void CplexBase::_eraseRowId(int i) {
  88.164 +    rows.eraseIndex(i);
  88.165 +    rows.shiftIndices(i);
  88.166 +  }
  88.167 +
  88.168 +  void CplexBase::_getColName(int col, std::string &name) const {
  88.169 +    int size;
  88.170 +    CPXgetcolname(cplexEnv(), _prob, 0, 0, 0, &size, col, col);
  88.171 +    if (size == 0) {
  88.172 +      name.clear();
  88.173 +      return;
  88.174 +    }
  88.175 +
  88.176 +    size *= -1;
  88.177 +    std::vector<char> buf(size);
  88.178 +    char *cname;
  88.179 +    int tmp;
  88.180 +    CPXgetcolname(cplexEnv(), _prob, &cname, &buf.front(), size,
  88.181 +                  &tmp, col, col);
  88.182 +    name = cname;
  88.183 +  }
  88.184 +
  88.185 +  void CplexBase::_setColName(int col, const std::string &name) {
  88.186 +    char *cname;
  88.187 +    cname = const_cast<char*>(name.c_str());
  88.188 +    CPXchgcolname(cplexEnv(), _prob, 1, &col, &cname);
  88.189 +  }
  88.190 +
  88.191 +  int CplexBase::_colByName(const std::string& name) const {
  88.192 +    int index;
  88.193 +    if (CPXgetcolindex(cplexEnv(), _prob,
  88.194 +                       const_cast<char*>(name.c_str()), &index) == 0) {
  88.195 +      return index;
  88.196 +    }
  88.197 +    return -1;
  88.198 +  }
  88.199 +
  88.200 +  void CplexBase::_getRowName(int row, std::string &name) const {
  88.201 +    int size;
  88.202 +    CPXgetrowname(cplexEnv(), _prob, 0, 0, 0, &size, row, row);
  88.203 +    if (size == 0) {
  88.204 +      name.clear();
  88.205 +      return;
  88.206 +    }
  88.207 +
  88.208 +    size *= -1;
  88.209 +    std::vector<char> buf(size);
  88.210 +    char *cname;
  88.211 +    int tmp;
  88.212 +    CPXgetrowname(cplexEnv(), _prob, &cname, &buf.front(), size,
  88.213 +                  &tmp, row, row);
  88.214 +    name = cname;
  88.215 +  }
  88.216 +
  88.217 +  void CplexBase::_setRowName(int row, const std::string &name) {
  88.218 +    char *cname;
  88.219 +    cname = const_cast<char*>(name.c_str());
  88.220 +    CPXchgrowname(cplexEnv(), _prob, 1, &row, &cname);
  88.221 +  }
  88.222 +
  88.223 +  int CplexBase::_rowByName(const std::string& name) const {
  88.224 +    int index;
  88.225 +    if (CPXgetrowindex(cplexEnv(), _prob,
  88.226 +                       const_cast<char*>(name.c_str()), &index) == 0) {
  88.227 +      return index;
  88.228 +    }
  88.229 +    return -1;
  88.230 +  }
  88.231 +
  88.232 +  void CplexBase::_setRowCoeffs(int i, ExprIterator b,
  88.233 +                                      ExprIterator e)
  88.234 +  {
  88.235 +    std::vector<int> indices;
  88.236 +    std::vector<int> rowlist;
  88.237 +    std::vector<Value> values;
  88.238 +
  88.239 +    for(ExprIterator it=b; it!=e; ++it) {
  88.240 +      indices.push_back(it->first);
  88.241 +      values.push_back(it->second);
  88.242 +      rowlist.push_back(i);
  88.243 +    }
  88.244 +
  88.245 +    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
  88.246 +                   &rowlist.front(), &indices.front(), &values.front());
  88.247 +  }
  88.248 +
  88.249 +  void CplexBase::_getRowCoeffs(int i, InsertIterator b) const {
  88.250 +    int tmp1, tmp2, tmp3, length;
  88.251 +    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
  88.252 +
  88.253 +    length = -length;
  88.254 +    std::vector<int> indices(length);
  88.255 +    std::vector<double> values(length);
  88.256 +
  88.257 +    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2,
  88.258 +               &indices.front(), &values.front(),
  88.259 +               length, &tmp3, i, i);
  88.260 +
  88.261 +    for (int i = 0; i < length; ++i) {
  88.262 +      *b = std::make_pair(indices[i], values[i]);
  88.263 +      ++b;
  88.264 +    }
  88.265 +  }
  88.266 +
  88.267 +  void CplexBase::_setColCoeffs(int i, ExprIterator b, ExprIterator e) {
  88.268 +    std::vector<int> indices;
  88.269 +    std::vector<int> collist;
  88.270 +    std::vector<Value> values;
  88.271 +
  88.272 +    for(ExprIterator it=b; it!=e; ++it) {
  88.273 +      indices.push_back(it->first);
  88.274 +      values.push_back(it->second);
  88.275 +      collist.push_back(i);
  88.276 +    }
  88.277 +
  88.278 +    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
  88.279 +                   &indices.front(), &collist.front(), &values.front());
  88.280 +  }
  88.281 +
  88.282 +  void CplexBase::_getColCoeffs(int i, InsertIterator b) const {
  88.283 +
  88.284 +    int tmp1, tmp2, tmp3, length;
  88.285 +    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
  88.286 +
  88.287 +    length = -length;
  88.288 +    std::vector<int> indices(length);
  88.289 +    std::vector<double> values(length);
  88.290 +
  88.291 +    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2,
  88.292 +               &indices.front(), &values.front(),
  88.293 +               length, &tmp3, i, i);
  88.294 +
  88.295 +    for (int i = 0; i < length; ++i) {
  88.296 +      *b = std::make_pair(indices[i], values[i]);
  88.297 +      ++b;
  88.298 +    }
  88.299 +
  88.300 +  }
  88.301 +
  88.302 +  void CplexBase::_setCoeff(int row, int col, Value value) {
  88.303 +    CPXchgcoef(cplexEnv(), _prob, row, col, value);
  88.304 +  }
  88.305 +
  88.306 +  CplexBase::Value CplexBase::_getCoeff(int row, int col) const {
  88.307 +    CplexBase::Value value;
  88.308 +    CPXgetcoef(cplexEnv(), _prob, row, col, &value);
  88.309 +    return value;
  88.310 +  }
  88.311 +
  88.312 +  void CplexBase::_setColLowerBound(int i, Value value) {
  88.313 +    const char s = 'L';
  88.314 +    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
  88.315 +  }
  88.316 +
  88.317 +  CplexBase::Value CplexBase::_getColLowerBound(int i) const {
  88.318 +    CplexBase::Value res;
  88.319 +    CPXgetlb(cplexEnv(), _prob, &res, i, i);
  88.320 +    return res <= -CPX_INFBOUND ? -INF : res;
  88.321 +  }
  88.322 +
  88.323 +  void CplexBase::_setColUpperBound(int i, Value value)
  88.324 +  {
  88.325 +    const char s = 'U';
  88.326 +    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
  88.327 +  }
  88.328 +
  88.329 +  CplexBase::Value CplexBase::_getColUpperBound(int i) const {
  88.330 +    CplexBase::Value res;
  88.331 +    CPXgetub(cplexEnv(), _prob, &res, i, i);
  88.332 +    return res >= CPX_INFBOUND ? INF : res;
  88.333 +  }
  88.334 +
  88.335 +  CplexBase::Value CplexBase::_getRowLowerBound(int i) const {
  88.336 +    char s;
  88.337 +    CPXgetsense(cplexEnv(), _prob, &s, i, i);
  88.338 +    CplexBase::Value res;
  88.339 +
  88.340 +    switch (s) {
  88.341 +    case 'G':
  88.342 +    case 'R':
  88.343 +    case 'E':
  88.344 +      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
  88.345 +      return res <= -CPX_INFBOUND ? -INF : res;
  88.346 +    default:
  88.347 +      return -INF;
  88.348 +    }
  88.349 +  }
  88.350 +
  88.351 +  CplexBase::Value CplexBase::_getRowUpperBound(int i) const {
  88.352 +    char s;
  88.353 +    CPXgetsense(cplexEnv(), _prob, &s, i, i);
  88.354 +    CplexBase::Value res;
  88.355 +
  88.356 +    switch (s) {
  88.357 +    case 'L':
  88.358 +    case 'E':
  88.359 +      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
  88.360 +      return res >= CPX_INFBOUND ? INF : res;
  88.361 +    case 'R':
  88.362 +      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
  88.363 +      {
  88.364 +        double rng;
  88.365 +        CPXgetrngval(cplexEnv(), _prob, &rng, i, i);
  88.366 +        res += rng;
  88.367 +      }
  88.368 +      return res >= CPX_INFBOUND ? INF : res;
  88.369 +    default:
  88.370 +      return INF;
  88.371 +    }
  88.372 +  }
  88.373 +
  88.374 +  //This is easier to implement
  88.375 +  void CplexBase::_set_row_bounds(int i, Value lb, Value ub) {
  88.376 +    if (lb == -INF) {
  88.377 +      const char s = 'L';
  88.378 +      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
  88.379 +      CPXchgrhs(cplexEnv(), _prob, 1, &i, &ub);
  88.380 +    } else if (ub == INF) {
  88.381 +      const char s = 'G';
  88.382 +      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
  88.383 +      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
  88.384 +    } else if (lb == ub){
  88.385 +      const char s = 'E';
  88.386 +      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
  88.387 +      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
  88.388 +    } else {
  88.389 +      const char s = 'R';
  88.390 +      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
  88.391 +      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
  88.392 +      double len = ub - lb;
  88.393 +      CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
  88.394 +    }
  88.395 +  }
  88.396 +
  88.397 +  void CplexBase::_setRowLowerBound(int i, Value lb)
  88.398 +  {
  88.399 +    LEMON_ASSERT(lb != INF, "Invalid bound");
  88.400 +    _set_row_bounds(i, lb, CplexBase::_getRowUpperBound(i));
  88.401 +  }
  88.402 +
  88.403 +  void CplexBase::_setRowUpperBound(int i, Value ub)
  88.404 +  {
  88.405 +
  88.406 +    LEMON_ASSERT(ub != -INF, "Invalid bound");
  88.407 +    _set_row_bounds(i, CplexBase::_getRowLowerBound(i), ub);
  88.408 +  }
  88.409 +
  88.410 +  void CplexBase::_setObjCoeffs(ExprIterator b, ExprIterator e)
  88.411 +  {
  88.412 +    std::vector<int> indices;
  88.413 +    std::vector<Value> values;
  88.414 +    for(ExprIterator it=b; it!=e; ++it) {
  88.415 +      indices.push_back(it->first);
  88.416 +      values.push_back(it->second);
  88.417 +    }
  88.418 +    CPXchgobj(cplexEnv(), _prob, values.size(),
  88.419 +              &indices.front(), &values.front());
  88.420 +
  88.421 +  }
  88.422 +
  88.423 +  void CplexBase::_getObjCoeffs(InsertIterator b) const
  88.424 +  {
  88.425 +    int num = CPXgetnumcols(cplexEnv(), _prob);
  88.426 +    std::vector<Value> x(num);
  88.427 +
  88.428 +    CPXgetobj(cplexEnv(), _prob, &x.front(), 0, num - 1);
  88.429 +    for (int i = 0; i < num; ++i) {
  88.430 +      if (x[i] != 0.0) {
  88.431 +        *b = std::make_pair(i, x[i]);
  88.432 +        ++b;
  88.433 +      }
  88.434 +    }
  88.435 +  }
  88.436 +
  88.437 +  void CplexBase::_setObjCoeff(int i, Value obj_coef)
  88.438 +  {
  88.439 +    CPXchgobj(cplexEnv(), _prob, 1, &i, &obj_coef);
  88.440 +  }
  88.441 +
  88.442 +  CplexBase::Value CplexBase::_getObjCoeff(int i) const
  88.443 +  {
  88.444 +    Value x;
  88.445 +    CPXgetobj(cplexEnv(), _prob, &x, i, i);
  88.446 +    return x;
  88.447 +  }
  88.448 +
  88.449 +  void CplexBase::_setSense(CplexBase::Sense sense) {
  88.450 +    switch (sense) {
  88.451 +    case MIN:
  88.452 +      CPXchgobjsen(cplexEnv(), _prob, CPX_MIN);
  88.453 +      break;
  88.454 +    case MAX:
  88.455 +      CPXchgobjsen(cplexEnv(), _prob, CPX_MAX);
  88.456 +      break;
  88.457 +    }
  88.458 +  }
  88.459 +
  88.460 +  CplexBase::Sense CplexBase::_getSense() const {
  88.461 +    switch (CPXgetobjsen(cplexEnv(), _prob)) {
  88.462 +    case CPX_MIN:
  88.463 +      return MIN;
  88.464 +    case CPX_MAX:
  88.465 +      return MAX;
  88.466 +    default:
  88.467 +      LEMON_ASSERT(false, "Invalid sense");
  88.468 +      return CplexBase::Sense();
  88.469 +    }
  88.470 +  }
  88.471 +
  88.472 +  void CplexBase::_clear() {
  88.473 +    CPXfreeprob(cplexEnv(),&_prob);
  88.474 +    int status;
  88.475 +    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
  88.476 +    rows.clear();
  88.477 +    cols.clear();
  88.478 +  }
  88.479 +
  88.480 +  void CplexBase::_messageLevel(MessageLevel level) {
  88.481 +    switch (level) {
  88.482 +    case MESSAGE_NOTHING:
  88.483 +      _message_enabled = false;
  88.484 +      break;
  88.485 +    case MESSAGE_ERROR:
  88.486 +    case MESSAGE_WARNING:
  88.487 +    case MESSAGE_NORMAL:
  88.488 +    case MESSAGE_VERBOSE:
  88.489 +      _message_enabled = true;
  88.490 +      break;
  88.491 +    }
  88.492 +  }
  88.493 +
  88.494 +  void CplexBase::_applyMessageLevel() {
  88.495 +    CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND, 
  88.496 +                   _message_enabled ? CPX_ON : CPX_OFF);
  88.497 +  }
  88.498 +
  88.499 +  // CplexLp members
  88.500 +
  88.501 +  CplexLp::CplexLp()
  88.502 +    : LpBase(), LpSolver(), CplexBase() {}
  88.503 +
  88.504 +  CplexLp::CplexLp(const CplexEnv& env)
  88.505 +    : LpBase(), LpSolver(), CplexBase(env) {}
  88.506 +
  88.507 +  CplexLp::CplexLp(const CplexLp& other)
  88.508 +    : LpBase(), LpSolver(), CplexBase(other) {}
  88.509 +
  88.510 +  CplexLp::~CplexLp() {}
  88.511 +
  88.512 +  CplexLp* CplexLp::newSolver() const { return new CplexLp; }
  88.513 +  CplexLp* CplexLp::cloneSolver() const {return new CplexLp(*this); }
  88.514 +
  88.515 +  const char* CplexLp::_solverName() const { return "CplexLp"; }
  88.516 +
  88.517 +  void CplexLp::_clear_temporals() {
  88.518 +    _col_status.clear();
  88.519 +    _row_status.clear();
  88.520 +    _primal_ray.clear();
  88.521 +    _dual_ray.clear();
  88.522 +  }
  88.523 +
  88.524 +  // The routine returns zero unless an error occurred during the
  88.525 +  // optimization. Examples of errors include exhausting available
  88.526 +  // memory (CPXERR_NO_MEMORY) or encountering invalid data in the
  88.527 +  // CPLEX problem object (CPXERR_NO_PROBLEM). Exceeding a
  88.528 +  // user-specified CPLEX limit, or proving the model infeasible or
  88.529 +  // unbounded, are not considered errors. Note that a zero return
  88.530 +  // value does not necessarily mean that a solution exists. Use query
  88.531 +  // routines CPXsolninfo, CPXgetstat, and CPXsolution to obtain
  88.532 +  // further information about the status of the optimization.
  88.533 +  CplexLp::SolveExitStatus CplexLp::convertStatus(int status) {
  88.534 +#if CPX_VERSION >= 800
  88.535 +    if (status == 0) {
  88.536 +      switch (CPXgetstat(cplexEnv(), _prob)) {
  88.537 +      case CPX_STAT_OPTIMAL:
  88.538 +      case CPX_STAT_INFEASIBLE:
  88.539 +      case CPX_STAT_UNBOUNDED:
  88.540 +        return SOLVED;
  88.541 +      default:
  88.542 +        return UNSOLVED;
  88.543 +      }
  88.544 +    } else {
  88.545 +      return UNSOLVED;
  88.546 +    }
  88.547 +#else
  88.548 +    if (status == 0) {
  88.549 +      //We want to exclude some cases
  88.550 +      switch (CPXgetstat(cplexEnv(), _prob)) {
  88.551 +      case CPX_OBJ_LIM:
  88.552 +      case CPX_IT_LIM_FEAS:
  88.553 +      case CPX_IT_LIM_INFEAS:
  88.554 +      case CPX_TIME_LIM_FEAS:
  88.555 +      case CPX_TIME_LIM_INFEAS:
  88.556 +        return UNSOLVED;
  88.557 +      default:
  88.558 +        return SOLVED;
  88.559 +      }
  88.560 +    } else {
  88.561 +      return UNSOLVED;
  88.562 +    }
  88.563 +#endif
  88.564 +  }
  88.565 +
  88.566 +  CplexLp::SolveExitStatus CplexLp::_solve() {
  88.567 +    _clear_temporals();
  88.568 +    _applyMessageLevel();
  88.569 +    return convertStatus(CPXlpopt(cplexEnv(), _prob));
  88.570 +  }
  88.571 +
  88.572 +  CplexLp::SolveExitStatus CplexLp::solvePrimal() {
  88.573 +    _clear_temporals();
  88.574 +    _applyMessageLevel();
  88.575 +    return convertStatus(CPXprimopt(cplexEnv(), _prob));
  88.576 +  }
  88.577 +
  88.578 +  CplexLp::SolveExitStatus CplexLp::solveDual() {
  88.579 +    _clear_temporals();
  88.580 +    _applyMessageLevel();
  88.581 +    return convertStatus(CPXdualopt(cplexEnv(), _prob));
  88.582 +  }
  88.583 +
  88.584 +  CplexLp::SolveExitStatus CplexLp::solveBarrier() {
  88.585 +    _clear_temporals();
  88.586 +    _applyMessageLevel();
  88.587 +    return convertStatus(CPXbaropt(cplexEnv(), _prob));
  88.588 +  }
  88.589 +
  88.590 +  CplexLp::Value CplexLp::_getPrimal(int i) const {
  88.591 +    Value x;
  88.592 +    CPXgetx(cplexEnv(), _prob, &x, i, i);
  88.593 +    return x;
  88.594 +  }
  88.595 +
  88.596 +  CplexLp::Value CplexLp::_getDual(int i) const {
  88.597 +    Value y;
  88.598 +    CPXgetpi(cplexEnv(), _prob, &y, i, i);
  88.599 +    return y;
  88.600 +  }
  88.601 +
  88.602 +  CplexLp::Value CplexLp::_getPrimalValue() const {
  88.603 +    Value objval;
  88.604 +    CPXgetobjval(cplexEnv(), _prob, &objval);
  88.605 +    return objval;
  88.606 +  }
  88.607 +
  88.608 +  CplexLp::VarStatus CplexLp::_getColStatus(int i) const {
  88.609 +    if (_col_status.empty()) {
  88.610 +      _col_status.resize(CPXgetnumcols(cplexEnv(), _prob));
  88.611 +      CPXgetbase(cplexEnv(), _prob, &_col_status.front(), 0);
  88.612 +    }
  88.613 +    switch (_col_status[i]) {
  88.614 +    case CPX_BASIC:
  88.615 +      return BASIC;
  88.616 +    case CPX_FREE_SUPER:
  88.617 +      return FREE;
  88.618 +    case CPX_AT_LOWER:
  88.619 +      return LOWER;
  88.620 +    case CPX_AT_UPPER:
  88.621 +      return UPPER;
  88.622 +    default:
  88.623 +      LEMON_ASSERT(false, "Wrong column status");
  88.624 +      return CplexLp::VarStatus();
  88.625 +    }
  88.626 +  }
  88.627 +
  88.628 +  CplexLp::VarStatus CplexLp::_getRowStatus(int i) const {
  88.629 +    if (_row_status.empty()) {
  88.630 +      _row_status.resize(CPXgetnumrows(cplexEnv(), _prob));
  88.631 +      CPXgetbase(cplexEnv(), _prob, 0, &_row_status.front());
  88.632 +    }
  88.633 +    switch (_row_status[i]) {
  88.634 +    case CPX_BASIC:
  88.635 +      return BASIC;
  88.636 +    case CPX_AT_LOWER:
  88.637 +      {
  88.638 +        char s;
  88.639 +        CPXgetsense(cplexEnv(), _prob, &s, i, i);
  88.640 +        return s != 'L' ? LOWER : UPPER;
  88.641 +      }
  88.642 +    case CPX_AT_UPPER:
  88.643 +      return UPPER;
  88.644 +    default:
  88.645 +      LEMON_ASSERT(false, "Wrong row status");
  88.646 +      return CplexLp::VarStatus();
  88.647 +    }
  88.648 +  }
  88.649 +
  88.650 +  CplexLp::Value CplexLp::_getPrimalRay(int i) const {
  88.651 +    if (_primal_ray.empty()) {
  88.652 +      _primal_ray.resize(CPXgetnumcols(cplexEnv(), _prob));
  88.653 +      CPXgetray(cplexEnv(), _prob, &_primal_ray.front());
  88.654 +    }
  88.655 +    return _primal_ray[i];
  88.656 +  }
  88.657 +
  88.658 +  CplexLp::Value CplexLp::_getDualRay(int i) const {
  88.659 +    if (_dual_ray.empty()) {
  88.660 +
  88.661 +    }
  88.662 +    return _dual_ray[i];
  88.663 +  }
  88.664 +
  88.665 +  // Cplex 7.0 status values
  88.666 +  // This table lists the statuses, returned by the CPXgetstat()
  88.667 +  // routine, for solutions to LP problems or mixed integer problems. If
  88.668 +  // no solution exists, the return value is zero.
  88.669 +
  88.670 +  // For Simplex, Barrier
  88.671 +  // 1          CPX_OPTIMAL
  88.672 +  //          Optimal solution found
  88.673 +  // 2          CPX_INFEASIBLE
  88.674 +  //          Problem infeasible
  88.675 +  // 3    CPX_UNBOUNDED
  88.676 +  //          Problem unbounded
  88.677 +  // 4          CPX_OBJ_LIM
  88.678 +  //          Objective limit exceeded in Phase II
  88.679 +  // 5          CPX_IT_LIM_FEAS
  88.680 +  //          Iteration limit exceeded in Phase II
  88.681 +  // 6          CPX_IT_LIM_INFEAS
  88.682 +  //          Iteration limit exceeded in Phase I
  88.683 +  // 7          CPX_TIME_LIM_FEAS
  88.684 +  //          Time limit exceeded in Phase II
  88.685 +  // 8          CPX_TIME_LIM_INFEAS
  88.686 +  //          Time limit exceeded in Phase I
  88.687 +  // 9          CPX_NUM_BEST_FEAS
  88.688 +  //          Problem non-optimal, singularities in Phase II
  88.689 +  // 10         CPX_NUM_BEST_INFEAS
  88.690 +  //          Problem non-optimal, singularities in Phase I
  88.691 +  // 11         CPX_OPTIMAL_INFEAS
  88.692 +  //          Optimal solution found, unscaled infeasibilities
  88.693 +  // 12         CPX_ABORT_FEAS
  88.694 +  //          Aborted in Phase II
  88.695 +  // 13         CPX_ABORT_INFEAS
  88.696 +  //          Aborted in Phase I
  88.697 +  // 14          CPX_ABORT_DUAL_INFEAS
  88.698 +  //          Aborted in barrier, dual infeasible
  88.699 +  // 15          CPX_ABORT_PRIM_INFEAS
  88.700 +  //          Aborted in barrier, primal infeasible
  88.701 +  // 16          CPX_ABORT_PRIM_DUAL_INFEAS
  88.702 +  //          Aborted in barrier, primal and dual infeasible
  88.703 +  // 17          CPX_ABORT_PRIM_DUAL_FEAS
  88.704 +  //          Aborted in barrier, primal and dual feasible
  88.705 +  // 18          CPX_ABORT_CROSSOVER
  88.706 +  //          Aborted in crossover
  88.707 +  // 19          CPX_INForUNBD
  88.708 +  //          Infeasible or unbounded
  88.709 +  // 20   CPX_PIVOT
  88.710 +  //       User pivot used
  88.711 +  //
  88.712 +  // Pending return values
  88.713 +  // ??case CPX_ABORT_DUAL_INFEAS
  88.714 +  // ??case CPX_ABORT_CROSSOVER
  88.715 +  // ??case CPX_INForUNBD
  88.716 +  // ??case CPX_PIVOT
  88.717 +
  88.718 +  //Some more interesting stuff:
  88.719 +
  88.720 +  // CPX_PARAM_PROBMETHOD  1062  int  LPMETHOD
  88.721 +  // 0 Automatic
  88.722 +  // 1 Primal Simplex
  88.723 +  // 2 Dual Simplex
  88.724 +  // 3 Network Simplex
  88.725 +  // 4 Standard Barrier
  88.726 +  // Default: 0
  88.727 +  // Description: Method for linear optimization.
  88.728 +  // Determines which algorithm is used when CPXlpopt() (or "optimize"
  88.729 +  // in the Interactive Optimizer) is called. Currently the behavior of
  88.730 +  // the "Automatic" setting is that CPLEX simply invokes the dual
  88.731 +  // simplex method, but this capability may be expanded in the future
  88.732 +  // so that CPLEX chooses the method based on problem characteristics
  88.733 +#if CPX_VERSION < 900
  88.734 +  void statusSwitch(CPXENVptr cplexEnv(),int& stat){
  88.735 +    int lpmethod;
  88.736 +    CPXgetintparam (cplexEnv(),CPX_PARAM_PROBMETHOD,&lpmethod);
  88.737 +    if (lpmethod==2){
  88.738 +      if (stat==CPX_UNBOUNDED){
  88.739 +        stat=CPX_INFEASIBLE;
  88.740 +      }
  88.741 +      else{
  88.742 +        if (stat==CPX_INFEASIBLE)
  88.743 +          stat=CPX_UNBOUNDED;
  88.744 +      }
  88.745 +    }
  88.746 +  }
  88.747 +#else
  88.748 +  void statusSwitch(CPXENVptr,int&){}
  88.749 +#endif
  88.750 +
  88.751 +  CplexLp::ProblemType CplexLp::_getPrimalType() const {
  88.752 +    // Unboundedness not treated well: the following is from cplex 9.0 doc
  88.753 +    // About Unboundedness
  88.754 +
  88.755 +    // The treatment of models that are unbounded involves a few
  88.756 +    // subtleties. Specifically, a declaration of unboundedness means that
  88.757 +    // ILOG CPLEX has determined that the model has an unbounded
  88.758 +    // ray. Given any feasible solution x with objective z, a multiple of
  88.759 +    // the unbounded ray can be added to x to give a feasible solution
  88.760 +    // with objective z-1 (or z+1 for maximization models). Thus, if a
  88.761 +    // feasible solution exists, then the optimal objective is
  88.762 +    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
  88.763 +    // a feasible solution exists. Users can call the routine CPXsolninfo
  88.764 +    // to determine whether ILOG CPLEX has also concluded that the model
  88.765 +    // has a feasible solution.
  88.766 +
  88.767 +    int stat = CPXgetstat(cplexEnv(), _prob);
  88.768 +#if CPX_VERSION >= 800
  88.769 +    switch (stat)
  88.770 +      {
  88.771 +      case CPX_STAT_OPTIMAL:
  88.772 +        return OPTIMAL;
  88.773 +      case CPX_STAT_UNBOUNDED:
  88.774 +        return UNBOUNDED;
  88.775 +      case CPX_STAT_INFEASIBLE:
  88.776 +        return INFEASIBLE;
  88.777 +      default:
  88.778 +        return UNDEFINED;
  88.779 +      }
  88.780 +#else
  88.781 +    statusSwitch(cplexEnv(),stat);
  88.782 +    //CPXgetstat(cplexEnv(), _prob);
  88.783 +    switch (stat) {
  88.784 +    case 0:
  88.785 +      return UNDEFINED; //Undefined
  88.786 +    case CPX_OPTIMAL://Optimal
  88.787 +      return OPTIMAL;
  88.788 +    case CPX_UNBOUNDED://Unbounded
  88.789 +      return INFEASIBLE;//In case of dual simplex
  88.790 +      //return UNBOUNDED;
  88.791 +    case CPX_INFEASIBLE://Infeasible
  88.792 +      //    case CPX_IT_LIM_INFEAS:
  88.793 +      //     case CPX_TIME_LIM_INFEAS:
  88.794 +      //     case CPX_NUM_BEST_INFEAS:
  88.795 +      //     case CPX_OPTIMAL_INFEAS:
  88.796 +      //     case CPX_ABORT_INFEAS:
  88.797 +      //     case CPX_ABORT_PRIM_INFEAS:
  88.798 +      //     case CPX_ABORT_PRIM_DUAL_INFEAS:
  88.799 +      return UNBOUNDED;//In case of dual simplex
  88.800 +      //return INFEASIBLE;
  88.801 +      //     case CPX_OBJ_LIM:
  88.802 +      //     case CPX_IT_LIM_FEAS:
  88.803 +      //     case CPX_TIME_LIM_FEAS:
  88.804 +      //     case CPX_NUM_BEST_FEAS:
  88.805 +      //     case CPX_ABORT_FEAS:
  88.806 +      //     case CPX_ABORT_PRIM_DUAL_FEAS:
  88.807 +      //       return FEASIBLE;
  88.808 +    default:
  88.809 +      return UNDEFINED; //Everything else comes here
  88.810 +      //FIXME error
  88.811 +    }
  88.812 +#endif
  88.813 +  }
  88.814 +
  88.815 +  // Cplex 9.0 status values
  88.816 +  // CPX_STAT_ABORT_DUAL_OBJ_LIM
  88.817 +  // CPX_STAT_ABORT_IT_LIM
  88.818 +  // CPX_STAT_ABORT_OBJ_LIM
  88.819 +  // CPX_STAT_ABORT_PRIM_OBJ_LIM
  88.820 +  // CPX_STAT_ABORT_TIME_LIM
  88.821 +  // CPX_STAT_ABORT_USER
  88.822 +  // CPX_STAT_FEASIBLE_RELAXED
  88.823 +  // CPX_STAT_INFEASIBLE
  88.824 +  // CPX_STAT_INForUNBD
  88.825 +  // CPX_STAT_NUM_BEST
  88.826 +  // CPX_STAT_OPTIMAL
  88.827 +  // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
  88.828 +  // CPX_STAT_OPTIMAL_INFEAS
  88.829 +  // CPX_STAT_OPTIMAL_RELAXED
  88.830 +  // CPX_STAT_UNBOUNDED
  88.831 +
  88.832 +  CplexLp::ProblemType CplexLp::_getDualType() const {
  88.833 +    int stat = CPXgetstat(cplexEnv(), _prob);
  88.834 +#if CPX_VERSION >= 800
  88.835 +    switch (stat) {
  88.836 +    case CPX_STAT_OPTIMAL:
  88.837 +      return OPTIMAL;
  88.838 +    case CPX_STAT_UNBOUNDED:
  88.839 +      return INFEASIBLE;
  88.840 +    default:
  88.841 +      return UNDEFINED;
  88.842 +    }
  88.843 +#else
  88.844 +    statusSwitch(cplexEnv(),stat);
  88.845 +    switch (stat) {
  88.846 +    case 0:
  88.847 +      return UNDEFINED; //Undefined
  88.848 +    case CPX_OPTIMAL://Optimal
  88.849 +      return OPTIMAL;
  88.850 +    case CPX_UNBOUNDED:
  88.851 +      return INFEASIBLE;
  88.852 +    default:
  88.853 +      return UNDEFINED; //Everything else comes here
  88.854 +      //FIXME error
  88.855 +    }
  88.856 +#endif
  88.857 +  }
  88.858 +
  88.859 +  // CplexMip members
  88.860 +
  88.861 +  CplexMip::CplexMip()
  88.862 +    : LpBase(), MipSolver(), CplexBase() {
  88.863 +
  88.864 +#if CPX_VERSION < 800
  88.865 +    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
  88.866 +#else
  88.867 +    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
  88.868 +#endif
  88.869 +  }
  88.870 +
  88.871 +  CplexMip::CplexMip(const CplexEnv& env)
  88.872 +    : LpBase(), MipSolver(), CplexBase(env) {
  88.873 +
  88.874 +#if CPX_VERSION < 800
  88.875 +    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
  88.876 +#else
  88.877 +    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
  88.878 +#endif
  88.879 +
  88.880 +  }
  88.881 +
  88.882 +  CplexMip::CplexMip(const CplexMip& other)
  88.883 +    : LpBase(), MipSolver(), CplexBase(other) {}
  88.884 +
  88.885 +  CplexMip::~CplexMip() {}
  88.886 +
  88.887 +  CplexMip* CplexMip::newSolver() const { return new CplexMip; }
  88.888 +  CplexMip* CplexMip::cloneSolver() const {return new CplexMip(*this); }
  88.889 +
  88.890 +  const char* CplexMip::_solverName() const { return "CplexMip"; }
  88.891 +
  88.892 +  void CplexMip::_setColType(int i, CplexMip::ColTypes col_type) {
  88.893 +
  88.894 +    // Note If a variable is to be changed to binary, a call to CPXchgbds
  88.895 +    // should also be made to change the bounds to 0 and 1.
  88.896 +
  88.897 +    switch (col_type){
  88.898 +    case INTEGER: {
  88.899 +      const char t = 'I';
  88.900 +      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
  88.901 +    } break;
  88.902 +    case REAL: {
  88.903 +      const char t = 'C';
  88.904 +      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
  88.905 +    } break;
  88.906 +    default:
  88.907 +      break;
  88.908 +    }
  88.909 +  }
  88.910 +
  88.911 +  CplexMip::ColTypes CplexMip::_getColType(int i) const {
  88.912 +    char t;
  88.913 +    CPXgetctype (cplexEnv(), _prob, &t, i, i);
  88.914 +    switch (t) {
  88.915 +    case 'I':
  88.916 +      return INTEGER;
  88.917 +    case 'C':
  88.918 +      return REAL;
  88.919 +    default:
  88.920 +      LEMON_ASSERT(false, "Invalid column type");
  88.921 +      return ColTypes();
  88.922 +    }
  88.923 +
  88.924 +  }
  88.925 +
  88.926 +  CplexMip::SolveExitStatus CplexMip::_solve() {
  88.927 +    int status;
  88.928 +    _applyMessageLevel();
  88.929 +    status = CPXmipopt (cplexEnv(), _prob);
  88.930 +    if (status==0)
  88.931 +      return SOLVED;
  88.932 +    else
  88.933 +      return UNSOLVED;
  88.934 +
  88.935 +  }
  88.936 +
  88.937 +
  88.938 +  CplexMip::ProblemType CplexMip::_getType() const {
  88.939 +
  88.940 +    int stat = CPXgetstat(cplexEnv(), _prob);
  88.941 +
  88.942 +    //Fortunately, MIP statuses did not change for cplex 8.0
  88.943 +    switch (stat) {
  88.944 +    case CPXMIP_OPTIMAL:
  88.945 +      // Optimal integer solution has been found.
  88.946 +    case CPXMIP_OPTIMAL_TOL:
  88.947 +      // Optimal soluton with the tolerance defined by epgap or epagap has
  88.948 +      // been found.
  88.949 +      return OPTIMAL;
  88.950 +      //This also exists in later issues
  88.951 +      //    case CPXMIP_UNBOUNDED:
  88.952 +      //return UNBOUNDED;
  88.953 +      case CPXMIP_INFEASIBLE:
  88.954 +        return INFEASIBLE;
  88.955 +    default:
  88.956 +      return UNDEFINED;
  88.957 +    }
  88.958 +    //Unboundedness not treated well: the following is from cplex 9.0 doc
  88.959 +    // About Unboundedness
  88.960 +
  88.961 +    // The treatment of models that are unbounded involves a few
  88.962 +    // subtleties. Specifically, a declaration of unboundedness means that
  88.963 +    // ILOG CPLEX has determined that the model has an unbounded
  88.964 +    // ray. Given any feasible solution x with objective z, a multiple of
  88.965 +    // the unbounded ray can be added to x to give a feasible solution
  88.966 +    // with objective z-1 (or z+1 for maximization models). Thus, if a
  88.967 +    // feasible solution exists, then the optimal objective is
  88.968 +    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
  88.969 +    // a feasible solution exists. Users can call the routine CPXsolninfo
  88.970 +    // to determine whether ILOG CPLEX has also concluded that the model
  88.971 +    // has a feasible solution.
  88.972 +  }
  88.973 +
  88.974 +  CplexMip::Value CplexMip::_getSol(int i) const {
  88.975 +    Value x;
  88.976 +    CPXgetmipx(cplexEnv(), _prob, &x, i, i);
  88.977 +    return x;
  88.978 +  }
  88.979 +
  88.980 +  CplexMip::Value CplexMip::_getSolValue() const {
  88.981 +    Value objval;
  88.982 +    CPXgetmipobjval(cplexEnv(), _prob, &objval);
  88.983 +    return objval;
  88.984 +  }
  88.985 +
  88.986 +} //namespace lemon
  88.987 +
    89.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.2 +++ b/lemon/cplex.h	Thu Nov 05 15:50:01 2009 +0100
    89.3 @@ -0,0 +1,277 @@
    89.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    89.5 + *
    89.6 + * This file is a part of LEMON, a generic C++ optimization library.
    89.7 + *
    89.8 + * Copyright (C) 2003-2009
    89.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   89.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   89.11 + *
   89.12 + * Permission to use, modify and distribute this software is granted
   89.13 + * provided that this copyright notice appears in all copies. For
   89.14 + * precise terms see the accompanying LICENSE file.
   89.15 + *
   89.16 + * This software is provided "AS IS" with no warranty of any kind,
   89.17 + * express or implied, and with no claim as to its suitability for any
   89.18 + * purpose.
   89.19 + *
   89.20 + */
   89.21 +
   89.22 +#ifndef LEMON_CPLEX_H
   89.23 +#define LEMON_CPLEX_H
   89.24 +
   89.25 +///\file
   89.26 +///\brief Header of the LEMON-CPLEX lp solver interface.
   89.27 +
   89.28 +#include <lemon/lp_base.h>
   89.29 +
   89.30 +struct cpxenv;
   89.31 +struct cpxlp;
   89.32 +
   89.33 +namespace lemon {
   89.34 +
   89.35 +  /// \brief Reference counted wrapper around cpxenv pointer
   89.36 +  ///
   89.37 +  /// The cplex uses environment object which is responsible for
   89.38 +  /// checking the proper license usage. This class provides a simple
   89.39 +  /// interface for share the environment object between different
   89.40 +  /// problems.
   89.41 +  class CplexEnv {
   89.42 +    friend class CplexBase;
   89.43 +  private:
   89.44 +    cpxenv* _env;
   89.45 +    mutable int* _cnt;
   89.46 +
   89.47 +  public:
   89.48 +
   89.49 +    /// \brief This exception is thrown when the license check is not
   89.50 +    /// sufficient
   89.51 +    class LicenseError : public Exception {
   89.52 +      friend class CplexEnv;
   89.53 +    private:
   89.54 +
   89.55 +      LicenseError(int status);
   89.56 +      char _message[510];
   89.57 +
   89.58 +    public:
   89.59 +
   89.60 +      /// The short error message
   89.61 +      virtual const char* what() const throw() {
   89.62 +        return _message;
   89.63 +      }
   89.64 +    };
   89.65 +
   89.66 +    /// Constructor
   89.67 +    CplexEnv();
   89.68 +    /// Shallow copy constructor
   89.69 +    CplexEnv(const CplexEnv&);
   89.70 +    /// Shallow assignement
   89.71 +    CplexEnv& operator=(const CplexEnv&);
   89.72 +    /// Destructor
   89.73 +    virtual ~CplexEnv();
   89.74 +
   89.75 +  protected:
   89.76 +
   89.77 +    cpxenv* cplexEnv() { return _env; }
   89.78 +    const cpxenv* cplexEnv() const { return _env; }
   89.79 +  };
   89.80 +
   89.81 +  /// \brief Base interface for the CPLEX LP and MIP solver
   89.82 +  ///
   89.83 +  /// This class implements the common interface of the CPLEX LP and
   89.84 +  /// MIP solvers.
   89.85 +  /// \ingroup lp_group
   89.86 +  class CplexBase : virtual public LpBase {
   89.87 +  protected:
   89.88 +
   89.89 +    CplexEnv _env;
   89.90 +    cpxlp* _prob;
   89.91 +
   89.92 +    CplexBase();
   89.93 +    CplexBase(const CplexEnv&);
   89.94 +    CplexBase(const CplexBase &);
   89.95 +    virtual ~CplexBase();
   89.96 +
   89.97 +    virtual int _addCol();
   89.98 +    virtual int _addRow();
   89.99 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
  89.100 +
  89.101 +    virtual void _eraseCol(int i);
  89.102 +    virtual void _eraseRow(int i);
  89.103 +
  89.104 +    virtual void _eraseColId(int i);
  89.105 +    virtual void _eraseRowId(int i);
  89.106 +
  89.107 +    virtual void _getColName(int col, std::string& name) const;
  89.108 +    virtual void _setColName(int col, const std::string& name);
  89.109 +    virtual int _colByName(const std::string& name) const;
  89.110 +
  89.111 +    virtual void _getRowName(int row, std::string& name) const;
  89.112 +    virtual void _setRowName(int row, const std::string& name);
  89.113 +    virtual int _rowByName(const std::string& name) const;
  89.114 +
  89.115 +    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
  89.116 +    virtual void _getRowCoeffs(int i, InsertIterator b) const;
  89.117 +
  89.118 +    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
  89.119 +    virtual void _getColCoeffs(int i, InsertIterator b) const;
  89.120 +
  89.121 +    virtual void _setCoeff(int row, int col, Value value);
  89.122 +    virtual Value _getCoeff(int row, int col) const;
  89.123 +
  89.124 +    virtual void _setColLowerBound(int i, Value value);
  89.125 +    virtual Value _getColLowerBound(int i) const;
  89.126 +
  89.127 +    virtual void _setColUpperBound(int i, Value value);
  89.128 +    virtual Value _getColUpperBound(int i) const;
  89.129 +
  89.130 +  private:
  89.131 +    void _set_row_bounds(int i, Value lb, Value ub);
  89.132 +  protected:
  89.133 +
  89.134 +    virtual void _setRowLowerBound(int i, Value value);
  89.135 +    virtual Value _getRowLowerBound(int i) const;
  89.136 +
  89.137 +    virtual void _setRowUpperBound(int i, Value value);
  89.138 +    virtual Value _getRowUpperBound(int i) const;
  89.139 +
  89.140 +    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
  89.141 +    virtual void _getObjCoeffs(InsertIterator b) const;
  89.142 +
  89.143 +    virtual void _setObjCoeff(int i, Value obj_coef);
  89.144 +    virtual Value _getObjCoeff(int i) const;
  89.145 +
  89.146 +    virtual void _setSense(Sense sense);
  89.147 +    virtual Sense _getSense() const;
  89.148 +
  89.149 +    virtual void _clear();
  89.150 +
  89.151 +    virtual void _messageLevel(MessageLevel level);
  89.152 +    void _applyMessageLevel();
  89.153 +
  89.154 +    bool _message_enabled;
  89.155 +
  89.156 +  public:
  89.157 +
  89.158 +    /// Returns the used \c CplexEnv instance
  89.159 +    const CplexEnv& env() const { return _env; }
  89.160 +
  89.161 +    /// \brief Returns the const cpxenv pointer
  89.162 +    ///
  89.163 +    /// \note The cpxenv might be destructed with the solver.
  89.164 +    const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
  89.165 +
  89.166 +    /// \brief Returns the const cpxenv pointer
  89.167 +    ///
  89.168 +    /// \note The cpxenv might be destructed with the solver.
  89.169 +    cpxenv* cplexEnv() { return _env.cplexEnv(); }
  89.170 +
  89.171 +    /// Returns the cplex problem object
  89.172 +    cpxlp* cplexLp() { return _prob; }
  89.173 +    /// Returns the cplex problem object
  89.174 +    const cpxlp* cplexLp() const { return _prob; }
  89.175 +
  89.176 +  };
  89.177 +
  89.178 +  /// \brief Interface for the CPLEX LP solver
  89.179 +  ///
  89.180 +  /// This class implements an interface for the CPLEX LP solver.
  89.181 +  ///\ingroup lp_group
  89.182 +  class CplexLp : public LpSolver, public CplexBase {
  89.183 +  public:
  89.184 +    /// \e
  89.185 +    CplexLp();
  89.186 +    /// \e
  89.187 +    CplexLp(const CplexEnv&);
  89.188 +    /// \e
  89.189 +    CplexLp(const CplexLp&);
  89.190 +    /// \e
  89.191 +    virtual ~CplexLp();
  89.192 +
  89.193 +    /// \e
  89.194 +    virtual CplexLp* cloneSolver() const;
  89.195 +    /// \e
  89.196 +    virtual CplexLp* newSolver() const;
  89.197 +
  89.198 +  private:
  89.199 +
  89.200 +    // these values cannot retrieved element by element
  89.201 +    mutable std::vector<int> _col_status;
  89.202 +    mutable std::vector<int> _row_status;
  89.203 +
  89.204 +    mutable std::vector<Value> _primal_ray;
  89.205 +    mutable std::vector<Value> _dual_ray;
  89.206 +
  89.207 +    void _clear_temporals();
  89.208 +
  89.209 +    SolveExitStatus convertStatus(int status);
  89.210 +
  89.211 +  protected:
  89.212 +
  89.213 +    virtual const char* _solverName() const;
  89.214 +
  89.215 +    virtual SolveExitStatus _solve();
  89.216 +    virtual Value _getPrimal(int i) const;
  89.217 +    virtual Value _getDual(int i) const;
  89.218 +    virtual Value _getPrimalValue() const;
  89.219 +
  89.220 +    virtual VarStatus _getColStatus(int i) const;
  89.221 +    virtual VarStatus _getRowStatus(int i) const;
  89.222 +
  89.223 +    virtual Value _getPrimalRay(int i) const;
  89.224 +    virtual Value _getDualRay(int i) const;
  89.225 +
  89.226 +    virtual ProblemType _getPrimalType() const;
  89.227 +    virtual ProblemType _getDualType() const;
  89.228 +
  89.229 +  public:
  89.230 +
  89.231 +    /// Solve with primal simplex method
  89.232 +    SolveExitStatus solvePrimal();
  89.233 +
  89.234 +    /// Solve with dual simplex method
  89.235 +    SolveExitStatus solveDual();
  89.236 +
  89.237 +    /// Solve with barrier method
  89.238 +    SolveExitStatus solveBarrier();
  89.239 +
  89.240 +  };
  89.241 +
  89.242 +  /// \brief Interface for the CPLEX MIP solver
  89.243 +  ///
  89.244 +  /// This class implements an interface for the CPLEX MIP solver.
  89.245 +  ///\ingroup lp_group
  89.246 +  class CplexMip : public MipSolver, public CplexBase {
  89.247 +  public:
  89.248 +    /// \e
  89.249 +    CplexMip();
  89.250 +    /// \e
  89.251 +    CplexMip(const CplexEnv&);
  89.252 +    /// \e
  89.253 +    CplexMip(const CplexMip&);
  89.254 +    /// \e
  89.255 +    virtual ~CplexMip();
  89.256 +
  89.257 +    /// \e
  89.258 +    virtual CplexMip* cloneSolver() const;
  89.259 +    /// \e
  89.260 +    virtual CplexMip* newSolver() const;
  89.261 +
  89.262 +  protected:
  89.263 +
  89.264 +
  89.265 +    virtual const char* _solverName() const;
  89.266 +
  89.267 +    virtual ColTypes _getColType(int col) const;
  89.268 +    virtual void _setColType(int col, ColTypes col_type);
  89.269 +
  89.270 +    virtual SolveExitStatus _solve();
  89.271 +    virtual ProblemType _getType() const;
  89.272 +    virtual Value _getSol(int i) const;
  89.273 +    virtual Value _getSolValue() const;
  89.274 +
  89.275 +  };
  89.276 +
  89.277 +} //END OF NAMESPACE LEMON
  89.278 +
  89.279 +#endif //LEMON_CPLEX_H
  89.280 +
    90.1 --- a/lemon/dfs.h	Fri Oct 16 10:21:37 2009 +0200
    90.2 +++ b/lemon/dfs.h	Thu Nov 05 15:50:01 2009 +0100
    90.3 @@ -2,7 +2,7 @@
    90.4   *
    90.5   * This file is a part of LEMON, a generic C++ optimization library.
    90.6   *
    90.7 - * Copyright (C) 2003-2008
    90.8 + * Copyright (C) 2003-2009
    90.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   90.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   90.11   *
   90.12 @@ -47,13 +47,13 @@
   90.13      ///
   90.14      ///The type of the map that stores the predecessor
   90.15      ///arcs of the %DFS paths.
   90.16 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   90.17 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   90.18      typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
   90.19 -    ///Instantiates a PredMap.
   90.20 +    ///Instantiates a \c PredMap.
   90.21  
   90.22 -    ///This function instantiates a PredMap.
   90.23 +    ///This function instantiates a \ref PredMap.
   90.24      ///\param g is the digraph, to which we would like to define the
   90.25 -    ///PredMap.
   90.26 +    ///\ref PredMap.
   90.27      static PredMap *createPredMap(const Digraph &g)
   90.28      {
   90.29        return new PredMap(g);
   90.30 @@ -62,13 +62,14 @@
   90.31      ///The type of the map that indicates which nodes are processed.
   90.32  
   90.33      ///The type of the map that indicates which nodes are processed.
   90.34 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   90.35 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   90.36 +    ///By default it is a NullMap.
   90.37      typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
   90.38 -    ///Instantiates a ProcessedMap.
   90.39 +    ///Instantiates a \c ProcessedMap.
   90.40  
   90.41 -    ///This function instantiates a ProcessedMap.
   90.42 +    ///This function instantiates a \ref ProcessedMap.
   90.43      ///\param g is the digraph, to which
   90.44 -    ///we would like to define the ProcessedMap
   90.45 +    ///we would like to define the \ref ProcessedMap.
   90.46  #ifdef DOXYGEN
   90.47      static ProcessedMap *createProcessedMap(const Digraph &g)
   90.48  #else
   90.49 @@ -81,13 +82,13 @@
   90.50      ///The type of the map that indicates which nodes are reached.
   90.51  
   90.52      ///The type of the map that indicates which nodes are reached.
   90.53 -    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   90.54 +    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   90.55      typedef typename Digraph::template NodeMap<bool> ReachedMap;
   90.56 -    ///Instantiates a ReachedMap.
   90.57 +    ///Instantiates a \c ReachedMap.
   90.58  
   90.59 -    ///This function instantiates a ReachedMap.
   90.60 +    ///This function instantiates a \ref ReachedMap.
   90.61      ///\param g is the digraph, to which
   90.62 -    ///we would like to define the ReachedMap.
   90.63 +    ///we would like to define the \ref ReachedMap.
   90.64      static ReachedMap *createReachedMap(const Digraph &g)
   90.65      {
   90.66        return new ReachedMap(g);
   90.67 @@ -96,13 +97,13 @@
   90.68      ///The type of the map that stores the distances of the nodes.
   90.69  
   90.70      ///The type of the map that stores the distances of the nodes.
   90.71 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   90.72 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   90.73      typedef typename Digraph::template NodeMap<int> DistMap;
   90.74 -    ///Instantiates a DistMap.
   90.75 +    ///Instantiates a \c DistMap.
   90.76  
   90.77 -    ///This function instantiates a DistMap.
   90.78 +    ///This function instantiates a \ref DistMap.
   90.79      ///\param g is the digraph, to which we would like to define the
   90.80 -    ///DistMap.
   90.81 +    ///\ref DistMap.
   90.82      static DistMap *createDistMap(const Digraph &g)
   90.83      {
   90.84        return new DistMap(g);
   90.85 @@ -119,13 +120,7 @@
   90.86    ///used easier.
   90.87    ///
   90.88    ///\tparam GR The type of the digraph the algorithm runs on.
   90.89 -  ///The default value is \ref ListDigraph. The value of GR is not used
   90.90 -  ///directly by \ref Dfs, it is only passed to \ref DfsDefaultTraits.
   90.91 -  ///\tparam TR Traits class to set various data types used by the algorithm.
   90.92 -  ///The default traits class is
   90.93 -  ///\ref DfsDefaultTraits "DfsDefaultTraits<GR>".
   90.94 -  ///See \ref DfsDefaultTraits for the documentation of
   90.95 -  ///a Dfs traits class.
   90.96 +  ///The default type is \ref ListDigraph.
   90.97  #ifdef DOXYGEN
   90.98    template <typename GR,
   90.99              typename TR>
  90.100 @@ -151,7 +146,7 @@
  90.101      ///The type of the paths.
  90.102      typedef PredMapPath<Digraph, PredMap> Path;
  90.103  
  90.104 -    ///The traits class.
  90.105 +    ///The \ref DfsDefaultTraits "traits class" of the algorithm.
  90.106      typedef TR Traits;
  90.107  
  90.108    private:
  90.109 @@ -212,7 +207,7 @@
  90.110  
  90.111      typedef Dfs Create;
  90.112  
  90.113 -    ///\name Named template parameters
  90.114 +    ///\name Named Template Parameters
  90.115  
  90.116      ///@{
  90.117  
  90.118 @@ -226,10 +221,11 @@
  90.119        }
  90.120      };
  90.121      ///\brief \ref named-templ-param "Named parameter" for setting
  90.122 -    ///PredMap type.
  90.123 +    ///\c PredMap type.
  90.124      ///
  90.125      ///\ref named-templ-param "Named parameter" for setting
  90.126 -    ///PredMap type.
  90.127 +    ///\c PredMap type.
  90.128 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  90.129      template <class T>
  90.130      struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
  90.131        typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
  90.132 @@ -245,10 +241,11 @@
  90.133        }
  90.134      };
  90.135      ///\brief \ref named-templ-param "Named parameter" for setting
  90.136 -    ///DistMap type.
  90.137 +    ///\c DistMap type.
  90.138      ///
  90.139      ///\ref named-templ-param "Named parameter" for setting
  90.140 -    ///DistMap type.
  90.141 +    ///\c DistMap type.
  90.142 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  90.143      template <class T>
  90.144      struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
  90.145        typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
  90.146 @@ -264,10 +261,11 @@
  90.147        }
  90.148      };
  90.149      ///\brief \ref named-templ-param "Named parameter" for setting
  90.150 -    ///ReachedMap type.
  90.151 +    ///\c ReachedMap type.
  90.152      ///
  90.153      ///\ref named-templ-param "Named parameter" for setting
  90.154 -    ///ReachedMap type.
  90.155 +    ///\c ReachedMap type.
  90.156 +    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  90.157      template <class T>
  90.158      struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
  90.159        typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
  90.160 @@ -283,10 +281,11 @@
  90.161        }
  90.162      };
  90.163      ///\brief \ref named-templ-param "Named parameter" for setting
  90.164 -    ///ProcessedMap type.
  90.165 +    ///\c ProcessedMap type.
  90.166      ///
  90.167      ///\ref named-templ-param "Named parameter" for setting
  90.168 -    ///ProcessedMap type.
  90.169 +    ///\c ProcessedMap type.
  90.170 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  90.171      template <class T>
  90.172      struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
  90.173        typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
  90.174 @@ -300,10 +299,10 @@
  90.175        }
  90.176      };
  90.177      ///\brief \ref named-templ-param "Named parameter" for setting
  90.178 -    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
  90.179 +    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
  90.180      ///
  90.181      ///\ref named-templ-param "Named parameter" for setting
  90.182 -    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
  90.183 +    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
  90.184      ///If you don't set it explicitly, it will be automatically allocated.
  90.185      struct SetStandardProcessedMap :
  90.186        public Dfs< Digraph, SetStandardProcessedMapTraits > {
  90.187 @@ -338,9 +337,10 @@
  90.188      ///Sets the map that stores the predecessor arcs.
  90.189  
  90.190      ///Sets the map that stores the predecessor arcs.
  90.191 -    ///If you don't use this function before calling \ref run(),
  90.192 -    ///it will allocate one. The destructor deallocates this
  90.193 -    ///automatically allocated map, of course.
  90.194 +    ///If you don't use this function before calling \ref run(Node) "run()"
  90.195 +    ///or \ref init(), an instance will be allocated automatically.
  90.196 +    ///The destructor deallocates this automatically allocated map,
  90.197 +    ///of course.
  90.198      ///\return <tt> (*this) </tt>
  90.199      Dfs &predMap(PredMap &m)
  90.200      {
  90.201 @@ -355,9 +355,10 @@
  90.202      ///Sets the map that indicates which nodes are reached.
  90.203  
  90.204      ///Sets the map that indicates which nodes are reached.
  90.205 -    ///If you don't use this function before calling \ref run(),
  90.206 -    ///it will allocate one. The destructor deallocates this
  90.207 -    ///automatically allocated map, of course.
  90.208 +    ///If you don't use this function before calling \ref run(Node) "run()"
  90.209 +    ///or \ref init(), an instance will be allocated automatically.
  90.210 +    ///The destructor deallocates this automatically allocated map,
  90.211 +    ///of course.
  90.212      ///\return <tt> (*this) </tt>
  90.213      Dfs &reachedMap(ReachedMap &m)
  90.214      {
  90.215 @@ -372,9 +373,10 @@
  90.216      ///Sets the map that indicates which nodes are processed.
  90.217  
  90.218      ///Sets the map that indicates which nodes are processed.
  90.219 -    ///If you don't use this function before calling \ref run(),
  90.220 -    ///it will allocate one. The destructor deallocates this
  90.221 -    ///automatically allocated map, of course.
  90.222 +    ///If you don't use this function before calling \ref run(Node) "run()"
  90.223 +    ///or \ref init(), an instance will be allocated automatically.
  90.224 +    ///The destructor deallocates this automatically allocated map,
  90.225 +    ///of course.
  90.226      ///\return <tt> (*this) </tt>
  90.227      Dfs &processedMap(ProcessedMap &m)
  90.228      {
  90.229 @@ -390,9 +392,10 @@
  90.230  
  90.231      ///Sets the map that stores the distances of the nodes calculated by
  90.232      ///the algorithm.
  90.233 -    ///If you don't use this function before calling \ref run(),
  90.234 -    ///it will allocate one. The destructor deallocates this
  90.235 -    ///automatically allocated map, of course.
  90.236 +    ///If you don't use this function before calling \ref run(Node) "run()"
  90.237 +    ///or \ref init(), an instance will be allocated automatically.
  90.238 +    ///The destructor deallocates this automatically allocated map,
  90.239 +    ///of course.
  90.240      ///\return <tt> (*this) </tt>
  90.241      Dfs &distMap(DistMap &m)
  90.242      {
  90.243 @@ -406,22 +409,20 @@
  90.244  
  90.245    public:
  90.246  
  90.247 -    ///\name Execution control
  90.248 -    ///The simplest way to execute the algorithm is to use
  90.249 -    ///one of the member functions called \ref lemon::Dfs::run() "run()".
  90.250 -    ///\n
  90.251 -    ///If you need more control on the execution, first you must call
  90.252 -    ///\ref lemon::Dfs::init() "init()", then you can add a source node
  90.253 -    ///with \ref lemon::Dfs::addSource() "addSource()".
  90.254 -    ///Finally \ref lemon::Dfs::start() "start()" will perform the
  90.255 -    ///actual path computation.
  90.256 +    ///\name Execution Control
  90.257 +    ///The simplest way to execute the DFS algorithm is to use one of the
  90.258 +    ///member functions called \ref run(Node) "run()".\n
  90.259 +    ///If you need better control on the execution, you have to call
  90.260 +    ///\ref init() first, then you can add a source node with \ref addSource()
  90.261 +    ///and perform the actual computation with \ref start().
  90.262 +    ///This procedure can be repeated if there are nodes that have not
  90.263 +    ///been reached.
  90.264  
  90.265      ///@{
  90.266  
  90.267 +    ///\brief Initializes the internal data structures.
  90.268 +    ///
  90.269      ///Initializes the internal data structures.
  90.270 -
  90.271 -    ///Initializes the internal data structures.
  90.272 -    ///
  90.273      void init()
  90.274      {
  90.275        create_maps();
  90.276 @@ -438,11 +439,10 @@
  90.277  
  90.278      ///Adds a new source node to the set of nodes to be processed.
  90.279      ///
  90.280 -    ///\pre The stack must be empty. (Otherwise the algorithm gives
  90.281 -    ///false results.)
  90.282 -    ///
  90.283 -    ///\warning Distances will be wrong (or at least strange) in case of
  90.284 -    ///multiple sources.
  90.285 +    ///\pre The stack must be empty. Otherwise the algorithm gives
  90.286 +    ///wrong results. (One of the outgoing arcs of all the source nodes
  90.287 +    ///except for the last one will not be visited and distances will
  90.288 +    ///also be wrong.)
  90.289      void addSource(Node s)
  90.290      {
  90.291        LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
  90.292 @@ -506,16 +506,16 @@
  90.293        return _stack_head>=0?_stack[_stack_head]:INVALID;
  90.294      }
  90.295  
  90.296 -    ///\brief Returns \c false if there are nodes
  90.297 -    ///to be processed.
  90.298 -    ///
  90.299 -    ///Returns \c false if there are nodes
  90.300 -    ///to be processed in the queue (stack).
  90.301 +    ///Returns \c false if there are nodes to be processed.
  90.302 +
  90.303 +    ///Returns \c false if there are nodes to be processed
  90.304 +    ///in the queue (stack).
  90.305      bool emptyQueue() const { return _stack_head<0; }
  90.306  
  90.307      ///Returns the number of the nodes to be processed.
  90.308  
  90.309 -    ///Returns the number of the nodes to be processed in the queue (stack).
  90.310 +    ///Returns the number of the nodes to be processed
  90.311 +    ///in the queue (stack).
  90.312      int queueSize() const { return _stack_head+1; }
  90.313  
  90.314      ///Executes the algorithm.
  90.315 @@ -637,8 +637,8 @@
  90.316      ///%DFS path to each node.
  90.317      ///
  90.318      ///The algorithm computes
  90.319 -    ///- the %DFS tree,
  90.320 -    ///- the distance of each node from the root in the %DFS tree.
  90.321 +    ///- the %DFS tree (forest),
  90.322 +    ///- the distance of each node from the root(s) in the %DFS tree.
  90.323      ///
  90.324      ///\note <tt>d.run()</tt> is just a shortcut of the following code.
  90.325      ///\code
  90.326 @@ -663,60 +663,60 @@
  90.327      ///@}
  90.328  
  90.329      ///\name Query Functions
  90.330 -    ///The result of the %DFS algorithm can be obtained using these
  90.331 +    ///The results of the DFS algorithm can be obtained using these
  90.332      ///functions.\n
  90.333 -    ///Either \ref lemon::Dfs::run() "run()" or \ref lemon::Dfs::start()
  90.334 -    ///"start()" must be called before using them.
  90.335 +    ///Either \ref run(Node) "run()" or \ref start() should be called
  90.336 +    ///before using them.
  90.337  
  90.338      ///@{
  90.339  
  90.340 -    ///The DFS path to a node.
  90.341 +    ///The DFS path to the given node.
  90.342  
  90.343 -    ///Returns the DFS path to a node.
  90.344 +    ///Returns the DFS path to the given node from the root(s).
  90.345      ///
  90.346 -    ///\warning \c t should be reachable from the root.
  90.347 +    ///\warning \c t should be reached from the root(s).
  90.348      ///
  90.349 -    ///\pre Either \ref run() or \ref start() must be called before
  90.350 -    ///using this function.
  90.351 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  90.352 +    ///must be called before using this function.
  90.353      Path path(Node t) const { return Path(*G, *_pred, t); }
  90.354  
  90.355 -    ///The distance of a node from the root.
  90.356 +    ///The distance of the given node from the root(s).
  90.357  
  90.358 -    ///Returns the distance of a node from the root.
  90.359 +    ///Returns the distance of the given node from the root(s).
  90.360      ///
  90.361 -    ///\warning If node \c v is not reachable from the root, then
  90.362 +    ///\warning If node \c v is not reached from the root(s), then
  90.363      ///the return value of this function is undefined.
  90.364      ///
  90.365 -    ///\pre Either \ref run() or \ref start() must be called before
  90.366 -    ///using this function.
  90.367 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  90.368 +    ///must be called before using this function.
  90.369      int dist(Node v) const { return (*_dist)[v]; }
  90.370  
  90.371 -    ///Returns the 'previous arc' of the %DFS tree for a node.
  90.372 +    ///Returns the 'previous arc' of the %DFS tree for the given node.
  90.373  
  90.374      ///This function returns the 'previous arc' of the %DFS tree for the
  90.375 -    ///node \c v, i.e. it returns the last arc of a %DFS path from the
  90.376 -    ///root to \c v. It is \c INVALID
  90.377 -    ///if \c v is not reachable from the root(s) or if \c v is a root.
  90.378 +    ///node \c v, i.e. it returns the last arc of a %DFS path from a
  90.379 +    ///root to \c v. It is \c INVALID if \c v is not reached from the
  90.380 +    ///root(s) or if \c v is a root.
  90.381      ///
  90.382      ///The %DFS tree used here is equal to the %DFS tree used in
  90.383 -    ///\ref predNode().
  90.384 +    ///\ref predNode() and \ref predMap().
  90.385      ///
  90.386 -    ///\pre Either \ref run() or \ref start() must be called before using
  90.387 -    ///this function.
  90.388 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  90.389 +    ///must be called before using this function.
  90.390      Arc predArc(Node v) const { return (*_pred)[v];}
  90.391  
  90.392 -    ///Returns the 'previous node' of the %DFS tree.
  90.393 +    ///Returns the 'previous node' of the %DFS tree for the given node.
  90.394  
  90.395      ///This function returns the 'previous node' of the %DFS
  90.396      ///tree for the node \c v, i.e. it returns the last but one node
  90.397 -    ///from a %DFS path from the root to \c v. It is \c INVALID
  90.398 -    ///if \c v is not reachable from the root(s) or if \c v is a root.
  90.399 +    ///of a %DFS path from a root to \c v. It is \c INVALID
  90.400 +    ///if \c v is not reached from the root(s) or if \c v is a root.
  90.401      ///
  90.402      ///The %DFS tree used here is equal to the %DFS tree used in
  90.403 -    ///\ref predArc().
  90.404 +    ///\ref predArc() and \ref predMap().
  90.405      ///
  90.406 -    ///\pre Either \ref run() or \ref start() must be called before
  90.407 -    ///using this function.
  90.408 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  90.409 +    ///must be called before using this function.
  90.410      Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
  90.411                                    G->source((*_pred)[v]); }
  90.412  
  90.413 @@ -726,7 +726,7 @@
  90.414      ///Returns a const reference to the node map that stores the
  90.415      ///distances of the nodes calculated by the algorithm.
  90.416      ///
  90.417 -    ///\pre Either \ref run() or \ref init()
  90.418 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  90.419      ///must be called before using this function.
  90.420      const DistMap &distMap() const { return *_dist;}
  90.421  
  90.422 @@ -734,16 +734,17 @@
  90.423      ///predecessor arcs.
  90.424      ///
  90.425      ///Returns a const reference to the node map that stores the predecessor
  90.426 -    ///arcs, which form the DFS tree.
  90.427 +    ///arcs, which form the DFS tree (forest).
  90.428      ///
  90.429 -    ///\pre Either \ref run() or \ref init()
  90.430 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  90.431      ///must be called before using this function.
  90.432      const PredMap &predMap() const { return *_pred;}
  90.433  
  90.434 -    ///Checks if a node is reachable from the root(s).
  90.435 +    ///Checks if the given node. node is reached from the root(s).
  90.436  
  90.437 -    ///Returns \c true if \c v is reachable from the root(s).
  90.438 -    ///\pre Either \ref run() or \ref start()
  90.439 +    ///Returns \c true if \c v is reached from the root(s).
  90.440 +    ///
  90.441 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  90.442      ///must be called before using this function.
  90.443      bool reached(Node v) const { return (*_reached)[v]; }
  90.444  
  90.445 @@ -765,7 +766,7 @@
  90.446      ///
  90.447      ///The type of the map that stores the predecessor
  90.448      ///arcs of the %DFS paths.
  90.449 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  90.450 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  90.451      typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
  90.452      ///Instantiates a PredMap.
  90.453  
  90.454 @@ -780,7 +781,7 @@
  90.455      ///The type of the map that indicates which nodes are processed.
  90.456  
  90.457      ///The type of the map that indicates which nodes are processed.
  90.458 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  90.459 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  90.460      ///By default it is a NullMap.
  90.461      typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
  90.462      ///Instantiates a ProcessedMap.
  90.463 @@ -800,7 +801,7 @@
  90.464      ///The type of the map that indicates which nodes are reached.
  90.465  
  90.466      ///The type of the map that indicates which nodes are reached.
  90.467 -    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  90.468 +    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  90.469      typedef typename Digraph::template NodeMap<bool> ReachedMap;
  90.470      ///Instantiates a ReachedMap.
  90.471  
  90.472 @@ -815,7 +816,7 @@
  90.473      ///The type of the map that stores the distances of the nodes.
  90.474  
  90.475      ///The type of the map that stores the distances of the nodes.
  90.476 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  90.477 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  90.478      typedef typename Digraph::template NodeMap<int> DistMap;
  90.479      ///Instantiates a DistMap.
  90.480  
  90.481 @@ -830,18 +831,14 @@
  90.482      ///The type of the DFS paths.
  90.483  
  90.484      ///The type of the DFS paths.
  90.485 -    ///It must meet the \ref concepts::Path "Path" concept.
  90.486 +    ///It must conform to the \ref concepts::Path "Path" concept.
  90.487      typedef lemon::Path<Digraph> Path;
  90.488    };
  90.489  
  90.490    /// Default traits class used by DfsWizard
  90.491  
  90.492 -  /// To make it easier to use Dfs algorithm
  90.493 -  /// we have created a wizard class.
  90.494 -  /// This \ref DfsWizard class needs default traits,
  90.495 -  /// as well as the \ref Dfs class.
  90.496 -  /// The \ref DfsWizardBase is a class to be the default traits of the
  90.497 -  /// \ref DfsWizard class.
  90.498 +  /// Default traits class used by DfsWizard.
  90.499 +  /// \tparam GR The type of the digraph.
  90.500    template<class GR>
  90.501    class DfsWizardBase : public DfsWizardDefaultTraits<GR>
  90.502    {
  90.503 @@ -869,7 +866,7 @@
  90.504      public:
  90.505      /// Constructor.
  90.506  
  90.507 -    /// This constructor does not require parameters, therefore it initiates
  90.508 +    /// This constructor does not require parameters, it initiates
  90.509      /// all of the attributes to \c 0.
  90.510      DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
  90.511                        _dist(0), _path(0), _di(0) {}
  90.512 @@ -889,8 +886,8 @@
  90.513  
  90.514    /// This auxiliary class is created to implement the
  90.515    /// \ref dfs() "function-type interface" of \ref Dfs algorithm.
  90.516 -  /// It does not have own \ref run() method, it uses the functions
  90.517 -  /// and features of the plain \ref Dfs.
  90.518 +  /// It does not have own \ref run(Node) "run()" method, it uses the
  90.519 +  /// functions and features of the plain \ref Dfs.
  90.520    ///
  90.521    /// This class should only be used through the \ref dfs() function,
  90.522    /// which makes it easier to use the algorithm.
  90.523 @@ -899,7 +896,6 @@
  90.524    {
  90.525      typedef TR Base;
  90.526  
  90.527 -    ///The type of the digraph the algorithm runs on.
  90.528      typedef typename TR::Digraph Digraph;
  90.529  
  90.530      typedef typename Digraph::Node Node;
  90.531 @@ -907,16 +903,10 @@
  90.532      typedef typename Digraph::Arc Arc;
  90.533      typedef typename Digraph::OutArcIt OutArcIt;
  90.534  
  90.535 -    ///\brief The type of the map that stores the predecessor
  90.536 -    ///arcs of the DFS paths.
  90.537      typedef typename TR::PredMap PredMap;
  90.538 -    ///\brief The type of the map that stores the distances of the nodes.
  90.539      typedef typename TR::DistMap DistMap;
  90.540 -    ///\brief The type of the map that indicates which nodes are reached.
  90.541      typedef typename TR::ReachedMap ReachedMap;
  90.542 -    ///\brief The type of the map that indicates which nodes are processed.
  90.543      typedef typename TR::ProcessedMap ProcessedMap;
  90.544 -    ///The type of the DFS paths
  90.545      typedef typename TR::Path Path;
  90.546  
  90.547    public:
  90.548 @@ -999,11 +989,12 @@
  90.549        static PredMap *createPredMap(const Digraph &) { return 0; };
  90.550        SetPredMapBase(const TR &b) : TR(b) {}
  90.551      };
  90.552 -    ///\brief \ref named-func-param "Named parameter"
  90.553 -    ///for setting PredMap object.
  90.554 +
  90.555 +    ///\brief \ref named-templ-param "Named parameter" for setting
  90.556 +    ///the predecessor map.
  90.557      ///
  90.558 -    ///\ref named-func-param "Named parameter"
  90.559 -    ///for setting PredMap object.
  90.560 +    ///\ref named-templ-param "Named parameter" function for setting
  90.561 +    ///the map that stores the predecessor arcs of the nodes.
  90.562      template<class T>
  90.563      DfsWizard<SetPredMapBase<T> > predMap(const T &t)
  90.564      {
  90.565 @@ -1017,11 +1008,12 @@
  90.566        static ReachedMap *createReachedMap(const Digraph &) { return 0; };
  90.567        SetReachedMapBase(const TR &b) : TR(b) {}
  90.568      };
  90.569 -    ///\brief \ref named-func-param "Named parameter"
  90.570 -    ///for setting ReachedMap object.
  90.571 +
  90.572 +    ///\brief \ref named-templ-param "Named parameter" for setting
  90.573 +    ///the reached map.
  90.574      ///
  90.575 -    /// \ref named-func-param "Named parameter"
  90.576 -    ///for setting ReachedMap object.
  90.577 +    ///\ref named-templ-param "Named parameter" function for setting
  90.578 +    ///the map that indicates which nodes are reached.
  90.579      template<class T>
  90.580      DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
  90.581      {
  90.582 @@ -1035,11 +1027,13 @@
  90.583        static DistMap *createDistMap(const Digraph &) { return 0; };
  90.584        SetDistMapBase(const TR &b) : TR(b) {}
  90.585      };
  90.586 -    ///\brief \ref named-func-param "Named parameter"
  90.587 -    ///for setting DistMap object.
  90.588 +
  90.589 +    ///\brief \ref named-templ-param "Named parameter" for setting
  90.590 +    ///the distance map.
  90.591      ///
  90.592 -    /// \ref named-func-param "Named parameter"
  90.593 -    ///for setting DistMap object.
  90.594 +    ///\ref named-templ-param "Named parameter" function for setting
  90.595 +    ///the map that stores the distances of the nodes calculated
  90.596 +    ///by the algorithm.
  90.597      template<class T>
  90.598      DfsWizard<SetDistMapBase<T> > distMap(const T &t)
  90.599      {
  90.600 @@ -1053,11 +1047,12 @@
  90.601        static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
  90.602        SetProcessedMapBase(const TR &b) : TR(b) {}
  90.603      };
  90.604 -    ///\brief \ref named-func-param "Named parameter"
  90.605 -    ///for setting ProcessedMap object.
  90.606 +
  90.607 +    ///\brief \ref named-func-param "Named parameter" for setting
  90.608 +    ///the processed map.
  90.609      ///
  90.610 -    /// \ref named-func-param "Named parameter"
  90.611 -    ///for setting ProcessedMap object.
  90.612 +    ///\ref named-templ-param "Named parameter" function for setting
  90.613 +    ///the map that indicates which nodes are processed.
  90.614      template<class T>
  90.615      DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
  90.616      {
  90.617 @@ -1110,8 +1105,7 @@
  90.618    ///  // Compute the DFS path from s to t
  90.619    ///  bool reached = dfs(g).path(p).dist(d).run(s,t);
  90.620    ///\endcode
  90.621 -
  90.622 -  ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
  90.623 +  ///\warning Don't forget to put the \ref DfsWizard::run(Node) "run()"
  90.624    ///to the end of the parameter list.
  90.625    ///\sa DfsWizard
  90.626    ///\sa Dfs
  90.627 @@ -1127,9 +1121,9 @@
  90.628    ///
  90.629    /// This class defines the interface of the DfsVisit events, and
  90.630    /// it could be the base of a real visitor class.
  90.631 -  template <typename _Digraph>
  90.632 +  template <typename GR>
  90.633    struct DfsVisitor {
  90.634 -    typedef _Digraph Digraph;
  90.635 +    typedef GR Digraph;
  90.636      typedef typename Digraph::Arc Arc;
  90.637      typedef typename Digraph::Node Node;
  90.638      /// \brief Called for the source node of the DFS.
  90.639 @@ -1165,9 +1159,9 @@
  90.640      void backtrack(const Arc& arc) {}
  90.641    };
  90.642  #else
  90.643 -  template <typename _Digraph>
  90.644 +  template <typename GR>
  90.645    struct DfsVisitor {
  90.646 -    typedef _Digraph Digraph;
  90.647 +    typedef GR Digraph;
  90.648      typedef typename Digraph::Arc Arc;
  90.649      typedef typename Digraph::Node Node;
  90.650      void start(const Node&) {}
  90.651 @@ -1200,16 +1194,16 @@
  90.652    ///
  90.653    /// Default traits class of DfsVisit class.
  90.654    /// \tparam _Digraph The type of the digraph the algorithm runs on.
  90.655 -  template<class _Digraph>
  90.656 +  template<class GR>
  90.657    struct DfsVisitDefaultTraits {
  90.658  
  90.659      /// \brief The type of the digraph the algorithm runs on.
  90.660 -    typedef _Digraph Digraph;
  90.661 +    typedef GR Digraph;
  90.662  
  90.663      /// \brief The type of the map that indicates which nodes are reached.
  90.664      ///
  90.665      /// The type of the map that indicates which nodes are reached.
  90.666 -    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  90.667 +    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  90.668      typedef typename Digraph::template NodeMap<bool> ReachedMap;
  90.669  
  90.670      /// \brief Instantiates a ReachedMap.
  90.671 @@ -1225,12 +1219,12 @@
  90.672  
  90.673    /// \ingroup search
  90.674    ///
  90.675 -  /// \brief %DFS algorithm class with visitor interface.
  90.676 +  /// \brief DFS algorithm class with visitor interface.
  90.677    ///
  90.678 -  /// This class provides an efficient implementation of the %DFS algorithm
  90.679 +  /// This class provides an efficient implementation of the DFS algorithm
  90.680    /// with visitor interface.
  90.681    ///
  90.682 -  /// The %DfsVisit class provides an alternative interface to the Dfs
  90.683 +  /// The DfsVisit class provides an alternative interface to the Dfs
  90.684    /// class. It works with callback mechanism, the DfsVisit object calls
  90.685    /// the member functions of the \c Visitor class on every DFS event.
  90.686    ///
  90.687 @@ -1239,37 +1233,37 @@
  90.688    /// events of the DFS algorithm. Otherwise consider to use Dfs or dfs()
  90.689    /// instead.
  90.690    ///
  90.691 -  /// \tparam _Digraph The type of the digraph the algorithm runs on.
  90.692 -  /// The default value is
  90.693 -  /// \ref ListDigraph. The value of _Digraph is not used directly by
  90.694 -  /// \ref DfsVisit, it is only passed to \ref DfsVisitDefaultTraits.
  90.695 -  /// \tparam _Visitor The Visitor type that is used by the algorithm.
  90.696 -  /// \ref DfsVisitor "DfsVisitor<_Digraph>" is an empty visitor, which
  90.697 +  /// \tparam GR The type of the digraph the algorithm runs on.
  90.698 +  /// The default type is \ref ListDigraph.
  90.699 +  /// The value of GR is not used directly by \ref DfsVisit,
  90.700 +  /// it is only passed to \ref DfsVisitDefaultTraits.
  90.701 +  /// \tparam VS The Visitor type that is used by the algorithm.
  90.702 +  /// \ref DfsVisitor "DfsVisitor<GR>" is an empty visitor, which
  90.703    /// does not observe the DFS events. If you want to observe the DFS
  90.704    /// events, you should implement your own visitor class.
  90.705 -  /// \tparam _Traits Traits class to set various data types used by the
  90.706 +  /// \tparam TR Traits class to set various data types used by the
  90.707    /// algorithm. The default traits class is
  90.708 -  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<_Digraph>".
  90.709 +  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<GR>".
  90.710    /// See \ref DfsVisitDefaultTraits for the documentation of
  90.711    /// a DFS visit traits class.
  90.712  #ifdef DOXYGEN
  90.713 -  template <typename _Digraph, typename _Visitor, typename _Traits>
  90.714 +  template <typename GR, typename VS, typename TR>
  90.715  #else
  90.716 -  template <typename _Digraph = ListDigraph,
  90.717 -            typename _Visitor = DfsVisitor<_Digraph>,
  90.718 -            typename _Traits = DfsVisitDefaultTraits<_Digraph> >
  90.719 +  template <typename GR = ListDigraph,
  90.720 +            typename VS = DfsVisitor<GR>,
  90.721 +            typename TR = DfsVisitDefaultTraits<GR> >
  90.722  #endif
  90.723    class DfsVisit {
  90.724    public:
  90.725  
  90.726      ///The traits class.
  90.727 -    typedef _Traits Traits;
  90.728 +    typedef TR Traits;
  90.729  
  90.730      ///The type of the digraph the algorithm runs on.
  90.731      typedef typename Traits::Digraph Digraph;
  90.732  
  90.733      ///The visitor type used by the algorithm.
  90.734 -    typedef _Visitor Visitor;
  90.735 +    typedef VS Visitor;
  90.736  
  90.737      ///The type of the map that indicates which nodes are reached.
  90.738      typedef typename Traits::ReachedMap ReachedMap;
  90.739 @@ -1309,7 +1303,7 @@
  90.740  
  90.741      typedef DfsVisit Create;
  90.742  
  90.743 -    /// \name Named template parameters
  90.744 +    /// \name Named Template Parameters
  90.745  
  90.746      ///@{
  90.747      template <class T>
  90.748 @@ -1351,9 +1345,10 @@
  90.749      /// \brief Sets the map that indicates which nodes are reached.
  90.750      ///
  90.751      /// Sets the map that indicates which nodes are reached.
  90.752 -    /// If you don't use this function before calling \ref run(),
  90.753 -    /// it will allocate one. The destructor deallocates this
  90.754 -    /// automatically allocated map, of course.
  90.755 +    /// If you don't use this function before calling \ref run(Node) "run()"
  90.756 +    /// or \ref init(), an instance will be allocated automatically.
  90.757 +    /// The destructor deallocates this automatically allocated map,
  90.758 +    /// of course.
  90.759      /// \return <tt> (*this) </tt>
  90.760      DfsVisit &reachedMap(ReachedMap &m) {
  90.761        if(local_reached) {
  90.762 @@ -1366,16 +1361,14 @@
  90.763  
  90.764    public:
  90.765  
  90.766 -    /// \name Execution control
  90.767 -    /// The simplest way to execute the algorithm is to use
  90.768 -    /// one of the member functions called \ref lemon::DfsVisit::run()
  90.769 -    /// "run()".
  90.770 -    /// \n
  90.771 -    /// If you need more control on the execution, first you must call
  90.772 -    /// \ref lemon::DfsVisit::init() "init()", then you can add several
  90.773 -    /// source nodes with \ref lemon::DfsVisit::addSource() "addSource()".
  90.774 -    /// Finally \ref lemon::DfsVisit::start() "start()" will perform the
  90.775 -    /// actual path computation.
  90.776 +    /// \name Execution Control
  90.777 +    /// The simplest way to execute the DFS algorithm is to use one of the
  90.778 +    /// member functions called \ref run(Node) "run()".\n
  90.779 +    /// If you need better control on the execution, you have to call
  90.780 +    /// \ref init() first, then you can add a source node with \ref addSource()
  90.781 +    /// and perform the actual computation with \ref start().
  90.782 +    /// This procedure can be repeated if there are nodes that have not
  90.783 +    /// been reached.
  90.784  
  90.785      /// @{
  90.786  
  90.787 @@ -1391,15 +1384,14 @@
  90.788        }
  90.789      }
  90.790  
  90.791 -    ///Adds a new source node.
  90.792 -
  90.793 -    ///Adds a new source node to the set of nodes to be processed.
  90.794 +    /// \brief Adds a new source node.
  90.795      ///
  90.796 -    ///\pre The stack must be empty. (Otherwise the algorithm gives
  90.797 -    ///false results.)
  90.798 +    /// Adds a new source node to the set of nodes to be processed.
  90.799      ///
  90.800 -    ///\warning Distances will be wrong (or at least strange) in case of
  90.801 -    ///multiple sources.
  90.802 +    /// \pre The stack must be empty. Otherwise the algorithm gives
  90.803 +    /// wrong results. (One of the outgoing arcs of all the source nodes
  90.804 +    /// except for the last one will not be visited and distances will
  90.805 +    /// also be wrong.)
  90.806      void addSource(Node s)
  90.807      {
  90.808        LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
  90.809 @@ -1413,6 +1405,7 @@
  90.810              _stack[++_stack_head] = e;
  90.811            } else {
  90.812              _visitor->leave(s);
  90.813 +            _visitor->stop(s);
  90.814            }
  90.815          }
  90.816      }
  90.817 @@ -1589,8 +1582,8 @@
  90.818      /// compute the %DFS path to each node.
  90.819      ///
  90.820      /// The algorithm computes
  90.821 -    /// - the %DFS tree,
  90.822 -    /// - the distance of each node from the root in the %DFS tree.
  90.823 +    /// - the %DFS tree (forest),
  90.824 +    /// - the distance of each node from the root(s) in the %DFS tree.
  90.825      ///
  90.826      /// \note <tt>d.run()</tt> is just a shortcut of the following code.
  90.827      ///\code
  90.828 @@ -1615,19 +1608,20 @@
  90.829      ///@}
  90.830  
  90.831      /// \name Query Functions
  90.832 -    /// The result of the %DFS algorithm can be obtained using these
  90.833 +    /// The results of the DFS algorithm can be obtained using these
  90.834      /// functions.\n
  90.835 -    /// Either \ref lemon::DfsVisit::run() "run()" or
  90.836 -    /// \ref lemon::DfsVisit::start() "start()" must be called before
  90.837 -    /// using them.
  90.838 +    /// Either \ref run(Node) "run()" or \ref start() should be called
  90.839 +    /// before using them.
  90.840 +
  90.841      ///@{
  90.842  
  90.843 -    /// \brief Checks if a node is reachable from the root(s).
  90.844 +    /// \brief Checks if the given node is reached from the root(s).
  90.845      ///
  90.846 -    /// Returns \c true if \c v is reachable from the root(s).
  90.847 -    /// \pre Either \ref run() or \ref start()
  90.848 +    /// Returns \c true if \c v is reached from the root(s).
  90.849 +    ///
  90.850 +    /// \pre Either \ref run(Node) "run()" or \ref init()
  90.851      /// must be called before using this function.
  90.852 -    bool reached(Node v) { return (*_reached)[v]; }
  90.853 +    bool reached(Node v) const { return (*_reached)[v]; }
  90.854  
  90.855      ///@}
  90.856  
    91.1 --- a/lemon/dijkstra.h	Fri Oct 16 10:21:37 2009 +0200
    91.2 +++ b/lemon/dijkstra.h	Thu Nov 05 15:50:01 2009 +0100
    91.3 @@ -2,7 +2,7 @@
    91.4   *
    91.5   * This file is a part of LEMON, a generic C++ optimization library.
    91.6   *
    91.7 - * Copyright (C) 2003-2008
    91.8 + * Copyright (C) 2003-2009
    91.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   91.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   91.11   *
   91.12 @@ -38,8 +38,10 @@
   91.13    ///
   91.14    /// This operation traits class defines all computational operations and
   91.15    /// constants which are used in the Dijkstra algorithm.
   91.16 -  template <typename Value>
   91.17 +  template <typename V>
   91.18    struct DijkstraDefaultOperationTraits {
   91.19 +    /// \e
   91.20 +    typedef V Value;
   91.21      /// \brief Gives back the zero value of the type.
   91.22      static Value zero() {
   91.23        return static_cast<Value>(0);
   91.24 @@ -58,8 +60,8 @@
   91.25  
   91.26    ///Default traits class of Dijkstra class.
   91.27    ///\tparam GR The type of the digraph.
   91.28 -  ///\tparam LM The type of the length map.
   91.29 -  template<class GR, class LM>
   91.30 +  ///\tparam LEN The type of the length map.
   91.31 +  template<typename GR, typename LEN>
   91.32    struct DijkstraDefaultTraits
   91.33    {
   91.34      ///The type of the digraph the algorithm runs on.
   91.35 @@ -68,12 +70,12 @@
   91.36      ///The type of the map that stores the arc lengths.
   91.37  
   91.38      ///The type of the map that stores the arc lengths.
   91.39 -    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
   91.40 -    typedef LM LengthMap;
   91.41 -    ///The type of the length of the arcs.
   91.42 -    typedef typename LM::Value Value;
   91.43 +    ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
   91.44 +    typedef LEN LengthMap;
   91.45 +    ///The type of the arc lengths.
   91.46 +    typedef typename LEN::Value Value;
   91.47  
   91.48 -    /// Operation traits for Dijkstra algorithm.
   91.49 +    /// Operation traits for %Dijkstra algorithm.
   91.50  
   91.51      /// This class defines the operations that are used in the algorithm.
   91.52      /// \see DijkstraDefaultOperationTraits
   91.53 @@ -84,7 +86,7 @@
   91.54      /// The cross reference type used by the heap.
   91.55      /// Usually it is \c Digraph::NodeMap<int>.
   91.56      typedef typename Digraph::template NodeMap<int> HeapCrossRef;
   91.57 -    ///Instantiates a \ref HeapCrossRef.
   91.58 +    ///Instantiates a \c HeapCrossRef.
   91.59  
   91.60      ///This function instantiates a \ref HeapCrossRef.
   91.61      /// \param g is the digraph, to which we would like to define the
   91.62 @@ -94,14 +96,14 @@
   91.63        return new HeapCrossRef(g);
   91.64      }
   91.65  
   91.66 -    ///The heap type used by the Dijkstra algorithm.
   91.67 +    ///The heap type used by the %Dijkstra algorithm.
   91.68  
   91.69      ///The heap type used by the Dijkstra algorithm.
   91.70      ///
   91.71      ///\sa BinHeap
   91.72      ///\sa Dijkstra
   91.73 -    typedef BinHeap<typename LM::Value, HeapCrossRef, std::less<Value> > Heap;
   91.74 -    ///Instantiates a \ref Heap.
   91.75 +    typedef BinHeap<typename LEN::Value, HeapCrossRef, std::less<Value> > Heap;
   91.76 +    ///Instantiates a \c Heap.
   91.77  
   91.78      ///This function instantiates a \ref Heap.
   91.79      static Heap *createHeap(HeapCrossRef& r)
   91.80 @@ -114,13 +116,13 @@
   91.81      ///
   91.82      ///The type of the map that stores the predecessor
   91.83      ///arcs of the shortest paths.
   91.84 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   91.85 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   91.86      typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
   91.87 -    ///Instantiates a PredMap.
   91.88 +    ///Instantiates a \c PredMap.
   91.89  
   91.90 -    ///This function instantiates a PredMap.
   91.91 +    ///This function instantiates a \ref PredMap.
   91.92      ///\param g is the digraph, to which we would like to define the
   91.93 -    ///PredMap.
   91.94 +    ///\ref PredMap.
   91.95      static PredMap *createPredMap(const Digraph &g)
   91.96      {
   91.97        return new PredMap(g);
   91.98 @@ -129,14 +131,14 @@
   91.99      ///The type of the map that indicates which nodes are processed.
  91.100  
  91.101      ///The type of the map that indicates which nodes are processed.
  91.102 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  91.103 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  91.104      ///By default it is a NullMap.
  91.105      typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
  91.106 -    ///Instantiates a ProcessedMap.
  91.107 +    ///Instantiates a \c ProcessedMap.
  91.108  
  91.109 -    ///This function instantiates a ProcessedMap.
  91.110 +    ///This function instantiates a \ref ProcessedMap.
  91.111      ///\param g is the digraph, to which
  91.112 -    ///we would like to define the ProcessedMap
  91.113 +    ///we would like to define the \ref ProcessedMap.
  91.114  #ifdef DOXYGEN
  91.115      static ProcessedMap *createProcessedMap(const Digraph &g)
  91.116  #else
  91.117 @@ -149,13 +151,13 @@
  91.118      ///The type of the map that stores the distances of the nodes.
  91.119  
  91.120      ///The type of the map that stores the distances of the nodes.
  91.121 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  91.122 -    typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
  91.123 -    ///Instantiates a DistMap.
  91.124 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  91.125 +    typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
  91.126 +    ///Instantiates a \c DistMap.
  91.127  
  91.128 -    ///This function instantiates a DistMap.
  91.129 +    ///This function instantiates a \ref DistMap.
  91.130      ///\param g is the digraph, to which we would like to define
  91.131 -    ///the DistMap
  91.132 +    ///the \ref DistMap.
  91.133      static DistMap *createDistMap(const Digraph &g)
  91.134      {
  91.135        return new DistMap(g);
  91.136 @@ -167,6 +169,10 @@
  91.137    /// \ingroup shortest_path
  91.138    ///This class provides an efficient implementation of the %Dijkstra algorithm.
  91.139    ///
  91.140 +  ///The %Dijkstra algorithm solves the single-source shortest path problem
  91.141 +  ///when all arc lengths are non-negative. If there are negative lengths,
  91.142 +  ///the BellmanFord algorithm should be used instead.
  91.143 +  ///
  91.144    ///The arc lengths are passed to the algorithm using a
  91.145    ///\ref concepts::ReadMap "ReadMap",
  91.146    ///so it is easy to change it to any kind of length.
  91.147 @@ -179,26 +185,19 @@
  91.148    ///it can be used easier.
  91.149    ///
  91.150    ///\tparam GR The type of the digraph the algorithm runs on.
  91.151 -  ///The default value is \ref ListDigraph.
  91.152 -  ///The value of GR is not used directly by \ref Dijkstra, it is only
  91.153 -  ///passed to \ref DijkstraDefaultTraits.
  91.154 -  ///\tparam LM A readable arc map that determines the lengths of the
  91.155 -  ///arcs. It is read once for each arc, so the map may involve in
  91.156 +  ///The default type is \ref ListDigraph.
  91.157 +  ///\tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
  91.158 +  ///the lengths of the arcs.
  91.159 +  ///It is read once for each arc, so the map may involve in
  91.160    ///relatively time consuming process to compute the arc lengths if
  91.161    ///it is necessary. The default map type is \ref
  91.162 -  ///concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
  91.163 -  ///The value of LM is not used directly by \ref Dijkstra, it is only
  91.164 -  ///passed to \ref DijkstraDefaultTraits.
  91.165 -  ///\tparam TR Traits class to set various data types used by the algorithm.
  91.166 -  ///The default traits class is \ref DijkstraDefaultTraits
  91.167 -  ///"DijkstraDefaultTraits<GR,LM>". See \ref DijkstraDefaultTraits
  91.168 -  ///for the documentation of a Dijkstra traits class.
  91.169 +  ///concepts::Digraph::ArcMap "GR::ArcMap<int>".
  91.170  #ifdef DOXYGEN
  91.171 -  template <typename GR, typename LM, typename TR>
  91.172 +  template <typename GR, typename LEN, typename TR>
  91.173  #else
  91.174    template <typename GR=ListDigraph,
  91.175 -            typename LM=typename GR::template ArcMap<int>,
  91.176 -            typename TR=DijkstraDefaultTraits<GR,LM> >
  91.177 +            typename LEN=typename GR::template ArcMap<int>,
  91.178 +            typename TR=DijkstraDefaultTraits<GR,LEN> >
  91.179  #endif
  91.180    class Dijkstra {
  91.181    public:
  91.182 @@ -206,7 +205,7 @@
  91.183      ///The type of the digraph the algorithm runs on.
  91.184      typedef typename TR::Digraph Digraph;
  91.185  
  91.186 -    ///The type of the length of the arcs.
  91.187 +    ///The type of the arc lengths.
  91.188      typedef typename TR::LengthMap::Value Value;
  91.189      ///The type of the map that stores the arc lengths.
  91.190      typedef typename TR::LengthMap LengthMap;
  91.191 @@ -223,10 +222,11 @@
  91.192      typedef typename TR::HeapCrossRef HeapCrossRef;
  91.193      ///The heap type used by the algorithm.
  91.194      typedef typename TR::Heap Heap;
  91.195 -    ///The operation traits class.
  91.196 +    ///\brief The \ref DijkstraDefaultOperationTraits "operation traits class"
  91.197 +    ///of the algorithm.
  91.198      typedef typename TR::OperationTraits OperationTraits;
  91.199  
  91.200 -    ///The traits class.
  91.201 +    ///The \ref DijkstraDefaultTraits "traits class" of the algorithm.
  91.202      typedef TR Traits;
  91.203  
  91.204    private:
  91.205 @@ -239,7 +239,7 @@
  91.206      //Pointer to the underlying digraph.
  91.207      const Digraph *G;
  91.208      //Pointer to the length map.
  91.209 -    const LengthMap *length;
  91.210 +    const LengthMap *_length;
  91.211      //Pointer to the map of predecessors arcs.
  91.212      PredMap *_pred;
  91.213      //Indicates if _pred is locally allocated (true) or not.
  91.214 @@ -290,7 +290,7 @@
  91.215  
  91.216      typedef Dijkstra Create;
  91.217  
  91.218 -    ///\name Named template parameters
  91.219 +    ///\name Named Template Parameters
  91.220  
  91.221      ///@{
  91.222  
  91.223 @@ -304,10 +304,11 @@
  91.224        }
  91.225      };
  91.226      ///\brief \ref named-templ-param "Named parameter" for setting
  91.227 -    ///PredMap type.
  91.228 +    ///\c PredMap type.
  91.229      ///
  91.230      ///\ref named-templ-param "Named parameter" for setting
  91.231 -    ///PredMap type.
  91.232 +    ///\c PredMap type.
  91.233 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  91.234      template <class T>
  91.235      struct SetPredMap
  91.236        : public Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > {
  91.237 @@ -324,10 +325,11 @@
  91.238        }
  91.239      };
  91.240      ///\brief \ref named-templ-param "Named parameter" for setting
  91.241 -    ///DistMap type.
  91.242 +    ///\c DistMap type.
  91.243      ///
  91.244      ///\ref named-templ-param "Named parameter" for setting
  91.245 -    ///DistMap type.
  91.246 +    ///\c DistMap type.
  91.247 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  91.248      template <class T>
  91.249      struct SetDistMap
  91.250        : public Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > {
  91.251 @@ -344,10 +346,11 @@
  91.252        }
  91.253      };
  91.254      ///\brief \ref named-templ-param "Named parameter" for setting
  91.255 -    ///ProcessedMap type.
  91.256 +    ///\c ProcessedMap type.
  91.257      ///
  91.258      ///\ref named-templ-param "Named parameter" for setting
  91.259 -    ///ProcessedMap type.
  91.260 +    ///\c ProcessedMap type.
  91.261 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  91.262      template <class T>
  91.263      struct SetProcessedMap
  91.264        : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > {
  91.265 @@ -362,10 +365,10 @@
  91.266        }
  91.267      };
  91.268      ///\brief \ref named-templ-param "Named parameter" for setting
  91.269 -    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
  91.270 +    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
  91.271      ///
  91.272      ///\ref named-templ-param "Named parameter" for setting
  91.273 -    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
  91.274 +    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
  91.275      ///If you don't set it explicitly, it will be automatically allocated.
  91.276      struct SetStandardProcessedMap
  91.277        : public Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits > {
  91.278 @@ -388,10 +391,14 @@
  91.279        }
  91.280      };
  91.281      ///\brief \ref named-templ-param "Named parameter" for setting
  91.282 -    ///heap and cross reference type
  91.283 +    ///heap and cross reference types
  91.284      ///
  91.285      ///\ref named-templ-param "Named parameter" for setting heap and cross
  91.286 -    ///reference type.
  91.287 +    ///reference types. If this named parameter is used, then external
  91.288 +    ///heap and cross reference objects must be passed to the algorithm
  91.289 +    ///using the \ref heap() function before calling \ref run(Node) "run()"
  91.290 +    ///or \ref init().
  91.291 +    ///\sa SetStandardHeap
  91.292      template <class H, class CR = typename Digraph::template NodeMap<int> >
  91.293      struct SetHeap
  91.294        : public Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > {
  91.295 @@ -411,12 +418,18 @@
  91.296        }
  91.297      };
  91.298      ///\brief \ref named-templ-param "Named parameter" for setting
  91.299 -    ///heap and cross reference type with automatic allocation
  91.300 +    ///heap and cross reference types with automatic allocation
  91.301      ///
  91.302      ///\ref named-templ-param "Named parameter" for setting heap and cross
  91.303 -    ///reference type. It can allocate the heap and the cross reference
  91.304 -    ///object if the cross reference's constructor waits for the digraph as
  91.305 -    ///parameter and the heap's constructor waits for the cross reference.
  91.306 +    ///reference types with automatic allocation.
  91.307 +    ///They should have standard constructor interfaces to be able to
  91.308 +    ///automatically created by the algorithm (i.e. the digraph should be
  91.309 +    ///passed to the constructor of the cross reference and the cross
  91.310 +    ///reference should be passed to the constructor of the heap).
  91.311 +    ///However external heap and cross reference objects could also be
  91.312 +    ///passed to the algorithm using the \ref heap() function before
  91.313 +    ///calling \ref run(Node) "run()" or \ref init().
  91.314 +    ///\sa SetHeap
  91.315      template <class H, class CR = typename Digraph::template NodeMap<int> >
  91.316      struct SetStandardHeap
  91.317        : public Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> > {
  91.318 @@ -433,7 +446,8 @@
  91.319      ///\c OperationTraits type
  91.320      ///
  91.321      ///\ref named-templ-param "Named parameter" for setting
  91.322 -    ///\ref OperationTraits type.
  91.323 +    ///\c OperationTraits type.
  91.324 +    /// For more information see \ref DijkstraDefaultOperationTraits.
  91.325      template <class T>
  91.326      struct SetOperationTraits
  91.327        : public Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> > {
  91.328 @@ -452,10 +466,10 @@
  91.329      ///Constructor.
  91.330  
  91.331      ///Constructor.
  91.332 -    ///\param _g The digraph the algorithm runs on.
  91.333 -    ///\param _length The length map used by the algorithm.
  91.334 -    Dijkstra(const Digraph& _g, const LengthMap& _length) :
  91.335 -      G(&_g), length(&_length),
  91.336 +    ///\param g The digraph the algorithm runs on.
  91.337 +    ///\param length The length map used by the algorithm.
  91.338 +    Dijkstra(const Digraph& g, const LengthMap& length) :
  91.339 +      G(&g), _length(&length),
  91.340        _pred(NULL), local_pred(false),
  91.341        _dist(NULL), local_dist(false),
  91.342        _processed(NULL), local_processed(false),
  91.343 @@ -479,16 +493,17 @@
  91.344      ///\return <tt> (*this) </tt>
  91.345      Dijkstra &lengthMap(const LengthMap &m)
  91.346      {
  91.347 -      length = &m;
  91.348 +      _length = &m;
  91.349        return *this;
  91.350      }
  91.351  
  91.352      ///Sets the map that stores the predecessor arcs.
  91.353  
  91.354      ///Sets the map that stores the predecessor arcs.
  91.355 -    ///If you don't use this function before calling \ref run(),
  91.356 -    ///it will allocate one. The destructor deallocates this
  91.357 -    ///automatically allocated map, of course.
  91.358 +    ///If you don't use this function before calling \ref run(Node) "run()"
  91.359 +    ///or \ref init(), an instance will be allocated automatically.
  91.360 +    ///The destructor deallocates this automatically allocated map,
  91.361 +    ///of course.
  91.362      ///\return <tt> (*this) </tt>
  91.363      Dijkstra &predMap(PredMap &m)
  91.364      {
  91.365 @@ -503,9 +518,10 @@
  91.366      ///Sets the map that indicates which nodes are processed.
  91.367  
  91.368      ///Sets the map that indicates which nodes are processed.
  91.369 -    ///If you don't use this function before calling \ref run(),
  91.370 -    ///it will allocate one. The destructor deallocates this
  91.371 -    ///automatically allocated map, of course.
  91.372 +    ///If you don't use this function before calling \ref run(Node) "run()"
  91.373 +    ///or \ref init(), an instance will be allocated automatically.
  91.374 +    ///The destructor deallocates this automatically allocated map,
  91.375 +    ///of course.
  91.376      ///\return <tt> (*this) </tt>
  91.377      Dijkstra &processedMap(ProcessedMap &m)
  91.378      {
  91.379 @@ -521,9 +537,10 @@
  91.380  
  91.381      ///Sets the map that stores the distances of the nodes calculated by the
  91.382      ///algorithm.
  91.383 -    ///If you don't use this function before calling \ref run(),
  91.384 -    ///it will allocate one. The destructor deallocates this
  91.385 -    ///automatically allocated map, of course.
  91.386 +    ///If you don't use this function before calling \ref run(Node) "run()"
  91.387 +    ///or \ref init(), an instance will be allocated automatically.
  91.388 +    ///The destructor deallocates this automatically allocated map,
  91.389 +    ///of course.
  91.390      ///\return <tt> (*this) </tt>
  91.391      Dijkstra &distMap(DistMap &m)
  91.392      {
  91.393 @@ -538,9 +555,11 @@
  91.394      ///Sets the heap and the cross reference used by algorithm.
  91.395  
  91.396      ///Sets the heap and the cross reference used by algorithm.
  91.397 -    ///If you don't use this function before calling \ref run(),
  91.398 -    ///it will allocate one. The destructor deallocates this
  91.399 -    ///automatically allocated heap and cross reference, of course.
  91.400 +    ///If you don't use this function before calling \ref run(Node) "run()"
  91.401 +    ///or \ref init(), heap and cross reference instances will be
  91.402 +    ///allocated automatically.
  91.403 +    ///The destructor deallocates these automatically allocated objects,
  91.404 +    ///of course.
  91.405      ///\return <tt> (*this) </tt>
  91.406      Dijkstra &heap(Heap& hp, HeapCrossRef &cr)
  91.407      {
  91.408 @@ -567,22 +586,19 @@
  91.409  
  91.410    public:
  91.411  
  91.412 -    ///\name Execution control
  91.413 -    ///The simplest way to execute the algorithm is to use one of the
  91.414 -    ///member functions called \ref lemon::Dijkstra::run() "run()".
  91.415 -    ///\n
  91.416 -    ///If you need more control on the execution, first you must call
  91.417 -    ///\ref lemon::Dijkstra::init() "init()", then you can add several
  91.418 -    ///source nodes with \ref lemon::Dijkstra::addSource() "addSource()".
  91.419 -    ///Finally \ref lemon::Dijkstra::start() "start()" will perform the
  91.420 -    ///actual path computation.
  91.421 +    ///\name Execution Control
  91.422 +    ///The simplest way to execute the %Dijkstra algorithm is to use
  91.423 +    ///one of the member functions called \ref run(Node) "run()".\n
  91.424 +    ///If you need better control on the execution, you have to call
  91.425 +    ///\ref init() first, then you can add several source nodes with
  91.426 +    ///\ref addSource(). Finally the actual path computation can be
  91.427 +    ///performed with one of the \ref start() functions.
  91.428  
  91.429      ///@{
  91.430  
  91.431 +    ///\brief Initializes the internal data structures.
  91.432 +    ///
  91.433      ///Initializes the internal data structures.
  91.434 -
  91.435 -    ///Initializes the internal data structures.
  91.436 -    ///
  91.437      void init()
  91.438      {
  91.439        create_maps();
  91.440 @@ -630,12 +646,12 @@
  91.441          Node w=G->target(e);
  91.442          switch(_heap->state(w)) {
  91.443          case Heap::PRE_HEAP:
  91.444 -          _heap->push(w,OperationTraits::plus(oldvalue, (*length)[e]));
  91.445 +          _heap->push(w,OperationTraits::plus(oldvalue, (*_length)[e]));
  91.446            _pred->set(w,e);
  91.447            break;
  91.448          case Heap::IN_HEAP:
  91.449            {
  91.450 -            Value newvalue = OperationTraits::plus(oldvalue, (*length)[e]);
  91.451 +            Value newvalue = OperationTraits::plus(oldvalue, (*_length)[e]);
  91.452              if ( OperationTraits::less(newvalue, (*_heap)[w]) ) {
  91.453                _heap->decrease(w, newvalue);
  91.454                _pred->set(w,e);
  91.455 @@ -658,17 +674,16 @@
  91.456        return !_heap->empty()?_heap->top():INVALID;
  91.457      }
  91.458  
  91.459 -    ///\brief Returns \c false if there are nodes
  91.460 -    ///to be processed.
  91.461 -    ///
  91.462 -    ///Returns \c false if there are nodes
  91.463 -    ///to be processed in the priority heap.
  91.464 +    ///Returns \c false if there are nodes to be processed.
  91.465 +
  91.466 +    ///Returns \c false if there are nodes to be processed
  91.467 +    ///in the priority heap.
  91.468      bool emptyQueue() const { return _heap->empty(); }
  91.469  
  91.470 -    ///Returns the number of the nodes to be processed in the priority heap
  91.471 +    ///Returns the number of the nodes to be processed.
  91.472  
  91.473 -    ///Returns the number of the nodes to be processed in the priority heap.
  91.474 -    ///
  91.475 +    ///Returns the number of the nodes to be processed
  91.476 +    ///in the priority heap.
  91.477      int queueSize() const { return _heap->size(); }
  91.478  
  91.479      ///Executes the algorithm.
  91.480 @@ -789,61 +804,62 @@
  91.481      ///@}
  91.482  
  91.483      ///\name Query Functions
  91.484 -    ///The result of the %Dijkstra algorithm can be obtained using these
  91.485 +    ///The results of the %Dijkstra algorithm can be obtained using these
  91.486      ///functions.\n
  91.487 -    ///Either \ref lemon::Dijkstra::run() "run()" or
  91.488 -    ///\ref lemon::Dijkstra::start() "start()" must be called before
  91.489 -    ///using them.
  91.490 +    ///Either \ref run(Node) "run()" or \ref init() should be called
  91.491 +    ///before using them.
  91.492  
  91.493      ///@{
  91.494  
  91.495 -    ///The shortest path to a node.
  91.496 +    ///The shortest path to the given node.
  91.497  
  91.498 -    ///Returns the shortest path to a node.
  91.499 +    ///Returns the shortest path to the given node from the root(s).
  91.500      ///
  91.501 -    ///\warning \c t should be reachable from the root(s).
  91.502 +    ///\warning \c t should be reached from the root(s).
  91.503      ///
  91.504 -    ///\pre Either \ref run() or \ref start() must be called before
  91.505 -    ///using this function.
  91.506 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  91.507 +    ///must be called before using this function.
  91.508      Path path(Node t) const { return Path(*G, *_pred, t); }
  91.509  
  91.510 -    ///The distance of a node from the root(s).
  91.511 +    ///The distance of the given node from the root(s).
  91.512  
  91.513 -    ///Returns the distance of a node from the root(s).
  91.514 +    ///Returns the distance of the given node from the root(s).
  91.515      ///
  91.516 -    ///\warning If node \c v is not reachable from the root(s), then
  91.517 +    ///\warning If node \c v is not reached from the root(s), then
  91.518      ///the return value of this function is undefined.
  91.519      ///
  91.520 -    ///\pre Either \ref run() or \ref start() must be called before
  91.521 -    ///using this function.
  91.522 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  91.523 +    ///must be called before using this function.
  91.524      Value dist(Node v) const { return (*_dist)[v]; }
  91.525  
  91.526 -    ///Returns the 'previous arc' of the shortest path tree for a node.
  91.527 -
  91.528 +    ///\brief Returns the 'previous arc' of the shortest path tree for
  91.529 +    ///the given node.
  91.530 +    ///
  91.531      ///This function returns the 'previous arc' of the shortest path
  91.532      ///tree for the node \c v, i.e. it returns the last arc of a
  91.533 -    ///shortest path from the root(s) to \c v. It is \c INVALID if \c v
  91.534 -    ///is not reachable from the root(s) or if \c v is a root.
  91.535 +    ///shortest path from a root to \c v. It is \c INVALID if \c v
  91.536 +    ///is not reached from the root(s) or if \c v is a root.
  91.537      ///
  91.538      ///The shortest path tree used here is equal to the shortest path
  91.539 -    ///tree used in \ref predNode().
  91.540 +    ///tree used in \ref predNode() and \ref predMap().
  91.541      ///
  91.542 -    ///\pre Either \ref run() or \ref start() must be called before
  91.543 -    ///using this function.
  91.544 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  91.545 +    ///must be called before using this function.
  91.546      Arc predArc(Node v) const { return (*_pred)[v]; }
  91.547  
  91.548 -    ///Returns the 'previous node' of the shortest path tree for a node.
  91.549 -
  91.550 +    ///\brief Returns the 'previous node' of the shortest path tree for
  91.551 +    ///the given node.
  91.552 +    ///
  91.553      ///This function returns the 'previous node' of the shortest path
  91.554      ///tree for the node \c v, i.e. it returns the last but one node
  91.555 -    ///from a shortest path from the root(s) to \c v. It is \c INVALID
  91.556 -    ///if \c v is not reachable from the root(s) or if \c v is a root.
  91.557 +    ///of a shortest path from a root to \c v. It is \c INVALID
  91.558 +    ///if \c v is not reached from the root(s) or if \c v is a root.
  91.559      ///
  91.560      ///The shortest path tree used here is equal to the shortest path
  91.561 -    ///tree used in \ref predArc().
  91.562 +    ///tree used in \ref predArc() and \ref predMap().
  91.563      ///
  91.564 -    ///\pre Either \ref run() or \ref start() must be called before
  91.565 -    ///using this function.
  91.566 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  91.567 +    ///must be called before using this function.
  91.568      Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
  91.569                                    G->source((*_pred)[v]); }
  91.570  
  91.571 @@ -853,7 +869,7 @@
  91.572      ///Returns a const reference to the node map that stores the distances
  91.573      ///of the nodes calculated by the algorithm.
  91.574      ///
  91.575 -    ///\pre Either \ref run() or \ref init()
  91.576 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  91.577      ///must be called before using this function.
  91.578      const DistMap &distMap() const { return *_dist;}
  91.579  
  91.580 @@ -861,16 +877,17 @@
  91.581      ///predecessor arcs.
  91.582      ///
  91.583      ///Returns a const reference to the node map that stores the predecessor
  91.584 -    ///arcs, which form the shortest path tree.
  91.585 +    ///arcs, which form the shortest path tree (forest).
  91.586      ///
  91.587 -    ///\pre Either \ref run() or \ref init()
  91.588 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  91.589      ///must be called before using this function.
  91.590      const PredMap &predMap() const { return *_pred;}
  91.591  
  91.592 -    ///Checks if a node is reachable from the root(s).
  91.593 +    ///Checks if the given node is reached from the root(s).
  91.594  
  91.595 -    ///Returns \c true if \c v is reachable from the root(s).
  91.596 -    ///\pre Either \ref run() or \ref start()
  91.597 +    ///Returns \c true if \c v is reached from the root(s).
  91.598 +    ///
  91.599 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  91.600      ///must be called before using this function.
  91.601      bool reached(Node v) const { return (*_heap_cross_ref)[v] !=
  91.602                                          Heap::PRE_HEAP; }
  91.603 @@ -879,16 +896,18 @@
  91.604  
  91.605      ///Returns \c true if \c v is processed, i.e. the shortest
  91.606      ///path to \c v has already found.
  91.607 -    ///\pre Either \ref run() or \ref init()
  91.608 +    ///
  91.609 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  91.610      ///must be called before using this function.
  91.611      bool processed(Node v) const { return (*_heap_cross_ref)[v] ==
  91.612                                            Heap::POST_HEAP; }
  91.613  
  91.614 -    ///The current distance of a node from the root(s).
  91.615 +    ///The current distance of the given node from the root(s).
  91.616  
  91.617 -    ///Returns the current distance of a node from the root(s).
  91.618 +    ///Returns the current distance of the given node from the root(s).
  91.619      ///It may be decreased in the following processes.
  91.620 -    ///\pre Either \ref run() or \ref init()
  91.621 +    ///
  91.622 +    ///\pre Either \ref run(Node) "run()" or \ref init()
  91.623      ///must be called before using this function and
  91.624      ///node \c v must be reached but not necessarily processed.
  91.625      Value currentDist(Node v) const {
  91.626 @@ -903,8 +922,8 @@
  91.627  
  91.628    ///Default traits class of dijkstra() function.
  91.629    ///\tparam GR The type of the digraph.
  91.630 -  ///\tparam LM The type of the length map.
  91.631 -  template<class GR, class LM>
  91.632 +  ///\tparam LEN The type of the length map.
  91.633 +  template<class GR, class LEN>
  91.634    struct DijkstraWizardDefaultTraits
  91.635    {
  91.636      ///The type of the digraph the algorithm runs on.
  91.637 @@ -912,10 +931,10 @@
  91.638      ///The type of the map that stores the arc lengths.
  91.639  
  91.640      ///The type of the map that stores the arc lengths.
  91.641 -    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
  91.642 -    typedef LM LengthMap;
  91.643 -    ///The type of the length of the arcs.
  91.644 -    typedef typename LM::Value Value;
  91.645 +    ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
  91.646 +    typedef LEN LengthMap;
  91.647 +    ///The type of the arc lengths.
  91.648 +    typedef typename LEN::Value Value;
  91.649  
  91.650      /// Operation traits for Dijkstra algorithm.
  91.651  
  91.652 @@ -961,7 +980,7 @@
  91.653      ///
  91.654      ///The type of the map that stores the predecessor
  91.655      ///arcs of the shortest paths.
  91.656 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  91.657 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  91.658      typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
  91.659      ///Instantiates a PredMap.
  91.660  
  91.661 @@ -976,7 +995,7 @@
  91.662      ///The type of the map that indicates which nodes are processed.
  91.663  
  91.664      ///The type of the map that indicates which nodes are processed.
  91.665 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  91.666 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  91.667      ///By default it is a NullMap.
  91.668      typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
  91.669      ///Instantiates a ProcessedMap.
  91.670 @@ -996,8 +1015,8 @@
  91.671      ///The type of the map that stores the distances of the nodes.
  91.672  
  91.673      ///The type of the map that stores the distances of the nodes.
  91.674 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  91.675 -    typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
  91.676 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  91.677 +    typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
  91.678      ///Instantiates a DistMap.
  91.679  
  91.680      ///This function instantiates a DistMap.
  91.681 @@ -1011,22 +1030,19 @@
  91.682      ///The type of the shortest paths.
  91.683  
  91.684      ///The type of the shortest paths.
  91.685 -    ///It must meet the \ref concepts::Path "Path" concept.
  91.686 +    ///It must conform to the \ref concepts::Path "Path" concept.
  91.687      typedef lemon::Path<Digraph> Path;
  91.688    };
  91.689  
  91.690    /// Default traits class used by DijkstraWizard
  91.691  
  91.692 -  /// To make it easier to use Dijkstra algorithm
  91.693 -  /// we have created a wizard class.
  91.694 -  /// This \ref DijkstraWizard class needs default traits,
  91.695 -  /// as well as the \ref Dijkstra class.
  91.696 -  /// The \ref DijkstraWizardBase is a class to be the default traits of the
  91.697 -  /// \ref DijkstraWizard class.
  91.698 -  template<class GR,class LM>
  91.699 -  class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LM>
  91.700 +  /// Default traits class used by DijkstraWizard.
  91.701 +  /// \tparam GR The type of the digraph.
  91.702 +  /// \tparam LEN The type of the length map.
  91.703 +  template<typename GR, typename LEN>
  91.704 +  class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LEN>
  91.705    {
  91.706 -    typedef DijkstraWizardDefaultTraits<GR,LM> Base;
  91.707 +    typedef DijkstraWizardDefaultTraits<GR,LEN> Base;
  91.708    protected:
  91.709      //The type of the nodes in the digraph.
  91.710      typedef typename Base::Digraph::Node Node;
  91.711 @@ -1060,9 +1076,9 @@
  91.712      /// others are initiated to \c 0.
  91.713      /// \param g The digraph the algorithm runs on.
  91.714      /// \param l The length map.
  91.715 -    DijkstraWizardBase(const GR &g,const LM &l) :
  91.716 +    DijkstraWizardBase(const GR &g,const LEN &l) :
  91.717        _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
  91.718 -      _length(reinterpret_cast<void*>(const_cast<LM*>(&l))),
  91.719 +      _length(reinterpret_cast<void*>(const_cast<LEN*>(&l))),
  91.720        _processed(0), _pred(0), _dist(0), _path(0), _di(0) {}
  91.721  
  91.722    };
  91.723 @@ -1071,8 +1087,8 @@
  91.724  
  91.725    /// This auxiliary class is created to implement the
  91.726    /// \ref dijkstra() "function-type interface" of \ref Dijkstra algorithm.
  91.727 -  /// It does not have own \ref run() method, it uses the functions
  91.728 -  /// and features of the plain \ref Dijkstra.
  91.729 +  /// It does not have own \ref run(Node) "run()" method, it uses the
  91.730 +  /// functions and features of the plain \ref Dijkstra.
  91.731    ///
  91.732    /// This class should only be used through the \ref dijkstra() function,
  91.733    /// which makes it easier to use the algorithm.
  91.734 @@ -1081,7 +1097,6 @@
  91.735    {
  91.736      typedef TR Base;
  91.737  
  91.738 -    ///The type of the digraph the algorithm runs on.
  91.739      typedef typename TR::Digraph Digraph;
  91.740  
  91.741      typedef typename Digraph::Node Node;
  91.742 @@ -1089,20 +1104,12 @@
  91.743      typedef typename Digraph::Arc Arc;
  91.744      typedef typename Digraph::OutArcIt OutArcIt;
  91.745  
  91.746 -    ///The type of the map that stores the arc lengths.
  91.747      typedef typename TR::LengthMap LengthMap;
  91.748 -    ///The type of the length of the arcs.
  91.749      typedef typename LengthMap::Value Value;
  91.750 -    ///\brief The type of the map that stores the predecessor
  91.751 -    ///arcs of the shortest paths.
  91.752      typedef typename TR::PredMap PredMap;
  91.753 -    ///The type of the map that stores the distances of the nodes.
  91.754      typedef typename TR::DistMap DistMap;
  91.755 -    ///The type of the map that indicates which nodes are processed.
  91.756      typedef typename TR::ProcessedMap ProcessedMap;
  91.757 -    ///The type of the shortest paths
  91.758      typedef typename TR::Path Path;
  91.759 -    ///The heap type used by the dijkstra algorithm.
  91.760      typedef typename TR::Heap Heap;
  91.761  
  91.762    public:
  91.763 @@ -1174,11 +1181,12 @@
  91.764        static PredMap *createPredMap(const Digraph &) { return 0; };
  91.765        SetPredMapBase(const TR &b) : TR(b) {}
  91.766      };
  91.767 -    ///\brief \ref named-func-param "Named parameter"
  91.768 -    ///for setting PredMap object.
  91.769 +
  91.770 +    ///\brief \ref named-templ-param "Named parameter" for setting
  91.771 +    ///the predecessor map.
  91.772      ///
  91.773 -    ///\ref named-func-param "Named parameter"
  91.774 -    ///for setting PredMap object.
  91.775 +    ///\ref named-templ-param "Named parameter" function for setting
  91.776 +    ///the map that stores the predecessor arcs of the nodes.
  91.777      template<class T>
  91.778      DijkstraWizard<SetPredMapBase<T> > predMap(const T &t)
  91.779      {
  91.780 @@ -1192,11 +1200,13 @@
  91.781        static DistMap *createDistMap(const Digraph &) { return 0; };
  91.782        SetDistMapBase(const TR &b) : TR(b) {}
  91.783      };
  91.784 -    ///\brief \ref named-func-param "Named parameter"
  91.785 -    ///for setting DistMap object.
  91.786 +
  91.787 +    ///\brief \ref named-templ-param "Named parameter" for setting
  91.788 +    ///the distance map.
  91.789      ///
  91.790 -    ///\ref named-func-param "Named parameter"
  91.791 -    ///for setting DistMap object.
  91.792 +    ///\ref named-templ-param "Named parameter" function for setting
  91.793 +    ///the map that stores the distances of the nodes calculated
  91.794 +    ///by the algorithm.
  91.795      template<class T>
  91.796      DijkstraWizard<SetDistMapBase<T> > distMap(const T &t)
  91.797      {
  91.798 @@ -1210,11 +1220,12 @@
  91.799        static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
  91.800        SetProcessedMapBase(const TR &b) : TR(b) {}
  91.801      };
  91.802 -    ///\brief \ref named-func-param "Named parameter"
  91.803 -    ///for setting ProcessedMap object.
  91.804 +
  91.805 +    ///\brief \ref named-func-param "Named parameter" for setting
  91.806 +    ///the processed map.
  91.807      ///
  91.808 -    /// \ref named-func-param "Named parameter"
  91.809 -    ///for setting ProcessedMap object.
  91.810 +    ///\ref named-templ-param "Named parameter" function for setting
  91.811 +    ///the map that indicates which nodes are processed.
  91.812      template<class T>
  91.813      DijkstraWizard<SetProcessedMapBase<T> > processedMap(const T &t)
  91.814      {
  91.815 @@ -1227,6 +1238,7 @@
  91.816        typedef T Path;
  91.817        SetPathBase(const TR &b) : TR(b) {}
  91.818      };
  91.819 +
  91.820      ///\brief \ref named-func-param "Named parameter"
  91.821      ///for getting the shortest path to the target node.
  91.822      ///
  91.823 @@ -1267,15 +1279,15 @@
  91.824    ///  // Compute shortest path from s to t
  91.825    ///  bool reached = dijkstra(g,length).path(p).dist(d).run(s,t);
  91.826    ///\endcode
  91.827 -  ///\warning Don't forget to put the \ref DijkstraWizard::run() "run()"
  91.828 +  ///\warning Don't forget to put the \ref DijkstraWizard::run(Node) "run()"
  91.829    ///to the end of the parameter list.
  91.830    ///\sa DijkstraWizard
  91.831    ///\sa Dijkstra
  91.832 -  template<class GR, class LM>
  91.833 -  DijkstraWizard<DijkstraWizardBase<GR,LM> >
  91.834 -  dijkstra(const GR &digraph, const LM &length)
  91.835 +  template<typename GR, typename LEN>
  91.836 +  DijkstraWizard<DijkstraWizardBase<GR,LEN> >
  91.837 +  dijkstra(const GR &digraph, const LEN &length)
  91.838    {
  91.839 -    return DijkstraWizard<DijkstraWizardBase<GR,LM> >(digraph,length);
  91.840 +    return DijkstraWizard<DijkstraWizardBase<GR,LEN> >(digraph,length);
  91.841    }
  91.842  
  91.843  } //END OF NAMESPACE LEMON
    92.1 --- a/lemon/dim2.h	Fri Oct 16 10:21:37 2009 +0200
    92.2 +++ b/lemon/dim2.h	Thu Nov 05 15:50:01 2009 +0100
    92.3 @@ -2,7 +2,7 @@
    92.4   *
    92.5   * This file is a part of LEMON, a generic C++ optimization library.
    92.6   *
    92.7 - * Copyright (C) 2003-2008
    92.8 + * Copyright (C) 2003-2009
    92.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   92.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   92.11   *
   92.12 @@ -21,16 +21,9 @@
   92.13  
   92.14  #include <iostream>
   92.15  
   92.16 -///\ingroup misc
   92.17 +///\ingroup geomdat
   92.18  ///\file
   92.19  ///\brief A simple two dimensional vector and a bounding box implementation
   92.20 -///
   92.21 -/// The class \ref lemon::dim2::Point "dim2::Point" implements
   92.22 -/// a two dimensional vector with the usual operations.
   92.23 -///
   92.24 -/// The class \ref lemon::dim2::Box "dim2::Box" can be used to determine
   92.25 -/// the rectangular bounding box of a set of
   92.26 -/// \ref lemon::dim2::Point "dim2::Point"'s.
   92.27  
   92.28  namespace lemon {
   92.29  
   92.30 @@ -40,7 +33,7 @@
   92.31    ///tools for handling two dimensional coordinates
   92.32    namespace dim2 {
   92.33  
   92.34 -  /// \addtogroup misc
   92.35 +  /// \addtogroup geomdat
   92.36    /// @{
   92.37  
   92.38    /// Two dimensional vector (plain vector)
    93.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.2 +++ b/lemon/dimacs.h	Thu Nov 05 15:50:01 2009 +0100
    93.3 @@ -0,0 +1,448 @@
    93.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    93.5 + *
    93.6 + * This file is a part of LEMON, a generic C++ optimization library.
    93.7 + *
    93.8 + * Copyright (C) 2003-2009
    93.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   93.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   93.11 + *
   93.12 + * Permission to use, modify and distribute this software is granted
   93.13 + * provided that this copyright notice appears in all copies. For
   93.14 + * precise terms see the accompanying LICENSE file.
   93.15 + *
   93.16 + * This software is provided "AS IS" with no warranty of any kind,
   93.17 + * express or implied, and with no claim as to its suitability for any
   93.18 + * purpose.
   93.19 + *
   93.20 + */
   93.21 +
   93.22 +#ifndef LEMON_DIMACS_H
   93.23 +#define LEMON_DIMACS_H
   93.24 +
   93.25 +#include <iostream>
   93.26 +#include <string>
   93.27 +#include <vector>
   93.28 +#include <limits>
   93.29 +#include <lemon/maps.h>
   93.30 +#include <lemon/error.h>
   93.31 +/// \ingroup dimacs_group
   93.32 +/// \file
   93.33 +/// \brief DIMACS file format reader.
   93.34 +
   93.35 +namespace lemon {
   93.36 +
   93.37 +  /// \addtogroup dimacs_group
   93.38 +  /// @{
   93.39 +
   93.40 +  /// DIMACS file type descriptor.
   93.41 +  struct DimacsDescriptor
   93.42 +  {
   93.43 +    ///\brief DIMACS file type enum
   93.44 +    ///
   93.45 +    ///DIMACS file type enum.
   93.46 +    enum Type {
   93.47 +      NONE,  ///< Undefined type.
   93.48 +      MIN,   ///< DIMACS file type for minimum cost flow problems.
   93.49 +      MAX,   ///< DIMACS file type for maximum flow problems.
   93.50 +      SP,    ///< DIMACS file type for shostest path problems.
   93.51 +      MAT    ///< DIMACS file type for plain graphs and matching problems.
   93.52 +    };
   93.53 +    ///The file type
   93.54 +    Type type;
   93.55 +    ///The number of nodes in the graph
   93.56 +    int nodeNum;
   93.57 +    ///The number of edges in the graph
   93.58 +    int edgeNum;
   93.59 +    int lineShift;
   93.60 +    ///Constructor. It sets the type to \c NONE.
   93.61 +    DimacsDescriptor() : type(NONE) {}
   93.62 +  };
   93.63 +
   93.64 +  ///Discover the type of a DIMACS file
   93.65 +
   93.66 +  ///This function starts seeking the beginning of the given file for the
   93.67 +  ///problem type and size info. 
   93.68 +  ///The found data is returned in a special struct that can be evaluated
   93.69 +  ///and passed to the appropriate reader function.
   93.70 +  DimacsDescriptor dimacsType(std::istream& is)
   93.71 +  {
   93.72 +    DimacsDescriptor r;
   93.73 +    std::string problem,str;
   93.74 +    char c;
   93.75 +    r.lineShift=0;
   93.76 +    while (is >> c)
   93.77 +      switch(c)
   93.78 +        {
   93.79 +        case 'p':
   93.80 +          if(is >> problem >> r.nodeNum >> r.edgeNum)
   93.81 +            {
   93.82 +              getline(is, str);
   93.83 +              r.lineShift++;
   93.84 +              if(problem=="min") r.type=DimacsDescriptor::MIN;
   93.85 +              else if(problem=="max") r.type=DimacsDescriptor::MAX;
   93.86 +              else if(problem=="sp") r.type=DimacsDescriptor::SP;
   93.87 +              else if(problem=="mat") r.type=DimacsDescriptor::MAT;
   93.88 +              else throw FormatError("Unknown problem type");
   93.89 +              return r;
   93.90 +            }
   93.91 +          else
   93.92 +            {
   93.93 +              throw FormatError("Missing or wrong problem type declaration.");
   93.94 +            }
   93.95 +          break;
   93.96 +        case 'c':
   93.97 +          getline(is, str);
   93.98 +          r.lineShift++;
   93.99 +          break;
  93.100 +        default:
  93.101 +          throw FormatError("Unknown DIMACS declaration.");
  93.102 +        }
  93.103 +    throw FormatError("Missing problem type declaration.");
  93.104 +  }
  93.105 +
  93.106 +
  93.107 +  /// \brief DIMACS minimum cost flow reader function.
  93.108 +  ///
  93.109 +  /// This function reads a minimum cost flow instance from DIMACS format,
  93.110 +  /// i.e. from a DIMACS file having a line starting with
  93.111 +  /// \code
  93.112 +  ///   p min
  93.113 +  /// \endcode
  93.114 +  /// At the beginning, \c g is cleared by \c g.clear(). The supply
  93.115 +  /// amount of the nodes are written to the \c supply node map
  93.116 +  /// (they are signed values). The lower bounds, capacities and costs
  93.117 +  /// of the arcs are written to the \c lower, \c capacity and \c cost
  93.118 +  /// arc maps.
  93.119 +  ///
  93.120 +  /// If the capacity of an arc is less than the lower bound, it will
  93.121 +  /// be set to "infinite" instead. The actual value of "infinite" is
  93.122 +  /// contolled by the \c infty parameter. If it is 0 (the default value),
  93.123 +  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
  93.124 +  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
  93.125 +  /// a non-zero value, that value will be used as "infinite".
  93.126 +  ///
  93.127 +  /// If the file type was previously evaluated by dimacsType(), then
  93.128 +  /// the descriptor struct should be given by the \c dest parameter.
  93.129 +  template <typename Digraph, typename LowerMap,
  93.130 +            typename CapacityMap, typename CostMap,
  93.131 +            typename SupplyMap>
  93.132 +  void readDimacsMin(std::istream& is,
  93.133 +                     Digraph &g,
  93.134 +                     LowerMap& lower,
  93.135 +                     CapacityMap& capacity,
  93.136 +                     CostMap& cost,
  93.137 +                     SupplyMap& supply,
  93.138 +                     typename CapacityMap::Value infty = 0,
  93.139 +                     DimacsDescriptor desc=DimacsDescriptor())
  93.140 +  {
  93.141 +    g.clear();
  93.142 +    std::vector<typename Digraph::Node> nodes;
  93.143 +    typename Digraph::Arc e;
  93.144 +    std::string problem, str;
  93.145 +    char c;
  93.146 +    int i, j;
  93.147 +    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
  93.148 +    if(desc.type!=DimacsDescriptor::MIN)
  93.149 +      throw FormatError("Problem type mismatch");
  93.150 +
  93.151 +    nodes.resize(desc.nodeNum + 1);
  93.152 +    for (int k = 1; k <= desc.nodeNum; ++k) {
  93.153 +      nodes[k] = g.addNode();
  93.154 +      supply.set(nodes[k], 0);
  93.155 +    }
  93.156 +
  93.157 +    typename SupplyMap::Value sup;
  93.158 +    typename CapacityMap::Value low;
  93.159 +    typename CapacityMap::Value cap;
  93.160 +    typename CostMap::Value co;
  93.161 +    typedef typename CapacityMap::Value Capacity;
  93.162 +    if(infty==0)
  93.163 +      infty = std::numeric_limits<Capacity>::has_infinity ?
  93.164 +        std::numeric_limits<Capacity>::infinity() :
  93.165 +        std::numeric_limits<Capacity>::max();
  93.166 +
  93.167 +    while (is >> c) {
  93.168 +      switch (c) {
  93.169 +      case 'c': // comment line
  93.170 +        getline(is, str);
  93.171 +        break;
  93.172 +      case 'n': // node definition line
  93.173 +        is >> i >> sup;
  93.174 +        getline(is, str);
  93.175 +        supply.set(nodes[i], sup);
  93.176 +        break;
  93.177 +      case 'a': // arc definition line
  93.178 +        is >> i >> j >> low >> cap >> co;
  93.179 +        getline(is, str);
  93.180 +        e = g.addArc(nodes[i], nodes[j]);
  93.181 +        lower.set(e, low);
  93.182 +        if (cap >= low)
  93.183 +          capacity.set(e, cap);
  93.184 +        else
  93.185 +          capacity.set(e, infty);
  93.186 +        cost.set(e, co);
  93.187 +        break;
  93.188 +      }
  93.189 +    }
  93.190 +  }
  93.191 +
  93.192 +  template<typename Digraph, typename CapacityMap>
  93.193 +  void _readDimacs(std::istream& is,
  93.194 +                   Digraph &g,
  93.195 +                   CapacityMap& capacity,
  93.196 +                   typename Digraph::Node &s,
  93.197 +                   typename Digraph::Node &t,
  93.198 +                   typename CapacityMap::Value infty = 0,
  93.199 +                   DimacsDescriptor desc=DimacsDescriptor()) {
  93.200 +    g.clear();
  93.201 +    s=t=INVALID;
  93.202 +    std::vector<typename Digraph::Node> nodes;
  93.203 +    typename Digraph::Arc e;
  93.204 +    char c, d;
  93.205 +    int i, j;
  93.206 +    typename CapacityMap::Value _cap;
  93.207 +    std::string str;
  93.208 +    nodes.resize(desc.nodeNum + 1);
  93.209 +    for (int k = 1; k <= desc.nodeNum; ++k) {
  93.210 +      nodes[k] = g.addNode();
  93.211 +    }
  93.212 +    typedef typename CapacityMap::Value Capacity;
  93.213 +
  93.214 +    if(infty==0)
  93.215 +      infty = std::numeric_limits<Capacity>::has_infinity ?
  93.216 +        std::numeric_limits<Capacity>::infinity() :
  93.217 +        std::numeric_limits<Capacity>::max();
  93.218 + 
  93.219 +    while (is >> c) {
  93.220 +      switch (c) {
  93.221 +      case 'c': // comment line
  93.222 +        getline(is, str);
  93.223 +        break;
  93.224 +      case 'n': // node definition line
  93.225 +        if (desc.type==DimacsDescriptor::SP) { // shortest path problem
  93.226 +          is >> i;
  93.227 +          getline(is, str);
  93.228 +          s = nodes[i];
  93.229 +        }
  93.230 +        if (desc.type==DimacsDescriptor::MAX) { // max flow problem
  93.231 +          is >> i >> d;
  93.232 +          getline(is, str);
  93.233 +          if (d == 's') s = nodes[i];
  93.234 +          if (d == 't') t = nodes[i];
  93.235 +        }
  93.236 +        break;
  93.237 +      case 'a': // arc definition line
  93.238 +        if (desc.type==DimacsDescriptor::SP) {
  93.239 +          is >> i >> j >> _cap;
  93.240 +          getline(is, str);
  93.241 +          e = g.addArc(nodes[i], nodes[j]);
  93.242 +          capacity.set(e, _cap);
  93.243 +        } 
  93.244 +        else if (desc.type==DimacsDescriptor::MAX) {
  93.245 +          is >> i >> j >> _cap;
  93.246 +          getline(is, str);
  93.247 +          e = g.addArc(nodes[i], nodes[j]);
  93.248 +          if (_cap >= 0)
  93.249 +            capacity.set(e, _cap);
  93.250 +          else
  93.251 +            capacity.set(e, infty);
  93.252 +        }
  93.253 +        else {
  93.254 +          is >> i >> j;
  93.255 +          getline(is, str);
  93.256 +          g.addArc(nodes[i], nodes[j]);
  93.257 +        }
  93.258 +        break;
  93.259 +      }
  93.260 +    }
  93.261 +  }
  93.262 +
  93.263 +  /// \brief DIMACS maximum flow reader function.
  93.264 +  ///
  93.265 +  /// This function reads a maximum flow instance from DIMACS format,
  93.266 +  /// i.e. from a DIMACS file having a line starting with
  93.267 +  /// \code
  93.268 +  ///   p max
  93.269 +  /// \endcode
  93.270 +  /// At the beginning, \c g is cleared by \c g.clear(). The arc
  93.271 +  /// capacities are written to the \c capacity arc map and \c s and
  93.272 +  /// \c t are set to the source and the target nodes.
  93.273 +  ///
  93.274 +  /// If the capacity of an arc is negative, it will
  93.275 +  /// be set to "infinite" instead. The actual value of "infinite" is
  93.276 +  /// contolled by the \c infty parameter. If it is 0 (the default value),
  93.277 +  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
  93.278 +  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
  93.279 +  /// a non-zero value, that value will be used as "infinite".
  93.280 +  ///
  93.281 +  /// If the file type was previously evaluated by dimacsType(), then
  93.282 +  /// the descriptor struct should be given by the \c dest parameter.
  93.283 +  template<typename Digraph, typename CapacityMap>
  93.284 +  void readDimacsMax(std::istream& is,
  93.285 +                     Digraph &g,
  93.286 +                     CapacityMap& capacity,
  93.287 +                     typename Digraph::Node &s,
  93.288 +                     typename Digraph::Node &t,
  93.289 +                     typename CapacityMap::Value infty = 0,
  93.290 +                     DimacsDescriptor desc=DimacsDescriptor()) {
  93.291 +    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
  93.292 +    if(desc.type!=DimacsDescriptor::MAX)
  93.293 +      throw FormatError("Problem type mismatch");
  93.294 +    _readDimacs(is,g,capacity,s,t,infty,desc);
  93.295 +  }
  93.296 +
  93.297 +  /// \brief DIMACS shortest path reader function.
  93.298 +  ///
  93.299 +  /// This function reads a shortest path instance from DIMACS format,
  93.300 +  /// i.e. from a DIMACS file having a line starting with
  93.301 +  /// \code
  93.302 +  ///   p sp
  93.303 +  /// \endcode
  93.304 +  /// At the beginning, \c g is cleared by \c g.clear(). The arc
  93.305 +  /// lengths are written to the \c length arc map and \c s is set to the
  93.306 +  /// source node.
  93.307 +  ///
  93.308 +  /// If the file type was previously evaluated by dimacsType(), then
  93.309 +  /// the descriptor struct should be given by the \c dest parameter.
  93.310 +  template<typename Digraph, typename LengthMap>
  93.311 +  void readDimacsSp(std::istream& is,
  93.312 +                    Digraph &g,
  93.313 +                    LengthMap& length,
  93.314 +                    typename Digraph::Node &s,
  93.315 +                    DimacsDescriptor desc=DimacsDescriptor()) {
  93.316 +    typename Digraph::Node t;
  93.317 +    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
  93.318 +    if(desc.type!=DimacsDescriptor::SP)
  93.319 +      throw FormatError("Problem type mismatch");
  93.320 +    _readDimacs(is, g, length, s, t, 0, desc);
  93.321 +  }
  93.322 +
  93.323 +  /// \brief DIMACS capacitated digraph reader function.
  93.324 +  ///
  93.325 +  /// This function reads an arc capacitated digraph instance from
  93.326 +  /// DIMACS 'max' or 'sp' format.
  93.327 +  /// At the beginning, \c g is cleared by \c g.clear()
  93.328 +  /// and the arc capacities/lengths are written to the \c capacity
  93.329 +  /// arc map.
  93.330 +  ///
  93.331 +  /// In case of the 'max' format, if the capacity of an arc is negative,
  93.332 +  /// it will
  93.333 +  /// be set to "infinite" instead. The actual value of "infinite" is
  93.334 +  /// contolled by the \c infty parameter. If it is 0 (the default value),
  93.335 +  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
  93.336 +  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
  93.337 +  /// a non-zero value, that value will be used as "infinite".
  93.338 +  ///
  93.339 +  /// If the file type was previously evaluated by dimacsType(), then
  93.340 +  /// the descriptor struct should be given by the \c dest parameter.
  93.341 +  template<typename Digraph, typename CapacityMap>
  93.342 +  void readDimacsCap(std::istream& is,
  93.343 +                     Digraph &g,
  93.344 +                     CapacityMap& capacity,
  93.345 +                     typename CapacityMap::Value infty = 0,
  93.346 +                     DimacsDescriptor desc=DimacsDescriptor()) {
  93.347 +    typename Digraph::Node u,v;
  93.348 +    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
  93.349 +    if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
  93.350 +      throw FormatError("Problem type mismatch");
  93.351 +    _readDimacs(is, g, capacity, u, v, infty, desc);
  93.352 +  }
  93.353 +
  93.354 +  template<typename Graph>
  93.355 +  typename enable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
  93.356 +  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
  93.357 +              dummy<0> = 0)
  93.358 +  {
  93.359 +    g.addEdge(s,t);
  93.360 +  }
  93.361 +  template<typename Graph>
  93.362 +  typename disable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
  93.363 +  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
  93.364 +              dummy<1> = 1)
  93.365 +  {
  93.366 +    g.addArc(s,t);
  93.367 +  }
  93.368 +  
  93.369 +  /// \brief DIMACS plain (di)graph reader function.
  93.370 +  ///
  93.371 +  /// This function reads a plain (di)graph without any designated nodes
  93.372 +  /// and maps (e.g. a matching instance) from DIMACS format, i.e. from 
  93.373 +  /// DIMACS files having a line starting with
  93.374 +  /// \code
  93.375 +  ///   p mat
  93.376 +  /// \endcode
  93.377 +  /// At the beginning, \c g is cleared by \c g.clear().
  93.378 +  ///
  93.379 +  /// If the file type was previously evaluated by dimacsType(), then
  93.380 +  /// the descriptor struct should be given by the \c dest parameter.
  93.381 +  template<typename Graph>
  93.382 +  void readDimacsMat(std::istream& is, Graph &g,
  93.383 +                     DimacsDescriptor desc=DimacsDescriptor())
  93.384 +  {
  93.385 +    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
  93.386 +    if(desc.type!=DimacsDescriptor::MAT)
  93.387 +      throw FormatError("Problem type mismatch");
  93.388 +
  93.389 +    g.clear();
  93.390 +    std::vector<typename Graph::Node> nodes;
  93.391 +    char c;
  93.392 +    int i, j;
  93.393 +    std::string str;
  93.394 +    nodes.resize(desc.nodeNum + 1);
  93.395 +    for (int k = 1; k <= desc.nodeNum; ++k) {
  93.396 +      nodes[k] = g.addNode();
  93.397 +    }
  93.398 +    
  93.399 +    while (is >> c) {
  93.400 +      switch (c) {
  93.401 +      case 'c': // comment line
  93.402 +        getline(is, str);
  93.403 +        break;
  93.404 +      case 'n': // node definition line
  93.405 +        break;
  93.406 +      case 'a': // arc definition line
  93.407 +        is >> i >> j;
  93.408 +        getline(is, str);
  93.409 +        _addArcEdge(g,nodes[i], nodes[j]);
  93.410 +        break;
  93.411 +      }
  93.412 +    }
  93.413 +  }
  93.414 +
  93.415 +  /// DIMACS plain digraph writer function.
  93.416 +  ///
  93.417 +  /// This function writes a digraph without any designated nodes and
  93.418 +  /// maps into DIMACS format, i.e. into DIMACS file having a line
  93.419 +  /// starting with
  93.420 +  /// \code
  93.421 +  ///   p mat
  93.422 +  /// \endcode
  93.423 +  /// If \c comment is not empty, then it will be printed in the first line
  93.424 +  /// prefixed by 'c'.
  93.425 +  template<typename Digraph>
  93.426 +  void writeDimacsMat(std::ostream& os, const Digraph &g,
  93.427 +                      std::string comment="") {
  93.428 +    typedef typename Digraph::NodeIt NodeIt;
  93.429 +    typedef typename Digraph::ArcIt ArcIt;
  93.430 +
  93.431 +    if(!comment.empty())
  93.432 +      os << "c " << comment << std::endl;
  93.433 +    os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
  93.434 +
  93.435 +    typename Digraph::template NodeMap<int> nodes(g);
  93.436 +    int i = 1;
  93.437 +    for(NodeIt v(g); v != INVALID; ++v) {
  93.438 +      nodes.set(v, i);
  93.439 +      ++i;
  93.440 +    }
  93.441 +    for(ArcIt e(g); e != INVALID; ++e) {
  93.442 +      os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
  93.443 +         << std::endl;
  93.444 +    }
  93.445 +  }
  93.446 +
  93.447 +  /// @}
  93.448 +
  93.449 +} //namespace lemon
  93.450 +
  93.451 +#endif //LEMON_DIMACS_H
    94.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.2 +++ b/lemon/edge_set.h	Thu Nov 05 15:50:01 2009 +0100
    94.3 @@ -0,0 +1,1416 @@
    94.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    94.5 + *
    94.6 + * This file is a part of LEMON, a generic C++ optimization library.
    94.7 + *
    94.8 + * Copyright (C) 2003-2008
    94.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   94.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   94.11 + *
   94.12 + * Permission to use, modify and distribute this software is granted
   94.13 + * provided that this copyright notice appears in all copies. For
   94.14 + * precise terms see the accompanying LICENSE file.
   94.15 + *
   94.16 + * This software is provided "AS IS" with no warranty of any kind,
   94.17 + * express or implied, and with no claim as to its suitability for any
   94.18 + * purpose.
   94.19 + *
   94.20 + */
   94.21 +
   94.22 +#ifndef LEMON_EDGE_SET_H
   94.23 +#define LEMON_EDGE_SET_H
   94.24 +
   94.25 +#include <lemon/core.h>
   94.26 +#include <lemon/bits/edge_set_extender.h>
   94.27 +
   94.28 +/// \ingroup graphs
   94.29 +/// \file
   94.30 +/// \brief ArcSet and EdgeSet classes.
   94.31 +///
   94.32 +/// Graphs which use another graph's node-set as own.
   94.33 +namespace lemon {
   94.34 +
   94.35 +  template <typename GR>
   94.36 +  class ListArcSetBase {
   94.37 +  public:
   94.38 +
   94.39 +    typedef typename GR::Node Node;
   94.40 +    typedef typename GR::NodeIt NodeIt;
   94.41 +
   94.42 +  protected:
   94.43 +
   94.44 +    struct NodeT {
   94.45 +      int first_out, first_in;
   94.46 +      NodeT() : first_out(-1), first_in(-1) {}
   94.47 +    };
   94.48 +
   94.49 +    typedef typename ItemSetTraits<GR, Node>::
   94.50 +    template Map<NodeT>::Type NodesImplBase;
   94.51 +
   94.52 +    NodesImplBase* _nodes;
   94.53 +
   94.54 +    struct ArcT {
   94.55 +      Node source, target;
   94.56 +      int next_out, next_in;
   94.57 +      int prev_out, prev_in;
   94.58 +      ArcT() : prev_out(-1), prev_in(-1) {}
   94.59 +    };
   94.60 +
   94.61 +    std::vector<ArcT> arcs;
   94.62 +
   94.63 +    int first_arc;
   94.64 +    int first_free_arc;
   94.65 +
   94.66 +    const GR* _graph;
   94.67 +
   94.68 +    void initalize(const GR& graph, NodesImplBase& nodes) {
   94.69 +      _graph = &graph;
   94.70 +      _nodes = &nodes;
   94.71 +    }
   94.72 +
   94.73 +  public:
   94.74 +
   94.75 +    class Arc {
   94.76 +      friend class ListArcSetBase<GR>;
   94.77 +    protected:
   94.78 +      Arc(int _id) : id(_id) {}
   94.79 +      int id;
   94.80 +    public:
   94.81 +      Arc() {}
   94.82 +      Arc(Invalid) : id(-1) {}
   94.83 +      bool operator==(const Arc& arc) const { return id == arc.id; }
   94.84 +      bool operator!=(const Arc& arc) const { return id != arc.id; }
   94.85 +      bool operator<(const Arc& arc) const { return id < arc.id; }
   94.86 +    };
   94.87 +
   94.88 +    ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
   94.89 +
   94.90 +    Node addNode() {
   94.91 +      LEMON_ASSERT(false,
   94.92 +        "This graph structure does not support node insertion");
   94.93 +      return INVALID; // avoid warning
   94.94 +    }
   94.95 +
   94.96 +    Arc addArc(const Node& u, const Node& v) {
   94.97 +      int n;
   94.98 +      if (first_free_arc == -1) {
   94.99 +        n = arcs.size();
  94.100 +        arcs.push_back(ArcT());
  94.101 +      } else {
  94.102 +        n = first_free_arc;
  94.103 +        first_free_arc = arcs[first_free_arc].next_in;
  94.104 +      }
  94.105 +      arcs[n].next_in = (*_nodes)[v].first_in;
  94.106 +      if ((*_nodes)[v].first_in != -1) {
  94.107 +        arcs[(*_nodes)[v].first_in].prev_in = n;
  94.108 +      }
  94.109 +      (*_nodes)[v].first_in = n;
  94.110 +      arcs[n].next_out = (*_nodes)[u].first_out;
  94.111 +      if ((*_nodes)[u].first_out != -1) {
  94.112 +        arcs[(*_nodes)[u].first_out].prev_out = n;
  94.113 +      }
  94.114 +      (*_nodes)[u].first_out = n;
  94.115 +      arcs[n].source = u;
  94.116 +      arcs[n].target = v;
  94.117 +      return Arc(n);
  94.118 +    }
  94.119 +
  94.120 +    void erase(const Arc& arc) {
  94.121 +      int n = arc.id;
  94.122 +      if (arcs[n].prev_in != -1) {
  94.123 +        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
  94.124 +      } else {
  94.125 +        (*_nodes)[arcs[n].target].first_in = arcs[n].next_in;
  94.126 +      }
  94.127 +      if (arcs[n].next_in != -1) {
  94.128 +        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
  94.129 +      }
  94.130 +
  94.131 +      if (arcs[n].prev_out != -1) {
  94.132 +        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
  94.133 +      } else {
  94.134 +        (*_nodes)[arcs[n].source].first_out = arcs[n].next_out;
  94.135 +      }
  94.136 +      if (arcs[n].next_out != -1) {
  94.137 +        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
  94.138 +      }
  94.139 +
  94.140 +    }
  94.141 +
  94.142 +    void clear() {
  94.143 +      Node node;
  94.144 +      for (first(node); node != INVALID; next(node)) {
  94.145 +        (*_nodes)[node].first_in = -1;
  94.146 +        (*_nodes)[node].first_out = -1;
  94.147 +      }
  94.148 +      arcs.clear();
  94.149 +      first_arc = -1;
  94.150 +      first_free_arc = -1;
  94.151 +    }
  94.152 +
  94.153 +    void first(Node& node) const {
  94.154 +      _graph->first(node);
  94.155 +    }
  94.156 +
  94.157 +    void next(Node& node) const {
  94.158 +      _graph->next(node);
  94.159 +    }
  94.160 +
  94.161 +    void first(Arc& arc) const {
  94.162 +      Node node;
  94.163 +      first(node);
  94.164 +      while (node != INVALID && (*_nodes)[node].first_in == -1) {
  94.165 +        next(node);
  94.166 +      }
  94.167 +      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
  94.168 +    }
  94.169 +
  94.170 +    void next(Arc& arc) const {
  94.171 +      if (arcs[arc.id].next_in != -1) {
  94.172 +        arc.id = arcs[arc.id].next_in;
  94.173 +      } else {
  94.174 +        Node node = arcs[arc.id].target;
  94.175 +        next(node);
  94.176 +        while (node != INVALID && (*_nodes)[node].first_in == -1) {
  94.177 +          next(node);
  94.178 +        }
  94.179 +        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
  94.180 +      }
  94.181 +    }
  94.182 +
  94.183 +    void firstOut(Arc& arc, const Node& node) const {
  94.184 +      arc.id = (*_nodes)[node].first_out;
  94.185 +    }
  94.186 +
  94.187 +    void nextOut(Arc& arc) const {
  94.188 +      arc.id = arcs[arc.id].next_out;
  94.189 +    }
  94.190 +
  94.191 +    void firstIn(Arc& arc, const Node& node) const {
  94.192 +      arc.id = (*_nodes)[node].first_in;
  94.193 +    }
  94.194 +
  94.195 +    void nextIn(Arc& arc) const {
  94.196 +      arc.id = arcs[arc.id].next_in;
  94.197 +    }
  94.198 +
  94.199 +    int id(const Node& node) const { return _graph->id(node); }
  94.200 +    int id(const Arc& arc) const { return arc.id; }
  94.201 +
  94.202 +    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
  94.203 +    Arc arcFromId(int ix) const { return Arc(ix); }
  94.204 +
  94.205 +    int maxNodeId() const { return _graph->maxNodeId(); };
  94.206 +    int maxArcId() const { return arcs.size() - 1; }
  94.207 +
  94.208 +    Node source(const Arc& arc) const { return arcs[arc.id].source;}
  94.209 +    Node target(const Arc& arc) const { return arcs[arc.id].target;}
  94.210 +
  94.211 +    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
  94.212 +
  94.213 +    NodeNotifier& notifier(Node) const {
  94.214 +      return _graph->notifier(Node());
  94.215 +    }
  94.216 +
  94.217 +    template <typename V>
  94.218 +    class NodeMap : public GR::template NodeMap<V> {
  94.219 +      typedef typename GR::template NodeMap<V> Parent;
  94.220 +
  94.221 +    public:
  94.222 +
  94.223 +      explicit NodeMap(const ListArcSetBase<GR>& arcset)
  94.224 +        : Parent(*arcset._graph) {}
  94.225 +
  94.226 +      NodeMap(const ListArcSetBase<GR>& arcset, const V& value)
  94.227 +        : Parent(*arcset._graph, value) {}
  94.228 +
  94.229 +      NodeMap& operator=(const NodeMap& cmap) {
  94.230 +        return operator=<NodeMap>(cmap);
  94.231 +      }
  94.232 +
  94.233 +      template <typename CMap>
  94.234 +      NodeMap& operator=(const CMap& cmap) {
  94.235 +        Parent::operator=(cmap);
  94.236 +        return *this;
  94.237 +      }
  94.238 +    };
  94.239 +
  94.240 +  };
  94.241 +
  94.242 +  /// \ingroup graphs
  94.243 +  ///
  94.244 +  /// \brief Digraph using a node set of another digraph or graph and
  94.245 +  /// an own arc set.
  94.246 +  ///
  94.247 +  /// This structure can be used to establish another directed graph
  94.248 +  /// over a node set of an existing one. This class uses the same
  94.249 +  /// Node type as the underlying graph, and each valid node of the
  94.250 +  /// original graph is valid in this arc set, therefore the node
  94.251 +  /// objects of the original graph can be used directly with this
  94.252 +  /// class. The node handling functions (id handling, observing, and
  94.253 +  /// iterators) works equivalently as in the original graph.
  94.254 +  ///
  94.255 +  /// This implementation is based on doubly-linked lists, from each
  94.256 +  /// node the outgoing and the incoming arcs make up lists, therefore
  94.257 +  /// one arc can be erased in constant time. It also makes possible,
  94.258 +  /// that node can be removed from the underlying graph, in this case
  94.259 +  /// all arcs incident to the given node is erased from the arc set.
  94.260 +  ///
  94.261 +  /// \param GR The type of the graph which shares its node set with
  94.262 +  /// this class. Its interface must conform to the
  94.263 +  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
  94.264 +  /// concept.
  94.265 +  ///
  94.266 +  /// This class fully conforms to the \ref concepts::Digraph
  94.267 +  /// "Digraph" concept.
  94.268 +  template <typename GR>
  94.269 +  class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
  94.270 +    typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
  94.271 +
  94.272 +  public:
  94.273 +
  94.274 +    typedef typename Parent::Node Node;
  94.275 +    typedef typename Parent::Arc Arc;
  94.276 +
  94.277 +    typedef typename Parent::NodesImplBase NodesImplBase;
  94.278 +
  94.279 +    void eraseNode(const Node& node) {
  94.280 +      Arc arc;
  94.281 +      Parent::firstOut(arc, node);
  94.282 +      while (arc != INVALID ) {
  94.283 +        erase(arc);
  94.284 +        Parent::firstOut(arc, node);
  94.285 +      }
  94.286 +
  94.287 +      Parent::firstIn(arc, node);
  94.288 +      while (arc != INVALID ) {
  94.289 +        erase(arc);
  94.290 +        Parent::firstIn(arc, node);
  94.291 +      }
  94.292 +    }
  94.293 +
  94.294 +    void clearNodes() {
  94.295 +      Parent::clear();
  94.296 +    }
  94.297 +
  94.298 +    class NodesImpl : public NodesImplBase {
  94.299 +      typedef NodesImplBase Parent;
  94.300 +
  94.301 +    public:
  94.302 +      NodesImpl(const GR& graph, ListArcSet& arcset)
  94.303 +        : Parent(graph), _arcset(arcset) {}
  94.304 +
  94.305 +      virtual ~NodesImpl() {}
  94.306 +
  94.307 +    protected:
  94.308 +
  94.309 +      virtual void erase(const Node& node) {
  94.310 +        _arcset.eraseNode(node);
  94.311 +        Parent::erase(node);
  94.312 +      }
  94.313 +      virtual void erase(const std::vector<Node>& nodes) {
  94.314 +        for (int i = 0; i < int(nodes.size()); ++i) {
  94.315 +          _arcset.eraseNode(nodes[i]);
  94.316 +        }
  94.317 +        Parent::erase(nodes);
  94.318 +      }
  94.319 +      virtual void clear() {
  94.320 +        _arcset.clearNodes();
  94.321 +        Parent::clear();
  94.322 +      }
  94.323 +
  94.324 +    private:
  94.325 +      ListArcSet& _arcset;
  94.326 +    };
  94.327 +
  94.328 +    NodesImpl _nodes;
  94.329 +
  94.330 +  public:
  94.331 +
  94.332 +    /// \brief Constructor of the ArcSet.
  94.333 +    ///
  94.334 +    /// Constructor of the ArcSet.
  94.335 +    ListArcSet(const GR& graph) : _nodes(graph, *this) {
  94.336 +      Parent::initalize(graph, _nodes);
  94.337 +    }
  94.338 +
  94.339 +    /// \brief Add a new arc to the digraph.
  94.340 +    ///
  94.341 +    /// Add a new arc to the digraph with source node \c s
  94.342 +    /// and target node \c t.
  94.343 +    /// \return The new arc.
  94.344 +    Arc addArc(const Node& s, const Node& t) {
  94.345 +      return Parent::addArc(s, t);
  94.346 +    }
  94.347 +
  94.348 +    /// \brief Erase an arc from the digraph.
  94.349 +    ///
  94.350 +    /// Erase an arc \c a from the digraph.
  94.351 +    void erase(const Arc& a) {
  94.352 +      return Parent::erase(a);
  94.353 +    }
  94.354 +
  94.355 +  };
  94.356 +
  94.357 +  template <typename GR>
  94.358 +  class ListEdgeSetBase {
  94.359 +  public:
  94.360 +
  94.361 +    typedef typename GR::Node Node;
  94.362 +    typedef typename GR::NodeIt NodeIt;
  94.363 +
  94.364 +  protected:
  94.365 +
  94.366 +    struct NodeT {
  94.367 +      int first_out;
  94.368 +      NodeT() : first_out(-1) {}
  94.369 +    };
  94.370 +
  94.371 +    typedef typename ItemSetTraits<GR, Node>::
  94.372 +    template Map<NodeT>::Type NodesImplBase;
  94.373 +
  94.374 +    NodesImplBase* _nodes;
  94.375 +
  94.376 +    struct ArcT {
  94.377 +      Node target;
  94.378 +      int prev_out, next_out;
  94.379 +      ArcT() : prev_out(-1), next_out(-1) {}
  94.380 +    };
  94.381 +
  94.382 +    std::vector<ArcT> arcs;
  94.383 +
  94.384 +    int first_arc;
  94.385 +    int first_free_arc;
  94.386 +
  94.387 +    const GR* _graph;
  94.388 +
  94.389 +    void initalize(const GR& graph, NodesImplBase& nodes) {
  94.390 +      _graph = &graph;
  94.391 +      _nodes = &nodes;
  94.392 +    }
  94.393 +
  94.394 +  public:
  94.395 +
  94.396 +    class Edge {
  94.397 +      friend class ListEdgeSetBase;
  94.398 +    protected:
  94.399 +
  94.400 +      int id;
  94.401 +      explicit Edge(int _id) { id = _id;}
  94.402 +
  94.403 +    public:
  94.404 +      Edge() {}
  94.405 +      Edge (Invalid) { id = -1; }
  94.406 +      bool operator==(const Edge& arc) const {return id == arc.id;}
  94.407 +      bool operator!=(const Edge& arc) const {return id != arc.id;}
  94.408 +      bool operator<(const Edge& arc) const {return id < arc.id;}
  94.409 +    };
  94.410 +
  94.411 +    class Arc {
  94.412 +      friend class ListEdgeSetBase;
  94.413 +    protected:
  94.414 +      Arc(int _id) : id(_id) {}
  94.415 +      int id;
  94.416 +    public:
  94.417 +      operator Edge() const { return edgeFromId(id / 2); }
  94.418 +
  94.419 +      Arc() {}
  94.420 +      Arc(Invalid) : id(-1) {}
  94.421 +      bool operator==(const Arc& arc) const { return id == arc.id; }
  94.422 +      bool operator!=(const Arc& arc) const { return id != arc.id; }
  94.423 +      bool operator<(const Arc& arc) const { return id < arc.id; }
  94.424 +    };
  94.425 +
  94.426 +    ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
  94.427 +
  94.428 +    Node addNode() {
  94.429 +      LEMON_ASSERT(false,
  94.430 +        "This graph structure does not support node insertion");
  94.431 +      return INVALID; // avoid warning
  94.432 +    }
  94.433 +
  94.434 +    Edge addEdge(const Node& u, const Node& v) {
  94.435 +      int n;
  94.436 +
  94.437 +      if (first_free_arc == -1) {
  94.438 +        n = arcs.size();
  94.439 +        arcs.push_back(ArcT());
  94.440 +        arcs.push_back(ArcT());
  94.441 +      } else {
  94.442 +        n = first_free_arc;
  94.443 +        first_free_arc = arcs[n].next_out;
  94.444 +      }
  94.445 +
  94.446 +      arcs[n].target = u;
  94.447 +      arcs[n | 1].target = v;
  94.448 +
  94.449 +      arcs[n].next_out = (*_nodes)[v].first_out;
  94.450 +      if ((*_nodes)[v].first_out != -1) {
  94.451 +        arcs[(*_nodes)[v].first_out].prev_out = n;
  94.452 +      }
  94.453 +      (*_nodes)[v].first_out = n;
  94.454 +      arcs[n].prev_out = -1;
  94.455 +
  94.456 +      if ((*_nodes)[u].first_out != -1) {
  94.457 +        arcs[(*_nodes)[u].first_out].prev_out = (n | 1);
  94.458 +      }
  94.459 +      arcs[n | 1].next_out = (*_nodes)[u].first_out;
  94.460 +      (*_nodes)[u].first_out = (n | 1);
  94.461 +      arcs[n | 1].prev_out = -1;
  94.462 +
  94.463 +      return Edge(n / 2);
  94.464 +    }
  94.465 +
  94.466 +    void erase(const Edge& arc) {
  94.467 +      int n = arc.id * 2;
  94.468 +
  94.469 +      if (arcs[n].next_out != -1) {
  94.470 +        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
  94.471 +      }
  94.472 +
  94.473 +      if (arcs[n].prev_out != -1) {
  94.474 +        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
  94.475 +      } else {
  94.476 +        (*_nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
  94.477 +      }
  94.478 +
  94.479 +      if (arcs[n | 1].next_out != -1) {
  94.480 +        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
  94.481 +      }
  94.482 +
  94.483 +      if (arcs[n | 1].prev_out != -1) {
  94.484 +        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
  94.485 +      } else {
  94.486 +        (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
  94.487 +      }
  94.488 +
  94.489 +      arcs[n].next_out = first_free_arc;
  94.490 +      first_free_arc = n;
  94.491 +
  94.492 +    }
  94.493 +
  94.494 +    void clear() {
  94.495 +      Node node;
  94.496 +      for (first(node); node != INVALID; next(node)) {
  94.497 +        (*_nodes)[node].first_out = -1;
  94.498 +      }
  94.499 +      arcs.clear();
  94.500 +      first_arc = -1;
  94.501 +      first_free_arc = -1;
  94.502 +    }
  94.503 +
  94.504 +    void first(Node& node) const {
  94.505 +      _graph->first(node);
  94.506 +    }
  94.507 +
  94.508 +    void next(Node& node) const {
  94.509 +      _graph->next(node);
  94.510 +    }
  94.511 +
  94.512 +    void first(Arc& arc) const {
  94.513 +      Node node;
  94.514 +      first(node);
  94.515 +      while (node != INVALID && (*_nodes)[node].first_out == -1) {
  94.516 +        next(node);
  94.517 +      }
  94.518 +      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
  94.519 +    }
  94.520 +
  94.521 +    void next(Arc& arc) const {
  94.522 +      if (arcs[arc.id].next_out != -1) {
  94.523 +        arc.id = arcs[arc.id].next_out;
  94.524 +      } else {
  94.525 +        Node node = arcs[arc.id ^ 1].target;
  94.526 +        next(node);
  94.527 +        while(node != INVALID && (*_nodes)[node].first_out == -1) {
  94.528 +          next(node);
  94.529 +        }
  94.530 +        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
  94.531 +      }
  94.532 +    }
  94.533 +
  94.534 +    void first(Edge& edge) const {
  94.535 +      Node node;
  94.536 +      first(node);
  94.537 +      while (node != INVALID) {
  94.538 +        edge.id = (*_nodes)[node].first_out;
  94.539 +        while ((edge.id & 1) != 1) {
  94.540 +          edge.id = arcs[edge.id].next_out;
  94.541 +        }
  94.542 +        if (edge.id != -1) {
  94.543 +          edge.id /= 2;
  94.544 +          return;
  94.545 +        }
  94.546 +        next(node);
  94.547 +      }
  94.548 +      edge.id = -1;
  94.549 +    }
  94.550 +
  94.551 +    void next(Edge& edge) const {
  94.552 +      Node node = arcs[edge.id * 2].target;
  94.553 +      edge.id = arcs[(edge.id * 2) | 1].next_out;
  94.554 +      while ((edge.id & 1) != 1) {
  94.555 +        edge.id = arcs[edge.id].next_out;
  94.556 +      }
  94.557 +      if (edge.id != -1) {
  94.558 +        edge.id /= 2;
  94.559 +        return;
  94.560 +      }
  94.561 +      next(node);
  94.562 +      while (node != INVALID) {
  94.563 +        edge.id = (*_nodes)[node].first_out;
  94.564 +        while ((edge.id & 1) != 1) {
  94.565 +          edge.id = arcs[edge.id].next_out;
  94.566 +        }
  94.567 +        if (edge.id != -1) {
  94.568 +          edge.id /= 2;
  94.569 +          return;
  94.570 +        }
  94.571 +        next(node);
  94.572 +      }
  94.573 +      edge.id = -1;
  94.574 +    }
  94.575 +
  94.576 +    void firstOut(Arc& arc, const Node& node) const {
  94.577 +      arc.id = (*_nodes)[node].first_out;
  94.578 +    }
  94.579 +
  94.580 +    void nextOut(Arc& arc) const {
  94.581 +      arc.id = arcs[arc.id].next_out;
  94.582 +    }
  94.583 +
  94.584 +    void firstIn(Arc& arc, const Node& node) const {
  94.585 +      arc.id = (((*_nodes)[node].first_out) ^ 1);
  94.586 +      if (arc.id == -2) arc.id = -1;
  94.587 +    }
  94.588 +
  94.589 +    void nextIn(Arc& arc) const {
  94.590 +      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
  94.591 +      if (arc.id == -2) arc.id = -1;
  94.592 +    }
  94.593 +
  94.594 +    void firstInc(Edge &arc, bool& dir, const Node& node) const {
  94.595 +      int de = (*_nodes)[node].first_out;
  94.596 +      if (de != -1 ) {
  94.597 +        arc.id = de / 2;
  94.598 +        dir = ((de & 1) == 1);
  94.599 +      } else {
  94.600 +        arc.id = -1;
  94.601 +        dir = true;
  94.602 +      }
  94.603 +    }
  94.604 +    void nextInc(Edge &arc, bool& dir) const {
  94.605 +      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
  94.606 +      if (de != -1 ) {
  94.607 +        arc.id = de / 2;
  94.608 +        dir = ((de & 1) == 1);
  94.609 +      } else {
  94.610 +        arc.id = -1;
  94.611 +        dir = true;
  94.612 +      }
  94.613 +    }
  94.614 +
  94.615 +    static bool direction(Arc arc) {
  94.616 +      return (arc.id & 1) == 1;
  94.617 +    }
  94.618 +
  94.619 +    static Arc direct(Edge edge, bool dir) {
  94.620 +      return Arc(edge.id * 2 + (dir ? 1 : 0));
  94.621 +    }
  94.622 +
  94.623 +    int id(const Node& node) const { return _graph->id(node); }
  94.624 +    static int id(Arc e) { return e.id; }
  94.625 +    static int id(Edge e) { return e.id; }
  94.626 +
  94.627 +    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
  94.628 +    static Arc arcFromId(int id) { return Arc(id);}
  94.629 +    static Edge edgeFromId(int id) { return Edge(id);}
  94.630 +
  94.631 +    int maxNodeId() const { return _graph->maxNodeId(); };
  94.632 +    int maxEdgeId() const { return arcs.size() / 2 - 1; }
  94.633 +    int maxArcId() const { return arcs.size()-1; }
  94.634 +
  94.635 +    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
  94.636 +    Node target(Arc e) const { return arcs[e.id].target; }
  94.637 +
  94.638 +    Node u(Edge e) const { return arcs[2 * e.id].target; }
  94.639 +    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
  94.640 +
  94.641 +    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
  94.642 +
  94.643 +    NodeNotifier& notifier(Node) const {
  94.644 +      return _graph->notifier(Node());
  94.645 +    }
  94.646 +
  94.647 +    template <typename V>
  94.648 +    class NodeMap : public GR::template NodeMap<V> {
  94.649 +      typedef typename GR::template NodeMap<V> Parent;
  94.650 +
  94.651 +    public:
  94.652 +
  94.653 +      explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
  94.654 +        : Parent(*arcset._graph) {}
  94.655 +
  94.656 +      NodeMap(const ListEdgeSetBase<GR>& arcset, const V& value)
  94.657 +        : Parent(*arcset._graph, value) {}
  94.658 +
  94.659 +      NodeMap& operator=(const NodeMap& cmap) {
  94.660 +        return operator=<NodeMap>(cmap);
  94.661 +      }
  94.662 +
  94.663 +      template <typename CMap>
  94.664 +      NodeMap& operator=(const CMap& cmap) {
  94.665 +        Parent::operator=(cmap);
  94.666 +        return *this;
  94.667 +      }
  94.668 +    };
  94.669 +
  94.670 +  };
  94.671 +
  94.672 +  /// \ingroup graphs
  94.673 +  ///
  94.674 +  /// \brief Graph using a node set of another digraph or graph and an
  94.675 +  /// own edge set.
  94.676 +  ///
  94.677 +  /// This structure can be used to establish another graph over a
  94.678 +  /// node set of an existing one. This class uses the same Node type
  94.679 +  /// as the underlying graph, and each valid node of the original
  94.680 +  /// graph is valid in this arc set, therefore the node objects of
  94.681 +  /// the original graph can be used directly with this class. The
  94.682 +  /// node handling functions (id handling, observing, and iterators)
  94.683 +  /// works equivalently as in the original graph.
  94.684 +  ///
  94.685 +  /// This implementation is based on doubly-linked lists, from each
  94.686 +  /// node the incident edges make up lists, therefore one edge can be
  94.687 +  /// erased in constant time. It also makes possible, that node can
  94.688 +  /// be removed from the underlying graph, in this case all edges
  94.689 +  /// incident to the given node is erased from the arc set.
  94.690 +  ///
  94.691 +  /// \param GR The type of the graph which shares its node set
  94.692 +  /// with this class. Its interface must conform to the
  94.693 +  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
  94.694 +  /// concept.
  94.695 +  ///
  94.696 +  /// This class fully conforms to the \ref concepts::Graph "Graph"
  94.697 +  /// concept.
  94.698 +  template <typename GR>
  94.699 +  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
  94.700 +    typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
  94.701 +
  94.702 +  public:
  94.703 +
  94.704 +    typedef typename Parent::Node Node;
  94.705 +    typedef typename Parent::Arc Arc;
  94.706 +    typedef typename Parent::Edge Edge;
  94.707 +
  94.708 +    typedef typename Parent::NodesImplBase NodesImplBase;
  94.709 +
  94.710 +    void eraseNode(const Node& node) {
  94.711 +      Arc arc;
  94.712 +      Parent::firstOut(arc, node);
  94.713 +      while (arc != INVALID ) {
  94.714 +        erase(arc);
  94.715 +        Parent::firstOut(arc, node);
  94.716 +      }
  94.717 +
  94.718 +    }
  94.719 +
  94.720 +    void clearNodes() {
  94.721 +      Parent::clear();
  94.722 +    }
  94.723 +
  94.724 +    class NodesImpl : public NodesImplBase {
  94.725 +      typedef NodesImplBase Parent;
  94.726 +
  94.727 +    public:
  94.728 +      NodesImpl(const GR& graph, ListEdgeSet& arcset)
  94.729 +        : Parent(graph), _arcset(arcset) {}
  94.730 +
  94.731 +      virtual ~NodesImpl() {}
  94.732 +
  94.733 +    protected:
  94.734 +
  94.735 +      virtual void erase(const Node& node) {
  94.736 +        _arcset.eraseNode(node);
  94.737 +        Parent::erase(node);
  94.738 +      }
  94.739 +      virtual void erase(const std::vector<Node>& nodes) {
  94.740 +        for (int i = 0; i < int(nodes.size()); ++i) {
  94.741 +          _arcset.eraseNode(nodes[i]);
  94.742 +        }
  94.743 +        Parent::erase(nodes);
  94.744 +      }
  94.745 +      virtual void clear() {
  94.746 +        _arcset.clearNodes();
  94.747 +        Parent::clear();
  94.748 +      }
  94.749 +
  94.750 +    private:
  94.751 +      ListEdgeSet& _arcset;
  94.752 +    };
  94.753 +
  94.754 +    NodesImpl _nodes;
  94.755 +
  94.756 +  public:
  94.757 +
  94.758 +    /// \brief Constructor of the EdgeSet.
  94.759 +    ///
  94.760 +    /// Constructor of the EdgeSet.
  94.761 +    ListEdgeSet(const GR& graph) : _nodes(graph, *this) {
  94.762 +      Parent::initalize(graph, _nodes);
  94.763 +    }
  94.764 +
  94.765 +    /// \brief Add a new edge to the graph.
  94.766 +    ///
  94.767 +    /// Add a new edge to the graph with node \c u
  94.768 +    /// and node \c v endpoints.
  94.769 +    /// \return The new edge.
  94.770 +    Edge addEdge(const Node& u, const Node& v) {
  94.771 +      return Parent::addEdge(u, v);
  94.772 +    }
  94.773 +
  94.774 +    /// \brief Erase an edge from the graph.
  94.775 +    ///
  94.776 +    /// Erase the edge \c e from the graph.
  94.777 +    void erase(const Edge& e) {
  94.778 +      return Parent::erase(e);
  94.779 +    }
  94.780 +
  94.781 +  };
  94.782 +
  94.783 +  template <typename GR>
  94.784 +  class SmartArcSetBase {
  94.785 +  public:
  94.786 +
  94.787 +    typedef typename GR::Node Node;
  94.788 +    typedef typename GR::NodeIt NodeIt;
  94.789 +
  94.790 +  protected:
  94.791 +
  94.792 +    struct NodeT {
  94.793 +      int first_out, first_in;
  94.794 +      NodeT() : first_out(-1), first_in(-1) {}
  94.795 +    };
  94.796 +
  94.797 +    typedef typename ItemSetTraits<GR, Node>::
  94.798 +    template Map<NodeT>::Type NodesImplBase;
  94.799 +
  94.800 +    NodesImplBase* _nodes;
  94.801 +
  94.802 +    struct ArcT {
  94.803 +      Node source, target;
  94.804 +      int next_out, next_in;
  94.805 +      ArcT() {}
  94.806 +    };
  94.807 +
  94.808 +    std::vector<ArcT> arcs;
  94.809 +
  94.810 +    const GR* _graph;
  94.811 +
  94.812 +    void initalize(const GR& graph, NodesImplBase& nodes) {
  94.813 +      _graph = &graph;
  94.814 +      _nodes = &nodes;
  94.815 +    }
  94.816 +
  94.817 +  public:
  94.818 +
  94.819 +    class Arc {
  94.820 +      friend class SmartArcSetBase<GR>;
  94.821 +    protected:
  94.822 +      Arc(int _id) : id(_id) {}
  94.823 +      int id;
  94.824 +    public:
  94.825 +      Arc() {}
  94.826 +      Arc(Invalid) : id(-1) {}
  94.827 +      bool operator==(const Arc& arc) const { return id == arc.id; }
  94.828 +      bool operator!=(const Arc& arc) const { return id != arc.id; }
  94.829 +      bool operator<(const Arc& arc) const { return id < arc.id; }
  94.830 +    };
  94.831 +
  94.832 +    SmartArcSetBase() {}
  94.833 +
  94.834 +    Node addNode() {
  94.835 +      LEMON_ASSERT(false,
  94.836 +        "This graph structure does not support node insertion");
  94.837 +      return INVALID; // avoid warning
  94.838 +    }
  94.839 +
  94.840 +    Arc addArc(const Node& u, const Node& v) {
  94.841 +      int n = arcs.size();
  94.842 +      arcs.push_back(ArcT());
  94.843 +      arcs[n].next_in = (*_nodes)[v].first_in;
  94.844 +      (*_nodes)[v].first_in = n;
  94.845 +      arcs[n].next_out = (*_nodes)[u].first_out;
  94.846 +      (*_nodes)[u].first_out = n;
  94.847 +      arcs[n].source = u;
  94.848 +      arcs[n].target = v;
  94.849 +      return Arc(n);
  94.850 +    }
  94.851 +
  94.852 +    void clear() {
  94.853 +      Node node;
  94.854 +      for (first(node); node != INVALID; next(node)) {
  94.855 +        (*_nodes)[node].first_in = -1;
  94.856 +        (*_nodes)[node].first_out = -1;
  94.857 +      }
  94.858 +      arcs.clear();
  94.859 +    }
  94.860 +
  94.861 +    void first(Node& node) const {
  94.862 +      _graph->first(node);
  94.863 +    }
  94.864 +
  94.865 +    void next(Node& node) const {
  94.866 +      _graph->next(node);
  94.867 +    }
  94.868 +
  94.869 +    void first(Arc& arc) const {
  94.870 +      arc.id = arcs.size() - 1;
  94.871 +    }
  94.872 +
  94.873 +    static void next(Arc& arc) {
  94.874 +      --arc.id;
  94.875 +    }
  94.876 +
  94.877 +    void firstOut(Arc& arc, const Node& node) const {
  94.878 +      arc.id = (*_nodes)[node].first_out;
  94.879 +    }
  94.880 +
  94.881 +    void nextOut(Arc& arc) const {
  94.882 +      arc.id = arcs[arc.id].next_out;
  94.883 +    }
  94.884 +
  94.885 +    void firstIn(Arc& arc, const Node& node) const {
  94.886 +      arc.id = (*_nodes)[node].first_in;
  94.887 +    }
  94.888 +
  94.889 +    void nextIn(Arc& arc) const {
  94.890 +      arc.id = arcs[arc.id].next_in;
  94.891 +    }
  94.892 +
  94.893 +    int id(const Node& node) const { return _graph->id(node); }
  94.894 +    int id(const Arc& arc) const { return arc.id; }
  94.895 +
  94.896 +    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
  94.897 +    Arc arcFromId(int ix) const { return Arc(ix); }
  94.898 +
  94.899 +    int maxNodeId() const { return _graph->maxNodeId(); };
  94.900 +    int maxArcId() const { return arcs.size() - 1; }
  94.901 +
  94.902 +    Node source(const Arc& arc) const { return arcs[arc.id].source;}
  94.903 +    Node target(const Arc& arc) const { return arcs[arc.id].target;}
  94.904 +
  94.905 +    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
  94.906 +
  94.907 +    NodeNotifier& notifier(Node) const {
  94.908 +      return _graph->notifier(Node());
  94.909 +    }
  94.910 +
  94.911 +    template <typename V>
  94.912 +    class NodeMap : public GR::template NodeMap<V> {
  94.913 +      typedef typename GR::template NodeMap<V> Parent;
  94.914 +
  94.915 +    public:
  94.916 +
  94.917 +      explicit NodeMap(const SmartArcSetBase<GR>& arcset)
  94.918 +        : Parent(*arcset._graph) { }
  94.919 +
  94.920 +      NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
  94.921 +        : Parent(*arcset._graph, value) { }
  94.922 +
  94.923 +      NodeMap& operator=(const NodeMap& cmap) {
  94.924 +        return operator=<NodeMap>(cmap);
  94.925 +      }
  94.926 +
  94.927 +      template <typename CMap>
  94.928 +      NodeMap& operator=(const CMap& cmap) {
  94.929 +        Parent::operator=(cmap);
  94.930 +        return *this;
  94.931 +      }
  94.932 +    };
  94.933 +
  94.934 +  };
  94.935 +
  94.936 +
  94.937 +  /// \ingroup graphs
  94.938 +  ///
  94.939 +  /// \brief Digraph using a node set of another digraph or graph and
  94.940 +  /// an own arc set.
  94.941 +  ///
  94.942 +  /// This structure can be used to establish another directed graph
  94.943 +  /// over a node set of an existing one. This class uses the same
  94.944 +  /// Node type as the underlying graph, and each valid node of the
  94.945 +  /// original graph is valid in this arc set, therefore the node
  94.946 +  /// objects of the original graph can be used directly with this
  94.947 +  /// class. The node handling functions (id handling, observing, and
  94.948 +  /// iterators) works equivalently as in the original graph.
  94.949 +  ///
  94.950 +  /// \param GR The type of the graph which shares its node set with
  94.951 +  /// this class. Its interface must conform to the
  94.952 +  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
  94.953 +  /// concept.
  94.954 +  ///
  94.955 +  /// This implementation is slightly faster than the \c ListArcSet,
  94.956 +  /// because it uses continuous storage for arcs and it uses just
  94.957 +  /// single-linked lists for enumerate outgoing and incoming
  94.958 +  /// arcs. Therefore the arcs cannot be erased from the arc sets.
  94.959 +  ///
  94.960 +  /// \warning If a node is erased from the underlying graph and this
  94.961 +  /// node is the source or target of one arc in the arc set, then
  94.962 +  /// the arc set is invalidated, and it cannot be used anymore. The
  94.963 +  /// validity can be checked with the \c valid() member function.
  94.964 +  ///
  94.965 +  /// This class fully conforms to the \ref concepts::Digraph
  94.966 +  /// "Digraph" concept.
  94.967 +  template <typename GR>
  94.968 +  class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
  94.969 +    typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
  94.970 +
  94.971 +  public:
  94.972 +
  94.973 +    typedef typename Parent::Node Node;
  94.974 +    typedef typename Parent::Arc Arc;
  94.975 +
  94.976 +  protected:
  94.977 +
  94.978 +    typedef typename Parent::NodesImplBase NodesImplBase;
  94.979 +
  94.980 +    void eraseNode(const Node& node) {
  94.981 +      if (typename Parent::InArcIt(*this, node) == INVALID &&
  94.982 +          typename Parent::OutArcIt(*this, node) == INVALID) {
  94.983 +        return;
  94.984 +      }
  94.985 +      throw typename NodesImplBase::Notifier::ImmediateDetach();
  94.986 +    }
  94.987 +
  94.988 +    void clearNodes() {
  94.989 +      Parent::clear();
  94.990 +    }
  94.991 +
  94.992 +    class NodesImpl : public NodesImplBase {
  94.993 +      typedef NodesImplBase Parent;
  94.994 +
  94.995 +    public:
  94.996 +      NodesImpl(const GR& graph, SmartArcSet& arcset)
  94.997 +        : Parent(graph), _arcset(arcset) {}
  94.998 +
  94.999 +      virtual ~NodesImpl() {}
 94.1000 +
 94.1001 +      bool attached() const {
 94.1002 +        return Parent::attached();
 94.1003 +      }
 94.1004 +
 94.1005 +    protected:
 94.1006 +
 94.1007 +      virtual void erase(const Node& node) {
 94.1008 +        try {
 94.1009 +          _arcset.eraseNode(node);
 94.1010 +          Parent::erase(node);
 94.1011 +        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
 94.1012 +          Parent::clear();
 94.1013 +          throw;
 94.1014 +        }
 94.1015 +      }
 94.1016 +      virtual void erase(const std::vector<Node>& nodes) {
 94.1017 +        try {
 94.1018 +          for (int i = 0; i < int(nodes.size()); ++i) {
 94.1019 +            _arcset.eraseNode(nodes[i]);
 94.1020 +          }
 94.1021 +          Parent::erase(nodes);
 94.1022 +        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
 94.1023 +          Parent::clear();
 94.1024 +          throw;
 94.1025 +        }
 94.1026 +      }
 94.1027 +      virtual void clear() {
 94.1028 +        _arcset.clearNodes();
 94.1029 +        Parent::clear();
 94.1030 +      }
 94.1031 +
 94.1032 +    private:
 94.1033 +      SmartArcSet& _arcset;
 94.1034 +    };
 94.1035 +
 94.1036 +    NodesImpl _nodes;
 94.1037 +
 94.1038 +  public:
 94.1039 +
 94.1040 +    /// \brief Constructor of the ArcSet.
 94.1041 +    ///
 94.1042 +    /// Constructor of the ArcSet.
 94.1043 +    SmartArcSet(const GR& graph) : _nodes(graph, *this) {
 94.1044 +      Parent::initalize(graph, _nodes);
 94.1045 +    }
 94.1046 +
 94.1047 +    /// \brief Add a new arc to the digraph.
 94.1048 +    ///
 94.1049 +    /// Add a new arc to the digraph with source node \c s
 94.1050 +    /// and target node \c t.
 94.1051 +    /// \return The new arc.
 94.1052 +    Arc addArc(const Node& s, const Node& t) {
 94.1053 +      return Parent::addArc(s, t);
 94.1054 +    }
 94.1055 +
 94.1056 +    /// \brief Validity check
 94.1057 +    ///
 94.1058 +    /// This functions gives back false if the ArcSet is
 94.1059 +    /// invalidated. It occurs when a node in the underlying graph is
 94.1060 +    /// erased and it is not isolated in the ArcSet.
 94.1061 +    bool valid() const {
 94.1062 +      return _nodes.attached();
 94.1063 +    }
 94.1064 +
 94.1065 +  };
 94.1066 +
 94.1067 +
 94.1068 +  template <typename GR>
 94.1069 +  class SmartEdgeSetBase {
 94.1070 +  public:
 94.1071 +
 94.1072 +    typedef typename GR::Node Node;
 94.1073 +    typedef typename GR::NodeIt NodeIt;
 94.1074 +
 94.1075 +  protected:
 94.1076 +
 94.1077 +    struct NodeT {
 94.1078 +      int first_out;
 94.1079 +      NodeT() : first_out(-1) {}
 94.1080 +    };
 94.1081 +
 94.1082 +    typedef typename ItemSetTraits<GR, Node>::
 94.1083 +    template Map<NodeT>::Type NodesImplBase;
 94.1084 +
 94.1085 +    NodesImplBase* _nodes;
 94.1086 +
 94.1087 +    struct ArcT {
 94.1088 +      Node target;
 94.1089 +      int next_out;
 94.1090 +      ArcT() {}
 94.1091 +    };
 94.1092 +
 94.1093 +    std::vector<ArcT> arcs;
 94.1094 +
 94.1095 +    const GR* _graph;
 94.1096 +
 94.1097 +    void initalize(const GR& graph, NodesImplBase& nodes) {
 94.1098 +      _graph = &graph;
 94.1099 +      _nodes = &nodes;
 94.1100 +    }
 94.1101 +
 94.1102 +  public:
 94.1103 +
 94.1104 +    class Edge {
 94.1105 +      friend class SmartEdgeSetBase;
 94.1106 +    protected:
 94.1107 +
 94.1108 +      int id;
 94.1109 +      explicit Edge(int _id) { id = _id;}
 94.1110 +
 94.1111 +    public:
 94.1112 +      Edge() {}
 94.1113 +      Edge (Invalid) { id = -1; }
 94.1114 +      bool operator==(const Edge& arc) const {return id == arc.id;}
 94.1115 +      bool operator!=(const Edge& arc) const {return id != arc.id;}
 94.1116 +      bool operator<(const Edge& arc) const {return id < arc.id;}
 94.1117 +    };
 94.1118 +
 94.1119 +    class Arc {
 94.1120 +      friend class SmartEdgeSetBase;
 94.1121 +    protected:
 94.1122 +      Arc(int _id) : id(_id) {}
 94.1123 +      int id;
 94.1124 +    public:
 94.1125 +      operator Edge() const { return edgeFromId(id / 2); }
 94.1126 +
 94.1127 +      Arc() {}
 94.1128 +      Arc(Invalid) : id(-1) {}
 94.1129 +      bool operator==(const Arc& arc) const { return id == arc.id; }
 94.1130 +      bool operator!=(const Arc& arc) const { return id != arc.id; }
 94.1131 +      bool operator<(const Arc& arc) const { return id < arc.id; }
 94.1132 +    };
 94.1133 +
 94.1134 +    SmartEdgeSetBase() {}
 94.1135 +
 94.1136 +    Node addNode() {
 94.1137 +      LEMON_ASSERT(false,
 94.1138 +        "This graph structure does not support node insertion");
 94.1139 +      return INVALID; // avoid warning
 94.1140 +    }
 94.1141 +
 94.1142 +    Edge addEdge(const Node& u, const Node& v) {
 94.1143 +      int n = arcs.size();
 94.1144 +      arcs.push_back(ArcT());
 94.1145 +      arcs.push_back(ArcT());
 94.1146 +
 94.1147 +      arcs[n].target = u;
 94.1148 +      arcs[n | 1].target = v;
 94.1149 +
 94.1150 +      arcs[n].next_out = (*_nodes)[v].first_out;
 94.1151 +      (*_nodes)[v].first_out = n;
 94.1152 +
 94.1153 +      arcs[n | 1].next_out = (*_nodes)[u].first_out;
 94.1154 +      (*_nodes)[u].first_out = (n | 1);
 94.1155 +
 94.1156 +      return Edge(n / 2);
 94.1157 +    }
 94.1158 +
 94.1159 +    void clear() {
 94.1160 +      Node node;
 94.1161 +      for (first(node); node != INVALID; next(node)) {
 94.1162 +        (*_nodes)[node].first_out = -1;
 94.1163 +      }
 94.1164 +      arcs.clear();
 94.1165 +    }
 94.1166 +
 94.1167 +    void first(Node& node) const {
 94.1168 +      _graph->first(node);
 94.1169 +    }
 94.1170 +
 94.1171 +    void next(Node& node) const {
 94.1172 +      _graph->next(node);
 94.1173 +    }
 94.1174 +
 94.1175 +    void first(Arc& arc) const {
 94.1176 +      arc.id = arcs.size() - 1;
 94.1177 +    }
 94.1178 +
 94.1179 +    static void next(Arc& arc) {
 94.1180 +      --arc.id;
 94.1181 +    }
 94.1182 +
 94.1183 +    void first(Edge& arc) const {
 94.1184 +      arc.id = arcs.size() / 2 - 1;
 94.1185 +    }
 94.1186 +
 94.1187 +    static void next(Edge& arc) {
 94.1188 +      --arc.id;
 94.1189 +    }
 94.1190 +
 94.1191 +    void firstOut(Arc& arc, const Node& node) const {
 94.1192 +      arc.id = (*_nodes)[node].first_out;
 94.1193 +    }
 94.1194 +
 94.1195 +    void nextOut(Arc& arc) const {
 94.1196 +      arc.id = arcs[arc.id].next_out;
 94.1197 +    }
 94.1198 +
 94.1199 +    void firstIn(Arc& arc, const Node& node) const {
 94.1200 +      arc.id = (((*_nodes)[node].first_out) ^ 1);
 94.1201 +      if (arc.id == -2) arc.id = -1;
 94.1202 +    }
 94.1203 +
 94.1204 +    void nextIn(Arc& arc) const {
 94.1205 +      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
 94.1206 +      if (arc.id == -2) arc.id = -1;
 94.1207 +    }
 94.1208 +
 94.1209 +    void firstInc(Edge &arc, bool& dir, const Node& node) const {
 94.1210 +      int de = (*_nodes)[node].first_out;
 94.1211 +      if (de != -1 ) {
 94.1212 +        arc.id = de / 2;
 94.1213 +        dir = ((de & 1) == 1);
 94.1214 +      } else {
 94.1215 +        arc.id = -1;
 94.1216 +        dir = true;
 94.1217 +      }
 94.1218 +    }
 94.1219 +    void nextInc(Edge &arc, bool& dir) const {
 94.1220 +      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
 94.1221 +      if (de != -1 ) {
 94.1222 +        arc.id = de / 2;
 94.1223 +        dir = ((de & 1) == 1);
 94.1224 +      } else {
 94.1225 +        arc.id = -1;
 94.1226 +        dir = true;
 94.1227 +      }
 94.1228 +    }
 94.1229 +
 94.1230 +    static bool direction(Arc arc) {
 94.1231 +      return (arc.id & 1) == 1;
 94.1232 +    }
 94.1233 +
 94.1234 +    static Arc direct(Edge edge, bool dir) {
 94.1235 +      return Arc(edge.id * 2 + (dir ? 1 : 0));
 94.1236 +    }
 94.1237 +
 94.1238 +    int id(Node node) const { return _graph->id(node); }
 94.1239 +    static int id(Arc arc) { return arc.id; }
 94.1240 +    static int id(Edge arc) { return arc.id; }
 94.1241 +
 94.1242 +    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
 94.1243 +    static Arc arcFromId(int id) { return Arc(id); }
 94.1244 +    static Edge edgeFromId(int id) { return Edge(id);}
 94.1245 +
 94.1246 +    int maxNodeId() const { return _graph->maxNodeId(); };
 94.1247 +    int maxArcId() const { return arcs.size() - 1; }
 94.1248 +    int maxEdgeId() const { return arcs.size() / 2 - 1; }
 94.1249 +
 94.1250 +    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
 94.1251 +    Node target(Arc e) const { return arcs[e.id].target; }
 94.1252 +
 94.1253 +    Node u(Edge e) const { return arcs[2 * e.id].target; }
 94.1254 +    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
 94.1255 +
 94.1256 +    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
 94.1257 +
 94.1258 +    NodeNotifier& notifier(Node) const {
 94.1259 +      return _graph->notifier(Node());
 94.1260 +    }
 94.1261 +
 94.1262 +    template <typename V>
 94.1263 +    class NodeMap : public GR::template NodeMap<V> {
 94.1264 +      typedef typename GR::template NodeMap<V> Parent;
 94.1265 +
 94.1266 +    public:
 94.1267 +
 94.1268 +      explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
 94.1269 +        : Parent(*arcset._graph) { }
 94.1270 +
 94.1271 +      NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& value)
 94.1272 +        : Parent(*arcset._graph, value) { }
 94.1273 +
 94.1274 +      NodeMap& operator=(const NodeMap& cmap) {
 94.1275 +        return operator=<NodeMap>(cmap);
 94.1276 +      }
 94.1277 +
 94.1278 +      template <typename CMap>
 94.1279 +      NodeMap& operator=(const CMap& cmap) {
 94.1280 +        Parent::operator=(cmap);
 94.1281 +        return *this;
 94.1282 +      }
 94.1283 +    };
 94.1284 +
 94.1285 +  };
 94.1286 +
 94.1287 +  /// \ingroup graphs
 94.1288 +  ///
 94.1289 +  /// \brief Graph using a node set of another digraph or graph and an
 94.1290 +  /// own edge set.
 94.1291 +  ///
 94.1292 +  /// This structure can be used to establish another graph over a
 94.1293 +  /// node set of an existing one. This class uses the same Node type
 94.1294 +  /// as the underlying graph, and each valid node of the original
 94.1295 +  /// graph is valid in this arc set, therefore the node objects of
 94.1296 +  /// the original graph can be used directly with this class. The
 94.1297 +  /// node handling functions (id handling, observing, and iterators)
 94.1298 +  /// works equivalently as in the original graph.
 94.1299 +  ///
 94.1300 +  /// \param GR The type of the graph which shares its node set
 94.1301 +  /// with this class. Its interface must conform to the
 94.1302 +  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
 94.1303 +  ///  concept.
 94.1304 +  ///
 94.1305 +  /// This implementation is slightly faster than the \c ListEdgeSet,
 94.1306 +  /// because it uses continuous storage for edges and it uses just
 94.1307 +  /// single-linked lists for enumerate incident edges. Therefore the
 94.1308 +  /// edges cannot be erased from the edge sets.
 94.1309 +  ///
 94.1310 +  /// \warning If a node is erased from the underlying graph and this
 94.1311 +  /// node is incident to one edge in the edge set, then the edge set
 94.1312 +  /// is invalidated, and it cannot be used anymore. The validity can
 94.1313 +  /// be checked with the \c valid() member function.
 94.1314 +  ///
 94.1315 +  /// This class fully conforms to the \ref concepts::Graph
 94.1316 +  /// "Graph" concept.
 94.1317 +  template <typename GR>
 94.1318 +  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
 94.1319 +    typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
 94.1320 +
 94.1321 +  public:
 94.1322 +
 94.1323 +    typedef typename Parent::Node Node;
 94.1324 +    typedef typename Parent::Arc Arc;
 94.1325 +    typedef typename Parent::Edge Edge;
 94.1326 +
 94.1327 +  protected:
 94.1328 +
 94.1329 +    typedef typename Parent::NodesImplBase NodesImplBase;
 94.1330 +
 94.1331 +    void eraseNode(const Node& node) {
 94.1332 +      if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
 94.1333 +        return;
 94.1334 +      }
 94.1335 +      throw typename NodesImplBase::Notifier::ImmediateDetach();
 94.1336 +    }
 94.1337 +
 94.1338 +    void clearNodes() {
 94.1339 +      Parent::clear();
 94.1340 +    }
 94.1341 +
 94.1342 +    class NodesImpl : public NodesImplBase {
 94.1343 +      typedef NodesImplBase Parent;
 94.1344 +
 94.1345 +    public:
 94.1346 +      NodesImpl(const GR& graph, SmartEdgeSet& arcset)
 94.1347 +        : Parent(graph), _arcset(arcset) {}
 94.1348 +
 94.1349 +      virtual ~NodesImpl() {}
 94.1350 +
 94.1351 +      bool attached() const {
 94.1352 +        return Parent::attached();
 94.1353 +      }
 94.1354 +
 94.1355 +    protected:
 94.1356 +
 94.1357 +      virtual void erase(const Node& node) {
 94.1358 +        try {
 94.1359 +          _arcset.eraseNode(node);
 94.1360 +          Parent::erase(node);
 94.1361 +        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
 94.1362 +          Parent::clear();
 94.1363 +          throw;
 94.1364 +        }
 94.1365 +      }
 94.1366 +      virtual void erase(const std::vector<Node>& nodes) {
 94.1367 +        try {
 94.1368 +          for (int i = 0; i < int(nodes.size()); ++i) {
 94.1369 +            _arcset.eraseNode(nodes[i]);
 94.1370 +          }
 94.1371 +          Parent::erase(nodes);
 94.1372 +        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
 94.1373 +          Parent::clear();
 94.1374 +          throw;
 94.1375 +        }
 94.1376 +      }
 94.1377 +      virtual void clear() {
 94.1378 +        _arcset.clearNodes();
 94.1379 +        Parent::clear();
 94.1380 +      }
 94.1381 +
 94.1382 +    private:
 94.1383 +      SmartEdgeSet& _arcset;
 94.1384 +    };
 94.1385 +
 94.1386 +    NodesImpl _nodes;
 94.1387 +
 94.1388 +  public:
 94.1389 +
 94.1390 +    /// \brief Constructor of the EdgeSet.
 94.1391 +    ///
 94.1392 +    /// Constructor of the EdgeSet.
 94.1393 +    SmartEdgeSet(const GR& graph) : _nodes(graph, *this) {
 94.1394 +      Parent::initalize(graph, _nodes);
 94.1395 +    }
 94.1396 +
 94.1397 +    /// \brief Add a new edge to the graph.
 94.1398 +    ///
 94.1399 +    /// Add a new edge to the graph with node \c u
 94.1400 +    /// and node \c v endpoints.
 94.1401 +    /// \return The new edge.
 94.1402 +    Edge addEdge(const Node& u, const Node& v) {
 94.1403 +      return Parent::addEdge(u, v);
 94.1404 +    }
 94.1405 +
 94.1406 +    /// \brief Validity check
 94.1407 +    ///
 94.1408 +    /// This functions gives back false if the EdgeSet is
 94.1409 +    /// invalidated. It occurs when a node in the underlying graph is
 94.1410 +    /// erased and it is not isolated in the EdgeSet.
 94.1411 +    bool valid() const {
 94.1412 +      return _nodes.attached();
 94.1413 +    }
 94.1414 +
 94.1415 +  };
 94.1416 +
 94.1417 +}
 94.1418 +
 94.1419 +#endif
    95.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.2 +++ b/lemon/elevator.h	Thu Nov 05 15:50:01 2009 +0100
    95.3 @@ -0,0 +1,982 @@
    95.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    95.5 + *
    95.6 + * This file is a part of LEMON, a generic C++ optimization library.
    95.7 + *
    95.8 + * Copyright (C) 2003-2009
    95.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   95.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   95.11 + *
   95.12 + * Permission to use, modify and distribute this software is granted
   95.13 + * provided that this copyright notice appears in all copies. For
   95.14 + * precise terms see the accompanying LICENSE file.
   95.15 + *
   95.16 + * This software is provided "AS IS" with no warranty of any kind,
   95.17 + * express or implied, and with no claim as to its suitability for any
   95.18 + * purpose.
   95.19 + *
   95.20 + */
   95.21 +
   95.22 +#ifndef LEMON_ELEVATOR_H
   95.23 +#define LEMON_ELEVATOR_H
   95.24 +
   95.25 +///\ingroup auxdat
   95.26 +///\file
   95.27 +///\brief Elevator class
   95.28 +///
   95.29 +///Elevator class implements an efficient data structure
   95.30 +///for labeling items in push-relabel type algorithms.
   95.31 +///
   95.32 +
   95.33 +#include <lemon/core.h>
   95.34 +#include <lemon/bits/traits.h>
   95.35 +
   95.36 +namespace lemon {
   95.37 +
   95.38 +  ///Class for handling "labels" in push-relabel type algorithms.
   95.39 +
   95.40 +  ///A class for handling "labels" in push-relabel type algorithms.
   95.41 +  ///
   95.42 +  ///\ingroup auxdat
   95.43 +  ///Using this class you can assign "labels" (nonnegative integer numbers)
   95.44 +  ///to the edges or nodes of a graph, manipulate and query them through
   95.45 +  ///operations typically arising in "push-relabel" type algorithms.
   95.46 +  ///
   95.47 +  ///Each item is either \em active or not, and you can also choose a
   95.48 +  ///highest level active item.
   95.49 +  ///
   95.50 +  ///\sa LinkedElevator
   95.51 +  ///
   95.52 +  ///\param GR Type of the underlying graph.
   95.53 +  ///\param Item Type of the items the data is assigned to (\c GR::Node,
   95.54 +  ///\c GR::Arc or \c GR::Edge).
   95.55 +  template<class GR, class Item>
   95.56 +  class Elevator
   95.57 +  {
   95.58 +  public:
   95.59 +
   95.60 +    typedef Item Key;
   95.61 +    typedef int Value;
   95.62 +
   95.63 +  private:
   95.64 +
   95.65 +    typedef Item *Vit;
   95.66 +    typedef typename ItemSetTraits<GR,Item>::template Map<Vit>::Type VitMap;
   95.67 +    typedef typename ItemSetTraits<GR,Item>::template Map<int>::Type IntMap;
   95.68 +
   95.69 +    const GR &_g;
   95.70 +    int _max_level;
   95.71 +    int _item_num;
   95.72 +    VitMap _where;
   95.73 +    IntMap _level;
   95.74 +    std::vector<Item> _items;
   95.75 +    std::vector<Vit> _first;
   95.76 +    std::vector<Vit> _last_active;
   95.77 +
   95.78 +    int _highest_active;
   95.79 +
   95.80 +    void copy(Item i, Vit p)
   95.81 +    {
   95.82 +      _where[*p=i] = p;
   95.83 +    }
   95.84 +    void copy(Vit s, Vit p)
   95.85 +    {
   95.86 +      if(s!=p)
   95.87 +        {
   95.88 +          Item i=*s;
   95.89 +          *p=i;
   95.90 +          _where[i] = p;
   95.91 +        }
   95.92 +    }
   95.93 +    void swap(Vit i, Vit j)
   95.94 +    {
   95.95 +      Item ti=*i;
   95.96 +      Vit ct = _where[ti];
   95.97 +      _where[ti] = _where[*i=*j];
   95.98 +      _where[*j] = ct;
   95.99 +      *j=ti;
  95.100 +    }
  95.101 +
  95.102 +  public:
  95.103 +
  95.104 +    ///Constructor with given maximum level.
  95.105 +
  95.106 +    ///Constructor with given maximum level.
  95.107 +    ///
  95.108 +    ///\param graph The underlying graph.
  95.109 +    ///\param max_level The maximum allowed level.
  95.110 +    ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
  95.111 +    Elevator(const GR &graph,int max_level) :
  95.112 +      _g(graph),
  95.113 +      _max_level(max_level),
  95.114 +      _item_num(_max_level),
  95.115 +      _where(graph),
  95.116 +      _level(graph,0),
  95.117 +      _items(_max_level),
  95.118 +      _first(_max_level+2),
  95.119 +      _last_active(_max_level+2),
  95.120 +      _highest_active(-1) {}
  95.121 +    ///Constructor.
  95.122 +
  95.123 +    ///Constructor.
  95.124 +    ///
  95.125 +    ///\param graph The underlying graph.
  95.126 +    ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
  95.127 +    ///where \c max_level is equal to the number of labeled items in the graph.
  95.128 +    Elevator(const GR &graph) :
  95.129 +      _g(graph),
  95.130 +      _max_level(countItems<GR, Item>(graph)),
  95.131 +      _item_num(_max_level),
  95.132 +      _where(graph),
  95.133 +      _level(graph,0),
  95.134 +      _items(_max_level),
  95.135 +      _first(_max_level+2),
  95.136 +      _last_active(_max_level+2),
  95.137 +      _highest_active(-1)
  95.138 +    {
  95.139 +    }
  95.140 +
  95.141 +    ///Activate item \c i.
  95.142 +
  95.143 +    ///Activate item \c i.
  95.144 +    ///\pre Item \c i shouldn't be active before.
  95.145 +    void activate(Item i)
  95.146 +    {
  95.147 +      const int l=_level[i];
  95.148 +      swap(_where[i],++_last_active[l]);
  95.149 +      if(l>_highest_active) _highest_active=l;
  95.150 +    }
  95.151 +
  95.152 +    ///Deactivate item \c i.
  95.153 +
  95.154 +    ///Deactivate item \c i.
  95.155 +    ///\pre Item \c i must be active before.
  95.156 +    void deactivate(Item i)
  95.157 +    {
  95.158 +      swap(_where[i],_last_active[_level[i]]--);
  95.159 +      while(_highest_active>=0 &&
  95.160 +            _last_active[_highest_active]<_first[_highest_active])
  95.161 +        _highest_active--;
  95.162 +    }
  95.163 +
  95.164 +    ///Query whether item \c i is active
  95.165 +    bool active(Item i) const { return _where[i]<=_last_active[_level[i]]; }
  95.166 +
  95.167 +    ///Return the level of item \c i.
  95.168 +    int operator[](Item i) const { return _level[i]; }
  95.169 +
  95.170 +    ///Return the number of items on level \c l.
  95.171 +    int onLevel(int l) const
  95.172 +    {
  95.173 +      return _first[l+1]-_first[l];
  95.174 +    }
  95.175 +    ///Return true if level \c l is empty.
  95.176 +    bool emptyLevel(int l) const
  95.177 +    {
  95.178 +      return _first[l+1]-_first[l]==0;
  95.179 +    }
  95.180 +    ///Return the number of items above level \c l.
  95.181 +    int aboveLevel(int l) const
  95.182 +    {
  95.183 +      return _first[_max_level+1]-_first[l+1];
  95.184 +    }
  95.185 +    ///Return the number of active items on level \c l.
  95.186 +    int activesOnLevel(int l) const
  95.187 +    {
  95.188 +      return _last_active[l]-_first[l]+1;
  95.189 +    }
  95.190 +    ///Return true if there is no active item on level \c l.
  95.191 +    bool activeFree(int l) const
  95.192 +    {
  95.193 +      return _last_active[l]<_first[l];
  95.194 +    }
  95.195 +    ///Return the maximum allowed level.
  95.196 +    int maxLevel() const
  95.197 +    {
  95.198 +      return _max_level;
  95.199 +    }
  95.200 +
  95.201 +    ///\name Highest Active Item
  95.202 +    ///Functions for working with the highest level
  95.203 +    ///active item.
  95.204 +
  95.205 +    ///@{
  95.206 +
  95.207 +    ///Return a highest level active item.
  95.208 +
  95.209 +    ///Return a highest level active item or INVALID if there is no active
  95.210 +    ///item.
  95.211 +    Item highestActive() const
  95.212 +    {
  95.213 +      return _highest_active>=0?*_last_active[_highest_active]:INVALID;
  95.214 +    }
  95.215 +
  95.216 +    ///Return the highest active level.
  95.217 +
  95.218 +    ///Return the level of the highest active item or -1 if there is no active
  95.219 +    ///item.
  95.220 +    int highestActiveLevel() const
  95.221 +    {
  95.222 +      return _highest_active;
  95.223 +    }
  95.224 +
  95.225 +    ///Lift the highest active item by one.
  95.226 +
  95.227 +    ///Lift the item returned by highestActive() by one.
  95.228 +    ///
  95.229 +    void liftHighestActive()
  95.230 +    {
  95.231 +      Item it = *_last_active[_highest_active];
  95.232 +      ++_level[it];
  95.233 +      swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
  95.234 +      --_first[++_highest_active];
  95.235 +    }
  95.236 +
  95.237 +    ///Lift the highest active item to the given level.
  95.238 +
  95.239 +    ///Lift the item returned by highestActive() to level \c new_level.
  95.240 +    ///
  95.241 +    ///\warning \c new_level must be strictly higher
  95.242 +    ///than the current level.
  95.243 +    ///
  95.244 +    void liftHighestActive(int new_level)
  95.245 +    {
  95.246 +      const Item li = *_last_active[_highest_active];
  95.247 +
  95.248 +      copy(--_first[_highest_active+1],_last_active[_highest_active]--);
  95.249 +      for(int l=_highest_active+1;l<new_level;l++)
  95.250 +        {
  95.251 +          copy(--_first[l+1],_first[l]);
  95.252 +          --_last_active[l];
  95.253 +        }
  95.254 +      copy(li,_first[new_level]);
  95.255 +      _level[li] = new_level;
  95.256 +      _highest_active=new_level;
  95.257 +    }
  95.258 +
  95.259 +    ///Lift the highest active item to the top level.
  95.260 +
  95.261 +    ///Lift the item returned by highestActive() to the top level and
  95.262 +    ///deactivate it.
  95.263 +    void liftHighestActiveToTop()
  95.264 +    {
  95.265 +      const Item li = *_last_active[_highest_active];
  95.266 +
  95.267 +      copy(--_first[_highest_active+1],_last_active[_highest_active]--);
  95.268 +      for(int l=_highest_active+1;l<_max_level;l++)
  95.269 +        {
  95.270 +          copy(--_first[l+1],_first[l]);
  95.271 +          --_last_active[l];
  95.272 +        }
  95.273 +      copy(li,_first[_max_level]);
  95.274 +      --_last_active[_max_level];
  95.275 +      _level[li] = _max_level;
  95.276 +
  95.277 +      while(_highest_active>=0 &&
  95.278 +            _last_active[_highest_active]<_first[_highest_active])
  95.279 +        _highest_active--;
  95.280 +    }
  95.281 +
  95.282 +    ///@}
  95.283 +
  95.284 +    ///\name Active Item on Certain Level
  95.285 +    ///Functions for working with the active items.
  95.286 +
  95.287 +    ///@{
  95.288 +
  95.289 +    ///Return an active item on level \c l.
  95.290 +
  95.291 +    ///Return an active item on level \c l or \ref INVALID if there is no such
  95.292 +    ///an item. (\c l must be from the range [0...\c max_level].
  95.293 +    Item activeOn(int l) const
  95.294 +    {
  95.295 +      return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
  95.296 +    }
  95.297 +
  95.298 +    ///Lift the active item returned by \c activeOn(level) by one.
  95.299 +
  95.300 +    ///Lift the active item returned by \ref activeOn() "activeOn(level)"
  95.301 +    ///by one.
  95.302 +    Item liftActiveOn(int level)
  95.303 +    {
  95.304 +      Item it =*_last_active[level];
  95.305 +      ++_level[it];
  95.306 +      swap(_last_active[level]--, --_first[level+1]);
  95.307 +      if (level+1>_highest_active) ++_highest_active;
  95.308 +    }
  95.309 +
  95.310 +    ///Lift the active item returned by \c activeOn(level) to the given level.
  95.311 +
  95.312 +    ///Lift the active item returned by \ref activeOn() "activeOn(level)"
  95.313 +    ///to the given level.
  95.314 +    void liftActiveOn(int level, int new_level)
  95.315 +    {
  95.316 +      const Item ai = *_last_active[level];
  95.317 +
  95.318 +      copy(--_first[level+1], _last_active[level]--);
  95.319 +      for(int l=level+1;l<new_level;l++)
  95.320 +        {
  95.321 +          copy(_last_active[l],_first[l]);
  95.322 +          copy(--_first[l+1], _last_active[l]--);
  95.323 +        }
  95.324 +      copy(ai,_first[new_level]);
  95.325 +      _level[ai] = new_level;
  95.326 +      if (new_level>_highest_active) _highest_active=new_level;
  95.327 +    }
  95.328 +
  95.329 +    ///Lift the active item returned by \c activeOn(level) to the top level.
  95.330 +
  95.331 +    ///Lift the active item returned by \ref activeOn() "activeOn(level)"
  95.332 +    ///to the top level and deactivate it.
  95.333 +    void liftActiveToTop(int level)
  95.334 +    {
  95.335 +      const Item ai = *_last_active[level];
  95.336 +
  95.337 +      copy(--_first[level+1],_last_active[level]--);
  95.338 +      for(int l=level+1;l<_max_level;l++)
  95.339 +        {
  95.340 +          copy(_last_active[l],_first[l]);
  95.341 +          copy(--_first[l+1], _last_active[l]--);
  95.342 +        }
  95.343 +      copy(ai,_first[_max_level]);
  95.344 +      --_last_active[_max_level];
  95.345 +      _level[ai] = _max_level;
  95.346 +
  95.347 +      if (_highest_active==level) {
  95.348 +        while(_highest_active>=0 &&
  95.349 +              _last_active[_highest_active]<_first[_highest_active])
  95.350 +          _highest_active--;
  95.351 +      }
  95.352 +    }
  95.353 +
  95.354 +    ///@}
  95.355 +
  95.356 +    ///Lift an active item to a higher level.
  95.357 +
  95.358 +    ///Lift an active item to a higher level.
  95.359 +    ///\param i The item to be lifted. It must be active.
  95.360 +    ///\param new_level The new level of \c i. It must be strictly higher
  95.361 +    ///than the current level.
  95.362 +    ///
  95.363 +    void lift(Item i, int new_level)
  95.364 +    {
  95.365 +      const int lo = _level[i];
  95.366 +      const Vit w = _where[i];
  95.367 +
  95.368 +      copy(_last_active[lo],w);
  95.369 +      copy(--_first[lo+1],_last_active[lo]--);
  95.370 +      for(int l=lo+1;l<new_level;l++)
  95.371 +        {
  95.372 +          copy(_last_active[l],_first[l]);
  95.373 +          copy(--_first[l+1],_last_active[l]--);
  95.374 +        }
  95.375 +      copy(i,_first[new_level]);
  95.376 +      _level[i] = new_level;
  95.377 +      if(new_level>_highest_active) _highest_active=new_level;
  95.378 +    }
  95.379 +
  95.380 +    ///Move an inactive item to the top but one level (in a dirty way).
  95.381 +
  95.382 +    ///This function moves an inactive item from the top level to the top
  95.383 +    ///but one level (in a dirty way).
  95.384 +    ///\warning It makes the underlying datastructure corrupt, so use it
  95.385 +    ///only if you really know what it is for.
  95.386 +    ///\pre The item is on the top level.
  95.387 +    void dirtyTopButOne(Item i) {
  95.388 +      _level[i] = _max_level - 1;
  95.389 +    }
  95.390 +
  95.391 +    ///Lift all items on and above the given level to the top level.
  95.392 +
  95.393 +    ///This function lifts all items on and above level \c l to the top
  95.394 +    ///level and deactivates them.
  95.395 +    void liftToTop(int l)
  95.396 +    {
  95.397 +      const Vit f=_first[l];
  95.398 +      const Vit tl=_first[_max_level];
  95.399 +      for(Vit i=f;i!=tl;++i)
  95.400 +        _level[*i] = _max_level;
  95.401 +      for(int i=l;i<=_max_level;i++)
  95.402 +        {
  95.403 +          _first[i]=f;
  95.404 +          _last_active[i]=f-1;
  95.405 +        }
  95.406 +      for(_highest_active=l-1;
  95.407 +          _highest_active>=0 &&
  95.408 +            _last_active[_highest_active]<_first[_highest_active];
  95.409 +          _highest_active--) ;
  95.410 +    }
  95.411 +
  95.412 +  private:
  95.413 +    int _init_lev;
  95.414 +    Vit _init_num;
  95.415 +
  95.416 +  public:
  95.417 +
  95.418 +    ///\name Initialization
  95.419 +    ///Using these functions you can initialize the levels of the items.
  95.420 +    ///\n
  95.421 +    ///The initialization must be started with calling \c initStart().
  95.422 +    ///Then the items should be listed level by level starting with the
  95.423 +    ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
  95.424 +    ///Finally \c initFinish() must be called.
  95.425 +    ///The items not listed are put on the highest level.
  95.426 +    ///@{
  95.427 +
  95.428 +    ///Start the initialization process.
  95.429 +    void initStart()
  95.430 +    {
  95.431 +      _init_lev=0;
  95.432 +      _init_num=&_items[0];
  95.433 +      _first[0]=&_items[0];
  95.434 +      _last_active[0]=&_items[0]-1;
  95.435 +      Vit n=&_items[0];
  95.436 +      for(typename ItemSetTraits<GR,Item>::ItemIt i(_g);i!=INVALID;++i)
  95.437 +        {
  95.438 +          *n=i;
  95.439 +          _where[i] = n;
  95.440 +          _level[i] = _max_level;
  95.441 +          ++n;
  95.442 +        }
  95.443 +    }
  95.444 +
  95.445 +    ///Add an item to the current level.
  95.446 +    void initAddItem(Item i)
  95.447 +    {
  95.448 +      swap(_where[i],_init_num);
  95.449 +      _level[i] = _init_lev;
  95.450 +      ++_init_num;
  95.451 +    }
  95.452 +
  95.453 +    ///Start a new level.
  95.454 +
  95.455 +    ///Start a new level.
  95.456 +    ///It shouldn't be used before the items on level 0 are listed.
  95.457 +    void initNewLevel()
  95.458 +    {
  95.459 +      _init_lev++;
  95.460 +      _first[_init_lev]=_init_num;
  95.461 +      _last_active[_init_lev]=_init_num-1;
  95.462 +    }
  95.463 +
  95.464 +    ///Finalize the initialization process.
  95.465 +    void initFinish()
  95.466 +    {
  95.467 +      for(_init_lev++;_init_lev<=_max_level;_init_lev++)
  95.468 +        {
  95.469 +          _first[_init_lev]=_init_num;
  95.470 +          _last_active[_init_lev]=_init_num-1;
  95.471 +        }
  95.472 +      _first[_max_level+1]=&_items[0]+_item_num;
  95.473 +      _last_active[_max_level+1]=&_items[0]+_item_num-1;
  95.474 +      _highest_active = -1;
  95.475 +    }
  95.476 +
  95.477 +    ///@}
  95.478 +
  95.479 +  };
  95.480 +
  95.481 +  ///Class for handling "labels" in push-relabel type algorithms.
  95.482 +
  95.483 +  ///A class for handling "labels" in push-relabel type algorithms.
  95.484 +  ///
  95.485 +  ///\ingroup auxdat
  95.486 +  ///Using this class you can assign "labels" (nonnegative integer numbers)
  95.487 +  ///to the edges or nodes of a graph, manipulate and query them through
  95.488 +  ///operations typically arising in "push-relabel" type algorithms.
  95.489 +  ///
  95.490 +  ///Each item is either \em active or not, and you can also choose a
  95.491 +  ///highest level active item.
  95.492 +  ///
  95.493 +  ///\sa Elevator
  95.494 +  ///
  95.495 +  ///\param GR Type of the underlying graph.
  95.496 +  ///\param Item Type of the items the data is assigned to (\c GR::Node,
  95.497 +  ///\c GR::Arc or \c GR::Edge).
  95.498 +  template <class GR, class Item>
  95.499 +  class LinkedElevator {
  95.500 +  public:
  95.501 +
  95.502 +    typedef Item Key;
  95.503 +    typedef int Value;
  95.504 +
  95.505 +  private:
  95.506 +
  95.507 +    typedef typename ItemSetTraits<GR,Item>::
  95.508 +    template Map<Item>::Type ItemMap;
  95.509 +    typedef typename ItemSetTraits<GR,Item>::
  95.510 +    template Map<int>::Type IntMap;
  95.511 +    typedef typename ItemSetTraits<GR,Item>::
  95.512 +    template Map<bool>::Type BoolMap;
  95.513 +
  95.514 +    const GR &_graph;
  95.515 +    int _max_level;
  95.516 +    int _item_num;
  95.517 +    std::vector<Item> _first, _last;
  95.518 +    ItemMap _prev, _next;
  95.519 +    int _highest_active;
  95.520 +    IntMap _level;
  95.521 +    BoolMap _active;
  95.522 +
  95.523 +  public:
  95.524 +    ///Constructor with given maximum level.
  95.525 +
  95.526 +    ///Constructor with given maximum level.
  95.527 +    ///
  95.528 +    ///\param graph The underlying graph.
  95.529 +    ///\param max_level The maximum allowed level.
  95.530 +    ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
  95.531 +    LinkedElevator(const GR& graph, int max_level)
  95.532 +      : _graph(graph), _max_level(max_level), _item_num(_max_level),
  95.533 +        _first(_max_level + 1), _last(_max_level + 1),
  95.534 +        _prev(graph), _next(graph),
  95.535 +        _highest_active(-1), _level(graph), _active(graph) {}
  95.536 +
  95.537 +    ///Constructor.
  95.538 +
  95.539 +    ///Constructor.
  95.540 +    ///
  95.541 +    ///\param graph The underlying graph.
  95.542 +    ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
  95.543 +    ///where \c max_level is equal to the number of labeled items in the graph.
  95.544 +    LinkedElevator(const GR& graph)
  95.545 +      : _graph(graph), _max_level(countItems<GR, Item>(graph)),
  95.546 +        _item_num(_max_level),
  95.547 +        _first(_max_level + 1), _last(_max_level + 1),
  95.548 +        _prev(graph, INVALID), _next(graph, INVALID),
  95.549 +        _highest_active(-1), _level(graph), _active(graph) {}
  95.550 +
  95.551 +
  95.552 +    ///Activate item \c i.
  95.553 +
  95.554 +    ///Activate item \c i.
  95.555 +    ///\pre Item \c i shouldn't be active before.
  95.556 +    void activate(Item i) {
  95.557 +      _active[i] = true;
  95.558 +
  95.559 +      int level = _level[i];
  95.560 +      if (level > _highest_active) {
  95.561 +        _highest_active = level;
  95.562 +      }
  95.563 +
  95.564 +      if (_prev[i] == INVALID || _active[_prev[i]]) return;
  95.565 +      //unlace
  95.566 +      _next[_prev[i]] = _next[i];
  95.567 +      if (_next[i] != INVALID) {
  95.568 +        _prev[_next[i]] = _prev[i];
  95.569 +      } else {
  95.570 +        _last[level] = _prev[i];
  95.571 +      }
  95.572 +      //lace
  95.573 +      _next[i] = _first[level];
  95.574 +      _prev[_first[level]] = i;
  95.575 +      _prev[i] = INVALID;
  95.576 +      _first[level] = i;
  95.577 +
  95.578 +    }
  95.579 +
  95.580 +    ///Deactivate item \c i.
  95.581 +
  95.582 +    ///Deactivate item \c i.
  95.583 +    ///\pre Item \c i must be active before.
  95.584 +    void deactivate(Item i) {
  95.585 +      _active[i] = false;
  95.586 +      int level = _level[i];
  95.587 +
  95.588 +      if (_next[i] == INVALID || !_active[_next[i]])
  95.589 +        goto find_highest_level;
  95.590 +
  95.591 +      //unlace
  95.592 +      _prev[_next[i]] = _prev[i];
  95.593 +      if (_prev[i] != INVALID) {
  95.594 +        _next[_prev[i]] = _next[i];
  95.595 +      } else {
  95.596 +        _first[_level[i]] = _next[i];
  95.597 +      }
  95.598 +      //lace
  95.599 +      _prev[i] = _last[level];
  95.600 +      _next[_last[level]] = i;
  95.601 +      _next[i] = INVALID;
  95.602 +      _last[level] = i;
  95.603 +
  95.604 +    find_highest_level:
  95.605 +      if (level == _highest_active) {
  95.606 +        while (_highest_active >= 0 && activeFree(_highest_active))
  95.607 +          --_highest_active;
  95.608 +      }
  95.609 +    }
  95.610 +
  95.611 +    ///Query whether item \c i is active
  95.612 +    bool active(Item i) const { return _active[i]; }
  95.613 +
  95.614 +    ///Return the level of item \c i.
  95.615 +    int operator[](Item i) const { return _level[i]; }
  95.616 +
  95.617 +    ///Return the number of items on level \c l.
  95.618 +    int onLevel(int l) const {
  95.619 +      int num = 0;
  95.620 +      Item n = _first[l];
  95.621 +      while (n != INVALID) {
  95.622 +        ++num;
  95.623 +        n = _next[n];
  95.624 +      }
  95.625 +      return num;
  95.626 +    }
  95.627 +
  95.628 +    ///Return true if the level is empty.
  95.629 +    bool emptyLevel(int l) const {
  95.630 +      return _first[l] == INVALID;
  95.631 +    }
  95.632 +
  95.633 +    ///Return the number of items above level \c l.
  95.634 +    int aboveLevel(int l) const {
  95.635 +      int num = 0;
  95.636 +      for (int level = l + 1; level < _max_level; ++level)
  95.637 +        num += onLevel(level);
  95.638 +      return num;
  95.639 +    }
  95.640 +
  95.641 +    ///Return the number of active items on level \c l.
  95.642 +    int activesOnLevel(int l) const {
  95.643 +      int num = 0;
  95.644 +      Item n = _first[l];
  95.645 +      while (n != INVALID && _active[n]) {
  95.646 +        ++num;
  95.647 +        n = _next[n];
  95.648 +      }
  95.649 +      return num;
  95.650 +    }
  95.651 +
  95.652 +    ///Return true if there is no active item on level \c l.
  95.653 +    bool activeFree(int l) const {
  95.654 +      return _first[l] == INVALID || !_active[_first[l]];
  95.655 +    }
  95.656 +
  95.657 +    ///Return the maximum allowed level.
  95.658 +    int maxLevel() const {
  95.659 +      return _max_level;
  95.660 +    }
  95.661 +
  95.662 +    ///\name Highest Active Item
  95.663 +    ///Functions for working with the highest level
  95.664 +    ///active item.
  95.665 +
  95.666 +    ///@{
  95.667 +
  95.668 +    ///Return a highest level active item.
  95.669 +
  95.670 +    ///Return a highest level active item or INVALID if there is no active
  95.671 +    ///item.
  95.672 +    Item highestActive() const {
  95.673 +      return _highest_active >= 0 ? _first[_highest_active] : INVALID;
  95.674 +    }
  95.675 +
  95.676 +    ///Return the highest active level.
  95.677 +
  95.678 +    ///Return the level of the highest active item or -1 if there is no active
  95.679 +    ///item.
  95.680 +    int highestActiveLevel() const {
  95.681 +      return _highest_active;
  95.682 +    }
  95.683 +
  95.684 +    ///Lift the highest active item by one.
  95.685 +
  95.686 +    ///Lift the item returned by highestActive() by one.
  95.687 +    ///
  95.688 +    void liftHighestActive() {
  95.689 +      Item i = _first[_highest_active];
  95.690 +      if (_next[i] != INVALID) {
  95.691 +        _prev[_next[i]] = INVALID;
  95.692 +        _first[_highest_active] = _next[i];
  95.693 +      } else {
  95.694 +        _first[_highest_active] = INVALID;
  95.695 +        _last[_highest_active] = INVALID;
  95.696 +      }
  95.697 +      _level[i] = ++_highest_active;
  95.698 +      if (_first[_highest_active] == INVALID) {
  95.699 +        _first[_highest_active] = i;
  95.700 +        _last[_highest_active] = i;
  95.701 +        _prev[i] = INVALID;
  95.702 +        _next[i] = INVALID;
  95.703 +      } else {
  95.704 +        _prev[_first[_highest_active]] = i;
  95.705 +        _next[i] = _first[_highest_active];
  95.706 +        _first[_highest_active] = i;
  95.707 +      }
  95.708 +    }
  95.709 +
  95.710 +    ///Lift the highest active item to the given level.
  95.711 +
  95.712 +    ///Lift the item returned by highestActive() to level \c new_level.
  95.713 +    ///
  95.714 +    ///\warning \c new_level must be strictly higher
  95.715 +    ///than the current level.
  95.716 +    ///
  95.717 +    void liftHighestActive(int new_level) {
  95.718 +      Item i = _first[_highest_active];
  95.719 +      if (_next[i] != INVALID) {
  95.720 +        _prev[_next[i]] = INVALID;
  95.721 +        _first[_highest_active] = _next[i];
  95.722 +      } else {
  95.723 +        _first[_highest_active] = INVALID;
  95.724 +        _last[_highest_active] = INVALID;
  95.725 +      }
  95.726 +      _level[i] = _highest_active = new_level;
  95.727 +      if (_first[_highest_active] == INVALID) {
  95.728 +        _first[_highest_active] = _last[_highest_active] = i;
  95.729 +        _prev[i] = INVALID;
  95.730 +        _next[i] = INVALID;
  95.731 +      } else {
  95.732 +        _prev[_first[_highest_active]] = i;
  95.733 +        _next[i] = _first[_highest_active];
  95.734 +        _first[_highest_active] = i;
  95.735 +      }
  95.736 +    }
  95.737 +
  95.738 +    ///Lift the highest active item to the top level.
  95.739 +
  95.740 +    ///Lift the item returned by highestActive() to the top level and
  95.741 +    ///deactivate it.
  95.742 +    void liftHighestActiveToTop() {
  95.743 +      Item i = _first[_highest_active];
  95.744 +      _level[i] = _max_level;
  95.745 +      if (_next[i] != INVALID) {
  95.746 +        _prev[_next[i]] = INVALID;
  95.747 +        _first[_highest_active] = _next[i];
  95.748 +      } else {
  95.749 +        _first[_highest_active] = INVALID;
  95.750 +        _last[_highest_active] = INVALID;
  95.751 +      }
  95.752 +      while (_highest_active >= 0 && activeFree(_highest_active))
  95.753 +        --_highest_active;
  95.754 +    }
  95.755 +
  95.756 +    ///@}
  95.757 +
  95.758 +    ///\name Active Item on Certain Level
  95.759 +    ///Functions for working with the active items.
  95.760 +
  95.761 +    ///@{
  95.762 +
  95.763 +    ///Return an active item on level \c l.
  95.764 +
  95.765 +    ///Return an active item on level \c l or \ref INVALID if there is no such
  95.766 +    ///an item. (\c l must be from the range [0...\c max_level].
  95.767 +    Item activeOn(int l) const
  95.768 +    {
  95.769 +      return _active[_first[l]] ? _first[l] : INVALID;
  95.770 +    }
  95.771 +
  95.772 +    ///Lift the active item returned by \c activeOn(l) by one.
  95.773 +
  95.774 +    ///Lift the active item returned by \ref activeOn() "activeOn(l)"
  95.775 +    ///by one.
  95.776 +    Item liftActiveOn(int l)
  95.777 +    {
  95.778 +      Item i = _first[l];
  95.779 +      if (_next[i] != INVALID) {
  95.780 +        _prev[_next[i]] = INVALID;
  95.781 +        _first[l] = _next[i];
  95.782 +      } else {
  95.783 +        _first[l] = INVALID;
  95.784 +        _last[l] = INVALID;
  95.785 +      }
  95.786 +      _level[i] = ++l;
  95.787 +      if (_first[l] == INVALID) {
  95.788 +        _first[l] = _last[l] = i;
  95.789 +        _prev[i] = INVALID;
  95.790 +        _next[i] = INVALID;
  95.791 +      } else {
  95.792 +        _prev[_first[l]] = i;
  95.793 +        _next[i] = _first[l];
  95.794 +        _first[l] = i;
  95.795 +      }
  95.796 +      if (_highest_active < l) {
  95.797 +        _highest_active = l;
  95.798 +      }
  95.799 +    }
  95.800 +
  95.801 +    ///Lift the active item returned by \c activeOn(l) to the given level.
  95.802 +
  95.803 +    ///Lift the active item returned by \ref activeOn() "activeOn(l)"
  95.804 +    ///to the given level.
  95.805 +    void liftActiveOn(int l, int new_level)
  95.806 +    {
  95.807 +      Item i = _first[l];
  95.808 +      if (_next[i] != INVALID) {
  95.809 +        _prev[_next[i]] = INVALID;
  95.810 +        _first[l] = _next[i];
  95.811 +      } else {
  95.812 +        _first[l] = INVALID;
  95.813 +        _last[l] = INVALID;
  95.814 +      }
  95.815 +      _level[i] = l = new_level;
  95.816 +      if (_first[l] == INVALID) {
  95.817 +        _first[l] = _last[l] = i;
  95.818 +        _prev[i] = INVALID;
  95.819 +        _next[i] = INVALID;
  95.820 +      } else {
  95.821 +        _prev[_first[l]] = i;
  95.822 +        _next[i] = _first[l];
  95.823 +        _first[l] = i;
  95.824 +      }
  95.825 +      if (_highest_active < l) {
  95.826 +        _highest_active = l;
  95.827 +      }
  95.828 +    }
  95.829 +
  95.830 +    ///Lift the active item returned by \c activeOn(l) to the top level.
  95.831 +
  95.832 +    ///Lift the active item returned by \ref activeOn() "activeOn(l)"
  95.833 +    ///to the top level and deactivate it.
  95.834 +    void liftActiveToTop(int l)
  95.835 +    {
  95.836 +      Item i = _first[l];
  95.837 +      if (_next[i] != INVALID) {
  95.838 +        _prev[_next[i]] = INVALID;
  95.839 +        _first[l] = _next[i];
  95.840 +      } else {
  95.841 +        _first[l] = INVALID;
  95.842 +        _last[l] = INVALID;
  95.843 +      }
  95.844 +      _level[i] = _max_level;
  95.845 +      if (l == _highest_active) {
  95.846 +        while (_highest_active >= 0 && activeFree(_highest_active))
  95.847 +          --_highest_active;
  95.848 +      }
  95.849 +    }
  95.850 +
  95.851 +    ///@}
  95.852 +
  95.853 +    /// \brief Lift an active item to a higher level.
  95.854 +    ///
  95.855 +    /// Lift an active item to a higher level.
  95.856 +    /// \param i The item to be lifted. It must be active.
  95.857 +    /// \param new_level The new level of \c i. It must be strictly higher
  95.858 +    /// than the current level.
  95.859 +    ///
  95.860 +    void lift(Item i, int new_level) {
  95.861 +      if (_next[i] != INVALID) {
  95.862 +        _prev[_next[i]] = _prev[i];
  95.863 +      } else {
  95.864 +        _last[new_level] = _prev[i];
  95.865 +      }
  95.866 +      if (_prev[i] != INVALID) {
  95.867 +        _next[_prev[i]] = _next[i];
  95.868 +      } else {
  95.869 +        _first[new_level] = _next[i];
  95.870 +      }
  95.871 +      _level[i] = new_level;
  95.872 +      if (_first[new_level] == INVALID) {
  95.873 +        _first[new_level] = _last[new_level] = i;
  95.874 +        _prev[i] = INVALID;
  95.875 +        _next[i] = INVALID;
  95.876 +      } else {
  95.877 +        _prev[_first[new_level]] = i;
  95.878 +        _next[i] = _first[new_level];
  95.879 +        _first[new_level] = i;
  95.880 +      }
  95.881 +      if (_highest_active < new_level) {
  95.882 +        _highest_active = new_level;
  95.883 +      }
  95.884 +    }
  95.885 +
  95.886 +    ///Move an inactive item to the top but one level (in a dirty way).
  95.887 +
  95.888 +    ///This function moves an inactive item from the top level to the top
  95.889 +    ///but one level (in a dirty way).
  95.890 +    ///\warning It makes the underlying datastructure corrupt, so use it
  95.891 +    ///only if you really know what it is for.
  95.892 +    ///\pre The item is on the top level.
  95.893 +    void dirtyTopButOne(Item i) {
  95.894 +      _level[i] = _max_level - 1;
  95.895 +    }
  95.896 +
  95.897 +    ///Lift all items on and above the given level to the top level.
  95.898 +
  95.899 +    ///This function lifts all items on and above level \c l to the top
  95.900 +    ///level and deactivates them.
  95.901 +    void liftToTop(int l)  {
  95.902 +      for (int i = l + 1; _first[i] != INVALID; ++i) {
  95.903 +        Item n = _first[i];
  95.904 +        while (n != INVALID) {
  95.905 +          _level[n] = _max_level;
  95.906 +          n = _next[n];
  95.907 +        }
  95.908 +        _first[i] = INVALID;
  95.909 +        _last[i] = INVALID;
  95.910 +      }
  95.911 +      if (_highest_active > l - 1) {
  95.912 +        _highest_active = l - 1;
  95.913 +        while (_highest_active >= 0 && activeFree(_highest_active))
  95.914 +          --_highest_active;
  95.915 +      }
  95.916 +    }
  95.917 +
  95.918 +  private:
  95.919 +
  95.920 +    int _init_level;
  95.921 +
  95.922 +  public:
  95.923 +
  95.924 +    ///\name Initialization
  95.925 +    ///Using these functions you can initialize the levels of the items.
  95.926 +    ///\n
  95.927 +    ///The initialization must be started with calling \c initStart().
  95.928 +    ///Then the items should be listed level by level starting with the
  95.929 +    ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
  95.930 +    ///Finally \c initFinish() must be called.
  95.931 +    ///The items not listed are put on the highest level.
  95.932 +    ///@{
  95.933 +
  95.934 +    ///Start the initialization process.
  95.935 +    void initStart() {
  95.936 +
  95.937 +      for (int i = 0; i <= _max_level; ++i) {
  95.938 +        _first[i] = _last[i] = INVALID;
  95.939 +      }
  95.940 +      _init_level = 0;
  95.941 +      for(typename ItemSetTraits<GR,Item>::ItemIt i(_graph);
  95.942 +          i != INVALID; ++i) {
  95.943 +        _level[i] = _max_level;
  95.944 +        _active[i] = false;
  95.945 +      }
  95.946 +    }
  95.947 +
  95.948 +    ///Add an item to the current level.
  95.949 +    void initAddItem(Item i) {
  95.950 +      _level[i] = _init_level;
  95.951 +      if (_last[_init_level] == INVALID) {
  95.952 +        _first[_init_level] = i;
  95.953 +        _last[_init_level] = i;
  95.954 +        _prev[i] = INVALID;
  95.955 +        _next[i] = INVALID;
  95.956 +      } else {
  95.957 +        _prev[i] = _last[_init_level];
  95.958 +        _next[i] = INVALID;
  95.959 +        _next[_last[_init_level]] = i;
  95.960 +        _last[_init_level] = i;
  95.961 +      }
  95.962 +    }
  95.963 +
  95.964 +    ///Start a new level.
  95.965 +
  95.966 +    ///Start a new level.
  95.967 +    ///It shouldn't be used before the items on level 0 are listed.
  95.968 +    void initNewLevel() {
  95.969 +      ++_init_level;
  95.970 +    }
  95.971 +
  95.972 +    ///Finalize the initialization process.
  95.973 +    void initFinish() {
  95.974 +      _highest_active = -1;
  95.975 +    }
  95.976 +
  95.977 +    ///@}
  95.978 +
  95.979 +  };
  95.980 +
  95.981 +
  95.982 +} //END OF NAMESPACE LEMON
  95.983 +
  95.984 +#endif
  95.985 +
    96.1 --- a/lemon/error.h	Fri Oct 16 10:21:37 2009 +0200
    96.2 +++ b/lemon/error.h	Thu Nov 05 15:50:01 2009 +0100
    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-2008
    96.8 + * Copyright (C) 2003-2009
    96.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   96.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   96.11   *
    97.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.2 +++ b/lemon/euler.h	Thu Nov 05 15:50:01 2009 +0100
    97.3 @@ -0,0 +1,287 @@
    97.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    97.5 + *
    97.6 + * This file is a part of LEMON, a generic C++ optimization library.
    97.7 + *
    97.8 + * Copyright (C) 2003-2009
    97.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   97.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   97.11 + *
   97.12 + * Permission to use, modify and distribute this software is granted
   97.13 + * provided that this copyright notice appears in all copies. For
   97.14 + * precise terms see the accompanying LICENSE file.
   97.15 + *
   97.16 + * This software is provided "AS IS" with no warranty of any kind,
   97.17 + * express or implied, and with no claim as to its suitability for any
   97.18 + * purpose.
   97.19 + *
   97.20 + */
   97.21 +
   97.22 +#ifndef LEMON_EULER_H
   97.23 +#define LEMON_EULER_H
   97.24 +
   97.25 +#include<lemon/core.h>
   97.26 +#include<lemon/adaptors.h>
   97.27 +#include<lemon/connectivity.h>
   97.28 +#include <list>
   97.29 +
   97.30 +/// \ingroup graph_properties
   97.31 +/// \file
   97.32 +/// \brief Euler tour iterators and a function for checking the \e Eulerian 
   97.33 +/// property.
   97.34 +///
   97.35 +///This file provides Euler tour iterators and a function to check
   97.36 +///if a (di)graph is \e Eulerian.
   97.37 +
   97.38 +namespace lemon {
   97.39 +
   97.40 +  ///Euler tour iterator for digraphs.
   97.41 +
   97.42 +  /// \ingroup graph_prop
   97.43 +  ///This iterator provides an Euler tour (Eulerian circuit) of a \e directed
   97.44 +  ///graph (if there exists) and it converts to the \c Arc type of the digraph.
   97.45 +  ///
   97.46 +  ///For example, if the given digraph has an Euler tour (i.e it has only one
   97.47 +  ///non-trivial component and the in-degree is equal to the out-degree 
   97.48 +  ///for all nodes), then the following code will put the arcs of \c g
   97.49 +  ///to the vector \c et according to an Euler tour of \c g.
   97.50 +  ///\code
   97.51 +  ///  std::vector<ListDigraph::Arc> et;
   97.52 +  ///  for(DiEulerIt<ListDigraph> e(g); e!=INVALID; ++e)
   97.53 +  ///    et.push_back(e);
   97.54 +  ///\endcode
   97.55 +  ///If \c g has no Euler tour, then the resulted walk will not be closed
   97.56 +  ///or not contain all arcs.
   97.57 +  ///\sa EulerIt
   97.58 +  template<typename GR>
   97.59 +  class DiEulerIt
   97.60 +  {
   97.61 +    typedef typename GR::Node Node;
   97.62 +    typedef typename GR::NodeIt NodeIt;
   97.63 +    typedef typename GR::Arc Arc;
   97.64 +    typedef typename GR::ArcIt ArcIt;
   97.65 +    typedef typename GR::OutArcIt OutArcIt;
   97.66 +    typedef typename GR::InArcIt InArcIt;
   97.67 +
   97.68 +    const GR &g;
   97.69 +    typename GR::template NodeMap<OutArcIt> narc;
   97.70 +    std::list<Arc> euler;
   97.71 +
   97.72 +  public:
   97.73 +
   97.74 +    ///Constructor
   97.75 +
   97.76 +    ///Constructor.
   97.77 +    ///\param gr A digraph.
   97.78 +    ///\param start The starting point of the tour. If it is not given,
   97.79 +    ///the tour will start from the first node that has an outgoing arc.
   97.80 +    DiEulerIt(const GR &gr, typename GR::Node start = INVALID)
   97.81 +      : g(gr), narc(g)
   97.82 +    {
   97.83 +      if (start==INVALID) {
   97.84 +        NodeIt n(g);
   97.85 +        while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
   97.86 +        start=n;
   97.87 +      }
   97.88 +      if (start!=INVALID) {
   97.89 +        for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
   97.90 +        while (narc[start]!=INVALID) {
   97.91 +          euler.push_back(narc[start]);
   97.92 +          Node next=g.target(narc[start]);
   97.93 +          ++narc[start];
   97.94 +          start=next;
   97.95 +        }
   97.96 +      }
   97.97 +    }
   97.98 +
   97.99 +    ///Arc conversion
  97.100 +    operator Arc() { return euler.empty()?INVALID:euler.front(); }
  97.101 +    ///Compare with \c INVALID
  97.102 +    bool operator==(Invalid) { return euler.empty(); }
  97.103 +    ///Compare with \c INVALID
  97.104 +    bool operator!=(Invalid) { return !euler.empty(); }
  97.105 +
  97.106 +    ///Next arc of the tour
  97.107 +
  97.108 +    ///Next arc of the tour
  97.109 +    ///
  97.110 +    DiEulerIt &operator++() {
  97.111 +      Node s=g.target(euler.front());
  97.112 +      euler.pop_front();
  97.113 +      typename std::list<Arc>::iterator next=euler.begin();
  97.114 +      while(narc[s]!=INVALID) {
  97.115 +        euler.insert(next,narc[s]);
  97.116 +        Node n=g.target(narc[s]);
  97.117 +        ++narc[s];
  97.118 +        s=n;
  97.119 +      }
  97.120 +      return *this;
  97.121 +    }
  97.122 +    ///Postfix incrementation
  97.123 +
  97.124 +    /// Postfix incrementation.
  97.125 +    ///
  97.126 +    ///\warning This incrementation
  97.127 +    ///returns an \c Arc, not a \ref DiEulerIt, as one may
  97.128 +    ///expect.
  97.129 +    Arc operator++(int)
  97.130 +    {
  97.131 +      Arc e=*this;
  97.132 +      ++(*this);
  97.133 +      return e;
  97.134 +    }
  97.135 +  };
  97.136 +
  97.137 +  ///Euler tour iterator for graphs.
  97.138 +
  97.139 +  /// \ingroup graph_properties
  97.140 +  ///This iterator provides an Euler tour (Eulerian circuit) of an
  97.141 +  ///\e undirected graph (if there exists) and it converts to the \c Arc
  97.142 +  ///and \c Edge types of the graph.
  97.143 +  ///
  97.144 +  ///For example, if the given graph has an Euler tour (i.e it has only one 
  97.145 +  ///non-trivial component and the degree of each node is even),
  97.146 +  ///the following code will print the arc IDs according to an
  97.147 +  ///Euler tour of \c g.
  97.148 +  ///\code
  97.149 +  ///  for(EulerIt<ListGraph> e(g); e!=INVALID; ++e) {
  97.150 +  ///    std::cout << g.id(Edge(e)) << std::eol;
  97.151 +  ///  }
  97.152 +  ///\endcode
  97.153 +  ///Although this iterator is for undirected graphs, it still returns 
  97.154 +  ///arcs in order to indicate the direction of the tour.
  97.155 +  ///(But arcs convert to edges, of course.)
  97.156 +  ///
  97.157 +  ///If \c g has no Euler tour, then the resulted walk will not be closed
  97.158 +  ///or not contain all edges.
  97.159 +  template<typename GR>
  97.160 +  class EulerIt
  97.161 +  {
  97.162 +    typedef typename GR::Node Node;
  97.163 +    typedef typename GR::NodeIt NodeIt;
  97.164 +    typedef typename GR::Arc Arc;
  97.165 +    typedef typename GR::Edge Edge;
  97.166 +    typedef typename GR::ArcIt ArcIt;
  97.167 +    typedef typename GR::OutArcIt OutArcIt;
  97.168 +    typedef typename GR::InArcIt InArcIt;
  97.169 +
  97.170 +    const GR &g;
  97.171 +    typename GR::template NodeMap<OutArcIt> narc;
  97.172 +    typename GR::template EdgeMap<bool> visited;
  97.173 +    std::list<Arc> euler;
  97.174 +
  97.175 +  public:
  97.176 +
  97.177 +    ///Constructor
  97.178 +
  97.179 +    ///Constructor.
  97.180 +    ///\param gr A graph.
  97.181 +    ///\param start The starting point of the tour. If it is not given,
  97.182 +    ///the tour will start from the first node that has an incident edge.
  97.183 +    EulerIt(const GR &gr, typename GR::Node start = INVALID)
  97.184 +      : g(gr), narc(g), visited(g, false)
  97.185 +    {
  97.186 +      if (start==INVALID) {
  97.187 +        NodeIt n(g);
  97.188 +        while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
  97.189 +        start=n;
  97.190 +      }
  97.191 +      if (start!=INVALID) {
  97.192 +        for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
  97.193 +        while(narc[start]!=INVALID) {
  97.194 +          euler.push_back(narc[start]);
  97.195 +          visited[narc[start]]=true;
  97.196 +          Node next=g.target(narc[start]);
  97.197 +          ++narc[start];
  97.198 +          start=next;
  97.199 +          while(narc[start]!=INVALID && visited[narc[start]]) ++narc[start];
  97.200 +        }
  97.201 +      }
  97.202 +    }
  97.203 +
  97.204 +    ///Arc conversion
  97.205 +    operator Arc() const { return euler.empty()?INVALID:euler.front(); }
  97.206 +    ///Edge conversion
  97.207 +    operator Edge() const { return euler.empty()?INVALID:euler.front(); }
  97.208 +    ///Compare with \c INVALID
  97.209 +    bool operator==(Invalid) const { return euler.empty(); }
  97.210 +    ///Compare with \c INVALID
  97.211 +    bool operator!=(Invalid) const { return !euler.empty(); }
  97.212 +
  97.213 +    ///Next arc of the tour
  97.214 +
  97.215 +    ///Next arc of the tour
  97.216 +    ///
  97.217 +    EulerIt &operator++() {
  97.218 +      Node s=g.target(euler.front());
  97.219 +      euler.pop_front();
  97.220 +      typename std::list<Arc>::iterator next=euler.begin();
  97.221 +      while(narc[s]!=INVALID) {
  97.222 +        while(narc[s]!=INVALID && visited[narc[s]]) ++narc[s];
  97.223 +        if(narc[s]==INVALID) break;
  97.224 +        else {
  97.225 +          euler.insert(next,narc[s]);
  97.226 +          visited[narc[s]]=true;
  97.227 +          Node n=g.target(narc[s]);
  97.228 +          ++narc[s];
  97.229 +          s=n;
  97.230 +        }
  97.231 +      }
  97.232 +      return *this;
  97.233 +    }
  97.234 +
  97.235 +    ///Postfix incrementation
  97.236 +
  97.237 +    /// Postfix incrementation.
  97.238 +    ///
  97.239 +    ///\warning This incrementation returns an \c Arc (which converts to 
  97.240 +    ///an \c Edge), not an \ref EulerIt, as one may expect.
  97.241 +    Arc operator++(int)
  97.242 +    {
  97.243 +      Arc e=*this;
  97.244 +      ++(*this);
  97.245 +      return e;
  97.246 +    }
  97.247 +  };
  97.248 +
  97.249 +
  97.250 +  ///Check if the given graph is Eulerian
  97.251 +
  97.252 +  /// \ingroup graph_properties
  97.253 +  ///This function checks if the given graph is Eulerian.
  97.254 +  ///It works for both directed and undirected graphs.
  97.255 +  ///
  97.256 +  ///By definition, a digraph is called \e Eulerian if
  97.257 +  ///and only if it is connected and the number of incoming and outgoing
  97.258 +  ///arcs are the same for each node.
  97.259 +  ///Similarly, an undirected graph is called \e Eulerian if
  97.260 +  ///and only if it is connected and the number of incident edges is even
  97.261 +  ///for each node.
  97.262 +  ///
  97.263 +  ///\note There are (di)graphs that are not Eulerian, but still have an
  97.264 +  /// Euler tour, since they may contain isolated nodes.
  97.265 +  ///
  97.266 +  ///\sa DiEulerIt, EulerIt
  97.267 +  template<typename GR>
  97.268 +#ifdef DOXYGEN
  97.269 +  bool
  97.270 +#else
  97.271 +  typename enable_if<UndirectedTagIndicator<GR>,bool>::type
  97.272 +  eulerian(const GR &g)
  97.273 +  {
  97.274 +    for(typename GR::NodeIt n(g);n!=INVALID;++n)
  97.275 +      if(countIncEdges(g,n)%2) return false;
  97.276 +    return connected(g);
  97.277 +  }
  97.278 +  template<class GR>
  97.279 +  typename disable_if<UndirectedTagIndicator<GR>,bool>::type
  97.280 +#endif
  97.281 +  eulerian(const GR &g)
  97.282 +  {
  97.283 +    for(typename GR::NodeIt n(g);n!=INVALID;++n)
  97.284 +      if(countInArcs(g,n)!=countOutArcs(g,n)) return false;
  97.285 +    return connected(undirector(g));
  97.286 +  }
  97.287 +
  97.288 +}
  97.289 +
  97.290 +#endif
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/lemon/fib_heap.h	Thu Nov 05 15:50:01 2009 +0100
    98.3 @@ -0,0 +1,475 @@
    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-2009
    98.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   98.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   98.11 + *
   98.12 + * Permission to use, modify and distribute this software is granted
   98.13 + * provided that this copyright notice appears in all copies. For
   98.14 + * precise terms see the accompanying LICENSE file.
   98.15 + *
   98.16 + * This software is provided "AS IS" with no warranty of any kind,
   98.17 + * express or implied, and with no claim as to its suitability for any
   98.18 + * purpose.
   98.19 + *
   98.20 + */
   98.21 +
   98.22 +#ifndef LEMON_FIB_HEAP_H
   98.23 +#define LEMON_FIB_HEAP_H
   98.24 +
   98.25 +///\file
   98.26 +///\ingroup heaps
   98.27 +///\brief Fibonacci heap implementation.
   98.28 +
   98.29 +#include <vector>
   98.30 +#include <utility>
   98.31 +#include <functional>
   98.32 +#include <lemon/math.h>
   98.33 +
   98.34 +namespace lemon {
   98.35 +
   98.36 +  /// \ingroup heaps
   98.37 +  ///
   98.38 +  /// \brief Fibonacci heap data structure.
   98.39 +  ///
   98.40 +  /// This class implements the \e Fibonacci \e heap data structure.
   98.41 +  /// It fully conforms to the \ref concepts::Heap "heap concept".
   98.42 +  ///
   98.43 +  /// The methods \ref increase() and \ref erase() are not efficient in a
   98.44 +  /// Fibonacci heap. In case of many calls of these operations, it is
   98.45 +  /// better to use other heap structure, e.g. \ref BinHeap "binary heap".
   98.46 +  ///
   98.47 +  /// \tparam PR Type of the priorities of the items.
   98.48 +  /// \tparam IM A read-writable item map with \c int values, used
   98.49 +  /// internally to handle the cross references.
   98.50 +  /// \tparam CMP A functor class for comparing the priorities.
   98.51 +  /// The default is \c std::less<PR>.
   98.52 +#ifdef DOXYGEN
   98.53 +  template <typename PR, typename IM, typename CMP>
   98.54 +#else
   98.55 +  template <typename PR, typename IM, typename CMP = std::less<PR> >
   98.56 +#endif
   98.57 +  class FibHeap {
   98.58 +  public:
   98.59 +
   98.60 +    /// Type of the item-int map.
   98.61 +    typedef IM ItemIntMap;
   98.62 +    /// Type of the priorities.
   98.63 +    typedef PR Prio;
   98.64 +    /// Type of the items stored in the heap.
   98.65 +    typedef typename ItemIntMap::Key Item;
   98.66 +    /// Type of the item-priority pairs.
   98.67 +    typedef std::pair<Item,Prio> Pair;
   98.68 +    /// Functor type for comparing the priorities.
   98.69 +    typedef CMP Compare;
   98.70 +
   98.71 +  private:
   98.72 +    class Store;
   98.73 +
   98.74 +    std::vector<Store> _data;
   98.75 +    int _minimum;
   98.76 +    ItemIntMap &_iim;
   98.77 +    Compare _comp;
   98.78 +    int _num;
   98.79 +
   98.80 +  public:
   98.81 +
   98.82 +    /// \brief Type to represent the states of the items.
   98.83 +    ///
   98.84 +    /// Each item has a state associated to it. It can be "in heap",
   98.85 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
   98.86 +    /// heap's point of view, but may be useful to the user.
   98.87 +    ///
   98.88 +    /// The item-int map must be initialized in such way that it assigns
   98.89 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
   98.90 +    enum State {
   98.91 +      IN_HEAP = 0,    ///< = 0.
   98.92 +      PRE_HEAP = -1,  ///< = -1.
   98.93 +      POST_HEAP = -2  ///< = -2.
   98.94 +    };
   98.95 +
   98.96 +    /// \brief Constructor.
   98.97 +    ///
   98.98 +    /// Constructor.
   98.99 +    /// \param map A map that assigns \c int values to the items.
  98.100 +    /// It is used internally to handle the cross references.
  98.101 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  98.102 +    explicit FibHeap(ItemIntMap &map)
  98.103 +      : _minimum(0), _iim(map), _num() {}
  98.104 +
  98.105 +    /// \brief Constructor.
  98.106 +    ///
  98.107 +    /// Constructor.
  98.108 +    /// \param map A map that assigns \c int values to the items.
  98.109 +    /// It is used internally to handle the cross references.
  98.110 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  98.111 +    /// \param comp The function object used for comparing the priorities.
  98.112 +    FibHeap(ItemIntMap &map, const Compare &comp)
  98.113 +      : _minimum(0), _iim(map), _comp(comp), _num() {}
  98.114 +
  98.115 +    /// \brief The number of items stored in the heap.
  98.116 +    ///
  98.117 +    /// This function returns the number of items stored in the heap.
  98.118 +    int size() const { return _num; }
  98.119 +
  98.120 +    /// \brief Check if the heap is empty.
  98.121 +    ///
  98.122 +    /// This function returns \c true if the heap is empty.
  98.123 +    bool empty() const { return _num==0; }
  98.124 +
  98.125 +    /// \brief Make the heap empty.
  98.126 +    ///
  98.127 +    /// This functon makes the heap empty.
  98.128 +    /// It does not change the cross reference map. If you want to reuse
  98.129 +    /// a heap that is not surely empty, you should first clear it and
  98.130 +    /// then you should set the cross reference map to \c PRE_HEAP
  98.131 +    /// for each item.
  98.132 +    void clear() {
  98.133 +      _data.clear(); _minimum = 0; _num = 0;
  98.134 +    }
  98.135 +
  98.136 +    /// \brief Insert an item into the heap with the given priority.
  98.137 +    ///
  98.138 +    /// This function inserts the given item into the heap with the
  98.139 +    /// given priority.
  98.140 +    /// \param item The item to insert.
  98.141 +    /// \param prio The priority of the item.
  98.142 +    /// \pre \e item must not be stored in the heap.
  98.143 +    void push (const Item& item, const Prio& prio) {
  98.144 +      int i=_iim[item];
  98.145 +      if ( i < 0 ) {
  98.146 +        int s=_data.size();
  98.147 +        _iim.set( item, s );
  98.148 +        Store st;
  98.149 +        st.name=item;
  98.150 +        _data.push_back(st);
  98.151 +        i=s;
  98.152 +      } else {
  98.153 +        _data[i].parent=_data[i].child=-1;
  98.154 +        _data[i].degree=0;
  98.155 +        _data[i].in=true;
  98.156 +        _data[i].marked=false;
  98.157 +      }
  98.158 +
  98.159 +      if ( _num ) {
  98.160 +        _data[_data[_minimum].right_neighbor].left_neighbor=i;
  98.161 +        _data[i].right_neighbor=_data[_minimum].right_neighbor;
  98.162 +        _data[_minimum].right_neighbor=i;
  98.163 +        _data[i].left_neighbor=_minimum;
  98.164 +        if ( _comp( prio, _data[_minimum].prio) ) _minimum=i;
  98.165 +      } else {
  98.166 +        _data[i].right_neighbor=_data[i].left_neighbor=i;
  98.167 +        _minimum=i;
  98.168 +      }
  98.169 +      _data[i].prio=prio;
  98.170 +      ++_num;
  98.171 +    }
  98.172 +
  98.173 +    /// \brief Return the item having minimum priority.
  98.174 +    ///
  98.175 +    /// This function returns the item having minimum priority.
  98.176 +    /// \pre The heap must be non-empty.
  98.177 +    Item top() const { return _data[_minimum].name; }
  98.178 +
  98.179 +    /// \brief The minimum priority.
  98.180 +    ///
  98.181 +    /// This function returns the minimum priority.
  98.182 +    /// \pre The heap must be non-empty.
  98.183 +    Prio prio() const { return _data[_minimum].prio; }
  98.184 +
  98.185 +    /// \brief Remove the item having minimum priority.
  98.186 +    ///
  98.187 +    /// This function removes the item having minimum priority.
  98.188 +    /// \pre The heap must be non-empty.
  98.189 +    void pop() {
  98.190 +      /*The first case is that there are only one root.*/
  98.191 +      if ( _data[_minimum].left_neighbor==_minimum ) {
  98.192 +        _data[_minimum].in=false;
  98.193 +        if ( _data[_minimum].degree!=0 ) {
  98.194 +          makeRoot(_data[_minimum].child);
  98.195 +          _minimum=_data[_minimum].child;
  98.196 +          balance();
  98.197 +        }
  98.198 +      } else {
  98.199 +        int right=_data[_minimum].right_neighbor;
  98.200 +        unlace(_minimum);
  98.201 +        _data[_minimum].in=false;
  98.202 +        if ( _data[_minimum].degree > 0 ) {
  98.203 +          int left=_data[_minimum].left_neighbor;
  98.204 +          int child=_data[_minimum].child;
  98.205 +          int last_child=_data[child].left_neighbor;
  98.206 +
  98.207 +          makeRoot(child);
  98.208 +
  98.209 +          _data[left].right_neighbor=child;
  98.210 +          _data[child].left_neighbor=left;
  98.211 +          _data[right].left_neighbor=last_child;
  98.212 +          _data[last_child].right_neighbor=right;
  98.213 +        }
  98.214 +        _minimum=right;
  98.215 +        balance();
  98.216 +      } // the case where there are more roots
  98.217 +      --_num;
  98.218 +    }
  98.219 +
  98.220 +    /// \brief Remove the given item from the heap.
  98.221 +    ///
  98.222 +    /// This function removes the given item from the heap if it is
  98.223 +    /// already stored.
  98.224 +    /// \param item The item to delete.
  98.225 +    /// \pre \e item must be in the heap.
  98.226 +    void erase (const Item& item) {
  98.227 +      int i=_iim[item];
  98.228 +
  98.229 +      if ( i >= 0 && _data[i].in ) {
  98.230 +        if ( _data[i].parent!=-1 ) {
  98.231 +          int p=_data[i].parent;
  98.232 +          cut(i,p);
  98.233 +          cascade(p);
  98.234 +        }
  98.235 +        _minimum=i;     //As if its prio would be -infinity
  98.236 +        pop();
  98.237 +      }
  98.238 +    }
  98.239 +
  98.240 +    /// \brief The priority of the given item.
  98.241 +    ///
  98.242 +    /// This function returns the priority of the given item.
  98.243 +    /// \param item The item.
  98.244 +    /// \pre \e item must be in the heap.
  98.245 +    Prio operator[](const Item& item) const {
  98.246 +      return _data[_iim[item]].prio;
  98.247 +    }
  98.248 +
  98.249 +    /// \brief Set the priority of an item or insert it, if it is
  98.250 +    /// not stored in the heap.
  98.251 +    ///
  98.252 +    /// This method sets the priority of the given item if it is
  98.253 +    /// already stored in the heap. Otherwise it inserts the given
  98.254 +    /// item into the heap with the given priority.
  98.255 +    /// \param item The item.
  98.256 +    /// \param prio The priority.
  98.257 +    void set (const Item& item, const Prio& prio) {
  98.258 +      int i=_iim[item];
  98.259 +      if ( i >= 0 && _data[i].in ) {
  98.260 +        if ( _comp(prio, _data[i].prio) ) decrease(item, prio);
  98.261 +        if ( _comp(_data[i].prio, prio) ) increase(item, prio);
  98.262 +      } else push(item, prio);
  98.263 +    }
  98.264 +
  98.265 +    /// \brief Decrease the priority of an item to the given value.
  98.266 +    ///
  98.267 +    /// This function decreases the priority of an item to the given value.
  98.268 +    /// \param item The item.
  98.269 +    /// \param prio The priority.
  98.270 +    /// \pre \e item must be stored in the heap with priority at least \e prio.
  98.271 +    void decrease (const Item& item, const Prio& prio) {
  98.272 +      int i=_iim[item];
  98.273 +      _data[i].prio=prio;
  98.274 +      int p=_data[i].parent;
  98.275 +
  98.276 +      if ( p!=-1 && _comp(prio, _data[p].prio) ) {
  98.277 +        cut(i,p);
  98.278 +        cascade(p);
  98.279 +      }
  98.280 +      if ( _comp(prio, _data[_minimum].prio) ) _minimum=i;
  98.281 +    }
  98.282 +
  98.283 +    /// \brief Increase the priority of an item to the given value.
  98.284 +    ///
  98.285 +    /// This function increases the priority of an item to the given value.
  98.286 +    /// \param item The item.
  98.287 +    /// \param prio The priority.
  98.288 +    /// \pre \e item must be stored in the heap with priority at most \e prio.
  98.289 +    void increase (const Item& item, const Prio& prio) {
  98.290 +      erase(item);
  98.291 +      push(item, prio);
  98.292 +    }
  98.293 +
  98.294 +    /// \brief Return the state of an item.
  98.295 +    ///
  98.296 +    /// This method returns \c PRE_HEAP if the given item has never
  98.297 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  98.298 +    /// and \c POST_HEAP otherwise.
  98.299 +    /// In the latter case it is possible that the item will get back
  98.300 +    /// to the heap again.
  98.301 +    /// \param item The item.
  98.302 +    State state(const Item &item) const {
  98.303 +      int i=_iim[item];
  98.304 +      if( i>=0 ) {
  98.305 +        if ( _data[i].in ) i=0;
  98.306 +        else i=-2;
  98.307 +      }
  98.308 +      return State(i);
  98.309 +    }
  98.310 +
  98.311 +    /// \brief Set the state of an item in the heap.
  98.312 +    ///
  98.313 +    /// This function sets the state of the given item in the heap.
  98.314 +    /// It can be used to manually clear the heap when it is important
  98.315 +    /// to achive better time complexity.
  98.316 +    /// \param i The item.
  98.317 +    /// \param st The state. It should not be \c IN_HEAP.
  98.318 +    void state(const Item& i, State st) {
  98.319 +      switch (st) {
  98.320 +      case POST_HEAP:
  98.321 +      case PRE_HEAP:
  98.322 +        if (state(i) == IN_HEAP) {
  98.323 +          erase(i);
  98.324 +        }
  98.325 +        _iim[i] = st;
  98.326 +        break;
  98.327 +      case IN_HEAP:
  98.328 +        break;
  98.329 +      }
  98.330 +    }
  98.331 +
  98.332 +  private:
  98.333 +
  98.334 +    void balance() {
  98.335 +
  98.336 +      int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;
  98.337 +
  98.338 +      std::vector<int> A(maxdeg,-1);
  98.339 +
  98.340 +      /*
  98.341 +       *Recall that now minimum does not point to the minimum prio element.
  98.342 +       *We set minimum to this during balance().
  98.343 +       */
  98.344 +      int anchor=_data[_minimum].left_neighbor;
  98.345 +      int next=_minimum;
  98.346 +      bool end=false;
  98.347 +
  98.348 +      do {
  98.349 +        int active=next;
  98.350 +        if ( anchor==active ) end=true;
  98.351 +        int d=_data[active].degree;
  98.352 +        next=_data[active].right_neighbor;
  98.353 +
  98.354 +        while (A[d]!=-1) {
  98.355 +          if( _comp(_data[active].prio, _data[A[d]].prio) ) {
  98.356 +            fuse(active,A[d]);
  98.357 +          } else {
  98.358 +            fuse(A[d],active);
  98.359 +            active=A[d];
  98.360 +          }
  98.361 +          A[d]=-1;
  98.362 +          ++d;
  98.363 +        }
  98.364 +        A[d]=active;
  98.365 +      } while ( !end );
  98.366 +
  98.367 +
  98.368 +      while ( _data[_minimum].parent >=0 )
  98.369 +        _minimum=_data[_minimum].parent;
  98.370 +      int s=_minimum;
  98.371 +      int m=_minimum;
  98.372 +      do {
  98.373 +        if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
  98.374 +        s=_data[s].right_neighbor;
  98.375 +      } while ( s != m );
  98.376 +    }
  98.377 +
  98.378 +    void makeRoot(int c) {
  98.379 +      int s=c;
  98.380 +      do {
  98.381 +        _data[s].parent=-1;
  98.382 +        s=_data[s].right_neighbor;
  98.383 +      } while ( s != c );
  98.384 +    }
  98.385 +
  98.386 +    void cut(int a, int b) {
  98.387 +      /*
  98.388 +       *Replacing a from the children of b.
  98.389 +       */
  98.390 +      --_data[b].degree;
  98.391 +
  98.392 +      if ( _data[b].degree !=0 ) {
  98.393 +        int child=_data[b].child;
  98.394 +        if ( child==a )
  98.395 +          _data[b].child=_data[child].right_neighbor;
  98.396 +        unlace(a);
  98.397 +      }
  98.398 +
  98.399 +
  98.400 +      /*Lacing a to the roots.*/
  98.401 +      int right=_data[_minimum].right_neighbor;
  98.402 +      _data[_minimum].right_neighbor=a;
  98.403 +      _data[a].left_neighbor=_minimum;
  98.404 +      _data[a].right_neighbor=right;
  98.405 +      _data[right].left_neighbor=a;
  98.406 +
  98.407 +      _data[a].parent=-1;
  98.408 +      _data[a].marked=false;
  98.409 +    }
  98.410 +
  98.411 +    void cascade(int a) {
  98.412 +      if ( _data[a].parent!=-1 ) {
  98.413 +        int p=_data[a].parent;
  98.414 +
  98.415 +        if ( _data[a].marked==false ) _data[a].marked=true;
  98.416 +        else {
  98.417 +          cut(a,p);
  98.418 +          cascade(p);
  98.419 +        }
  98.420 +      }
  98.421 +    }
  98.422 +
  98.423 +    void fuse(int a, int b) {
  98.424 +      unlace(b);
  98.425 +
  98.426 +      /*Lacing b under a.*/
  98.427 +      _data[b].parent=a;
  98.428 +
  98.429 +      if (_data[a].degree==0) {
  98.430 +        _data[b].left_neighbor=b;
  98.431 +        _data[b].right_neighbor=b;
  98.432 +        _data[a].child=b;
  98.433 +      } else {
  98.434 +        int child=_data[a].child;
  98.435 +        int last_child=_data[child].left_neighbor;
  98.436 +        _data[child].left_neighbor=b;
  98.437 +        _data[b].right_neighbor=child;
  98.438 +        _data[last_child].right_neighbor=b;
  98.439 +        _data[b].left_neighbor=last_child;
  98.440 +      }
  98.441 +
  98.442 +      ++_data[a].degree;
  98.443 +
  98.444 +      _data[b].marked=false;
  98.445 +    }
  98.446 +
  98.447 +    /*
  98.448 +     *It is invoked only if a has siblings.
  98.449 +     */
  98.450 +    void unlace(int a) {
  98.451 +      int leftn=_data[a].left_neighbor;
  98.452 +      int rightn=_data[a].right_neighbor;
  98.453 +      _data[leftn].right_neighbor=rightn;
  98.454 +      _data[rightn].left_neighbor=leftn;
  98.455 +    }
  98.456 +
  98.457 +
  98.458 +    class Store {
  98.459 +      friend class FibHeap;
  98.460 +
  98.461 +      Item name;
  98.462 +      int parent;
  98.463 +      int left_neighbor;
  98.464 +      int right_neighbor;
  98.465 +      int child;
  98.466 +      int degree;
  98.467 +      bool marked;
  98.468 +      bool in;
  98.469 +      Prio prio;
  98.470 +
  98.471 +      Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
  98.472 +    };
  98.473 +  };
  98.474 +
  98.475 +} //namespace lemon
  98.476 +
  98.477 +#endif //LEMON_FIB_HEAP_H
  98.478 +
    99.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.2 +++ b/lemon/fourary_heap.h	Thu Nov 05 15:50:01 2009 +0100
    99.3 @@ -0,0 +1,342 @@
    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-2009
    99.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   99.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   99.11 + *
   99.12 + * Permission to use, modify and distribute this software is granted
   99.13 + * provided that this copyright notice appears in all copies. For
   99.14 + * precise terms see the accompanying LICENSE file.
   99.15 + *
   99.16 + * This software is provided "AS IS" with no warranty of any kind,
   99.17 + * express or implied, and with no claim as to its suitability for any
   99.18 + * purpose.
   99.19 + *
   99.20 + */
   99.21 +
   99.22 +#ifndef LEMON_FOURARY_HEAP_H
   99.23 +#define LEMON_FOURARY_HEAP_H
   99.24 +
   99.25 +///\ingroup heaps
   99.26 +///\file
   99.27 +///\brief Fourary heap implementation.
   99.28 +
   99.29 +#include <vector>
   99.30 +#include <utility>
   99.31 +#include <functional>
   99.32 +
   99.33 +namespace lemon {
   99.34 +
   99.35 +  /// \ingroup heaps
   99.36 +  ///
   99.37 +  ///\brief Fourary heap data structure.
   99.38 +  ///
   99.39 +  /// This class implements the \e fourary \e heap data structure.
   99.40 +  /// It fully conforms to the \ref concepts::Heap "heap concept".
   99.41 +  ///
   99.42 +  /// The fourary heap is a specialization of the \ref KaryHeap "K-ary heap"
   99.43 +  /// for <tt>K=4</tt>. It is similar to the \ref BinHeap "binary heap",
   99.44 +  /// but its nodes have at most four children, instead of two.
   99.45 +  ///
   99.46 +  /// \tparam PR Type of the priorities of the items.
   99.47 +  /// \tparam IM A read-writable item map with \c int values, used
   99.48 +  /// internally to handle the cross references.
   99.49 +  /// \tparam CMP A functor class for comparing the priorities.
   99.50 +  /// The default is \c std::less<PR>.
   99.51 +  ///
   99.52 +  ///\sa BinHeap
   99.53 +  ///\sa KaryHeap
   99.54 +#ifdef DOXYGEN
   99.55 +  template <typename PR, typename IM, typename CMP>
   99.56 +#else
   99.57 +  template <typename PR, typename IM, typename CMP = std::less<PR> >
   99.58 +#endif
   99.59 +  class FouraryHeap {
   99.60 +  public:
   99.61 +    /// Type of the item-int map.
   99.62 +    typedef IM ItemIntMap;
   99.63 +    /// Type of the priorities.
   99.64 +    typedef PR Prio;
   99.65 +    /// Type of the items stored in the heap.
   99.66 +    typedef typename ItemIntMap::Key Item;
   99.67 +    /// Type of the item-priority pairs.
   99.68 +    typedef std::pair<Item,Prio> Pair;
   99.69 +    /// Functor type for comparing the priorities.
   99.70 +    typedef CMP Compare;
   99.71 +
   99.72 +    /// \brief Type to represent the states of the items.
   99.73 +    ///
   99.74 +    /// Each item has a state associated to it. It can be "in heap",
   99.75 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
   99.76 +    /// heap's point of view, but may be useful to the user.
   99.77 +    ///
   99.78 +    /// The item-int map must be initialized in such way that it assigns
   99.79 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
   99.80 +    enum State {
   99.81 +      IN_HEAP = 0,    ///< = 0.
   99.82 +      PRE_HEAP = -1,  ///< = -1.
   99.83 +      POST_HEAP = -2  ///< = -2.
   99.84 +    };
   99.85 +
   99.86 +  private:
   99.87 +    std::vector<Pair> _data;
   99.88 +    Compare _comp;
   99.89 +    ItemIntMap &_iim;
   99.90 +
   99.91 +  public:
   99.92 +    /// \brief Constructor.
   99.93 +    ///
   99.94 +    /// Constructor.
   99.95 +    /// \param map A map that assigns \c int values to the items.
   99.96 +    /// It is used internally to handle the cross references.
   99.97 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
   99.98 +    explicit FouraryHeap(ItemIntMap &map) : _iim(map) {}
   99.99 +
  99.100 +    /// \brief Constructor.
  99.101 +    ///
  99.102 +    /// Constructor.
  99.103 +    /// \param map A map that assigns \c int values to the items.
  99.104 +    /// It is used internally to handle the cross references.
  99.105 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  99.106 +    /// \param comp The function object used for comparing the priorities.
  99.107 +    FouraryHeap(ItemIntMap &map, const Compare &comp)
  99.108 +      : _iim(map), _comp(comp) {}
  99.109 +
  99.110 +    /// \brief The number of items stored in the heap.
  99.111 +    ///
  99.112 +    /// This function returns the number of items stored in the heap.
  99.113 +    int size() const { return _data.size(); }
  99.114 +
  99.115 +    /// \brief Check if the heap is empty.
  99.116 +    ///
  99.117 +    /// This function returns \c true if the heap is empty.
  99.118 +    bool empty() const { return _data.empty(); }
  99.119 +
  99.120 +    /// \brief Make the heap empty.
  99.121 +    ///
  99.122 +    /// This functon makes the heap empty.
  99.123 +    /// It does not change the cross reference map. If you want to reuse
  99.124 +    /// a heap that is not surely empty, you should first clear it and
  99.125 +    /// then you should set the cross reference map to \c PRE_HEAP
  99.126 +    /// for each item.
  99.127 +    void clear() { _data.clear(); }
  99.128 +
  99.129 +  private:
  99.130 +    static int parent(int i) { return (i-1)/4; }
  99.131 +    static int firstChild(int i) { return 4*i+1; }
  99.132 +
  99.133 +    bool less(const Pair &p1, const Pair &p2) const {
  99.134 +      return _comp(p1.second, p2.second);
  99.135 +    }
  99.136 +
  99.137 +    void bubbleUp(int hole, Pair p) {
  99.138 +      int par = parent(hole);
  99.139 +      while( hole>0 && less(p,_data[par]) ) {
  99.140 +        move(_data[par],hole);
  99.141 +        hole = par;
  99.142 +        par = parent(hole);
  99.143 +      }
  99.144 +      move(p, hole);
  99.145 +    }
  99.146 +
  99.147 +    void bubbleDown(int hole, Pair p, int length) {
  99.148 +      if( length>1 ) {
  99.149 +        int child = firstChild(hole);
  99.150 +        while( child+3<length ) {
  99.151 +          int min=child;
  99.152 +          if( less(_data[++child], _data[min]) ) min=child;
  99.153 +          if( less(_data[++child], _data[min]) ) min=child;
  99.154 +          if( less(_data[++child], _data[min]) ) min=child;
  99.155 +          if( !less(_data[min], p) )
  99.156 +            goto ok;
  99.157 +          move(_data[min], hole);
  99.158 +          hole = min;
  99.159 +          child = firstChild(hole);
  99.160 +        }
  99.161 +        if ( child<length ) {
  99.162 +          int min = child;
  99.163 +          if( ++child<length && less(_data[child], _data[min]) ) min=child;
  99.164 +          if( ++child<length && less(_data[child], _data[min]) ) min=child;
  99.165 +          if( less(_data[min], p) ) {
  99.166 +            move(_data[min], hole);
  99.167 +            hole = min;
  99.168 +          }
  99.169 +        }
  99.170 +      }
  99.171 +    ok:
  99.172 +      move(p, hole);
  99.173 +    }
  99.174 +
  99.175 +    void move(const Pair &p, int i) {
  99.176 +      _data[i] = p;
  99.177 +      _iim.set(p.first, i);
  99.178 +    }
  99.179 +
  99.180 +  public:
  99.181 +    /// \brief Insert a pair of item and priority into the heap.
  99.182 +    ///
  99.183 +    /// This function inserts \c p.first to the heap with priority
  99.184 +    /// \c p.second.
  99.185 +    /// \param p The pair to insert.
  99.186 +    /// \pre \c p.first must not be stored in the heap.
  99.187 +    void push(const Pair &p) {
  99.188 +      int n = _data.size();
  99.189 +      _data.resize(n+1);
  99.190 +      bubbleUp(n, p);
  99.191 +    }
  99.192 +
  99.193 +    /// \brief Insert an item into the heap with the given priority.
  99.194 +    ///
  99.195 +    /// This function inserts the given item into the heap with the
  99.196 +    /// given priority.
  99.197 +    /// \param i The item to insert.
  99.198 +    /// \param p The priority of the item.
  99.199 +    /// \pre \e i must not be stored in the heap.
  99.200 +    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
  99.201 +
  99.202 +    /// \brief Return the item having minimum priority.
  99.203 +    ///
  99.204 +    /// This function returns the item having minimum priority.
  99.205 +    /// \pre The heap must be non-empty.
  99.206 +    Item top() const { return _data[0].first; }
  99.207 +
  99.208 +    /// \brief The minimum priority.
  99.209 +    ///
  99.210 +    /// This function returns the minimum priority.
  99.211 +    /// \pre The heap must be non-empty.
  99.212 +    Prio prio() const { return _data[0].second; }
  99.213 +
  99.214 +    /// \brief Remove the item having minimum priority.
  99.215 +    ///
  99.216 +    /// This function removes the item having minimum priority.
  99.217 +    /// \pre The heap must be non-empty.
  99.218 +    void pop() {
  99.219 +      int n = _data.size()-1;
  99.220 +      _iim.set(_data[0].first, POST_HEAP);
  99.221 +      if (n>0) bubbleDown(0, _data[n], n);
  99.222 +      _data.pop_back();
  99.223 +    }
  99.224 +
  99.225 +    /// \brief Remove the given item from the heap.
  99.226 +    ///
  99.227 +    /// This function removes the given item from the heap if it is
  99.228 +    /// already stored.
  99.229 +    /// \param i The item to delete.
  99.230 +    /// \pre \e i must be in the heap.
  99.231 +    void erase(const Item &i) {
  99.232 +      int h = _iim[i];
  99.233 +      int n = _data.size()-1;
  99.234 +      _iim.set(_data[h].first, POST_HEAP);
  99.235 +      if( h<n ) {
  99.236 +        if( less(_data[parent(h)], _data[n]) )
  99.237 +          bubbleDown(h, _data[n], n);
  99.238 +        else
  99.239 +          bubbleUp(h, _data[n]);
  99.240 +      }
  99.241 +      _data.pop_back();
  99.242 +    }
  99.243 +
  99.244 +    /// \brief The priority of the given item.
  99.245 +    ///
  99.246 +    /// This function returns the priority of the given item.
  99.247 +    /// \param i The item.
  99.248 +    /// \pre \e i must be in the heap.
  99.249 +    Prio operator[](const Item &i) const {
  99.250 +      int idx = _iim[i];
  99.251 +      return _data[idx].second;
  99.252 +    }
  99.253 +
  99.254 +    /// \brief Set the priority of an item or insert it, if it is
  99.255 +    /// not stored in the heap.
  99.256 +    ///
  99.257 +    /// This method sets the priority of the given item if it is
  99.258 +    /// already stored in the heap. Otherwise it inserts the given
  99.259 +    /// item into the heap with the given priority.
  99.260 +    /// \param i The item.
  99.261 +    /// \param p The priority.
  99.262 +    void set(const Item &i, const Prio &p) {
  99.263 +      int idx = _iim[i];
  99.264 +      if( idx < 0 )
  99.265 +        push(i,p);
  99.266 +      else if( _comp(p, _data[idx].second) )
  99.267 +        bubbleUp(idx, Pair(i,p));
  99.268 +      else
  99.269 +        bubbleDown(idx, Pair(i,p), _data.size());
  99.270 +    }
  99.271 +
  99.272 +    /// \brief Decrease the priority of an item to the given value.
  99.273 +    ///
  99.274 +    /// This function decreases the priority of an item to the given value.
  99.275 +    /// \param i The item.
  99.276 +    /// \param p The priority.
  99.277 +    /// \pre \e i must be stored in the heap with priority at least \e p.
  99.278 +    void decrease(const Item &i, const Prio &p) {
  99.279 +      int idx = _iim[i];
  99.280 +      bubbleUp(idx, Pair(i,p));
  99.281 +    }
  99.282 +
  99.283 +    /// \brief Increase the priority of an item to the given value.
  99.284 +    ///
  99.285 +    /// This function increases the priority of an item to the given value.
  99.286 +    /// \param i The item.
  99.287 +    /// \param p The priority.
  99.288 +    /// \pre \e i must be stored in the heap with priority at most \e p.
  99.289 +    void increase(const Item &i, const Prio &p) {
  99.290 +      int idx = _iim[i];
  99.291 +      bubbleDown(idx, Pair(i,p), _data.size());
  99.292 +    }
  99.293 +
  99.294 +    /// \brief Return the state of an item.
  99.295 +    ///
  99.296 +    /// This method returns \c PRE_HEAP if the given item has never
  99.297 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  99.298 +    /// and \c POST_HEAP otherwise.
  99.299 +    /// In the latter case it is possible that the item will get back
  99.300 +    /// to the heap again.
  99.301 +    /// \param i The item.
  99.302 +    State state(const Item &i) const {
  99.303 +      int s = _iim[i];
  99.304 +      if (s>=0) s=0;
  99.305 +      return State(s);
  99.306 +    }
  99.307 +
  99.308 +    /// \brief Set the state of an item in the heap.
  99.309 +    ///
  99.310 +    /// This function sets the state of the given item in the heap.
  99.311 +    /// It can be used to manually clear the heap when it is important
  99.312 +    /// to achive better time complexity.
  99.313 +    /// \param i The item.
  99.314 +    /// \param st The state. It should not be \c IN_HEAP.
  99.315 +    void state(const Item& i, State st) {
  99.316 +      switch (st) {
  99.317 +        case POST_HEAP:
  99.318 +        case PRE_HEAP:
  99.319 +          if (state(i) == IN_HEAP) erase(i);
  99.320 +          _iim[i] = st;
  99.321 +          break;
  99.322 +        case IN_HEAP:
  99.323 +          break;
  99.324 +      }
  99.325 +    }
  99.326 +
  99.327 +    /// \brief Replace an item in the heap.
  99.328 +    ///
  99.329 +    /// This function replaces item \c i with item \c j.
  99.330 +    /// Item \c i must be in the heap, while \c j must be out of the heap.
  99.331 +    /// After calling this method, item \c i will be out of the
  99.332 +    /// heap and \c j will be in the heap with the same prioriority
  99.333 +    /// as item \c i had before.
  99.334 +    void replace(const Item& i, const Item& j) {
  99.335 +      int idx = _iim[i];
  99.336 +      _iim.set(i, _iim[j]);
  99.337 +      _iim.set(j, idx);
  99.338 +      _data[idx].first = j;
  99.339 +    }
  99.340 +
  99.341 +  }; // class FouraryHeap
  99.342 +
  99.343 +} // namespace lemon
  99.344 +
  99.345 +#endif // LEMON_FOURARY_HEAP_H
   100.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.2 +++ b/lemon/full_graph.h	Thu Nov 05 15:50:01 2009 +0100
   100.3 @@ -0,0 +1,620 @@
   100.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   100.5 + *
   100.6 + * This file is a part of LEMON, a generic C++ optimization library.
   100.7 + *
   100.8 + * Copyright (C) 2003-2009
   100.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  100.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  100.11 + *
  100.12 + * Permission to use, modify and distribute this software is granted
  100.13 + * provided that this copyright notice appears in all copies. For
  100.14 + * precise terms see the accompanying LICENSE file.
  100.15 + *
  100.16 + * This software is provided "AS IS" with no warranty of any kind,
  100.17 + * express or implied, and with no claim as to its suitability for any
  100.18 + * purpose.
  100.19 + *
  100.20 + */
  100.21 +
  100.22 +#ifndef LEMON_FULL_GRAPH_H
  100.23 +#define LEMON_FULL_GRAPH_H
  100.24 +
  100.25 +#include <lemon/core.h>
  100.26 +#include <lemon/bits/graph_extender.h>
  100.27 +
  100.28 +///\ingroup graphs
  100.29 +///\file
  100.30 +///\brief FullDigraph and FullGraph classes.
  100.31 +
  100.32 +namespace lemon {
  100.33 +
  100.34 +  class FullDigraphBase {
  100.35 +  public:
  100.36 +
  100.37 +    typedef FullDigraphBase Digraph;
  100.38 +
  100.39 +    class Node;
  100.40 +    class Arc;
  100.41 +
  100.42 +  protected:
  100.43 +
  100.44 +    int _node_num;
  100.45 +    int _arc_num;
  100.46 +
  100.47 +    FullDigraphBase() {}
  100.48 +
  100.49 +    void construct(int n) { _node_num = n; _arc_num = n * n; }
  100.50 +
  100.51 +  public:
  100.52 +
  100.53 +    typedef True NodeNumTag;
  100.54 +    typedef True ArcNumTag;
  100.55 +
  100.56 +    Node operator()(int ix) const { return Node(ix); }
  100.57 +    static int index(const Node& node) { return node._id; }
  100.58 +
  100.59 +    Arc arc(const Node& s, const Node& t) const {
  100.60 +      return Arc(s._id * _node_num + t._id);
  100.61 +    }
  100.62 +
  100.63 +    int nodeNum() const { return _node_num; }
  100.64 +    int arcNum() const { return _arc_num; }
  100.65 +
  100.66 +    int maxNodeId() const { return _node_num - 1; }
  100.67 +    int maxArcId() const { return _arc_num - 1; }
  100.68 +
  100.69 +    Node source(Arc arc) const { return arc._id / _node_num; }
  100.70 +    Node target(Arc arc) const { return arc._id % _node_num; }
  100.71 +
  100.72 +    static int id(Node node) { return node._id; }
  100.73 +    static int id(Arc arc) { return arc._id; }
  100.74 +
  100.75 +    static Node nodeFromId(int id) { return Node(id);}
  100.76 +    static Arc arcFromId(int id) { return Arc(id);}
  100.77 +
  100.78 +    typedef True FindArcTag;
  100.79 +
  100.80 +    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
  100.81 +      return prev == INVALID ? arc(s, t) : INVALID;
  100.82 +    }
  100.83 +
  100.84 +    class Node {
  100.85 +      friend class FullDigraphBase;
  100.86 +
  100.87 +    protected:
  100.88 +      int _id;
  100.89 +      Node(int id) : _id(id) {}
  100.90 +    public:
  100.91 +      Node() {}
  100.92 +      Node (Invalid) : _id(-1) {}
  100.93 +      bool operator==(const Node node) const {return _id == node._id;}
  100.94 +      bool operator!=(const Node node) const {return _id != node._id;}
  100.95 +      bool operator<(const Node node) const {return _id < node._id;}
  100.96 +    };
  100.97 +
  100.98 +    class Arc {
  100.99 +      friend class FullDigraphBase;
 100.100 +
 100.101 +    protected:
 100.102 +      int _id;  // _node_num * source + target;
 100.103 +
 100.104 +      Arc(int id) : _id(id) {}
 100.105 +
 100.106 +    public:
 100.107 +      Arc() { }
 100.108 +      Arc (Invalid) { _id = -1; }
 100.109 +      bool operator==(const Arc arc) const {return _id == arc._id;}
 100.110 +      bool operator!=(const Arc arc) const {return _id != arc._id;}
 100.111 +      bool operator<(const Arc arc) const {return _id < arc._id;}
 100.112 +    };
 100.113 +
 100.114 +    void first(Node& node) const {
 100.115 +      node._id = _node_num - 1;
 100.116 +    }
 100.117 +
 100.118 +    static void next(Node& node) {
 100.119 +      --node._id;
 100.120 +    }
 100.121 +
 100.122 +    void first(Arc& arc) const {
 100.123 +      arc._id = _arc_num - 1;
 100.124 +    }
 100.125 +
 100.126 +    static void next(Arc& arc) {
 100.127 +      --arc._id;
 100.128 +    }
 100.129 +
 100.130 +    void firstOut(Arc& arc, const Node& node) const {
 100.131 +      arc._id = (node._id + 1) * _node_num - 1;
 100.132 +    }
 100.133 +
 100.134 +    void nextOut(Arc& arc) const {
 100.135 +      if (arc._id % _node_num == 0) arc._id = 0;
 100.136 +      --arc._id;
 100.137 +    }
 100.138 +
 100.139 +    void firstIn(Arc& arc, const Node& node) const {
 100.140 +      arc._id = _arc_num + node._id - _node_num;
 100.141 +    }
 100.142 +
 100.143 +    void nextIn(Arc& arc) const {
 100.144 +      arc._id -= _node_num;
 100.145 +      if (arc._id < 0) arc._id = -1;
 100.146 +    }
 100.147 +
 100.148 +  };
 100.149 +
 100.150 +  typedef DigraphExtender<FullDigraphBase> ExtendedFullDigraphBase;
 100.151 +
 100.152 +  /// \ingroup graphs
 100.153 +  ///
 100.154 +  /// \brief A directed full graph class.
 100.155 +  ///
 100.156 +  /// FullDigraph is a simple and fast implmenetation of directed full
 100.157 +  /// (complete) graphs. It contains an arc from each node to each node
 100.158 +  /// (including a loop for each node), therefore the number of arcs
 100.159 +  /// is the square of the number of nodes.
 100.160 +  /// This class is completely static and it needs constant memory space.
 100.161 +  /// Thus you can neither add nor delete nodes or arcs, however
 100.162 +  /// the structure can be resized using resize().
 100.163 +  ///
 100.164 +  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
 100.165 +  /// Most of its member functions and nested classes are documented
 100.166 +  /// only in the concept class.
 100.167 +  ///
 100.168 +  /// \note FullDigraph and FullGraph classes are very similar,
 100.169 +  /// but there are two differences. While this class conforms only
 100.170 +  /// to the \ref concepts::Digraph "Digraph" concept, FullGraph
 100.171 +  /// conforms to the \ref concepts::Graph "Graph" concept,
 100.172 +  /// moreover FullGraph does not contain a loop for each
 100.173 +  /// node as this class does.
 100.174 +  ///
 100.175 +  /// \sa FullGraph
 100.176 +  class FullDigraph : public ExtendedFullDigraphBase {
 100.177 +    typedef ExtendedFullDigraphBase Parent;
 100.178 +
 100.179 +  public:
 100.180 +
 100.181 +    /// \brief Default constructor.
 100.182 +    ///
 100.183 +    /// Default constructor. The number of nodes and arcs will be zero.
 100.184 +    FullDigraph() { construct(0); }
 100.185 +
 100.186 +    /// \brief Constructor
 100.187 +    ///
 100.188 +    /// Constructor.
 100.189 +    /// \param n The number of the nodes.
 100.190 +    FullDigraph(int n) { construct(n); }
 100.191 +
 100.192 +    /// \brief Resizes the digraph
 100.193 +    ///
 100.194 +    /// This function resizes the digraph. It fully destroys and
 100.195 +    /// rebuilds the structure, therefore the maps of the digraph will be
 100.196 +    /// reallocated automatically and the previous values will be lost.
 100.197 +    void resize(int n) {
 100.198 +      Parent::notifier(Arc()).clear();
 100.199 +      Parent::notifier(Node()).clear();
 100.200 +      construct(n);
 100.201 +      Parent::notifier(Node()).build();
 100.202 +      Parent::notifier(Arc()).build();
 100.203 +    }
 100.204 +
 100.205 +    /// \brief Returns the node with the given index.
 100.206 +    ///
 100.207 +    /// Returns the node with the given index. Since this structure is 
 100.208 +    /// completely static, the nodes can be indexed with integers from
 100.209 +    /// the range <tt>[0..nodeNum()-1]</tt>.
 100.210 +    /// \sa index()
 100.211 +    Node operator()(int ix) const { return Parent::operator()(ix); }
 100.212 +
 100.213 +    /// \brief Returns the index of the given node.
 100.214 +    ///
 100.215 +    /// Returns the index of the given node. Since this structure is 
 100.216 +    /// completely static, the nodes can be indexed with integers from
 100.217 +    /// the range <tt>[0..nodeNum()-1]</tt>.
 100.218 +    /// \sa operator()()
 100.219 +    static int index(const Node& node) { return Parent::index(node); }
 100.220 +
 100.221 +    /// \brief Returns the arc connecting the given nodes.
 100.222 +    ///
 100.223 +    /// Returns the arc connecting the given nodes.
 100.224 +    Arc arc(Node u, Node v) const {
 100.225 +      return Parent::arc(u, v);
 100.226 +    }
 100.227 +
 100.228 +    /// \brief Number of nodes.
 100.229 +    int nodeNum() const { return Parent::nodeNum(); }
 100.230 +    /// \brief Number of arcs.
 100.231 +    int arcNum() const { return Parent::arcNum(); }
 100.232 +  };
 100.233 +
 100.234 +
 100.235 +  class FullGraphBase {
 100.236 +  public:
 100.237 +
 100.238 +    typedef FullGraphBase Graph;
 100.239 +
 100.240 +    class Node;
 100.241 +    class Arc;
 100.242 +    class Edge;
 100.243 +
 100.244 +  protected:
 100.245 +
 100.246 +    int _node_num;
 100.247 +    int _edge_num;
 100.248 +
 100.249 +    FullGraphBase() {}
 100.250 +
 100.251 +    void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; }
 100.252 +
 100.253 +    int _uid(int e) const {
 100.254 +      int u = e / _node_num;
 100.255 +      int v = e % _node_num;
 100.256 +      return u < v ? u : _node_num - 2 - u;
 100.257 +    }
 100.258 +
 100.259 +    int _vid(int e) const {
 100.260 +      int u = e / _node_num;
 100.261 +      int v = e % _node_num;
 100.262 +      return u < v ? v : _node_num - 1 - v;
 100.263 +    }
 100.264 +
 100.265 +    void _uvid(int e, int& u, int& v) const {
 100.266 +      u = e / _node_num;
 100.267 +      v = e % _node_num;
 100.268 +      if  (u >= v) {
 100.269 +        u = _node_num - 2 - u;
 100.270 +        v = _node_num - 1 - v;
 100.271 +      }
 100.272 +    }
 100.273 +
 100.274 +    void _stid(int a, int& s, int& t) const {
 100.275 +      if ((a & 1) == 1) {
 100.276 +        _uvid(a >> 1, s, t);
 100.277 +      } else {
 100.278 +        _uvid(a >> 1, t, s);
 100.279 +      }
 100.280 +    }
 100.281 +
 100.282 +    int _eid(int u, int v) const {
 100.283 +      if (u < (_node_num - 1) / 2) {
 100.284 +        return u * _node_num + v;
 100.285 +      } else {
 100.286 +        return (_node_num - 1 - u) * _node_num - v - 1;
 100.287 +      }
 100.288 +    }
 100.289 +
 100.290 +  public:
 100.291 +
 100.292 +    Node operator()(int ix) const { return Node(ix); }
 100.293 +    static int index(const Node& node) { return node._id; }
 100.294 +
 100.295 +    Edge edge(const Node& u, const Node& v) const {
 100.296 +      if (u._id < v._id) {
 100.297 +        return Edge(_eid(u._id, v._id));
 100.298 +      } else if (u._id != v._id) {
 100.299 +        return Edge(_eid(v._id, u._id));
 100.300 +      } else {
 100.301 +        return INVALID;
 100.302 +      }
 100.303 +    }
 100.304 +
 100.305 +    Arc arc(const Node& s, const Node& t) const {
 100.306 +      if (s._id < t._id) {
 100.307 +        return Arc((_eid(s._id, t._id) << 1) | 1);
 100.308 +      } else if (s._id != t._id) {
 100.309 +        return Arc(_eid(t._id, s._id) << 1);
 100.310 +      } else {
 100.311 +        return INVALID;
 100.312 +      }
 100.313 +    }
 100.314 +
 100.315 +    typedef True NodeNumTag;
 100.316 +    typedef True ArcNumTag;
 100.317 +    typedef True EdgeNumTag;
 100.318 +
 100.319 +    int nodeNum() const { return _node_num; }
 100.320 +    int arcNum() const { return 2 * _edge_num; }
 100.321 +    int edgeNum() const { return _edge_num; }
 100.322 +
 100.323 +    static int id(Node node) { return node._id; }
 100.324 +    static int id(Arc arc) { return arc._id; }
 100.325 +    static int id(Edge edge) { return edge._id; }
 100.326 +
 100.327 +    int maxNodeId() const { return _node_num-1; }
 100.328 +    int maxArcId() const { return 2 * _edge_num-1; }
 100.329 +    int maxEdgeId() const { return _edge_num-1; }
 100.330 +
 100.331 +    static Node nodeFromId(int id) { return Node(id);}
 100.332 +    static Arc arcFromId(int id) { return Arc(id);}
 100.333 +    static Edge edgeFromId(int id) { return Edge(id);}
 100.334 +
 100.335 +    Node u(Edge edge) const {
 100.336 +      return Node(_uid(edge._id));
 100.337 +    }
 100.338 +
 100.339 +    Node v(Edge edge) const {
 100.340 +      return Node(_vid(edge._id));
 100.341 +    }
 100.342 +
 100.343 +    Node source(Arc arc) const {
 100.344 +      return Node((arc._id & 1) == 1 ?
 100.345 +                  _uid(arc._id >> 1) : _vid(arc._id >> 1));
 100.346 +    }
 100.347 +
 100.348 +    Node target(Arc arc) const {
 100.349 +      return Node((arc._id & 1) == 1 ?
 100.350 +                  _vid(arc._id >> 1) : _uid(arc._id >> 1));
 100.351 +    }
 100.352 +
 100.353 +    typedef True FindEdgeTag;
 100.354 +    typedef True FindArcTag;
 100.355 +
 100.356 +    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
 100.357 +      return prev != INVALID ? INVALID : edge(u, v);
 100.358 +    }
 100.359 +
 100.360 +    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
 100.361 +      return prev != INVALID ? INVALID : arc(s, t);
 100.362 +    }
 100.363 +
 100.364 +    class Node {
 100.365 +      friend class FullGraphBase;
 100.366 +
 100.367 +    protected:
 100.368 +      int _id;
 100.369 +      Node(int id) : _id(id) {}
 100.370 +    public:
 100.371 +      Node() {}
 100.372 +      Node (Invalid) { _id = -1; }
 100.373 +      bool operator==(const Node node) const {return _id == node._id;}
 100.374 +      bool operator!=(const Node node) const {return _id != node._id;}
 100.375 +      bool operator<(const Node node) const {return _id < node._id;}
 100.376 +    };
 100.377 +
 100.378 +    class Edge {
 100.379 +      friend class FullGraphBase;
 100.380 +      friend class Arc;
 100.381 +
 100.382 +    protected:
 100.383 +      int _id;
 100.384 +
 100.385 +      Edge(int id) : _id(id) {}
 100.386 +
 100.387 +    public:
 100.388 +      Edge() { }
 100.389 +      Edge (Invalid) { _id = -1; }
 100.390 +
 100.391 +      bool operator==(const Edge edge) const {return _id == edge._id;}
 100.392 +      bool operator!=(const Edge edge) const {return _id != edge._id;}
 100.393 +      bool operator<(const Edge edge) const {return _id < edge._id;}
 100.394 +    };
 100.395 +
 100.396 +    class Arc {
 100.397 +      friend class FullGraphBase;
 100.398 +
 100.399 +    protected:
 100.400 +      int _id;
 100.401 +
 100.402 +      Arc(int id) : _id(id) {}
 100.403 +
 100.404 +    public:
 100.405 +      Arc() { }
 100.406 +      Arc (Invalid) { _id = -1; }
 100.407 +
 100.408 +      operator Edge() const { return Edge(_id != -1 ? (_id >> 1) : -1); }
 100.409 +
 100.410 +      bool operator==(const Arc arc) const {return _id == arc._id;}
 100.411 +      bool operator!=(const Arc arc) const {return _id != arc._id;}
 100.412 +      bool operator<(const Arc arc) const {return _id < arc._id;}
 100.413 +    };
 100.414 +
 100.415 +    static bool direction(Arc arc) {
 100.416 +      return (arc._id & 1) == 1;
 100.417 +    }
 100.418 +
 100.419 +    static Arc direct(Edge edge, bool dir) {
 100.420 +      return Arc((edge._id << 1) | (dir ? 1 : 0));
 100.421 +    }
 100.422 +
 100.423 +    void first(Node& node) const {
 100.424 +      node._id = _node_num - 1;
 100.425 +    }
 100.426 +
 100.427 +    static void next(Node& node) {
 100.428 +      --node._id;
 100.429 +    }
 100.430 +
 100.431 +    void first(Arc& arc) const {
 100.432 +      arc._id = (_edge_num << 1) - 1;
 100.433 +    }
 100.434 +
 100.435 +    static void next(Arc& arc) {
 100.436 +      --arc._id;
 100.437 +    }
 100.438 +
 100.439 +    void first(Edge& edge) const {
 100.440 +      edge._id = _edge_num - 1;
 100.441 +    }
 100.442 +
 100.443 +    static void next(Edge& edge) {
 100.444 +      --edge._id;
 100.445 +    }
 100.446 +
 100.447 +    void firstOut(Arc& arc, const Node& node) const {
 100.448 +      int s = node._id, t = _node_num - 1;
 100.449 +      if (s < t) {
 100.450 +        arc._id = (_eid(s, t) << 1) | 1;
 100.451 +      } else {
 100.452 +        --t;
 100.453 +        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
 100.454 +      }
 100.455 +    }
 100.456 +
 100.457 +    void nextOut(Arc& arc) const {
 100.458 +      int s, t;
 100.459 +      _stid(arc._id, s, t);
 100.460 +      --t;
 100.461 +      if (s < t) {
 100.462 +        arc._id = (_eid(s, t) << 1) | 1;
 100.463 +      } else {
 100.464 +        if (s == t) --t;
 100.465 +        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
 100.466 +      }
 100.467 +    }
 100.468 +
 100.469 +    void firstIn(Arc& arc, const Node& node) const {
 100.470 +      int s = _node_num - 1, t = node._id;
 100.471 +      if (s > t) {
 100.472 +        arc._id = (_eid(t, s) << 1);
 100.473 +      } else {
 100.474 +        --s;
 100.475 +        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
 100.476 +      }
 100.477 +    }
 100.478 +
 100.479 +    void nextIn(Arc& arc) const {
 100.480 +      int s, t;
 100.481 +      _stid(arc._id, s, t);
 100.482 +      --s;
 100.483 +      if (s > t) {
 100.484 +        arc._id = (_eid(t, s) << 1);
 100.485 +      } else {
 100.486 +        if (s == t) --s;
 100.487 +        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
 100.488 +      }
 100.489 +    }
 100.490 +
 100.491 +    void firstInc(Edge& edge, bool& dir, const Node& node) const {
 100.492 +      int u = node._id, v = _node_num - 1;
 100.493 +      if (u < v) {
 100.494 +        edge._id = _eid(u, v);
 100.495 +        dir = true;
 100.496 +      } else {
 100.497 +        --v;
 100.498 +        edge._id = (v != -1 ? _eid(v, u) : -1);
 100.499 +        dir = false;
 100.500 +      }
 100.501 +    }
 100.502 +
 100.503 +    void nextInc(Edge& edge, bool& dir) const {
 100.504 +      int u, v;
 100.505 +      if (dir) {
 100.506 +        _uvid(edge._id, u, v);
 100.507 +        --v;
 100.508 +        if (u < v) {
 100.509 +          edge._id = _eid(u, v);
 100.510 +        } else {
 100.511 +          --v;
 100.512 +          edge._id = (v != -1 ? _eid(v, u) : -1);
 100.513 +          dir = false;
 100.514 +        }
 100.515 +      } else {
 100.516 +        _uvid(edge._id, v, u);
 100.517 +        --v;
 100.518 +        edge._id = (v != -1 ? _eid(v, u) : -1);
 100.519 +      }
 100.520 +    }
 100.521 +
 100.522 +  };
 100.523 +
 100.524 +  typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
 100.525 +
 100.526 +  /// \ingroup graphs
 100.527 +  ///
 100.528 +  /// \brief An undirected full graph class.
 100.529 +  ///
 100.530 +  /// FullGraph is a simple and fast implmenetation of undirected full
 100.531 +  /// (complete) graphs. It contains an edge between every distinct pair
 100.532 +  /// of nodes, therefore the number of edges is <tt>n(n-1)/2</tt>.
 100.533 +  /// This class is completely static and it needs constant memory space.
 100.534 +  /// Thus you can neither add nor delete nodes or edges, however
 100.535 +  /// the structure can be resized using resize().
 100.536 +  ///
 100.537 +  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
 100.538 +  /// Most of its member functions and nested classes are documented
 100.539 +  /// only in the concept class.
 100.540 +  ///
 100.541 +  /// \note FullDigraph and FullGraph classes are very similar,
 100.542 +  /// but there are two differences. While FullDigraph
 100.543 +  /// conforms only to the \ref concepts::Digraph "Digraph" concept,
 100.544 +  /// this class conforms to the \ref concepts::Graph "Graph" concept,
 100.545 +  /// moreover this class does not contain a loop for each
 100.546 +  /// node as FullDigraph does.
 100.547 +  ///
 100.548 +  /// \sa FullDigraph
 100.549 +  class FullGraph : public ExtendedFullGraphBase {
 100.550 +    typedef ExtendedFullGraphBase Parent;
 100.551 +
 100.552 +  public:
 100.553 +
 100.554 +    /// \brief Default constructor.
 100.555 +    ///
 100.556 +    /// Default constructor. The number of nodes and edges will be zero.
 100.557 +    FullGraph() { construct(0); }
 100.558 +
 100.559 +    /// \brief Constructor
 100.560 +    ///
 100.561 +    /// Constructor.
 100.562 +    /// \param n The number of the nodes.
 100.563 +    FullGraph(int n) { construct(n); }
 100.564 +
 100.565 +    /// \brief Resizes the graph
 100.566 +    ///
 100.567 +    /// This function resizes the graph. It fully destroys and
 100.568 +    /// rebuilds the structure, therefore the maps of the graph will be
 100.569 +    /// reallocated automatically and the previous values will be lost.
 100.570 +    void resize(int n) {
 100.571 +      Parent::notifier(Arc()).clear();
 100.572 +      Parent::notifier(Edge()).clear();
 100.573 +      Parent::notifier(Node()).clear();
 100.574 +      construct(n);
 100.575 +      Parent::notifier(Node()).build();
 100.576 +      Parent::notifier(Edge()).build();
 100.577 +      Parent::notifier(Arc()).build();
 100.578 +    }
 100.579 +
 100.580 +    /// \brief Returns the node with the given index.
 100.581 +    ///
 100.582 +    /// Returns the node with the given index. Since this structure is 
 100.583 +    /// completely static, the nodes can be indexed with integers from
 100.584 +    /// the range <tt>[0..nodeNum()-1]</tt>.
 100.585 +    /// \sa index()
 100.586 +    Node operator()(int ix) const { return Parent::operator()(ix); }
 100.587 +
 100.588 +    /// \brief Returns the index of the given node.
 100.589 +    ///
 100.590 +    /// Returns the index of the given node. Since this structure is 
 100.591 +    /// completely static, the nodes can be indexed with integers from
 100.592 +    /// the range <tt>[0..nodeNum()-1]</tt>.
 100.593 +    /// \sa operator()()
 100.594 +    static int index(const Node& node) { return Parent::index(node); }
 100.595 +
 100.596 +    /// \brief Returns the arc connecting the given nodes.
 100.597 +    ///
 100.598 +    /// Returns the arc connecting the given nodes.
 100.599 +    Arc arc(Node s, Node t) const {
 100.600 +      return Parent::arc(s, t);
 100.601 +    }
 100.602 +
 100.603 +    /// \brief Returns the edge connecting the given nodes.
 100.604 +    ///
 100.605 +    /// Returns the edge connecting the given nodes.
 100.606 +    Edge edge(Node u, Node v) const {
 100.607 +      return Parent::edge(u, v);
 100.608 +    }
 100.609 +
 100.610 +    /// \brief Number of nodes.
 100.611 +    int nodeNum() const { return Parent::nodeNum(); }
 100.612 +    /// \brief Number of arcs.
 100.613 +    int arcNum() const { return Parent::arcNum(); }
 100.614 +    /// \brief Number of edges.
 100.615 +    int edgeNum() const { return Parent::edgeNum(); }
 100.616 +
 100.617 +  };
 100.618 +
 100.619 +
 100.620 +} //namespace lemon
 100.621 +
 100.622 +
 100.623 +#endif //LEMON_FULL_GRAPH_H
   101.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.2 +++ b/lemon/glpk.cc	Thu Nov 05 15:50:01 2009 +0100
   101.3 @@ -0,0 +1,1003 @@
   101.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   101.5 + *
   101.6 + * This file is a part of LEMON, a generic C++ optimization library.
   101.7 + *
   101.8 + * Copyright (C) 2003-2009
   101.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  101.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  101.11 + *
  101.12 + * Permission to use, modify and distribute this software is granted
  101.13 + * provided that this copyright notice appears in all copies. For
  101.14 + * precise terms see the accompanying LICENSE file.
  101.15 + *
  101.16 + * This software is provided "AS IS" with no warranty of any kind,
  101.17 + * express or implied, and with no claim as to its suitability for any
  101.18 + * purpose.
  101.19 + *
  101.20 + */
  101.21 +
  101.22 +///\file
  101.23 +///\brief Implementation of the LEMON GLPK LP and MIP solver interface.
  101.24 +
  101.25 +#include <lemon/glpk.h>
  101.26 +#include <glpk.h>
  101.27 +
  101.28 +#include <lemon/assert.h>
  101.29 +
  101.30 +namespace lemon {
  101.31 +
  101.32 +  // GlpkBase members
  101.33 +
  101.34 +  GlpkBase::GlpkBase() : LpBase() {
  101.35 +    lp = glp_create_prob();
  101.36 +    glp_create_index(lp);
  101.37 +    messageLevel(MESSAGE_NOTHING);
  101.38 +  }
  101.39 +
  101.40 +  GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() {
  101.41 +    lp = glp_create_prob();
  101.42 +    glp_copy_prob(lp, other.lp, GLP_ON);
  101.43 +    glp_create_index(lp);
  101.44 +    rows = other.rows;
  101.45 +    cols = other.cols;
  101.46 +    messageLevel(MESSAGE_NOTHING);
  101.47 +  }
  101.48 +
  101.49 +  GlpkBase::~GlpkBase() {
  101.50 +    glp_delete_prob(lp);
  101.51 +  }
  101.52 +
  101.53 +  int GlpkBase::_addCol() {
  101.54 +    int i = glp_add_cols(lp, 1);
  101.55 +    glp_set_col_bnds(lp, i, GLP_FR, 0.0, 0.0);
  101.56 +    return i;
  101.57 +  }
  101.58 +
  101.59 +  int GlpkBase::_addRow() {
  101.60 +    int i = glp_add_rows(lp, 1);
  101.61 +    glp_set_row_bnds(lp, i, GLP_FR, 0.0, 0.0);
  101.62 +    return i;
  101.63 +  }
  101.64 +
  101.65 +  int GlpkBase::_addRow(Value lo, ExprIterator b, 
  101.66 +                        ExprIterator e, Value up) {
  101.67 +    int i = glp_add_rows(lp, 1);
  101.68 +
  101.69 +    if (lo == -INF) {
  101.70 +      if (up == INF) {
  101.71 +        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
  101.72 +      } else {
  101.73 +        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
  101.74 +      }    
  101.75 +    } else {
  101.76 +      if (up == INF) {
  101.77 +        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
  101.78 +      } else if (lo != up) {        
  101.79 +        glp_set_row_bnds(lp, i, GLP_DB, lo, up);
  101.80 +      } else {
  101.81 +        glp_set_row_bnds(lp, i, GLP_FX, lo, up);
  101.82 +      }
  101.83 +    }
  101.84 +
  101.85 +    std::vector<int> indexes;
  101.86 +    std::vector<Value> values;
  101.87 +
  101.88 +    indexes.push_back(0);
  101.89 +    values.push_back(0);
  101.90 +
  101.91 +    for(ExprIterator it = b; it != e; ++it) {
  101.92 +      indexes.push_back(it->first);
  101.93 +      values.push_back(it->second);
  101.94 +    }
  101.95 +
  101.96 +    glp_set_mat_row(lp, i, values.size() - 1,
  101.97 +                    &indexes.front(), &values.front());
  101.98 +    return i;
  101.99 +  }
 101.100 +
 101.101 +  void GlpkBase::_eraseCol(int i) {
 101.102 +    int ca[2];
 101.103 +    ca[1] = i;
 101.104 +    glp_del_cols(lp, 1, ca);
 101.105 +  }
 101.106 +
 101.107 +  void GlpkBase::_eraseRow(int i) {
 101.108 +    int ra[2];
 101.109 +    ra[1] = i;
 101.110 +    glp_del_rows(lp, 1, ra);
 101.111 +  }
 101.112 +
 101.113 +  void GlpkBase::_eraseColId(int i) {
 101.114 +    cols.eraseIndex(i);
 101.115 +    cols.shiftIndices(i);
 101.116 +  }
 101.117 +
 101.118 +  void GlpkBase::_eraseRowId(int i) {
 101.119 +    rows.eraseIndex(i);
 101.120 +    rows.shiftIndices(i);
 101.121 +  }
 101.122 +
 101.123 +  void GlpkBase::_getColName(int c, std::string& name) const {
 101.124 +    const char *str = glp_get_col_name(lp, c);
 101.125 +    if (str) name = str;
 101.126 +    else name.clear();
 101.127 +  }
 101.128 +
 101.129 +  void GlpkBase::_setColName(int c, const std::string & name) {
 101.130 +    glp_set_col_name(lp, c, const_cast<char*>(name.c_str()));
 101.131 +
 101.132 +  }
 101.133 +
 101.134 +  int GlpkBase::_colByName(const std::string& name) const {
 101.135 +    int k = glp_find_col(lp, const_cast<char*>(name.c_str()));
 101.136 +    return k > 0 ? k : -1;
 101.137 +  }
 101.138 +
 101.139 +  void GlpkBase::_getRowName(int r, std::string& name) const {
 101.140 +    const char *str = glp_get_row_name(lp, r);
 101.141 +    if (str) name = str;
 101.142 +    else name.clear();
 101.143 +  }
 101.144 +
 101.145 +  void GlpkBase::_setRowName(int r, const std::string & name) {
 101.146 +    glp_set_row_name(lp, r, const_cast<char*>(name.c_str()));
 101.147 +
 101.148 +  }
 101.149 +
 101.150 +  int GlpkBase::_rowByName(const std::string& name) const {
 101.151 +    int k = glp_find_row(lp, const_cast<char*>(name.c_str()));
 101.152 +    return k > 0 ? k : -1;
 101.153 +  }
 101.154 +
 101.155 +  void GlpkBase::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
 101.156 +    std::vector<int> indexes;
 101.157 +    std::vector<Value> values;
 101.158 +
 101.159 +    indexes.push_back(0);
 101.160 +    values.push_back(0);
 101.161 +
 101.162 +    for(ExprIterator it = b; it != e; ++it) {
 101.163 +      indexes.push_back(it->first);
 101.164 +      values.push_back(it->second);
 101.165 +    }
 101.166 +
 101.167 +    glp_set_mat_row(lp, i, values.size() - 1,
 101.168 +                    &indexes.front(), &values.front());
 101.169 +  }
 101.170 +
 101.171 +  void GlpkBase::_getRowCoeffs(int ix, InsertIterator b) const {
 101.172 +    int length = glp_get_mat_row(lp, ix, 0, 0);
 101.173 +
 101.174 +    std::vector<int> indexes(length + 1);
 101.175 +    std::vector<Value> values(length + 1);
 101.176 +
 101.177 +    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
 101.178 +
 101.179 +    for (int i = 1; i <= length; ++i) {
 101.180 +      *b = std::make_pair(indexes[i], values[i]);
 101.181 +      ++b;
 101.182 +    }
 101.183 +  }
 101.184 +
 101.185 +  void GlpkBase::_setColCoeffs(int ix, ExprIterator b,
 101.186 +                                     ExprIterator e) {
 101.187 +
 101.188 +    std::vector<int> indexes;
 101.189 +    std::vector<Value> values;
 101.190 +
 101.191 +    indexes.push_back(0);
 101.192 +    values.push_back(0);
 101.193 +
 101.194 +    for(ExprIterator it = b; it != e; ++it) {
 101.195 +      indexes.push_back(it->first);
 101.196 +      values.push_back(it->second);
 101.197 +    }
 101.198 +
 101.199 +    glp_set_mat_col(lp, ix, values.size() - 1,
 101.200 +                    &indexes.front(), &values.front());
 101.201 +  }
 101.202 +
 101.203 +  void GlpkBase::_getColCoeffs(int ix, InsertIterator b) const {
 101.204 +    int length = glp_get_mat_col(lp, ix, 0, 0);
 101.205 +
 101.206 +    std::vector<int> indexes(length + 1);
 101.207 +    std::vector<Value> values(length + 1);
 101.208 +
 101.209 +    glp_get_mat_col(lp, ix, &indexes.front(), &values.front());
 101.210 +
 101.211 +    for (int i = 1; i  <= length; ++i) {
 101.212 +      *b = std::make_pair(indexes[i], values[i]);
 101.213 +      ++b;
 101.214 +    }
 101.215 +  }
 101.216 +
 101.217 +  void GlpkBase::_setCoeff(int ix, int jx, Value value) {
 101.218 +
 101.219 +    if (glp_get_num_cols(lp) < glp_get_num_rows(lp)) {
 101.220 +
 101.221 +      int length = glp_get_mat_row(lp, ix, 0, 0);
 101.222 +
 101.223 +      std::vector<int> indexes(length + 2);
 101.224 +      std::vector<Value> values(length + 2);
 101.225 +
 101.226 +      glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
 101.227 +
 101.228 +      //The following code does not suppose that the elements of the
 101.229 +      //array indexes are sorted
 101.230 +      bool found = false;
 101.231 +      for (int i = 1; i  <= length; ++i) {
 101.232 +        if (indexes[i] == jx) {
 101.233 +          found = true;
 101.234 +          values[i] = value;
 101.235 +          break;
 101.236 +        }
 101.237 +      }
 101.238 +      if (!found) {
 101.239 +        ++length;
 101.240 +        indexes[length] = jx;
 101.241 +        values[length] = value;
 101.242 +      }
 101.243 +
 101.244 +      glp_set_mat_row(lp, ix, length, &indexes.front(), &values.front());
 101.245 +
 101.246 +    } else {
 101.247 +
 101.248 +      int length = glp_get_mat_col(lp, jx, 0, 0);
 101.249 +
 101.250 +      std::vector<int> indexes(length + 2);
 101.251 +      std::vector<Value> values(length + 2);
 101.252 +
 101.253 +      glp_get_mat_col(lp, jx, &indexes.front(), &values.front());
 101.254 +
 101.255 +      //The following code does not suppose that the elements of the
 101.256 +      //array indexes are sorted
 101.257 +      bool found = false;
 101.258 +      for (int i = 1; i <= length; ++i) {
 101.259 +        if (indexes[i] == ix) {
 101.260 +          found = true;
 101.261 +          values[i] = value;
 101.262 +          break;
 101.263 +        }
 101.264 +      }
 101.265 +      if (!found) {
 101.266 +        ++length;
 101.267 +        indexes[length] = ix;
 101.268 +        values[length] = value;
 101.269 +      }
 101.270 +
 101.271 +      glp_set_mat_col(lp, jx, length, &indexes.front(), &values.front());
 101.272 +    }
 101.273 +
 101.274 +  }
 101.275 +
 101.276 +  GlpkBase::Value GlpkBase::_getCoeff(int ix, int jx) const {
 101.277 +
 101.278 +    int length = glp_get_mat_row(lp, ix, 0, 0);
 101.279 +
 101.280 +    std::vector<int> indexes(length + 1);
 101.281 +    std::vector<Value> values(length + 1);
 101.282 +
 101.283 +    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
 101.284 +
 101.285 +    for (int i = 1; i  <= length; ++i) {
 101.286 +      if (indexes[i] == jx) {
 101.287 +        return values[i];
 101.288 +      }
 101.289 +    }
 101.290 +
 101.291 +    return 0;
 101.292 +  }
 101.293 +
 101.294 +  void GlpkBase::_setColLowerBound(int i, Value lo) {
 101.295 +    LEMON_ASSERT(lo != INF, "Invalid bound");
 101.296 +
 101.297 +    int b = glp_get_col_type(lp, i);
 101.298 +    double up = glp_get_col_ub(lp, i);
 101.299 +    if (lo == -INF) {
 101.300 +      switch (b) {
 101.301 +      case GLP_FR:
 101.302 +      case GLP_LO:
 101.303 +        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
 101.304 +        break;
 101.305 +      case GLP_UP:
 101.306 +        break;
 101.307 +      case GLP_DB:
 101.308 +      case GLP_FX:
 101.309 +        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
 101.310 +        break;
 101.311 +      default:
 101.312 +        break;
 101.313 +      }
 101.314 +    } else {
 101.315 +      switch (b) {
 101.316 +      case GLP_FR:
 101.317 +      case GLP_LO:
 101.318 +        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
 101.319 +        break;
 101.320 +      case GLP_UP:
 101.321 +      case GLP_DB:
 101.322 +      case GLP_FX:
 101.323 +        if (lo == up)
 101.324 +          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
 101.325 +        else
 101.326 +          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
 101.327 +        break;
 101.328 +      default:
 101.329 +        break;
 101.330 +      }
 101.331 +    }
 101.332 +  }
 101.333 +
 101.334 +  GlpkBase::Value GlpkBase::_getColLowerBound(int i) const {
 101.335 +    int b = glp_get_col_type(lp, i);
 101.336 +    switch (b) {
 101.337 +    case GLP_LO:
 101.338 +    case GLP_DB:
 101.339 +    case GLP_FX:
 101.340 +      return glp_get_col_lb(lp, i);
 101.341 +    default:
 101.342 +      return -INF;
 101.343 +    }
 101.344 +  }
 101.345 +
 101.346 +  void GlpkBase::_setColUpperBound(int i, Value up) {
 101.347 +    LEMON_ASSERT(up != -INF, "Invalid bound");
 101.348 +
 101.349 +    int b = glp_get_col_type(lp, i);
 101.350 +    double lo = glp_get_col_lb(lp, i);
 101.351 +    if (up == INF) {
 101.352 +      switch (b) {
 101.353 +      case GLP_FR:
 101.354 +      case GLP_LO:
 101.355 +        break;
 101.356 +      case GLP_UP:
 101.357 +        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
 101.358 +        break;
 101.359 +      case GLP_DB:
 101.360 +      case GLP_FX:
 101.361 +        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
 101.362 +        break;
 101.363 +      default:
 101.364 +        break;
 101.365 +      }
 101.366 +    } else {
 101.367 +      switch (b) {
 101.368 +      case GLP_FR:
 101.369 +        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
 101.370 +        break;
 101.371 +      case GLP_UP:
 101.372 +        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
 101.373 +        break;
 101.374 +      case GLP_LO:
 101.375 +      case GLP_DB:
 101.376 +      case GLP_FX:
 101.377 +        if (lo == up)
 101.378 +          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
 101.379 +        else
 101.380 +          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
 101.381 +        break;
 101.382 +      default:
 101.383 +        break;
 101.384 +      }
 101.385 +    }
 101.386 +
 101.387 +  }
 101.388 +
 101.389 +  GlpkBase::Value GlpkBase::_getColUpperBound(int i) const {
 101.390 +    int b = glp_get_col_type(lp, i);
 101.391 +      switch (b) {
 101.392 +      case GLP_UP:
 101.393 +      case GLP_DB:
 101.394 +      case GLP_FX:
 101.395 +        return glp_get_col_ub(lp, i);
 101.396 +      default:
 101.397 +        return INF;
 101.398 +      }
 101.399 +  }
 101.400 +
 101.401 +  void GlpkBase::_setRowLowerBound(int i, Value lo) {
 101.402 +    LEMON_ASSERT(lo != INF, "Invalid bound");
 101.403 +
 101.404 +    int b = glp_get_row_type(lp, i);
 101.405 +    double up = glp_get_row_ub(lp, i);
 101.406 +    if (lo == -INF) {
 101.407 +      switch (b) {
 101.408 +      case GLP_FR:
 101.409 +      case GLP_LO:
 101.410 +        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
 101.411 +        break;
 101.412 +      case GLP_UP:
 101.413 +        break;
 101.414 +      case GLP_DB:
 101.415 +      case GLP_FX:
 101.416 +        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
 101.417 +        break;
 101.418 +      default:
 101.419 +        break;
 101.420 +      }
 101.421 +    } else {
 101.422 +      switch (b) {
 101.423 +      case GLP_FR:
 101.424 +      case GLP_LO:
 101.425 +        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
 101.426 +        break;
 101.427 +      case GLP_UP:
 101.428 +      case GLP_DB:
 101.429 +      case GLP_FX:
 101.430 +        if (lo == up)
 101.431 +          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
 101.432 +        else
 101.433 +          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
 101.434 +        break;
 101.435 +      default:
 101.436 +        break;
 101.437 +      }
 101.438 +    }
 101.439 +
 101.440 +  }
 101.441 +
 101.442 +  GlpkBase::Value GlpkBase::_getRowLowerBound(int i) const {
 101.443 +    int b = glp_get_row_type(lp, i);
 101.444 +    switch (b) {
 101.445 +    case GLP_LO:
 101.446 +    case GLP_DB:
 101.447 +    case GLP_FX:
 101.448 +      return glp_get_row_lb(lp, i);
 101.449 +    default:
 101.450 +      return -INF;
 101.451 +    }
 101.452 +  }
 101.453 +
 101.454 +  void GlpkBase::_setRowUpperBound(int i, Value up) {
 101.455 +    LEMON_ASSERT(up != -INF, "Invalid bound");
 101.456 +
 101.457 +    int b = glp_get_row_type(lp, i);
 101.458 +    double lo = glp_get_row_lb(lp, i);
 101.459 +    if (up == INF) {
 101.460 +      switch (b) {
 101.461 +      case GLP_FR:
 101.462 +      case GLP_LO:
 101.463 +        break;
 101.464 +      case GLP_UP:
 101.465 +        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
 101.466 +        break;
 101.467 +      case GLP_DB:
 101.468 +      case GLP_FX:
 101.469 +        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
 101.470 +        break;
 101.471 +      default:
 101.472 +        break;
 101.473 +      }
 101.474 +    } else {
 101.475 +      switch (b) {
 101.476 +      case GLP_FR:
 101.477 +        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
 101.478 +        break;
 101.479 +      case GLP_UP:
 101.480 +        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
 101.481 +        break;
 101.482 +      case GLP_LO:
 101.483 +      case GLP_DB:
 101.484 +      case GLP_FX:
 101.485 +        if (lo == up)
 101.486 +          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
 101.487 +        else
 101.488 +          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
 101.489 +        break;
 101.490 +      default:
 101.491 +        break;
 101.492 +      }
 101.493 +    }
 101.494 +  }
 101.495 +
 101.496 +  GlpkBase::Value GlpkBase::_getRowUpperBound(int i) const {
 101.497 +    int b = glp_get_row_type(lp, i);
 101.498 +    switch (b) {
 101.499 +    case GLP_UP:
 101.500 +    case GLP_DB:
 101.501 +    case GLP_FX:
 101.502 +      return glp_get_row_ub(lp, i);
 101.503 +    default:
 101.504 +      return INF;
 101.505 +    }
 101.506 +  }
 101.507 +
 101.508 +  void GlpkBase::_setObjCoeffs(ExprIterator b, ExprIterator e) {
 101.509 +    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
 101.510 +      glp_set_obj_coef(lp, i, 0.0);
 101.511 +    }
 101.512 +    for (ExprIterator it = b; it != e; ++it) {
 101.513 +      glp_set_obj_coef(lp, it->first, it->second);
 101.514 +    }
 101.515 +  }
 101.516 +
 101.517 +  void GlpkBase::_getObjCoeffs(InsertIterator b) const {
 101.518 +    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
 101.519 +      Value val = glp_get_obj_coef(lp, i);
 101.520 +      if (val != 0.0) {
 101.521 +        *b = std::make_pair(i, val);
 101.522 +        ++b;
 101.523 +      }
 101.524 +    }
 101.525 +  }
 101.526 +
 101.527 +  void GlpkBase::_setObjCoeff(int i, Value obj_coef) {
 101.528 +    //i = 0 means the constant term (shift)
 101.529 +    glp_set_obj_coef(lp, i, obj_coef);
 101.530 +  }
 101.531 +
 101.532 +  GlpkBase::Value GlpkBase::_getObjCoeff(int i) const {
 101.533 +    //i = 0 means the constant term (shift)
 101.534 +    return glp_get_obj_coef(lp, i);
 101.535 +  }
 101.536 +
 101.537 +  void GlpkBase::_setSense(GlpkBase::Sense sense) {
 101.538 +    switch (sense) {
 101.539 +    case MIN:
 101.540 +      glp_set_obj_dir(lp, GLP_MIN);
 101.541 +      break;
 101.542 +    case MAX:
 101.543 +      glp_set_obj_dir(lp, GLP_MAX);
 101.544 +      break;
 101.545 +    }
 101.546 +  }
 101.547 +
 101.548 +  GlpkBase::Sense GlpkBase::_getSense() const {
 101.549 +    switch(glp_get_obj_dir(lp)) {
 101.550 +    case GLP_MIN:
 101.551 +      return MIN;
 101.552 +    case GLP_MAX:
 101.553 +      return MAX;
 101.554 +    default:
 101.555 +      LEMON_ASSERT(false, "Wrong sense");
 101.556 +      return GlpkBase::Sense();
 101.557 +    }
 101.558 +  }
 101.559 +
 101.560 +  void GlpkBase::_clear() {
 101.561 +    glp_erase_prob(lp);
 101.562 +    rows.clear();
 101.563 +    cols.clear();
 101.564 +  }
 101.565 +
 101.566 +  void GlpkBase::freeEnv() {
 101.567 +    glp_free_env();
 101.568 +  }
 101.569 +
 101.570 +  void GlpkBase::_messageLevel(MessageLevel level) {
 101.571 +    switch (level) {
 101.572 +    case MESSAGE_NOTHING:
 101.573 +      _message_level = GLP_MSG_OFF;
 101.574 +      break;
 101.575 +    case MESSAGE_ERROR:
 101.576 +      _message_level = GLP_MSG_ERR;
 101.577 +      break;
 101.578 +    case MESSAGE_WARNING:
 101.579 +      _message_level = GLP_MSG_ERR;
 101.580 +      break;
 101.581 +    case MESSAGE_NORMAL:
 101.582 +      _message_level = GLP_MSG_ON;
 101.583 +      break;
 101.584 +    case MESSAGE_VERBOSE:
 101.585 +      _message_level = GLP_MSG_ALL;
 101.586 +      break;
 101.587 +    }
 101.588 +  }
 101.589 +
 101.590 +  GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
 101.591 +
 101.592 +  // GlpkLp members
 101.593 +
 101.594 +  GlpkLp::GlpkLp()
 101.595 +    : LpBase(), LpSolver(), GlpkBase() {
 101.596 +    presolver(false);
 101.597 +  }
 101.598 +
 101.599 +  GlpkLp::GlpkLp(const GlpkLp& other)
 101.600 +    : LpBase(other), LpSolver(other), GlpkBase(other) {
 101.601 +    presolver(false);
 101.602 +  }
 101.603 +
 101.604 +  GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
 101.605 +  GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); }
 101.606 +
 101.607 +  const char* GlpkLp::_solverName() const { return "GlpkLp"; }
 101.608 +
 101.609 +  void GlpkLp::_clear_temporals() {
 101.610 +    _primal_ray.clear();
 101.611 +    _dual_ray.clear();
 101.612 +  }
 101.613 +
 101.614 +  GlpkLp::SolveExitStatus GlpkLp::_solve() {
 101.615 +    return solvePrimal();
 101.616 +  }
 101.617 +
 101.618 +  GlpkLp::SolveExitStatus GlpkLp::solvePrimal() {
 101.619 +    _clear_temporals();
 101.620 +
 101.621 +    glp_smcp smcp;
 101.622 +    glp_init_smcp(&smcp);
 101.623 +
 101.624 +    smcp.msg_lev = _message_level;
 101.625 +    smcp.presolve = _presolve;
 101.626 +
 101.627 +    // If the basis is not valid we get an error return value.
 101.628 +    // In this case we can try to create a new basis.
 101.629 +    switch (glp_simplex(lp, &smcp)) {
 101.630 +    case 0:
 101.631 +      break;
 101.632 +    case GLP_EBADB:
 101.633 +    case GLP_ESING:
 101.634 +    case GLP_ECOND:
 101.635 +      glp_term_out(false);
 101.636 +      glp_adv_basis(lp, 0);
 101.637 +      glp_term_out(true);
 101.638 +      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
 101.639 +      break;
 101.640 +    default:
 101.641 +      return UNSOLVED;
 101.642 +    }
 101.643 +
 101.644 +    return SOLVED;
 101.645 +  }
 101.646 +
 101.647 +  GlpkLp::SolveExitStatus GlpkLp::solveDual() {
 101.648 +    _clear_temporals();
 101.649 +
 101.650 +    glp_smcp smcp;
 101.651 +    glp_init_smcp(&smcp);
 101.652 +
 101.653 +    smcp.msg_lev = _message_level;
 101.654 +    smcp.meth = GLP_DUAL;
 101.655 +    smcp.presolve = _presolve;
 101.656 +
 101.657 +    // If the basis is not valid we get an error return value.
 101.658 +    // In this case we can try to create a new basis.
 101.659 +    switch (glp_simplex(lp, &smcp)) {
 101.660 +    case 0:
 101.661 +      break;
 101.662 +    case GLP_EBADB:
 101.663 +    case GLP_ESING:
 101.664 +    case GLP_ECOND:
 101.665 +      glp_term_out(false);
 101.666 +      glp_adv_basis(lp, 0);
 101.667 +      glp_term_out(true);
 101.668 +      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
 101.669 +      break;
 101.670 +    default:
 101.671 +      return UNSOLVED;
 101.672 +    }
 101.673 +    return SOLVED;
 101.674 +  }
 101.675 +
 101.676 +  GlpkLp::Value GlpkLp::_getPrimal(int i) const {
 101.677 +    return glp_get_col_prim(lp, i);
 101.678 +  }
 101.679 +
 101.680 +  GlpkLp::Value GlpkLp::_getDual(int i) const {
 101.681 +    return glp_get_row_dual(lp, i);
 101.682 +  }
 101.683 +
 101.684 +  GlpkLp::Value GlpkLp::_getPrimalValue() const {
 101.685 +    return glp_get_obj_val(lp);
 101.686 +  }
 101.687 +
 101.688 +  GlpkLp::VarStatus GlpkLp::_getColStatus(int i) const {
 101.689 +    switch (glp_get_col_stat(lp, i)) {
 101.690 +    case GLP_BS:
 101.691 +      return BASIC;
 101.692 +    case GLP_UP:
 101.693 +      return UPPER;
 101.694 +    case GLP_LO:
 101.695 +      return LOWER;
 101.696 +    case GLP_NF:
 101.697 +      return FREE;
 101.698 +    case GLP_NS:
 101.699 +      return FIXED;
 101.700 +    default:
 101.701 +      LEMON_ASSERT(false, "Wrong column status");
 101.702 +      return GlpkLp::VarStatus();
 101.703 +    }
 101.704 +  }
 101.705 +
 101.706 +  GlpkLp::VarStatus GlpkLp::_getRowStatus(int i) const {
 101.707 +    switch (glp_get_row_stat(lp, i)) {
 101.708 +    case GLP_BS:
 101.709 +      return BASIC;
 101.710 +    case GLP_UP:
 101.711 +      return UPPER;
 101.712 +    case GLP_LO:
 101.713 +      return LOWER;
 101.714 +    case GLP_NF:
 101.715 +      return FREE;
 101.716 +    case GLP_NS:
 101.717 +      return FIXED;
 101.718 +    default:
 101.719 +      LEMON_ASSERT(false, "Wrong row status");
 101.720 +      return GlpkLp::VarStatus();
 101.721 +    }
 101.722 +  }
 101.723 +
 101.724 +  GlpkLp::Value GlpkLp::_getPrimalRay(int i) const {
 101.725 +    if (_primal_ray.empty()) {
 101.726 +      int row_num = glp_get_num_rows(lp);
 101.727 +      int col_num = glp_get_num_cols(lp);
 101.728 +
 101.729 +      _primal_ray.resize(col_num + 1, 0.0);
 101.730 +
 101.731 +      int index = glp_get_unbnd_ray(lp);
 101.732 +      if (index != 0) {
 101.733 +        // The primal ray is found in primal simplex second phase
 101.734 +        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
 101.735 +                      glp_get_col_stat(lp, index - row_num)) != GLP_BS,
 101.736 +                     "Wrong primal ray");
 101.737 +
 101.738 +        bool negate = glp_get_obj_dir(lp) == GLP_MAX;
 101.739 +
 101.740 +        if (index > row_num) {
 101.741 +          _primal_ray[index - row_num] = 1.0;
 101.742 +          if (glp_get_col_dual(lp, index - row_num) > 0) {
 101.743 +            negate = !negate;
 101.744 +          }
 101.745 +        } else {
 101.746 +          if (glp_get_row_dual(lp, index) > 0) {
 101.747 +            negate = !negate;
 101.748 +          }
 101.749 +        }
 101.750 +
 101.751 +        std::vector<int> ray_indexes(row_num + 1);
 101.752 +        std::vector<Value> ray_values(row_num + 1);
 101.753 +        int ray_length = glp_eval_tab_col(lp, index, &ray_indexes.front(),
 101.754 +                                          &ray_values.front());
 101.755 +
 101.756 +        for (int i = 1; i <= ray_length; ++i) {
 101.757 +          if (ray_indexes[i] > row_num) {
 101.758 +            _primal_ray[ray_indexes[i] - row_num] = ray_values[i];
 101.759 +          }
 101.760 +        }
 101.761 +
 101.762 +        if (negate) {
 101.763 +          for (int i = 1; i <= col_num; ++i) {
 101.764 +            _primal_ray[i] = - _primal_ray[i];
 101.765 +          }
 101.766 +        }
 101.767 +      } else {
 101.768 +        for (int i = 1; i <= col_num; ++i) {
 101.769 +          _primal_ray[i] = glp_get_col_prim(lp, i);
 101.770 +        }
 101.771 +      }
 101.772 +    }
 101.773 +    return _primal_ray[i];
 101.774 +  }
 101.775 +
 101.776 +  GlpkLp::Value GlpkLp::_getDualRay(int i) const {
 101.777 +    if (_dual_ray.empty()) {
 101.778 +      int row_num = glp_get_num_rows(lp);
 101.779 +
 101.780 +      _dual_ray.resize(row_num + 1, 0.0);
 101.781 +
 101.782 +      int index = glp_get_unbnd_ray(lp);
 101.783 +      if (index != 0) {
 101.784 +        // The dual ray is found in dual simplex second phase
 101.785 +        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
 101.786 +                      glp_get_col_stat(lp, index - row_num)) == GLP_BS,
 101.787 +
 101.788 +                     "Wrong dual ray");
 101.789 +
 101.790 +        int idx;
 101.791 +        bool negate = false;
 101.792 +
 101.793 +        if (index > row_num) {
 101.794 +          idx = glp_get_col_bind(lp, index - row_num);
 101.795 +          if (glp_get_col_prim(lp, index - row_num) >
 101.796 +              glp_get_col_ub(lp, index - row_num)) {
 101.797 +            negate = true;
 101.798 +          }
 101.799 +        } else {
 101.800 +          idx = glp_get_row_bind(lp, index);
 101.801 +          if (glp_get_row_prim(lp, index) > glp_get_row_ub(lp, index)) {
 101.802 +            negate = true;
 101.803 +          }
 101.804 +        }
 101.805 +
 101.806 +        _dual_ray[idx] = negate ?  - 1.0 : 1.0;
 101.807 +
 101.808 +        glp_btran(lp, &_dual_ray.front());
 101.809 +      } else {
 101.810 +        double eps = 1e-7;
 101.811 +        // The dual ray is found in primal simplex first phase
 101.812 +        // We assume that the glpk minimizes the slack to get feasible solution
 101.813 +        for (int i = 1; i <= row_num; ++i) {
 101.814 +          int index = glp_get_bhead(lp, i);
 101.815 +          if (index <= row_num) {
 101.816 +            double res = glp_get_row_prim(lp, index);
 101.817 +            if (res > glp_get_row_ub(lp, index) + eps) {
 101.818 +              _dual_ray[i] = -1;
 101.819 +            } else if (res < glp_get_row_lb(lp, index) - eps) {
 101.820 +              _dual_ray[i] = 1;
 101.821 +            } else {
 101.822 +              _dual_ray[i] = 0;
 101.823 +            }
 101.824 +            _dual_ray[i] *= glp_get_rii(lp, index);
 101.825 +          } else {
 101.826 +            double res = glp_get_col_prim(lp, index - row_num);
 101.827 +            if (res > glp_get_col_ub(lp, index - row_num) + eps) {
 101.828 +              _dual_ray[i] = -1;
 101.829 +            } else if (res < glp_get_col_lb(lp, index - row_num) - eps) {
 101.830 +              _dual_ray[i] = 1;
 101.831 +            } else {
 101.832 +              _dual_ray[i] = 0;
 101.833 +            }
 101.834 +            _dual_ray[i] /= glp_get_sjj(lp, index - row_num);
 101.835 +          }
 101.836 +        }
 101.837 +
 101.838 +        glp_btran(lp, &_dual_ray.front());
 101.839 +
 101.840 +        for (int i = 1; i <= row_num; ++i) {
 101.841 +          _dual_ray[i] /= glp_get_rii(lp, i);
 101.842 +        }
 101.843 +      }
 101.844 +    }
 101.845 +    return _dual_ray[i];
 101.846 +  }
 101.847 +
 101.848 +  GlpkLp::ProblemType GlpkLp::_getPrimalType() const {
 101.849 +    if (glp_get_status(lp) == GLP_OPT)
 101.850 +      return OPTIMAL;
 101.851 +    switch (glp_get_prim_stat(lp)) {
 101.852 +    case GLP_UNDEF:
 101.853 +      return UNDEFINED;
 101.854 +    case GLP_FEAS:
 101.855 +    case GLP_INFEAS:
 101.856 +      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
 101.857 +        return UNBOUNDED;
 101.858 +      } else {
 101.859 +        return UNDEFINED;
 101.860 +      }
 101.861 +    case GLP_NOFEAS:
 101.862 +      return INFEASIBLE;
 101.863 +    default:
 101.864 +      LEMON_ASSERT(false, "Wrong primal type");
 101.865 +      return  GlpkLp::ProblemType();
 101.866 +    }
 101.867 +  }
 101.868 +
 101.869 +  GlpkLp::ProblemType GlpkLp::_getDualType() const {
 101.870 +    if (glp_get_status(lp) == GLP_OPT)
 101.871 +      return OPTIMAL;
 101.872 +    switch (glp_get_dual_stat(lp)) {
 101.873 +    case GLP_UNDEF:
 101.874 +      return UNDEFINED;
 101.875 +    case GLP_FEAS:
 101.876 +    case GLP_INFEAS:
 101.877 +      if (glp_get_prim_stat(lp) == GLP_NOFEAS) {
 101.878 +        return UNBOUNDED;
 101.879 +      } else {
 101.880 +        return UNDEFINED;
 101.881 +      }
 101.882 +    case GLP_NOFEAS:
 101.883 +      return INFEASIBLE;
 101.884 +    default:
 101.885 +      LEMON_ASSERT(false, "Wrong primal type");
 101.886 +      return  GlpkLp::ProblemType();
 101.887 +    }
 101.888 +  }
 101.889 +
 101.890 +  void GlpkLp::presolver(bool presolve) {
 101.891 +    _presolve = presolve;
 101.892 +  }
 101.893 +
 101.894 +  // GlpkMip members
 101.895 +
 101.896 +  GlpkMip::GlpkMip()
 101.897 +    : LpBase(), MipSolver(), GlpkBase() {
 101.898 +  }
 101.899 +
 101.900 +  GlpkMip::GlpkMip(const GlpkMip& other)
 101.901 +    : LpBase(), MipSolver(), GlpkBase(other) {
 101.902 +  }
 101.903 +
 101.904 +  void GlpkMip::_setColType(int i, GlpkMip::ColTypes col_type) {
 101.905 +    switch (col_type) {
 101.906 +    case INTEGER:
 101.907 +      glp_set_col_kind(lp, i, GLP_IV);
 101.908 +      break;
 101.909 +    case REAL:
 101.910 +      glp_set_col_kind(lp, i, GLP_CV);
 101.911 +      break;
 101.912 +    }
 101.913 +  }
 101.914 +
 101.915 +  GlpkMip::ColTypes GlpkMip::_getColType(int i) const {
 101.916 +    switch (glp_get_col_kind(lp, i)) {
 101.917 +    case GLP_IV:
 101.918 +    case GLP_BV:
 101.919 +      return INTEGER;
 101.920 +    default:
 101.921 +      return REAL;
 101.922 +    }
 101.923 +
 101.924 +  }
 101.925 +
 101.926 +  GlpkMip::SolveExitStatus GlpkMip::_solve() {
 101.927 +    glp_smcp smcp;
 101.928 +    glp_init_smcp(&smcp);
 101.929 +
 101.930 +    smcp.msg_lev = _message_level;
 101.931 +    smcp.meth = GLP_DUAL;
 101.932 +
 101.933 +    // If the basis is not valid we get an error return value.
 101.934 +    // In this case we can try to create a new basis.
 101.935 +    switch (glp_simplex(lp, &smcp)) {
 101.936 +    case 0:
 101.937 +      break;
 101.938 +    case GLP_EBADB:
 101.939 +    case GLP_ESING:
 101.940 +    case GLP_ECOND:
 101.941 +      glp_term_out(false);
 101.942 +      glp_adv_basis(lp, 0);
 101.943 +      glp_term_out(true);
 101.944 +      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
 101.945 +      break;
 101.946 +    default:
 101.947 +      return UNSOLVED;
 101.948 +    }
 101.949 +
 101.950 +    if (glp_get_status(lp) != GLP_OPT) return SOLVED;
 101.951 +
 101.952 +    glp_iocp iocp;
 101.953 +    glp_init_iocp(&iocp);
 101.954 +
 101.955 +    iocp.msg_lev = _message_level;
 101.956 +
 101.957 +    if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
 101.958 +    return SOLVED;
 101.959 +  }
 101.960 +
 101.961 +
 101.962 +  GlpkMip::ProblemType GlpkMip::_getType() const {
 101.963 +    switch (glp_get_status(lp)) {
 101.964 +    case GLP_OPT:
 101.965 +      switch (glp_mip_status(lp)) {
 101.966 +      case GLP_UNDEF:
 101.967 +        return UNDEFINED;
 101.968 +      case GLP_NOFEAS:
 101.969 +        return INFEASIBLE;
 101.970 +      case GLP_FEAS:
 101.971 +        return FEASIBLE;
 101.972 +      case GLP_OPT:
 101.973 +        return OPTIMAL;
 101.974 +      default:
 101.975 +        LEMON_ASSERT(false, "Wrong problem type.");
 101.976 +        return GlpkMip::ProblemType();
 101.977 +      }
 101.978 +    case GLP_NOFEAS:
 101.979 +      return INFEASIBLE;
 101.980 +    case GLP_INFEAS:
 101.981 +    case GLP_FEAS:
 101.982 +      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
 101.983 +        return UNBOUNDED;
 101.984 +      } else {
 101.985 +        return UNDEFINED;
 101.986 +      }
 101.987 +    default:
 101.988 +      LEMON_ASSERT(false, "Wrong problem type.");
 101.989 +      return GlpkMip::ProblemType();
 101.990 +    }
 101.991 +  }
 101.992 +
 101.993 +  GlpkMip::Value GlpkMip::_getSol(int i) const {
 101.994 +    return glp_mip_col_val(lp, i);
 101.995 +  }
 101.996 +
 101.997 +  GlpkMip::Value GlpkMip::_getSolValue() const {
 101.998 +    return glp_mip_obj_val(lp);
 101.999 +  }
101.1000 +
101.1001 +  GlpkMip* GlpkMip::newSolver() const { return new GlpkMip; }
101.1002 +  GlpkMip* GlpkMip::cloneSolver() const {return new GlpkMip(*this); }
101.1003 +
101.1004 +  const char* GlpkMip::_solverName() const { return "GlpkMip"; }
101.1005 +
101.1006 +} //END OF NAMESPACE LEMON
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/lemon/glpk.h	Thu Nov 05 15:50:01 2009 +0100
   102.3 @@ -0,0 +1,237 @@
   102.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   102.5 + *
   102.6 + * This file is a part of LEMON, a generic C++ optimization library.
   102.7 + *
   102.8 + * Copyright (C) 2003-2008
   102.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  102.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  102.11 + *
  102.12 + * Permission to use, modify and distribute this software is granted
  102.13 + * provided that this copyright notice appears in all copies. For
  102.14 + * precise terms see the accompanying LICENSE file.
  102.15 + *
  102.16 + * This software is provided "AS IS" with no warranty of any kind,
  102.17 + * express or implied, and with no claim as to its suitability for any
  102.18 + * purpose.
  102.19 + *
  102.20 + */
  102.21 +
  102.22 +#ifndef LEMON_GLPK_H
  102.23 +#define LEMON_GLPK_H
  102.24 +
  102.25 +///\file
  102.26 +///\brief Header of the LEMON-GLPK lp solver interface.
  102.27 +///\ingroup lp_group
  102.28 +
  102.29 +#include <lemon/lp_base.h>
  102.30 +
  102.31 +// forward declaration
  102.32 +#if !defined _GLP_PROB && !defined GLP_PROB
  102.33 +#define _GLP_PROB
  102.34 +#define GLP_PROB
  102.35 +typedef struct { double _opaque_prob; } glp_prob;
  102.36 +/* LP/MIP problem object */
  102.37 +#endif
  102.38 +
  102.39 +namespace lemon {
  102.40 +
  102.41 +
  102.42 +  /// \brief Base interface for the GLPK LP and MIP solver
  102.43 +  ///
  102.44 +  /// This class implements the common interface of the GLPK LP and MIP solver.
  102.45 +  /// \ingroup lp_group
  102.46 +  class GlpkBase : virtual public LpBase {
  102.47 +  protected:
  102.48 +
  102.49 +    typedef glp_prob LPX;
  102.50 +    glp_prob* lp;
  102.51 +
  102.52 +    GlpkBase();
  102.53 +    GlpkBase(const GlpkBase&);
  102.54 +    virtual ~GlpkBase();
  102.55 +
  102.56 +  protected:
  102.57 +
  102.58 +    virtual int _addCol();
  102.59 +    virtual int _addRow();
  102.60 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
  102.61 +
  102.62 +    virtual void _eraseCol(int i);
  102.63 +    virtual void _eraseRow(int i);
  102.64 +
  102.65 +    virtual void _eraseColId(int i);
  102.66 +    virtual void _eraseRowId(int i);
  102.67 +
  102.68 +    virtual void _getColName(int col, std::string& name) const;
  102.69 +    virtual void _setColName(int col, const std::string& name);
  102.70 +    virtual int _colByName(const std::string& name) const;
  102.71 +
  102.72 +    virtual void _getRowName(int row, std::string& name) const;
  102.73 +    virtual void _setRowName(int row, const std::string& name);
  102.74 +    virtual int _rowByName(const std::string& name) const;
  102.75 +
  102.76 +    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
  102.77 +    virtual void _getRowCoeffs(int i, InsertIterator b) const;
  102.78 +
  102.79 +    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
  102.80 +    virtual void _getColCoeffs(int i, InsertIterator b) const;
  102.81 +
  102.82 +    virtual void _setCoeff(int row, int col, Value value);
  102.83 +    virtual Value _getCoeff(int row, int col) const;
  102.84 +
  102.85 +    virtual void _setColLowerBound(int i, Value value);
  102.86 +    virtual Value _getColLowerBound(int i) const;
  102.87 +
  102.88 +    virtual void _setColUpperBound(int i, Value value);
  102.89 +    virtual Value _getColUpperBound(int i) const;
  102.90 +
  102.91 +    virtual void _setRowLowerBound(int i, Value value);
  102.92 +    virtual Value _getRowLowerBound(int i) const;
  102.93 +
  102.94 +    virtual void _setRowUpperBound(int i, Value value);
  102.95 +    virtual Value _getRowUpperBound(int i) const;
  102.96 +
  102.97 +    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
  102.98 +    virtual void _getObjCoeffs(InsertIterator b) const;
  102.99 +
 102.100 +    virtual void _setObjCoeff(int i, Value obj_coef);
 102.101 +    virtual Value _getObjCoeff(int i) const;
 102.102 +
 102.103 +    virtual void _setSense(Sense);
 102.104 +    virtual Sense _getSense() const;
 102.105 +
 102.106 +    virtual void _clear();
 102.107 +
 102.108 +    virtual void _messageLevel(MessageLevel level);
 102.109 +
 102.110 +  private:
 102.111 +
 102.112 +    static void freeEnv();
 102.113 +
 102.114 +    struct FreeEnvHelper {
 102.115 +      ~FreeEnvHelper() {
 102.116 +        freeEnv();
 102.117 +      }
 102.118 +    };
 102.119 +    
 102.120 +    static FreeEnvHelper freeEnvHelper;
 102.121 +
 102.122 +  protected:
 102.123 +    
 102.124 +    int _message_level;
 102.125 +    
 102.126 +  public:
 102.127 +
 102.128 +    ///Pointer to the underlying GLPK data structure.
 102.129 +    LPX *lpx() {return lp;}
 102.130 +    ///Const pointer to the underlying GLPK data structure.
 102.131 +    const LPX *lpx() const {return lp;}
 102.132 +
 102.133 +    ///Returns the constraint identifier understood by GLPK.
 102.134 +    int lpxRow(Row r) const { return rows(id(r)); }
 102.135 +
 102.136 +    ///Returns the variable identifier understood by GLPK.
 102.137 +    int lpxCol(Col c) const { return cols(id(c)); }
 102.138 +
 102.139 +  };
 102.140 +
 102.141 +  /// \brief Interface for the GLPK LP solver
 102.142 +  ///
 102.143 +  /// This class implements an interface for the GLPK LP solver.
 102.144 +  ///\ingroup lp_group
 102.145 +  class GlpkLp : public LpSolver, public GlpkBase {
 102.146 +  public:
 102.147 +
 102.148 +    ///\e
 102.149 +    GlpkLp();
 102.150 +    ///\e
 102.151 +    GlpkLp(const GlpkLp&);
 102.152 +
 102.153 +    ///\e
 102.154 +    virtual GlpkLp* cloneSolver() const;
 102.155 +    ///\e
 102.156 +    virtual GlpkLp* newSolver() const;
 102.157 +
 102.158 +  private:
 102.159 +
 102.160 +    mutable std::vector<double> _primal_ray;
 102.161 +    mutable std::vector<double> _dual_ray;
 102.162 +
 102.163 +    void _clear_temporals();
 102.164 +
 102.165 +  protected:
 102.166 +
 102.167 +    virtual const char* _solverName() const;
 102.168 +
 102.169 +    virtual SolveExitStatus _solve();
 102.170 +    virtual Value _getPrimal(int i) const;
 102.171 +    virtual Value _getDual(int i) const;
 102.172 +
 102.173 +    virtual Value _getPrimalValue() const;
 102.174 +
 102.175 +    virtual VarStatus _getColStatus(int i) const;
 102.176 +    virtual VarStatus _getRowStatus(int i) const;
 102.177 +
 102.178 +    virtual Value _getPrimalRay(int i) const;
 102.179 +    virtual Value _getDualRay(int i) const;
 102.180 +
 102.181 +    virtual ProblemType _getPrimalType() const;
 102.182 +    virtual ProblemType _getDualType() const;
 102.183 +
 102.184 +  public:
 102.185 +
 102.186 +    ///Solve with primal simplex
 102.187 +    SolveExitStatus solvePrimal();
 102.188 +
 102.189 +    ///Solve with dual simplex
 102.190 +    SolveExitStatus solveDual();
 102.191 +
 102.192 +  private:
 102.193 +
 102.194 +    bool _presolve;
 102.195 +
 102.196 +  public:
 102.197 +
 102.198 +    ///Turns on or off the presolver
 102.199 +
 102.200 +    ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
 102.201 +    ///
 102.202 +    ///The presolver is off by default.
 102.203 +    void presolver(bool presolve);
 102.204 +
 102.205 +  };
 102.206 +
 102.207 +  /// \brief Interface for the GLPK MIP solver
 102.208 +  ///
 102.209 +  /// This class implements an interface for the GLPK MIP solver.
 102.210 +  ///\ingroup lp_group
 102.211 +  class GlpkMip : public MipSolver, public GlpkBase {
 102.212 +  public:
 102.213 +
 102.214 +    ///\e
 102.215 +    GlpkMip();
 102.216 +    ///\e
 102.217 +    GlpkMip(const GlpkMip&);
 102.218 +
 102.219 +    virtual GlpkMip* cloneSolver() const;
 102.220 +    virtual GlpkMip* newSolver() const;
 102.221 +
 102.222 +  protected:
 102.223 +
 102.224 +    virtual const char* _solverName() const;
 102.225 +
 102.226 +    virtual ColTypes _getColType(int col) const;
 102.227 +    virtual void _setColType(int col, ColTypes col_type);
 102.228 +
 102.229 +    virtual SolveExitStatus _solve();
 102.230 +    virtual ProblemType _getType() const;
 102.231 +    virtual Value _getSol(int i) const;
 102.232 +    virtual Value _getSolValue() const;
 102.233 +
 102.234 +  };
 102.235 +
 102.236 +
 102.237 +} //END OF NAMESPACE LEMON
 102.238 +
 102.239 +#endif //LEMON_GLPK_H
 102.240 +
   103.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.2 +++ b/lemon/gomory_hu.h	Thu Nov 05 15:50:01 2009 +0100
   103.3 @@ -0,0 +1,570 @@
   103.4 +/* -*- C++ -*-
   103.5 + *
   103.6 + * This file is a part of LEMON, a generic C++ optimization library
   103.7 + *
   103.8 + * Copyright (C) 2003-2008
   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_GOMORY_HU_TREE_H
  103.23 +#define LEMON_GOMORY_HU_TREE_H
  103.24 +
  103.25 +#include <limits>
  103.26 +
  103.27 +#include <lemon/core.h>
  103.28 +#include <lemon/preflow.h>
  103.29 +#include <lemon/concept_check.h>
  103.30 +#include <lemon/concepts/maps.h>
  103.31 +
  103.32 +/// \ingroup min_cut
  103.33 +/// \file 
  103.34 +/// \brief Gomory-Hu cut tree in graphs.
  103.35 +
  103.36 +namespace lemon {
  103.37 +
  103.38 +  /// \ingroup min_cut
  103.39 +  ///
  103.40 +  /// \brief Gomory-Hu cut tree algorithm
  103.41 +  ///
  103.42 +  /// The Gomory-Hu tree is a tree on the node set of a given graph, but it
  103.43 +  /// may contain edges which are not in the original graph. It has the
  103.44 +  /// property that the minimum capacity edge of the path between two nodes 
  103.45 +  /// in this tree has the same weight as the minimum cut in the graph
  103.46 +  /// between these nodes. Moreover the components obtained by removing
  103.47 +  /// this edge from the tree determine the corresponding minimum cut.
  103.48 +  /// Therefore once this tree is computed, the minimum cut between any pair
  103.49 +  /// of nodes can easily be obtained.
  103.50 +  /// 
  103.51 +  /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
  103.52 +  /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{e})\f$ overall
  103.53 +  /// time complexity. It calculates a rooted Gomory-Hu tree.
  103.54 +  /// The structure of the tree and the edge weights can be
  103.55 +  /// obtained using \c predNode(), \c predValue() and \c rootDist().
  103.56 +  /// The functions \c minCutMap() and \c minCutValue() calculate
  103.57 +  /// the minimum cut and the minimum cut value between any two nodes
  103.58 +  /// in the graph. You can also list (iterate on) the nodes and the
  103.59 +  /// edges of the cuts using \c MinCutNodeIt and \c MinCutEdgeIt.
  103.60 +  ///
  103.61 +  /// \tparam GR The type of the undirected graph the algorithm runs on.
  103.62 +  /// \tparam CAP The type of the edge map containing the capacities.
  103.63 +  /// The default map type is \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
  103.64 +#ifdef DOXYGEN
  103.65 +  template <typename GR,
  103.66 +	    typename CAP>
  103.67 +#else
  103.68 +  template <typename GR,
  103.69 +	    typename CAP = typename GR::template EdgeMap<int> >
  103.70 +#endif
  103.71 +  class GomoryHu {
  103.72 +  public:
  103.73 +
  103.74 +    /// The graph type of the algorithm
  103.75 +    typedef GR Graph;
  103.76 +    /// The capacity map type of the algorithm
  103.77 +    typedef CAP Capacity;
  103.78 +    /// The value type of capacities
  103.79 +    typedef typename Capacity::Value Value;
  103.80 +    
  103.81 +  private:
  103.82 +
  103.83 +    TEMPLATE_GRAPH_TYPEDEFS(Graph);
  103.84 +
  103.85 +    const Graph& _graph;
  103.86 +    const Capacity& _capacity;
  103.87 +
  103.88 +    Node _root;
  103.89 +    typename Graph::template NodeMap<Node>* _pred;
  103.90 +    typename Graph::template NodeMap<Value>* _weight;
  103.91 +    typename Graph::template NodeMap<int>* _order;
  103.92 +
  103.93 +    void createStructures() {
  103.94 +      if (!_pred) {
  103.95 +	_pred = new typename Graph::template NodeMap<Node>(_graph);
  103.96 +      }
  103.97 +      if (!_weight) {
  103.98 +	_weight = new typename Graph::template NodeMap<Value>(_graph);
  103.99 +      }
 103.100 +      if (!_order) {
 103.101 +	_order = new typename Graph::template NodeMap<int>(_graph);
 103.102 +      }
 103.103 +    }
 103.104 +
 103.105 +    void destroyStructures() {
 103.106 +      if (_pred) {
 103.107 +	delete _pred;
 103.108 +      }
 103.109 +      if (_weight) {
 103.110 +	delete _weight;
 103.111 +      }
 103.112 +      if (_order) {
 103.113 +	delete _order;
 103.114 +      }
 103.115 +    }
 103.116 +  
 103.117 +  public:
 103.118 +
 103.119 +    /// \brief Constructor
 103.120 +    ///
 103.121 +    /// Constructor.
 103.122 +    /// \param graph The undirected graph the algorithm runs on.
 103.123 +    /// \param capacity The edge capacity map.
 103.124 +    GomoryHu(const Graph& graph, const Capacity& capacity) 
 103.125 +      : _graph(graph), _capacity(capacity),
 103.126 +	_pred(0), _weight(0), _order(0) 
 103.127 +    {
 103.128 +      checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
 103.129 +    }
 103.130 +
 103.131 +
 103.132 +    /// \brief Destructor
 103.133 +    ///
 103.134 +    /// Destructor.
 103.135 +    ~GomoryHu() {
 103.136 +      destroyStructures();
 103.137 +    }
 103.138 +
 103.139 +  private:
 103.140 +  
 103.141 +    // Initialize the internal data structures
 103.142 +    void init() {
 103.143 +      createStructures();
 103.144 +
 103.145 +      _root = NodeIt(_graph);
 103.146 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 103.147 +        (*_pred)[n] = _root;
 103.148 +        (*_order)[n] = -1;
 103.149 +      }
 103.150 +      (*_pred)[_root] = INVALID;
 103.151 +      (*_weight)[_root] = std::numeric_limits<Value>::max(); 
 103.152 +    }
 103.153 +
 103.154 +
 103.155 +    // Start the algorithm
 103.156 +    void start() {
 103.157 +      Preflow<Graph, Capacity> fa(_graph, _capacity, _root, INVALID);
 103.158 +
 103.159 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 103.160 +	if (n == _root) continue;
 103.161 +
 103.162 +	Node pn = (*_pred)[n];
 103.163 +	fa.source(n);
 103.164 +	fa.target(pn);
 103.165 +
 103.166 +	fa.runMinCut();
 103.167 +
 103.168 +	(*_weight)[n] = fa.flowValue();
 103.169 +
 103.170 +	for (NodeIt nn(_graph); nn != INVALID; ++nn) {
 103.171 +	  if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
 103.172 +	    (*_pred)[nn] = n;
 103.173 +	  }
 103.174 +	}
 103.175 +	if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
 103.176 +	  (*_pred)[n] = (*_pred)[pn];
 103.177 +	  (*_pred)[pn] = n;
 103.178 +	  (*_weight)[n] = (*_weight)[pn];
 103.179 +	  (*_weight)[pn] = fa.flowValue();
 103.180 +	}
 103.181 +      }
 103.182 +
 103.183 +      (*_order)[_root] = 0;
 103.184 +      int index = 1;
 103.185 +
 103.186 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 103.187 +	std::vector<Node> st;
 103.188 +	Node nn = n;
 103.189 +	while ((*_order)[nn] == -1) {
 103.190 +	  st.push_back(nn);
 103.191 +	  nn = (*_pred)[nn];
 103.192 +	}
 103.193 +	while (!st.empty()) {
 103.194 +	  (*_order)[st.back()] = index++;
 103.195 +	  st.pop_back();
 103.196 +	}
 103.197 +      }
 103.198 +    }
 103.199 +
 103.200 +  public:
 103.201 +
 103.202 +    ///\name Execution Control
 103.203 + 
 103.204 +    ///@{
 103.205 +
 103.206 +    /// \brief Run the Gomory-Hu algorithm.
 103.207 +    ///
 103.208 +    /// This function runs the Gomory-Hu algorithm.
 103.209 +    void run() {
 103.210 +      init();
 103.211 +      start();
 103.212 +    }
 103.213 +    
 103.214 +    /// @}
 103.215 +
 103.216 +    ///\name Query Functions
 103.217 +    ///The results of the algorithm can be obtained using these
 103.218 +    ///functions.\n
 103.219 +    ///\ref run() should be called before using them.\n
 103.220 +    ///See also \ref MinCutNodeIt and \ref MinCutEdgeIt.
 103.221 +
 103.222 +    ///@{
 103.223 +
 103.224 +    /// \brief Return the predecessor node in the Gomory-Hu tree.
 103.225 +    ///
 103.226 +    /// This function returns the predecessor node of the given node
 103.227 +    /// in the Gomory-Hu tree.
 103.228 +    /// If \c node is the root of the tree, then it returns \c INVALID.
 103.229 +    ///
 103.230 +    /// \pre \ref run() must be called before using this function.
 103.231 +    Node predNode(const Node& node) const {
 103.232 +      return (*_pred)[node];
 103.233 +    }
 103.234 +
 103.235 +    /// \brief Return the weight of the predecessor edge in the
 103.236 +    /// Gomory-Hu tree.
 103.237 +    ///
 103.238 +    /// This function returns the weight of the predecessor edge of the 
 103.239 +    /// given node in the Gomory-Hu tree.
 103.240 +    /// If \c node is the root of the tree, the result is undefined.
 103.241 +    ///
 103.242 +    /// \pre \ref run() must be called before using this function.
 103.243 +    Value predValue(const Node& node) const {
 103.244 +      return (*_weight)[node];
 103.245 +    }
 103.246 +
 103.247 +    /// \brief Return the distance from the root node in the Gomory-Hu tree.
 103.248 +    ///
 103.249 +    /// This function returns the distance of the given node from the root
 103.250 +    /// node in the Gomory-Hu tree.
 103.251 +    ///
 103.252 +    /// \pre \ref run() must be called before using this function.
 103.253 +    int rootDist(const Node& node) const {
 103.254 +      return (*_order)[node];
 103.255 +    }
 103.256 +
 103.257 +    /// \brief Return the minimum cut value between two nodes
 103.258 +    ///
 103.259 +    /// This function returns the minimum cut value between the nodes
 103.260 +    /// \c s and \c t. 
 103.261 +    /// It finds the nearest common ancestor of the given nodes in the
 103.262 +    /// Gomory-Hu tree and calculates the minimum weight edge on the
 103.263 +    /// paths to the ancestor.
 103.264 +    ///
 103.265 +    /// \pre \ref run() must be called before using this function.
 103.266 +    Value minCutValue(const Node& s, const Node& t) const {
 103.267 +      Node sn = s, tn = t;
 103.268 +      Value value = std::numeric_limits<Value>::max();
 103.269 +      
 103.270 +      while (sn != tn) {
 103.271 +	if ((*_order)[sn] < (*_order)[tn]) {
 103.272 +	  if ((*_weight)[tn] <= value) value = (*_weight)[tn];
 103.273 +	  tn = (*_pred)[tn];
 103.274 +	} else {
 103.275 +	  if ((*_weight)[sn] <= value) value = (*_weight)[sn];
 103.276 +	  sn = (*_pred)[sn];
 103.277 +	}
 103.278 +      }
 103.279 +      return value;
 103.280 +    }
 103.281 +
 103.282 +    /// \brief Return the minimum cut between two nodes
 103.283 +    ///
 103.284 +    /// This function returns the minimum cut between the nodes \c s and \c t
 103.285 +    /// in the \c cutMap parameter by setting the nodes in the component of
 103.286 +    /// \c s to \c true and the other nodes to \c false.
 103.287 +    ///
 103.288 +    /// For higher level interfaces see MinCutNodeIt and MinCutEdgeIt.
 103.289 +    ///
 103.290 +    /// \param s The base node.
 103.291 +    /// \param t The node you want to separate from node \c s.
 103.292 +    /// \param cutMap The cut will be returned in this map.
 103.293 +    /// It must be a \c bool (or convertible) \ref concepts::ReadWriteMap
 103.294 +    /// "ReadWriteMap" on the graph nodes.
 103.295 +    ///
 103.296 +    /// \return The value of the minimum cut between \c s and \c t.
 103.297 +    ///
 103.298 +    /// \pre \ref run() must be called before using this function.
 103.299 +    template <typename CutMap>
 103.300 +    Value minCutMap(const Node& s, ///< 
 103.301 +                    const Node& t,
 103.302 +                    ///< 
 103.303 +                    CutMap& cutMap
 103.304 +                    ///< 
 103.305 +                    ) const {
 103.306 +      Node sn = s, tn = t;
 103.307 +      bool s_root=false;
 103.308 +      Node rn = INVALID;
 103.309 +      Value value = std::numeric_limits<Value>::max();
 103.310 +      
 103.311 +      while (sn != tn) {
 103.312 +	if ((*_order)[sn] < (*_order)[tn]) {
 103.313 +	  if ((*_weight)[tn] <= value) {
 103.314 +	    rn = tn;
 103.315 +            s_root = false;
 103.316 +	    value = (*_weight)[tn];
 103.317 +	  }
 103.318 +	  tn = (*_pred)[tn];
 103.319 +	} else {
 103.320 +	  if ((*_weight)[sn] <= value) {
 103.321 +	    rn = sn;
 103.322 +            s_root = true;
 103.323 +	    value = (*_weight)[sn];
 103.324 +	  }
 103.325 +	  sn = (*_pred)[sn];
 103.326 +	}
 103.327 +      }
 103.328 +
 103.329 +      typename Graph::template NodeMap<bool> reached(_graph, false);
 103.330 +      reached[_root] = true;
 103.331 +      cutMap.set(_root, !s_root);
 103.332 +      reached[rn] = true;
 103.333 +      cutMap.set(rn, s_root);
 103.334 +
 103.335 +      std::vector<Node> st;
 103.336 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 103.337 +	st.clear();
 103.338 +        Node nn = n;
 103.339 +	while (!reached[nn]) {
 103.340 +	  st.push_back(nn);
 103.341 +	  nn = (*_pred)[nn];
 103.342 +	}
 103.343 +	while (!st.empty()) {
 103.344 +	  cutMap.set(st.back(), cutMap[nn]);
 103.345 +	  st.pop_back();
 103.346 +	}
 103.347 +      }
 103.348 +      
 103.349 +      return value;
 103.350 +    }
 103.351 +
 103.352 +    ///@}
 103.353 +
 103.354 +    friend class MinCutNodeIt;
 103.355 +
 103.356 +    /// Iterate on the nodes of a minimum cut
 103.357 +    
 103.358 +    /// This iterator class lists the nodes of a minimum cut found by
 103.359 +    /// GomoryHu. Before using it, you must allocate a GomoryHu class
 103.360 +    /// and call its \ref GomoryHu::run() "run()" method.
 103.361 +    ///
 103.362 +    /// This example counts the nodes in the minimum cut separating \c s from
 103.363 +    /// \c t.
 103.364 +    /// \code
 103.365 +    /// GomoryHu<Graph> gom(g, capacities);
 103.366 +    /// gom.run();
 103.367 +    /// int cnt=0;
 103.368 +    /// for(GomoryHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
 103.369 +    /// \endcode
 103.370 +    class MinCutNodeIt
 103.371 +    {
 103.372 +      bool _side;
 103.373 +      typename Graph::NodeIt _node_it;
 103.374 +      typename Graph::template NodeMap<bool> _cut;
 103.375 +    public:
 103.376 +      /// Constructor
 103.377 +
 103.378 +      /// Constructor.
 103.379 +      ///
 103.380 +      MinCutNodeIt(GomoryHu const &gomory,
 103.381 +                   ///< The GomoryHu class. You must call its
 103.382 +                   ///  run() method
 103.383 +                   ///  before initializing this iterator.
 103.384 +                   const Node& s, ///< The base node.
 103.385 +                   const Node& t,
 103.386 +                   ///< The node you want to separate from node \c s.
 103.387 +                   bool side=true
 103.388 +                   ///< If it is \c true (default) then the iterator lists
 103.389 +                   ///  the nodes of the component containing \c s,
 103.390 +                   ///  otherwise it lists the other component.
 103.391 +                   /// \note As the minimum cut is not always unique,
 103.392 +                   /// \code
 103.393 +                   /// MinCutNodeIt(gomory, s, t, true);
 103.394 +                   /// \endcode
 103.395 +                   /// and
 103.396 +                   /// \code
 103.397 +                   /// MinCutNodeIt(gomory, t, s, false);
 103.398 +                   /// \endcode
 103.399 +                   /// does not necessarily give the same set of nodes.
 103.400 +                   /// However it is ensured that
 103.401 +                   /// \code
 103.402 +                   /// MinCutNodeIt(gomory, s, t, true);
 103.403 +                   /// \endcode
 103.404 +                   /// and
 103.405 +                   /// \code
 103.406 +                   /// MinCutNodeIt(gomory, s, t, false);
 103.407 +                   /// \endcode
 103.408 +                   /// together list each node exactly once.
 103.409 +                   )
 103.410 +        : _side(side), _cut(gomory._graph)
 103.411 +      {
 103.412 +        gomory.minCutMap(s,t,_cut);
 103.413 +        for(_node_it=typename Graph::NodeIt(gomory._graph);
 103.414 +            _node_it!=INVALID && _cut[_node_it]!=_side;
 103.415 +            ++_node_it) {}
 103.416 +      }
 103.417 +      /// Conversion to \c Node
 103.418 +
 103.419 +      /// Conversion to \c Node.
 103.420 +      ///
 103.421 +      operator typename Graph::Node() const
 103.422 +      {
 103.423 +        return _node_it;
 103.424 +      }
 103.425 +      bool operator==(Invalid) { return _node_it==INVALID; }
 103.426 +      bool operator!=(Invalid) { return _node_it!=INVALID; }
 103.427 +      /// Next node
 103.428 +
 103.429 +      /// Next node.
 103.430 +      ///
 103.431 +      MinCutNodeIt &operator++()
 103.432 +      {
 103.433 +        for(++_node_it;_node_it!=INVALID&&_cut[_node_it]!=_side;++_node_it) {}
 103.434 +        return *this;
 103.435 +      }
 103.436 +      /// Postfix incrementation
 103.437 +
 103.438 +      /// Postfix incrementation.
 103.439 +      ///
 103.440 +      /// \warning This incrementation
 103.441 +      /// returns a \c Node, not a \c MinCutNodeIt, as one may
 103.442 +      /// expect.
 103.443 +      typename Graph::Node operator++(int)
 103.444 +      {
 103.445 +        typename Graph::Node n=*this;
 103.446 +        ++(*this);
 103.447 +        return n;
 103.448 +      }
 103.449 +    };
 103.450 +    
 103.451 +    friend class MinCutEdgeIt;
 103.452 +    
 103.453 +    /// Iterate on the edges of a minimum cut
 103.454 +    
 103.455 +    /// This iterator class lists the edges of a minimum cut found by
 103.456 +    /// GomoryHu. Before using it, you must allocate a GomoryHu class
 103.457 +    /// and call its \ref GomoryHu::run() "run()" method.
 103.458 +    ///
 103.459 +    /// This example computes the value of the minimum cut separating \c s from
 103.460 +    /// \c t.
 103.461 +    /// \code
 103.462 +    /// GomoryHu<Graph> gom(g, capacities);
 103.463 +    /// gom.run();
 103.464 +    /// int value=0;
 103.465 +    /// for(GomoryHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
 103.466 +    ///   value+=capacities[e];
 103.467 +    /// \endcode
 103.468 +    /// The result will be the same as the value returned by
 103.469 +    /// \ref GomoryHu::minCutValue() "gom.minCutValue(s,t)".
 103.470 +    class MinCutEdgeIt
 103.471 +    {
 103.472 +      bool _side;
 103.473 +      const Graph &_graph;
 103.474 +      typename Graph::NodeIt _node_it;
 103.475 +      typename Graph::OutArcIt _arc_it;
 103.476 +      typename Graph::template NodeMap<bool> _cut;
 103.477 +      void step()
 103.478 +      {
 103.479 +        ++_arc_it;
 103.480 +        while(_node_it!=INVALID && _arc_it==INVALID)
 103.481 +          {
 103.482 +            for(++_node_it;_node_it!=INVALID&&!_cut[_node_it];++_node_it) {}
 103.483 +            if(_node_it!=INVALID)
 103.484 +              _arc_it=typename Graph::OutArcIt(_graph,_node_it);
 103.485 +          }
 103.486 +      }
 103.487 +      
 103.488 +    public:
 103.489 +      /// Constructor
 103.490 +
 103.491 +      /// Constructor.
 103.492 +      ///
 103.493 +      MinCutEdgeIt(GomoryHu const &gomory,
 103.494 +                   ///< The GomoryHu class. You must call its
 103.495 +                   ///  run() method
 103.496 +                   ///  before initializing this iterator.
 103.497 +                   const Node& s,  ///< The base node.
 103.498 +                   const Node& t,
 103.499 +                   ///< The node you want to separate from node \c s.
 103.500 +                   bool side=true
 103.501 +                   ///< If it is \c true (default) then the listed arcs
 103.502 +                   ///  will be oriented from the
 103.503 +                   ///  nodes of the component containing \c s,
 103.504 +                   ///  otherwise they will be oriented in the opposite
 103.505 +                   ///  direction.
 103.506 +                   )
 103.507 +        : _graph(gomory._graph), _cut(_graph)
 103.508 +      {
 103.509 +        gomory.minCutMap(s,t,_cut);
 103.510 +        if(!side)
 103.511 +          for(typename Graph::NodeIt n(_graph);n!=INVALID;++n)
 103.512 +            _cut[n]=!_cut[n];
 103.513 +
 103.514 +        for(_node_it=typename Graph::NodeIt(_graph);
 103.515 +            _node_it!=INVALID && !_cut[_node_it];
 103.516 +            ++_node_it) {}
 103.517 +        _arc_it = _node_it!=INVALID ?
 103.518 +          typename Graph::OutArcIt(_graph,_node_it) : INVALID;
 103.519 +        while(_node_it!=INVALID && _arc_it == INVALID)
 103.520 +          {
 103.521 +            for(++_node_it; _node_it!=INVALID&&!_cut[_node_it]; ++_node_it) {}
 103.522 +            if(_node_it!=INVALID)
 103.523 +              _arc_it= typename Graph::OutArcIt(_graph,_node_it);
 103.524 +          }
 103.525 +        while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
 103.526 +      }
 103.527 +      /// Conversion to \c Arc
 103.528 +
 103.529 +      /// Conversion to \c Arc.
 103.530 +      ///
 103.531 +      operator typename Graph::Arc() const
 103.532 +      {
 103.533 +        return _arc_it;
 103.534 +      }
 103.535 +      /// Conversion to \c Edge
 103.536 +
 103.537 +      /// Conversion to \c Edge.
 103.538 +      ///
 103.539 +      operator typename Graph::Edge() const
 103.540 +      {
 103.541 +        return _arc_it;
 103.542 +      }
 103.543 +      bool operator==(Invalid) { return _node_it==INVALID; }
 103.544 +      bool operator!=(Invalid) { return _node_it!=INVALID; }
 103.545 +      /// Next edge
 103.546 +
 103.547 +      /// Next edge.
 103.548 +      ///
 103.549 +      MinCutEdgeIt &operator++()
 103.550 +      {
 103.551 +        step();
 103.552 +        while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
 103.553 +        return *this;
 103.554 +      }
 103.555 +      /// Postfix incrementation
 103.556 +      
 103.557 +      /// Postfix incrementation.
 103.558 +      ///
 103.559 +      /// \warning This incrementation
 103.560 +      /// returns an \c Arc, not a \c MinCutEdgeIt, as one may expect.
 103.561 +      typename Graph::Arc operator++(int)
 103.562 +      {
 103.563 +        typename Graph::Arc e=*this;
 103.564 +        ++(*this);
 103.565 +        return e;
 103.566 +      }
 103.567 +    };
 103.568 +
 103.569 +  };
 103.570 +
 103.571 +}
 103.572 +
 103.573 +#endif
   104.1 --- a/lemon/graph_to_eps.h	Fri Oct 16 10:21:37 2009 +0200
   104.2 +++ b/lemon/graph_to_eps.h	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   104.8 + * Copyright (C) 2003-2009
   104.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  104.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  104.11   *
  104.12 @@ -64,11 +64,12 @@
  104.13  
  104.14  ///Default traits class of \ref GraphToEps.
  104.15  ///
  104.16 -///\c G is the type of the underlying graph.
  104.17 -template<class G>
  104.18 +///\param GR is the type of the underlying graph.
  104.19 +template<class GR>
  104.20  struct DefaultGraphToEpsTraits
  104.21  {
  104.22 -  typedef G Graph;
  104.23 +  typedef GR Graph;
  104.24 +  typedef GR Digraph;
  104.25    typedef typename Graph::Node Node;
  104.26    typedef typename Graph::NodeIt NodeIt;
  104.27    typedef typename Graph::Arc Arc;
  104.28 @@ -139,15 +140,14 @@
  104.29    ///Constructor
  104.30  
  104.31    ///Constructor
  104.32 -  ///\param _g  Reference to the graph to be printed.
  104.33 -  ///\param _os Reference to the output stream.
  104.34 -  ///\param _os Reference to the output stream.
  104.35 +  ///\param gr  Reference to the graph to be printed.
  104.36 +  ///\param ost Reference to the output stream.
  104.37    ///By default it is <tt>std::cout</tt>.
  104.38 -  ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
  104.39 +  ///\param pros If it is \c true, then the \c ostream referenced by \c os
  104.40    ///will be explicitly deallocated by the destructor.
  104.41 -  DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
  104.42 -                          bool _pros=false) :
  104.43 -    g(_g), os(_os),
  104.44 +  DefaultGraphToEpsTraits(const GR &gr, std::ostream& ost = std::cout,
  104.45 +                          bool pros = false) :
  104.46 +    g(gr), os(ost),
  104.47      _coords(dim2::Point<double>(1,1)), _nodeSizes(1), _nodeShapes(0),
  104.48      _nodeColors(WHITE), _arcColors(BLACK),
  104.49      _arcWidths(1.0), _arcWidthScale(0.003),
  104.50 @@ -158,8 +158,8 @@
  104.51      _enableParallel(false), _parArcDist(1),
  104.52      _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
  104.53      _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
  104.54 -    _undirected(lemon::UndirectedTagIndicator<G>::value),
  104.55 -    _pleaseRemoveOsStream(_pros), _scaleToA4(false),
  104.56 +    _undirected(lemon::UndirectedTagIndicator<GR>::value),
  104.57 +    _pleaseRemoveOsStream(pros), _scaleToA4(false),
  104.58      _nodeTextColorType(SAME_COL), _nodeTextColors(BLACK),
  104.59      _autoNodeScale(false),
  104.60      _autoArcWidthScale(false),
  104.61 @@ -242,6 +242,7 @@
  104.62    // dradnats ++C eht yb deriuqer si ti eveileb t'naC
  104.63  
  104.64    typedef typename T::Graph Graph;
  104.65 +  typedef typename T::Digraph Digraph;
  104.66    typedef typename Graph::Node Node;
  104.67    typedef typename Graph::NodeIt NodeIt;
  104.68    typedef typename Graph::Arc Arc;
  104.69 @@ -269,22 +270,18 @@
  104.70      /// = 1
  104.71      ///\image html nodeshape_1.png
  104.72      ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm
  104.73 -    ///
  104.74      SQUARE=1,
  104.75      /// = 2
  104.76      ///\image html nodeshape_2.png
  104.77      ///\image latex nodeshape_2.eps "DIAMOND shape (2)" width=2cm
  104.78 -    ///
  104.79      DIAMOND=2,
  104.80      /// = 3
  104.81      ///\image html nodeshape_3.png
  104.82 -    ///\image latex nodeshape_2.eps "MALE shape (4)" width=2cm
  104.83 -    ///
  104.84 +    ///\image latex nodeshape_3.eps "MALE shape (3)" width=2cm
  104.85      MALE=3,
  104.86      /// = 4
  104.87      ///\image html nodeshape_4.png
  104.88 -    ///\image latex nodeshape_2.eps "FEMALE shape (4)" width=2cm
  104.89 -    ///
  104.90 +    ///\image latex nodeshape_4.eps "FEMALE shape (4)" width=2cm
  104.91      FEMALE=4
  104.92    };
  104.93  
  104.94 @@ -1134,55 +1131,55 @@
  104.95  ///\warning Don't forget to put the \ref GraphToEps::run() "run()"
  104.96  ///to the end of the parameter list.
  104.97  ///\sa GraphToEps
  104.98 -///\sa graphToEps(G &g, const char *file_name)
  104.99 -template<class G>
 104.100 -GraphToEps<DefaultGraphToEpsTraits<G> >
 104.101 -graphToEps(G &g, std::ostream& os=std::cout)
 104.102 +///\sa graphToEps(GR &g, const char *file_name)
 104.103 +template<class GR>
 104.104 +GraphToEps<DefaultGraphToEpsTraits<GR> >
 104.105 +graphToEps(GR &g, std::ostream& os=std::cout)
 104.106  {
 104.107    return
 104.108 -    GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
 104.109 +    GraphToEps<DefaultGraphToEpsTraits<GR> >(DefaultGraphToEpsTraits<GR>(g,os));
 104.110  }
 104.111  
 104.112  ///Generates an EPS file from a graph
 104.113  
 104.114  ///\ingroup eps_io
 104.115  ///This function does the same as
 104.116 -///\ref graphToEps(G &g,std::ostream& os)
 104.117 +///\ref graphToEps(GR &g,std::ostream& os)
 104.118  ///but it writes its output into the file \c file_name
 104.119  ///instead of a stream.
 104.120 -///\sa graphToEps(G &g, std::ostream& os)
 104.121 -template<class G>
 104.122 -GraphToEps<DefaultGraphToEpsTraits<G> >
 104.123 -graphToEps(G &g,const char *file_name)
 104.124 +///\sa graphToEps(GR &g, std::ostream& os)
 104.125 +template<class GR>
 104.126 +GraphToEps<DefaultGraphToEpsTraits<GR> >
 104.127 +graphToEps(GR &g,const char *file_name)
 104.128  {
 104.129    std::ostream* os = new std::ofstream(file_name);
 104.130    if (!(*os)) {
 104.131      delete os;
 104.132      throw IoError("Cannot write file", file_name);
 104.133    }
 104.134 -  return GraphToEps<DefaultGraphToEpsTraits<G> >
 104.135 -    (DefaultGraphToEpsTraits<G>(g,*os,true));
 104.136 +  return GraphToEps<DefaultGraphToEpsTraits<GR> >
 104.137 +    (DefaultGraphToEpsTraits<GR>(g,*os,true));
 104.138  }
 104.139  
 104.140  ///Generates an EPS file from a graph
 104.141  
 104.142  ///\ingroup eps_io
 104.143  ///This function does the same as
 104.144 -///\ref graphToEps(G &g,std::ostream& os)
 104.145 +///\ref graphToEps(GR &g,std::ostream& os)
 104.146  ///but it writes its output into the file \c file_name
 104.147  ///instead of a stream.
 104.148 -///\sa graphToEps(G &g, std::ostream& os)
 104.149 -template<class G>
 104.150 -GraphToEps<DefaultGraphToEpsTraits<G> >
 104.151 -graphToEps(G &g,const std::string& file_name)
 104.152 +///\sa graphToEps(GR &g, std::ostream& os)
 104.153 +template<class GR>
 104.154 +GraphToEps<DefaultGraphToEpsTraits<GR> >
 104.155 +graphToEps(GR &g,const std::string& file_name)
 104.156  {
 104.157    std::ostream* os = new std::ofstream(file_name.c_str());
 104.158    if (!(*os)) {
 104.159      delete os;
 104.160      throw IoError("Cannot write file", file_name);
 104.161    }
 104.162 -  return GraphToEps<DefaultGraphToEpsTraits<G> >
 104.163 -    (DefaultGraphToEpsTraits<G>(g,*os,true));
 104.164 +  return GraphToEps<DefaultGraphToEpsTraits<GR> >
 104.165 +    (DefaultGraphToEpsTraits<GR>(g,*os,true));
 104.166  }
 104.167  
 104.168  } //END OF NAMESPACE LEMON
   105.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.2 +++ b/lemon/grid_graph.h	Thu Nov 05 15:50:01 2009 +0100
   105.3 @@ -0,0 +1,697 @@
   105.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   105.5 + *
   105.6 + * This file is a part of LEMON, a generic C++ optimization library.
   105.7 + *
   105.8 + * Copyright (C) 2003-2009
   105.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  105.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  105.11 + *
  105.12 + * Permission to use, modify and distribute this software is granted
  105.13 + * provided that this copyright notice appears in all copies. For
  105.14 + * precise terms see the accompanying LICENSE file.
  105.15 + *
  105.16 + * This software is provided "AS IS" with no warranty of any kind,
  105.17 + * express or implied, and with no claim as to its suitability for any
  105.18 + * purpose.
  105.19 + *
  105.20 + */
  105.21 +
  105.22 +#ifndef GRID_GRAPH_H
  105.23 +#define GRID_GRAPH_H
  105.24 +
  105.25 +#include <lemon/core.h>
  105.26 +#include <lemon/bits/graph_extender.h>
  105.27 +#include <lemon/dim2.h>
  105.28 +#include <lemon/assert.h>
  105.29 +
  105.30 +///\ingroup graphs
  105.31 +///\file
  105.32 +///\brief GridGraph class.
  105.33 +
  105.34 +namespace lemon {
  105.35 +
  105.36 +  class GridGraphBase {
  105.37 +
  105.38 +  public:
  105.39 +
  105.40 +    typedef GridGraphBase Graph;
  105.41 +
  105.42 +    class Node;
  105.43 +    class Edge;
  105.44 +    class Arc;
  105.45 +
  105.46 +  public:
  105.47 +
  105.48 +    GridGraphBase() {}
  105.49 +
  105.50 +  protected:
  105.51 +
  105.52 +    void construct(int width, int height) {
  105.53 +       _width = width; _height = height;
  105.54 +      _node_num = width * height;
  105.55 +      _edge_num = 2 * _node_num - width - height;
  105.56 +      _edge_limit = _node_num - _width;
  105.57 +    }
  105.58 +
  105.59 +  public:
  105.60 +
  105.61 +    Node operator()(int i, int j) const {
  105.62 +      LEMON_DEBUG(0 <= i && i < _width &&
  105.63 +                  0 <= j  && j < _height, "Index out of range");
  105.64 +      return Node(i + j * _width);
  105.65 +    }
  105.66 +
  105.67 +    int col(Node n) const {
  105.68 +      return n._id % _width;
  105.69 +    }
  105.70 +
  105.71 +    int row(Node n) const {
  105.72 +      return n._id / _width;
  105.73 +    }
  105.74 +
  105.75 +    dim2::Point<int> pos(Node n) const {
  105.76 +      return dim2::Point<int>(col(n), row(n));
  105.77 +    }
  105.78 +
  105.79 +    int width() const {
  105.80 +      return _width;
  105.81 +    }
  105.82 +
  105.83 +    int height() const {
  105.84 +      return _height;
  105.85 +    }
  105.86 +
  105.87 +    typedef True NodeNumTag;
  105.88 +    typedef True EdgeNumTag;
  105.89 +    typedef True ArcNumTag;
  105.90 +
  105.91 +    int nodeNum() const { return _node_num; }
  105.92 +    int edgeNum() const { return _edge_num; }
  105.93 +    int arcNum() const { return 2 * _edge_num; }
  105.94 +
  105.95 +    Node u(Edge edge) const {
  105.96 +      if (edge._id < _edge_limit) {
  105.97 +        return edge._id;
  105.98 +      } else {
  105.99 +        return (edge._id - _edge_limit) % (_width - 1) +
 105.100 +          (edge._id - _edge_limit) / (_width - 1) * _width;
 105.101 +      }
 105.102 +    }
 105.103 +
 105.104 +    Node v(Edge edge) const {
 105.105 +      if (edge._id < _edge_limit) {
 105.106 +        return edge._id + _width;
 105.107 +      } else {
 105.108 +        return (edge._id - _edge_limit) % (_width - 1) +
 105.109 +          (edge._id - _edge_limit) / (_width - 1) * _width + 1;
 105.110 +      }
 105.111 +    }
 105.112 +
 105.113 +    Node source(Arc arc) const {
 105.114 +      return (arc._id & 1) == 1 ? u(arc) : v(arc);
 105.115 +    }
 105.116 +
 105.117 +    Node target(Arc arc) const {
 105.118 +      return (arc._id & 1) == 1 ? v(arc) : u(arc);
 105.119 +    }
 105.120 +
 105.121 +    static int id(Node node) { return node._id; }
 105.122 +    static int id(Edge edge) { return edge._id; }
 105.123 +    static int id(Arc arc) { return arc._id; }
 105.124 +
 105.125 +    int maxNodeId() const { return _node_num - 1; }
 105.126 +    int maxEdgeId() const { return _edge_num - 1; }
 105.127 +    int maxArcId() const { return 2 * _edge_num - 1; }
 105.128 +
 105.129 +    static Node nodeFromId(int id) { return Node(id);}
 105.130 +    static Edge edgeFromId(int id) { return Edge(id);}
 105.131 +    static Arc arcFromId(int id) { return Arc(id);}
 105.132 +
 105.133 +    typedef True FindEdgeTag;
 105.134 +    typedef True FindArcTag;
 105.135 +
 105.136 +    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
 105.137 +      if (prev != INVALID) return INVALID;
 105.138 +      if (v._id > u._id) {
 105.139 +        if (v._id - u._id == _width)
 105.140 +          return Edge(u._id);
 105.141 +        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
 105.142 +          return Edge(u._id / _width * (_width - 1) +
 105.143 +                      u._id % _width + _edge_limit);
 105.144 +        }
 105.145 +      } else {
 105.146 +        if (u._id - v._id == _width)
 105.147 +          return Edge(v._id);
 105.148 +        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
 105.149 +          return Edge(v._id / _width * (_width - 1) +
 105.150 +                      v._id % _width + _edge_limit);
 105.151 +        }
 105.152 +      }
 105.153 +      return INVALID;
 105.154 +    }
 105.155 +
 105.156 +    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
 105.157 +      if (prev != INVALID) return INVALID;
 105.158 +      if (v._id > u._id) {
 105.159 +        if (v._id - u._id == _width)
 105.160 +          return Arc((u._id << 1) | 1);
 105.161 +        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
 105.162 +          return Arc(((u._id / _width * (_width - 1) +
 105.163 +                       u._id % _width + _edge_limit) << 1) | 1);
 105.164 +        }
 105.165 +      } else {
 105.166 +        if (u._id - v._id == _width)
 105.167 +          return Arc(v._id << 1);
 105.168 +        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
 105.169 +          return Arc((v._id / _width * (_width - 1) +
 105.170 +                       v._id % _width + _edge_limit) << 1);
 105.171 +        }
 105.172 +      }
 105.173 +      return INVALID;
 105.174 +    }
 105.175 +
 105.176 +    class Node {
 105.177 +      friend class GridGraphBase;
 105.178 +
 105.179 +    protected:
 105.180 +      int _id;
 105.181 +      Node(int id) : _id(id) {}
 105.182 +    public:
 105.183 +      Node() {}
 105.184 +      Node (Invalid) : _id(-1) {}
 105.185 +      bool operator==(const Node node) const {return _id == node._id;}
 105.186 +      bool operator!=(const Node node) const {return _id != node._id;}
 105.187 +      bool operator<(const Node node) const {return _id < node._id;}
 105.188 +    };
 105.189 +
 105.190 +    class Edge {
 105.191 +      friend class GridGraphBase;
 105.192 +      friend class Arc;
 105.193 +
 105.194 +    protected:
 105.195 +      int _id;
 105.196 +
 105.197 +      Edge(int id) : _id(id) {}
 105.198 +
 105.199 +    public:
 105.200 +      Edge() {}
 105.201 +      Edge (Invalid) : _id(-1) {}
 105.202 +      bool operator==(const Edge edge) const {return _id == edge._id;}
 105.203 +      bool operator!=(const Edge edge) const {return _id != edge._id;}
 105.204 +      bool operator<(const Edge edge) const {return _id < edge._id;}
 105.205 +    };
 105.206 +
 105.207 +    class Arc {
 105.208 +      friend class GridGraphBase;
 105.209 +
 105.210 +    protected:
 105.211 +      int _id;
 105.212 +
 105.213 +      Arc(int id) : _id(id) {}
 105.214 +
 105.215 +    public:
 105.216 +      Arc() {}
 105.217 +      Arc (Invalid) : _id(-1) {}
 105.218 +      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
 105.219 +      bool operator==(const Arc arc) const {return _id == arc._id;}
 105.220 +      bool operator!=(const Arc arc) const {return _id != arc._id;}
 105.221 +      bool operator<(const Arc arc) const {return _id < arc._id;}
 105.222 +    };
 105.223 +
 105.224 +    static bool direction(Arc arc) {
 105.225 +      return (arc._id & 1) == 1;
 105.226 +    }
 105.227 +
 105.228 +    static Arc direct(Edge edge, bool dir) {
 105.229 +      return Arc((edge._id << 1) | (dir ? 1 : 0));
 105.230 +    }
 105.231 +
 105.232 +    void first(Node& node) const {
 105.233 +      node._id = _node_num - 1;
 105.234 +    }
 105.235 +
 105.236 +    static void next(Node& node) {
 105.237 +      --node._id;
 105.238 +    }
 105.239 +
 105.240 +    void first(Edge& edge) const {
 105.241 +      edge._id = _edge_num - 1;
 105.242 +    }
 105.243 +
 105.244 +    static void next(Edge& edge) {
 105.245 +      --edge._id;
 105.246 +    }
 105.247 +
 105.248 +    void first(Arc& arc) const {
 105.249 +      arc._id = 2 * _edge_num - 1;
 105.250 +    }
 105.251 +
 105.252 +    static void next(Arc& arc) {
 105.253 +      --arc._id;
 105.254 +    }
 105.255 +
 105.256 +    void firstOut(Arc& arc, const Node& node) const {
 105.257 +      if (node._id % _width < _width - 1) {
 105.258 +        arc._id = (_edge_limit + node._id % _width +
 105.259 +                   (node._id / _width) * (_width - 1)) << 1 | 1;
 105.260 +        return;
 105.261 +      }
 105.262 +      if (node._id < _node_num - _width) {
 105.263 +        arc._id = node._id << 1 | 1;
 105.264 +        return;
 105.265 +      }
 105.266 +      if (node._id % _width > 0) {
 105.267 +        arc._id = (_edge_limit + node._id % _width +
 105.268 +                   (node._id / _width) * (_width - 1) - 1) << 1;
 105.269 +        return;
 105.270 +      }
 105.271 +      if (node._id >= _width) {
 105.272 +        arc._id = (node._id - _width) << 1;
 105.273 +        return;
 105.274 +      }
 105.275 +      arc._id = -1;
 105.276 +    }
 105.277 +
 105.278 +    void nextOut(Arc& arc) const {
 105.279 +      int nid = arc._id >> 1;
 105.280 +      if ((arc._id & 1) == 1) {
 105.281 +        if (nid >= _edge_limit) {
 105.282 +          nid = (nid - _edge_limit) % (_width - 1) +
 105.283 +            (nid - _edge_limit) / (_width - 1) * _width;
 105.284 +          if (nid < _node_num - _width) {
 105.285 +            arc._id = nid << 1 | 1;
 105.286 +            return;
 105.287 +          }
 105.288 +        }
 105.289 +        if (nid % _width > 0) {
 105.290 +          arc._id = (_edge_limit + nid % _width +
 105.291 +                     (nid / _width) * (_width - 1) - 1) << 1;
 105.292 +          return;
 105.293 +        }
 105.294 +        if (nid >= _width) {
 105.295 +          arc._id = (nid - _width) << 1;
 105.296 +          return;
 105.297 +        }
 105.298 +      } else {
 105.299 +        if (nid >= _edge_limit) {
 105.300 +          nid = (nid - _edge_limit) % (_width - 1) +
 105.301 +            (nid - _edge_limit) / (_width - 1) * _width + 1;
 105.302 +          if (nid >= _width) {
 105.303 +            arc._id = (nid - _width) << 1;
 105.304 +            return;
 105.305 +          }
 105.306 +        }
 105.307 +      }
 105.308 +      arc._id = -1;
 105.309 +    }
 105.310 +
 105.311 +    void firstIn(Arc& arc, const Node& node) const {
 105.312 +      if (node._id % _width < _width - 1) {
 105.313 +        arc._id = (_edge_limit + node._id % _width +
 105.314 +                   (node._id / _width) * (_width - 1)) << 1;
 105.315 +        return;
 105.316 +      }
 105.317 +      if (node._id < _node_num - _width) {
 105.318 +        arc._id = node._id << 1;
 105.319 +        return;
 105.320 +      }
 105.321 +      if (node._id % _width > 0) {
 105.322 +        arc._id = (_edge_limit + node._id % _width +
 105.323 +                   (node._id / _width) * (_width - 1) - 1) << 1 | 1;
 105.324 +        return;
 105.325 +      }
 105.326 +      if (node._id >= _width) {
 105.327 +        arc._id = (node._id - _width) << 1 | 1;
 105.328 +        return;
 105.329 +      }
 105.330 +      arc._id = -1;
 105.331 +    }
 105.332 +
 105.333 +    void nextIn(Arc& arc) const {
 105.334 +      int nid = arc._id >> 1;
 105.335 +      if ((arc._id & 1) == 0) {
 105.336 +        if (nid >= _edge_limit) {
 105.337 +          nid = (nid - _edge_limit) % (_width - 1) +
 105.338 +            (nid - _edge_limit) / (_width - 1) * _width;
 105.339 +          if (nid < _node_num - _width) {
 105.340 +            arc._id = nid << 1;
 105.341 +            return;
 105.342 +          }
 105.343 +        }
 105.344 +        if (nid % _width > 0) {
 105.345 +          arc._id = (_edge_limit + nid % _width +
 105.346 +                     (nid / _width) * (_width - 1) - 1) << 1 | 1;
 105.347 +          return;
 105.348 +        }
 105.349 +        if (nid >= _width) {
 105.350 +          arc._id = (nid - _width) << 1 | 1;
 105.351 +          return;
 105.352 +        }
 105.353 +      } else {
 105.354 +        if (nid >= _edge_limit) {
 105.355 +          nid = (nid - _edge_limit) % (_width - 1) +
 105.356 +            (nid - _edge_limit) / (_width - 1) * _width + 1;
 105.357 +          if (nid >= _width) {
 105.358 +            arc._id = (nid - _width) << 1 | 1;
 105.359 +            return;
 105.360 +          }
 105.361 +        }
 105.362 +      }
 105.363 +      arc._id = -1;
 105.364 +    }
 105.365 +
 105.366 +    void firstInc(Edge& edge, bool& dir, const Node& node) const {
 105.367 +      if (node._id % _width < _width - 1) {
 105.368 +        edge._id = _edge_limit + node._id % _width +
 105.369 +          (node._id / _width) * (_width - 1);
 105.370 +        dir = true;
 105.371 +        return;
 105.372 +      }
 105.373 +      if (node._id < _node_num - _width) {
 105.374 +        edge._id = node._id;
 105.375 +        dir = true;
 105.376 +        return;
 105.377 +      }
 105.378 +      if (node._id % _width > 0) {
 105.379 +        edge._id = _edge_limit + node._id % _width +
 105.380 +          (node._id / _width) * (_width - 1) - 1;
 105.381 +        dir = false;
 105.382 +        return;
 105.383 +      }
 105.384 +      if (node._id >= _width) {
 105.385 +        edge._id = node._id - _width;
 105.386 +        dir = false;
 105.387 +        return;
 105.388 +      }
 105.389 +      edge._id = -1;
 105.390 +      dir = true;
 105.391 +    }
 105.392 +
 105.393 +    void nextInc(Edge& edge, bool& dir) const {
 105.394 +      int nid = edge._id;
 105.395 +      if (dir) {
 105.396 +        if (nid >= _edge_limit) {
 105.397 +          nid = (nid - _edge_limit) % (_width - 1) +
 105.398 +            (nid - _edge_limit) / (_width - 1) * _width;
 105.399 +          if (nid < _node_num - _width) {
 105.400 +            edge._id = nid;
 105.401 +            return;
 105.402 +          }
 105.403 +        }
 105.404 +        if (nid % _width > 0) {
 105.405 +          edge._id = _edge_limit + nid % _width +
 105.406 +            (nid / _width) * (_width - 1) - 1;
 105.407 +          dir = false;
 105.408 +          return;
 105.409 +        }
 105.410 +        if (nid >= _width) {
 105.411 +          edge._id = nid - _width;
 105.412 +          dir = false;
 105.413 +          return;
 105.414 +        }
 105.415 +      } else {
 105.416 +        if (nid >= _edge_limit) {
 105.417 +          nid = (nid - _edge_limit) % (_width - 1) +
 105.418 +            (nid - _edge_limit) / (_width - 1) * _width + 1;
 105.419 +          if (nid >= _width) {
 105.420 +            edge._id = nid - _width;
 105.421 +            return;
 105.422 +          }
 105.423 +        }
 105.424 +      }
 105.425 +      edge._id = -1;
 105.426 +      dir = true;
 105.427 +    }
 105.428 +
 105.429 +    Arc right(Node n) const {
 105.430 +      if (n._id % _width < _width - 1) {
 105.431 +        return Arc(((_edge_limit + n._id % _width +
 105.432 +                    (n._id / _width) * (_width - 1)) << 1) | 1);
 105.433 +      } else {
 105.434 +        return INVALID;
 105.435 +      }
 105.436 +    }
 105.437 +
 105.438 +    Arc left(Node n) const {
 105.439 +      if (n._id % _width > 0) {
 105.440 +        return Arc((_edge_limit + n._id % _width +
 105.441 +                     (n._id / _width) * (_width - 1) - 1) << 1);
 105.442 +      } else {
 105.443 +        return INVALID;
 105.444 +      }
 105.445 +    }
 105.446 +
 105.447 +    Arc up(Node n) const {
 105.448 +      if (n._id < _edge_limit) {
 105.449 +        return Arc((n._id << 1) | 1);
 105.450 +      } else {
 105.451 +        return INVALID;
 105.452 +      }
 105.453 +    }
 105.454 +
 105.455 +    Arc down(Node n) const {
 105.456 +      if (n._id >= _width) {
 105.457 +        return Arc((n._id - _width) << 1);
 105.458 +      } else {
 105.459 +        return INVALID;
 105.460 +      }
 105.461 +    }
 105.462 +
 105.463 +  private:
 105.464 +    int _width, _height;
 105.465 +    int _node_num, _edge_num;
 105.466 +    int _edge_limit;
 105.467 +  };
 105.468 +
 105.469 +
 105.470 +  typedef GraphExtender<GridGraphBase> ExtendedGridGraphBase;
 105.471 +
 105.472 +  /// \ingroup graphs
 105.473 +  ///
 105.474 +  /// \brief Grid graph class
 105.475 +  ///
 105.476 +  /// GridGraph implements a special graph type. The nodes of the
 105.477 +  /// graph can be indexed by two integer values \c (i,j) where \c i is
 105.478 +  /// in the range <tt>[0..width()-1]</tt> and j is in the range
 105.479 +  /// <tt>[0..height()-1]</tt>. Two nodes are connected in the graph if
 105.480 +  /// the indices differ exactly on one position and the difference is
 105.481 +  /// also exactly one. The nodes of the graph can be obtained by position
 105.482 +  /// using the \c operator()() function and the indices of the nodes can
 105.483 +  /// be obtained using \c pos(), \c col() and \c row() members. The outgoing
 105.484 +  /// arcs can be retrieved with the \c right(), \c up(), \c left()
 105.485 +  /// and \c down() functions, where the bottom-left corner is the
 105.486 +  /// origin.
 105.487 +  ///
 105.488 +  /// This class is completely static and it needs constant memory space.
 105.489 +  /// Thus you can neither add nor delete nodes or edges, however
 105.490 +  /// the structure can be resized using resize().
 105.491 +  ///
 105.492 +  /// \image html grid_graph.png
 105.493 +  /// \image latex grid_graph.eps "Grid graph" width=\textwidth
 105.494 +  ///
 105.495 +  /// A short example about the basic usage:
 105.496 +  ///\code
 105.497 +  /// GridGraph graph(rows, cols);
 105.498 +  /// GridGraph::NodeMap<int> val(graph);
 105.499 +  /// for (int i = 0; i < graph.width(); ++i) {
 105.500 +  ///   for (int j = 0; j < graph.height(); ++j) {
 105.501 +  ///     val[graph(i, j)] = i + j;
 105.502 +  ///   }
 105.503 +  /// }
 105.504 +  ///\endcode
 105.505 +  ///
 105.506 +  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
 105.507 +  /// Most of its member functions and nested classes are documented
 105.508 +  /// only in the concept class.
 105.509 +  class GridGraph : public ExtendedGridGraphBase {
 105.510 +    typedef ExtendedGridGraphBase Parent;
 105.511 +
 105.512 +  public:
 105.513 +
 105.514 +    /// \brief Map to get the indices of the nodes as \ref dim2::Point
 105.515 +    /// "dim2::Point<int>".
 105.516 +    ///
 105.517 +    /// Map to get the indices of the nodes as \ref dim2::Point
 105.518 +    /// "dim2::Point<int>".
 105.519 +    class IndexMap {
 105.520 +    public:
 105.521 +      /// \brief The key type of the map
 105.522 +      typedef GridGraph::Node Key;
 105.523 +      /// \brief The value type of the map
 105.524 +      typedef dim2::Point<int> Value;
 105.525 +
 105.526 +      /// \brief Constructor
 105.527 +      IndexMap(const GridGraph& graph) : _graph(graph) {}
 105.528 +
 105.529 +      /// \brief The subscript operator
 105.530 +      Value operator[](Key key) const {
 105.531 +        return _graph.pos(key);
 105.532 +      }
 105.533 +
 105.534 +    private:
 105.535 +      const GridGraph& _graph;
 105.536 +    };
 105.537 +
 105.538 +    /// \brief Map to get the column of the nodes.
 105.539 +    ///
 105.540 +    /// Map to get the column of the nodes.
 105.541 +    class ColMap {
 105.542 +    public:
 105.543 +      /// \brief The key type of the map
 105.544 +      typedef GridGraph::Node Key;
 105.545 +      /// \brief The value type of the map
 105.546 +      typedef int Value;
 105.547 +
 105.548 +      /// \brief Constructor
 105.549 +      ColMap(const GridGraph& graph) : _graph(graph) {}
 105.550 +
 105.551 +      /// \brief The subscript operator
 105.552 +      Value operator[](Key key) const {
 105.553 +        return _graph.col(key);
 105.554 +      }
 105.555 +
 105.556 +    private:
 105.557 +      const GridGraph& _graph;
 105.558 +    };
 105.559 +
 105.560 +    /// \brief Map to get the row of the nodes.
 105.561 +    ///
 105.562 +    /// Map to get the row of the nodes.
 105.563 +    class RowMap {
 105.564 +    public:
 105.565 +      /// \brief The key type of the map
 105.566 +      typedef GridGraph::Node Key;
 105.567 +      /// \brief The value type of the map
 105.568 +      typedef int Value;
 105.569 +
 105.570 +      /// \brief Constructor
 105.571 +      RowMap(const GridGraph& graph) : _graph(graph) {}
 105.572 +
 105.573 +      /// \brief The subscript operator
 105.574 +      Value operator[](Key key) const {
 105.575 +        return _graph.row(key);
 105.576 +      }
 105.577 +
 105.578 +    private:
 105.579 +      const GridGraph& _graph;
 105.580 +    };
 105.581 +
 105.582 +    /// \brief Constructor
 105.583 +    ///
 105.584 +    /// Construct a grid graph with the given size.
 105.585 +    GridGraph(int width, int height) { construct(width, height); }
 105.586 +
 105.587 +    /// \brief Resizes the graph
 105.588 +    ///
 105.589 +    /// This function resizes the graph. It fully destroys and
 105.590 +    /// rebuilds the structure, therefore the maps of the graph will be
 105.591 +    /// reallocated automatically and the previous values will be lost.
 105.592 +    void resize(int width, int height) {
 105.593 +      Parent::notifier(Arc()).clear();
 105.594 +      Parent::notifier(Edge()).clear();
 105.595 +      Parent::notifier(Node()).clear();
 105.596 +      construct(width, height);
 105.597 +      Parent::notifier(Node()).build();
 105.598 +      Parent::notifier(Edge()).build();
 105.599 +      Parent::notifier(Arc()).build();
 105.600 +    }
 105.601 +
 105.602 +    /// \brief The node on the given position.
 105.603 +    ///
 105.604 +    /// Gives back the node on the given position.
 105.605 +    Node operator()(int i, int j) const {
 105.606 +      return Parent::operator()(i, j);
 105.607 +    }
 105.608 +
 105.609 +    /// \brief The column index of the node.
 105.610 +    ///
 105.611 +    /// Gives back the column index of the node.
 105.612 +    int col(Node n) const {
 105.613 +      return Parent::col(n);
 105.614 +    }
 105.615 +
 105.616 +    /// \brief The row index of the node.
 105.617 +    ///
 105.618 +    /// Gives back the row index of the node.
 105.619 +    int row(Node n) const {
 105.620 +      return Parent::row(n);
 105.621 +    }
 105.622 +
 105.623 +    /// \brief The position of the node.
 105.624 +    ///
 105.625 +    /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
 105.626 +    dim2::Point<int> pos(Node n) const {
 105.627 +      return Parent::pos(n);
 105.628 +    }
 105.629 +
 105.630 +    /// \brief The number of the columns.
 105.631 +    ///
 105.632 +    /// Gives back the number of the columns.
 105.633 +    int width() const {
 105.634 +      return Parent::width();
 105.635 +    }
 105.636 +
 105.637 +    /// \brief The number of the rows.
 105.638 +    ///
 105.639 +    /// Gives back the number of the rows.
 105.640 +    int height() const {
 105.641 +      return Parent::height();
 105.642 +    }
 105.643 +
 105.644 +    /// \brief The arc goes right from the node.
 105.645 +    ///
 105.646 +    /// Gives back the arc goes right from the node. If there is not
 105.647 +    /// outgoing arc then it gives back INVALID.
 105.648 +    Arc right(Node n) const {
 105.649 +      return Parent::right(n);
 105.650 +    }
 105.651 +
 105.652 +    /// \brief The arc goes left from the node.
 105.653 +    ///
 105.654 +    /// Gives back the arc goes left from the node. If there is not
 105.655 +    /// outgoing arc then it gives back INVALID.
 105.656 +    Arc left(Node n) const {
 105.657 +      return Parent::left(n);
 105.658 +    }
 105.659 +
 105.660 +    /// \brief The arc goes up from the node.
 105.661 +    ///
 105.662 +    /// Gives back the arc goes up from the node. If there is not
 105.663 +    /// outgoing arc then it gives back INVALID.
 105.664 +    Arc up(Node n) const {
 105.665 +      return Parent::up(n);
 105.666 +    }
 105.667 +
 105.668 +    /// \brief The arc goes down from the node.
 105.669 +    ///
 105.670 +    /// Gives back the arc goes down from the node. If there is not
 105.671 +    /// outgoing arc then it gives back INVALID.
 105.672 +    Arc down(Node n) const {
 105.673 +      return Parent::down(n);
 105.674 +    }
 105.675 +
 105.676 +    /// \brief Index map of the grid graph
 105.677 +    ///
 105.678 +    /// Just returns an IndexMap for the grid graph.
 105.679 +    IndexMap indexMap() const {
 105.680 +      return IndexMap(*this);
 105.681 +    }
 105.682 +
 105.683 +    /// \brief Row map of the grid graph
 105.684 +    ///
 105.685 +    /// Just returns a RowMap for the grid graph.
 105.686 +    RowMap rowMap() const {
 105.687 +      return RowMap(*this);
 105.688 +    }
 105.689 +
 105.690 +    /// \brief Column map of the grid graph
 105.691 +    ///
 105.692 +    /// Just returns a ColMap for the grid graph.
 105.693 +    ColMap colMap() const {
 105.694 +      return ColMap(*this);
 105.695 +    }
 105.696 +
 105.697 +  };
 105.698 +
 105.699 +}
 105.700 +#endif
   106.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.2 +++ b/lemon/hao_orlin.h	Thu Nov 05 15:50:01 2009 +0100
   106.3 @@ -0,0 +1,988 @@
   106.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   106.5 + *
   106.6 + * This file is a part of LEMON, a generic C++ optimization library.
   106.7 + *
   106.8 + * Copyright (C) 2003-2009
   106.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  106.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  106.11 + *
  106.12 + * Permission to use, modify and distribute this software is granted
  106.13 + * provided that this copyright notice appears in all copies. For
  106.14 + * precise terms see the accompanying LICENSE file.
  106.15 + *
  106.16 + * This software is provided "AS IS" with no warranty of any kind,
  106.17 + * express or implied, and with no claim as to its suitability for any
  106.18 + * purpose.
  106.19 + *
  106.20 + */
  106.21 +
  106.22 +#ifndef LEMON_HAO_ORLIN_H
  106.23 +#define LEMON_HAO_ORLIN_H
  106.24 +
  106.25 +#include <vector>
  106.26 +#include <list>
  106.27 +#include <limits>
  106.28 +
  106.29 +#include <lemon/maps.h>
  106.30 +#include <lemon/core.h>
  106.31 +#include <lemon/tolerance.h>
  106.32 +
  106.33 +/// \file
  106.34 +/// \ingroup min_cut
  106.35 +/// \brief Implementation of the Hao-Orlin algorithm.
  106.36 +///
  106.37 +/// Implementation of the Hao-Orlin algorithm for finding a minimum cut 
  106.38 +/// in a digraph.
  106.39 +
  106.40 +namespace lemon {
  106.41 +
  106.42 +  /// \ingroup min_cut
  106.43 +  ///
  106.44 +  /// \brief Hao-Orlin algorithm for finding a minimum cut in a digraph.
  106.45 +  ///
  106.46 +  /// This class implements the Hao-Orlin algorithm for finding a minimum
  106.47 +  /// value cut in a directed graph \f$D=(V,A)\f$. 
  106.48 +  /// It takes a fixed node \f$ source \in V \f$ and
  106.49 +  /// consists of two phases: in the first phase it determines a
  106.50 +  /// minimum cut with \f$ source \f$ on the source-side (i.e. a set
  106.51 +  /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal outgoing
  106.52 +  /// capacity) and in the second phase it determines a minimum cut
  106.53 +  /// with \f$ source \f$ on the sink-side (i.e. a set
  106.54 +  /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal outgoing
  106.55 +  /// capacity). Obviously, the smaller of these two cuts will be a
  106.56 +  /// minimum cut of \f$ D \f$. The algorithm is a modified
  106.57 +  /// preflow push-relabel algorithm. Our implementation calculates
  106.58 +  /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the
  106.59 +  /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The
  106.60 +  /// purpose of such algorithm is e.g. testing network reliability.
  106.61 +  ///
  106.62 +  /// For an undirected graph you can run just the first phase of the
  106.63 +  /// algorithm or you can use the algorithm of Nagamochi and Ibaraki,
  106.64 +  /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$ 
  106.65 +  /// time. It is implemented in the NagamochiIbaraki algorithm class.
  106.66 +  ///
  106.67 +  /// \tparam GR The type of the digraph the algorithm runs on.
  106.68 +  /// \tparam CAP The type of the arc map containing the capacities,
  106.69 +  /// which can be any numreric type. The default map type is
  106.70 +  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
  106.71 +  /// \tparam TOL Tolerance class for handling inexact computations. The
  106.72 +  /// default tolerance type is \ref Tolerance "Tolerance<CAP::Value>".
  106.73 +#ifdef DOXYGEN
  106.74 +  template <typename GR, typename CAP, typename TOL>
  106.75 +#else
  106.76 +  template <typename GR,
  106.77 +            typename CAP = typename GR::template ArcMap<int>,
  106.78 +            typename TOL = Tolerance<typename CAP::Value> >
  106.79 +#endif
  106.80 +  class HaoOrlin {
  106.81 +  public:
  106.82 +   
  106.83 +    /// The digraph type of the algorithm
  106.84 +    typedef GR Digraph;
  106.85 +    /// The capacity map type of the algorithm
  106.86 +    typedef CAP CapacityMap;
  106.87 +    /// The tolerance type of the algorithm
  106.88 +    typedef TOL Tolerance;
  106.89 +
  106.90 +  private:
  106.91 +
  106.92 +    typedef typename CapacityMap::Value Value;
  106.93 +
  106.94 +    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
  106.95 +
  106.96 +    const Digraph& _graph;
  106.97 +    const CapacityMap* _capacity;
  106.98 +
  106.99 +    typedef typename Digraph::template ArcMap<Value> FlowMap;
 106.100 +    FlowMap* _flow;
 106.101 +
 106.102 +    Node _source;
 106.103 +
 106.104 +    int _node_num;
 106.105 +
 106.106 +    // Bucketing structure
 106.107 +    std::vector<Node> _first, _last;
 106.108 +    typename Digraph::template NodeMap<Node>* _next;
 106.109 +    typename Digraph::template NodeMap<Node>* _prev;
 106.110 +    typename Digraph::template NodeMap<bool>* _active;
 106.111 +    typename Digraph::template NodeMap<int>* _bucket;
 106.112 +
 106.113 +    std::vector<bool> _dormant;
 106.114 +
 106.115 +    std::list<std::list<int> > _sets;
 106.116 +    std::list<int>::iterator _highest;
 106.117 +
 106.118 +    typedef typename Digraph::template NodeMap<Value> ExcessMap;
 106.119 +    ExcessMap* _excess;
 106.120 +
 106.121 +    typedef typename Digraph::template NodeMap<bool> SourceSetMap;
 106.122 +    SourceSetMap* _source_set;
 106.123 +
 106.124 +    Value _min_cut;
 106.125 +
 106.126 +    typedef typename Digraph::template NodeMap<bool> MinCutMap;
 106.127 +    MinCutMap* _min_cut_map;
 106.128 +
 106.129 +    Tolerance _tolerance;
 106.130 +
 106.131 +  public:
 106.132 +
 106.133 +    /// \brief Constructor
 106.134 +    ///
 106.135 +    /// Constructor of the algorithm class.
 106.136 +    HaoOrlin(const Digraph& graph, const CapacityMap& capacity,
 106.137 +             const Tolerance& tolerance = Tolerance()) :
 106.138 +      _graph(graph), _capacity(&capacity), _flow(0), _source(),
 106.139 +      _node_num(), _first(), _last(), _next(0), _prev(0),
 106.140 +      _active(0), _bucket(0), _dormant(), _sets(), _highest(),
 106.141 +      _excess(0), _source_set(0), _min_cut(), _min_cut_map(0),
 106.142 +      _tolerance(tolerance) {}
 106.143 +
 106.144 +    ~HaoOrlin() {
 106.145 +      if (_min_cut_map) {
 106.146 +        delete _min_cut_map;
 106.147 +      }
 106.148 +      if (_source_set) {
 106.149 +        delete _source_set;
 106.150 +      }
 106.151 +      if (_excess) {
 106.152 +        delete _excess;
 106.153 +      }
 106.154 +      if (_next) {
 106.155 +        delete _next;
 106.156 +      }
 106.157 +      if (_prev) {
 106.158 +        delete _prev;
 106.159 +      }
 106.160 +      if (_active) {
 106.161 +        delete _active;
 106.162 +      }
 106.163 +      if (_bucket) {
 106.164 +        delete _bucket;
 106.165 +      }
 106.166 +      if (_flow) {
 106.167 +        delete _flow;
 106.168 +      }
 106.169 +    }
 106.170 +
 106.171 +  private:
 106.172 +
 106.173 +    void activate(const Node& i) {
 106.174 +      (*_active)[i] = true;
 106.175 +
 106.176 +      int bucket = (*_bucket)[i];
 106.177 +
 106.178 +      if ((*_prev)[i] == INVALID || (*_active)[(*_prev)[i]]) return;
 106.179 +      //unlace
 106.180 +      (*_next)[(*_prev)[i]] = (*_next)[i];
 106.181 +      if ((*_next)[i] != INVALID) {
 106.182 +        (*_prev)[(*_next)[i]] = (*_prev)[i];
 106.183 +      } else {
 106.184 +        _last[bucket] = (*_prev)[i];
 106.185 +      }
 106.186 +      //lace
 106.187 +      (*_next)[i] = _first[bucket];
 106.188 +      (*_prev)[_first[bucket]] = i;
 106.189 +      (*_prev)[i] = INVALID;
 106.190 +      _first[bucket] = i;
 106.191 +    }
 106.192 +
 106.193 +    void deactivate(const Node& i) {
 106.194 +      (*_active)[i] = false;
 106.195 +      int bucket = (*_bucket)[i];
 106.196 +
 106.197 +      if ((*_next)[i] == INVALID || !(*_active)[(*_next)[i]]) return;
 106.198 +
 106.199 +      //unlace
 106.200 +      (*_prev)[(*_next)[i]] = (*_prev)[i];
 106.201 +      if ((*_prev)[i] != INVALID) {
 106.202 +        (*_next)[(*_prev)[i]] = (*_next)[i];
 106.203 +      } else {
 106.204 +        _first[bucket] = (*_next)[i];
 106.205 +      }
 106.206 +      //lace
 106.207 +      (*_prev)[i] = _last[bucket];
 106.208 +      (*_next)[_last[bucket]] = i;
 106.209 +      (*_next)[i] = INVALID;
 106.210 +      _last[bucket] = i;
 106.211 +    }
 106.212 +
 106.213 +    void addItem(const Node& i, int bucket) {
 106.214 +      (*_bucket)[i] = bucket;
 106.215 +      if (_last[bucket] != INVALID) {
 106.216 +        (*_prev)[i] = _last[bucket];
 106.217 +        (*_next)[_last[bucket]] = i;
 106.218 +        (*_next)[i] = INVALID;
 106.219 +        _last[bucket] = i;
 106.220 +      } else {
 106.221 +        (*_prev)[i] = INVALID;
 106.222 +        _first[bucket] = i;
 106.223 +        (*_next)[i] = INVALID;
 106.224 +        _last[bucket] = i;
 106.225 +      }
 106.226 +    }
 106.227 +
 106.228 +    void findMinCutOut() {
 106.229 +
 106.230 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 106.231 +        (*_excess)[n] = 0;
 106.232 +        (*_source_set)[n] = false;
 106.233 +      }
 106.234 +
 106.235 +      for (ArcIt a(_graph); a != INVALID; ++a) {
 106.236 +        (*_flow)[a] = 0;
 106.237 +      }
 106.238 +
 106.239 +      int bucket_num = 0;
 106.240 +      std::vector<Node> queue(_node_num);
 106.241 +      int qfirst = 0, qlast = 0, qsep = 0;
 106.242 +
 106.243 +      {
 106.244 +        typename Digraph::template NodeMap<bool> reached(_graph, false);
 106.245 +
 106.246 +        reached[_source] = true;
 106.247 +        bool first_set = true;
 106.248 +
 106.249 +        for (NodeIt t(_graph); t != INVALID; ++t) {
 106.250 +          if (reached[t]) continue;
 106.251 +          _sets.push_front(std::list<int>());
 106.252 +
 106.253 +          queue[qlast++] = t;
 106.254 +          reached[t] = true;
 106.255 +
 106.256 +          while (qfirst != qlast) {
 106.257 +            if (qsep == qfirst) {
 106.258 +              ++bucket_num;
 106.259 +              _sets.front().push_front(bucket_num);
 106.260 +              _dormant[bucket_num] = !first_set;
 106.261 +              _first[bucket_num] = _last[bucket_num] = INVALID;
 106.262 +              qsep = qlast;
 106.263 +            }
 106.264 +
 106.265 +            Node n = queue[qfirst++];
 106.266 +            addItem(n, bucket_num);
 106.267 +
 106.268 +            for (InArcIt a(_graph, n); a != INVALID; ++a) {
 106.269 +              Node u = _graph.source(a);
 106.270 +              if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
 106.271 +                reached[u] = true;
 106.272 +                queue[qlast++] = u;
 106.273 +              }
 106.274 +            }
 106.275 +          }
 106.276 +          first_set = false;
 106.277 +        }
 106.278 +
 106.279 +        ++bucket_num;
 106.280 +        (*_bucket)[_source] = 0;
 106.281 +        _dormant[0] = true;
 106.282 +      }
 106.283 +      (*_source_set)[_source] = true;
 106.284 +
 106.285 +      Node target = _last[_sets.back().back()];
 106.286 +      {
 106.287 +        for (OutArcIt a(_graph, _source); a != INVALID; ++a) {
 106.288 +          if (_tolerance.positive((*_capacity)[a])) {
 106.289 +            Node u = _graph.target(a);
 106.290 +            (*_flow)[a] = (*_capacity)[a];
 106.291 +            (*_excess)[u] += (*_capacity)[a];
 106.292 +            if (!(*_active)[u] && u != _source) {
 106.293 +              activate(u);
 106.294 +            }
 106.295 +          }
 106.296 +        }
 106.297 +
 106.298 +        if ((*_active)[target]) {
 106.299 +          deactivate(target);
 106.300 +        }
 106.301 +
 106.302 +        _highest = _sets.back().begin();
 106.303 +        while (_highest != _sets.back().end() &&
 106.304 +               !(*_active)[_first[*_highest]]) {
 106.305 +          ++_highest;
 106.306 +        }
 106.307 +      }
 106.308 +
 106.309 +      while (true) {
 106.310 +        while (_highest != _sets.back().end()) {
 106.311 +          Node n = _first[*_highest];
 106.312 +          Value excess = (*_excess)[n];
 106.313 +          int next_bucket = _node_num;
 106.314 +
 106.315 +          int under_bucket;
 106.316 +          if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
 106.317 +            under_bucket = -1;
 106.318 +          } else {
 106.319 +            under_bucket = *(++std::list<int>::iterator(_highest));
 106.320 +          }
 106.321 +
 106.322 +          for (OutArcIt a(_graph, n); a != INVALID; ++a) {
 106.323 +            Node v = _graph.target(a);
 106.324 +            if (_dormant[(*_bucket)[v]]) continue;
 106.325 +            Value rem = (*_capacity)[a] - (*_flow)[a];
 106.326 +            if (!_tolerance.positive(rem)) continue;
 106.327 +            if ((*_bucket)[v] == under_bucket) {
 106.328 +              if (!(*_active)[v] && v != target) {
 106.329 +                activate(v);
 106.330 +              }
 106.331 +              if (!_tolerance.less(rem, excess)) {
 106.332 +                (*_flow)[a] += excess;
 106.333 +                (*_excess)[v] += excess;
 106.334 +                excess = 0;
 106.335 +                goto no_more_push;
 106.336 +              } else {
 106.337 +                excess -= rem;
 106.338 +                (*_excess)[v] += rem;
 106.339 +                (*_flow)[a] = (*_capacity)[a];
 106.340 +              }
 106.341 +            } else if (next_bucket > (*_bucket)[v]) {
 106.342 +              next_bucket = (*_bucket)[v];
 106.343 +            }
 106.344 +          }
 106.345 +
 106.346 +          for (InArcIt a(_graph, n); a != INVALID; ++a) {
 106.347 +            Node v = _graph.source(a);
 106.348 +            if (_dormant[(*_bucket)[v]]) continue;
 106.349 +            Value rem = (*_flow)[a];
 106.350 +            if (!_tolerance.positive(rem)) continue;
 106.351 +            if ((*_bucket)[v] == under_bucket) {
 106.352 +              if (!(*_active)[v] && v != target) {
 106.353 +                activate(v);
 106.354 +              }
 106.355 +              if (!_tolerance.less(rem, excess)) {
 106.356 +                (*_flow)[a] -= excess;
 106.357 +                (*_excess)[v] += excess;
 106.358 +                excess = 0;
 106.359 +                goto no_more_push;
 106.360 +              } else {
 106.361 +                excess -= rem;
 106.362 +                (*_excess)[v] += rem;
 106.363 +                (*_flow)[a] = 0;
 106.364 +              }
 106.365 +            } else if (next_bucket > (*_bucket)[v]) {
 106.366 +              next_bucket = (*_bucket)[v];
 106.367 +            }
 106.368 +          }
 106.369 +
 106.370 +        no_more_push:
 106.371 +
 106.372 +          (*_excess)[n] = excess;
 106.373 +
 106.374 +          if (excess != 0) {
 106.375 +            if ((*_next)[n] == INVALID) {
 106.376 +              typename std::list<std::list<int> >::iterator new_set =
 106.377 +                _sets.insert(--_sets.end(), std::list<int>());
 106.378 +              new_set->splice(new_set->end(), _sets.back(),
 106.379 +                              _sets.back().begin(), ++_highest);
 106.380 +              for (std::list<int>::iterator it = new_set->begin();
 106.381 +                   it != new_set->end(); ++it) {
 106.382 +                _dormant[*it] = true;
 106.383 +              }
 106.384 +              while (_highest != _sets.back().end() &&
 106.385 +                     !(*_active)[_first[*_highest]]) {
 106.386 +                ++_highest;
 106.387 +              }
 106.388 +            } else if (next_bucket == _node_num) {
 106.389 +              _first[(*_bucket)[n]] = (*_next)[n];
 106.390 +              (*_prev)[(*_next)[n]] = INVALID;
 106.391 +
 106.392 +              std::list<std::list<int> >::iterator new_set =
 106.393 +                _sets.insert(--_sets.end(), std::list<int>());
 106.394 +
 106.395 +              new_set->push_front(bucket_num);
 106.396 +              (*_bucket)[n] = bucket_num;
 106.397 +              _first[bucket_num] = _last[bucket_num] = n;
 106.398 +              (*_next)[n] = INVALID;
 106.399 +              (*_prev)[n] = INVALID;
 106.400 +              _dormant[bucket_num] = true;
 106.401 +              ++bucket_num;
 106.402 +
 106.403 +              while (_highest != _sets.back().end() &&
 106.404 +                     !(*_active)[_first[*_highest]]) {
 106.405 +                ++_highest;
 106.406 +              }
 106.407 +            } else {
 106.408 +              _first[*_highest] = (*_next)[n];
 106.409 +              (*_prev)[(*_next)[n]] = INVALID;
 106.410 +
 106.411 +              while (next_bucket != *_highest) {
 106.412 +                --_highest;
 106.413 +              }
 106.414 +
 106.415 +              if (_highest == _sets.back().begin()) {
 106.416 +                _sets.back().push_front(bucket_num);
 106.417 +                _dormant[bucket_num] = false;
 106.418 +                _first[bucket_num] = _last[bucket_num] = INVALID;
 106.419 +                ++bucket_num;
 106.420 +              }
 106.421 +              --_highest;
 106.422 +
 106.423 +              (*_bucket)[n] = *_highest;
 106.424 +              (*_next)[n] = _first[*_highest];
 106.425 +              if (_first[*_highest] != INVALID) {
 106.426 +                (*_prev)[_first[*_highest]] = n;
 106.427 +              } else {
 106.428 +                _last[*_highest] = n;
 106.429 +              }
 106.430 +              _first[*_highest] = n;
 106.431 +            }
 106.432 +          } else {
 106.433 +
 106.434 +            deactivate(n);
 106.435 +            if (!(*_active)[_first[*_highest]]) {
 106.436 +              ++_highest;
 106.437 +              if (_highest != _sets.back().end() &&
 106.438 +                  !(*_active)[_first[*_highest]]) {
 106.439 +                _highest = _sets.back().end();
 106.440 +              }
 106.441 +            }
 106.442 +          }
 106.443 +        }
 106.444 +
 106.445 +        if ((*_excess)[target] < _min_cut) {
 106.446 +          _min_cut = (*_excess)[target];
 106.447 +          for (NodeIt i(_graph); i != INVALID; ++i) {
 106.448 +            (*_min_cut_map)[i] = true;
 106.449 +          }
 106.450 +          for (std::list<int>::iterator it = _sets.back().begin();
 106.451 +               it != _sets.back().end(); ++it) {
 106.452 +            Node n = _first[*it];
 106.453 +            while (n != INVALID) {
 106.454 +              (*_min_cut_map)[n] = false;
 106.455 +              n = (*_next)[n];
 106.456 +            }
 106.457 +          }
 106.458 +        }
 106.459 +
 106.460 +        {
 106.461 +          Node new_target;
 106.462 +          if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
 106.463 +            if ((*_next)[target] == INVALID) {
 106.464 +              _last[(*_bucket)[target]] = (*_prev)[target];
 106.465 +              new_target = (*_prev)[target];
 106.466 +            } else {
 106.467 +              (*_prev)[(*_next)[target]] = (*_prev)[target];
 106.468 +              new_target = (*_next)[target];
 106.469 +            }
 106.470 +            if ((*_prev)[target] == INVALID) {
 106.471 +              _first[(*_bucket)[target]] = (*_next)[target];
 106.472 +            } else {
 106.473 +              (*_next)[(*_prev)[target]] = (*_next)[target];
 106.474 +            }
 106.475 +          } else {
 106.476 +            _sets.back().pop_back();
 106.477 +            if (_sets.back().empty()) {
 106.478 +              _sets.pop_back();
 106.479 +              if (_sets.empty())
 106.480 +                break;
 106.481 +              for (std::list<int>::iterator it = _sets.back().begin();
 106.482 +                   it != _sets.back().end(); ++it) {
 106.483 +                _dormant[*it] = false;
 106.484 +              }
 106.485 +            }
 106.486 +            new_target = _last[_sets.back().back()];
 106.487 +          }
 106.488 +
 106.489 +          (*_bucket)[target] = 0;
 106.490 +
 106.491 +          (*_source_set)[target] = true;
 106.492 +          for (OutArcIt a(_graph, target); a != INVALID; ++a) {
 106.493 +            Value rem = (*_capacity)[a] - (*_flow)[a];
 106.494 +            if (!_tolerance.positive(rem)) continue;
 106.495 +            Node v = _graph.target(a);
 106.496 +            if (!(*_active)[v] && !(*_source_set)[v]) {
 106.497 +              activate(v);
 106.498 +            }
 106.499 +            (*_excess)[v] += rem;
 106.500 +            (*_flow)[a] = (*_capacity)[a];
 106.501 +          }
 106.502 +
 106.503 +          for (InArcIt a(_graph, target); a != INVALID; ++a) {
 106.504 +            Value rem = (*_flow)[a];
 106.505 +            if (!_tolerance.positive(rem)) continue;
 106.506 +            Node v = _graph.source(a);
 106.507 +            if (!(*_active)[v] && !(*_source_set)[v]) {
 106.508 +              activate(v);
 106.509 +            }
 106.510 +            (*_excess)[v] += rem;
 106.511 +            (*_flow)[a] = 0;
 106.512 +          }
 106.513 +
 106.514 +          target = new_target;
 106.515 +          if ((*_active)[target]) {
 106.516 +            deactivate(target);
 106.517 +          }
 106.518 +
 106.519 +          _highest = _sets.back().begin();
 106.520 +          while (_highest != _sets.back().end() &&
 106.521 +                 !(*_active)[_first[*_highest]]) {
 106.522 +            ++_highest;
 106.523 +          }
 106.524 +        }
 106.525 +      }
 106.526 +    }
 106.527 +
 106.528 +    void findMinCutIn() {
 106.529 +
 106.530 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 106.531 +        (*_excess)[n] = 0;
 106.532 +        (*_source_set)[n] = false;
 106.533 +      }
 106.534 +
 106.535 +      for (ArcIt a(_graph); a != INVALID; ++a) {
 106.536 +        (*_flow)[a] = 0;
 106.537 +      }
 106.538 +
 106.539 +      int bucket_num = 0;
 106.540 +      std::vector<Node> queue(_node_num);
 106.541 +      int qfirst = 0, qlast = 0, qsep = 0;
 106.542 +
 106.543 +      {
 106.544 +        typename Digraph::template NodeMap<bool> reached(_graph, false);
 106.545 +
 106.546 +        reached[_source] = true;
 106.547 +
 106.548 +        bool first_set = true;
 106.549 +
 106.550 +        for (NodeIt t(_graph); t != INVALID; ++t) {
 106.551 +          if (reached[t]) continue;
 106.552 +          _sets.push_front(std::list<int>());
 106.553 +
 106.554 +          queue[qlast++] = t;
 106.555 +          reached[t] = true;
 106.556 +
 106.557 +          while (qfirst != qlast) {
 106.558 +            if (qsep == qfirst) {
 106.559 +              ++bucket_num;
 106.560 +              _sets.front().push_front(bucket_num);
 106.561 +              _dormant[bucket_num] = !first_set;
 106.562 +              _first[bucket_num] = _last[bucket_num] = INVALID;
 106.563 +              qsep = qlast;
 106.564 +            }
 106.565 +
 106.566 +            Node n = queue[qfirst++];
 106.567 +            addItem(n, bucket_num);
 106.568 +
 106.569 +            for (OutArcIt a(_graph, n); a != INVALID; ++a) {
 106.570 +              Node u = _graph.target(a);
 106.571 +              if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
 106.572 +                reached[u] = true;
 106.573 +                queue[qlast++] = u;
 106.574 +              }
 106.575 +            }
 106.576 +          }
 106.577 +          first_set = false;
 106.578 +        }
 106.579 +
 106.580 +        ++bucket_num;
 106.581 +        (*_bucket)[_source] = 0;
 106.582 +        _dormant[0] = true;
 106.583 +      }
 106.584 +      (*_source_set)[_source] = true;
 106.585 +
 106.586 +      Node target = _last[_sets.back().back()];
 106.587 +      {
 106.588 +        for (InArcIt a(_graph, _source); a != INVALID; ++a) {
 106.589 +          if (_tolerance.positive((*_capacity)[a])) {
 106.590 +            Node u = _graph.source(a);
 106.591 +            (*_flow)[a] = (*_capacity)[a];
 106.592 +            (*_excess)[u] += (*_capacity)[a];
 106.593 +            if (!(*_active)[u] && u != _source) {
 106.594 +              activate(u);
 106.595 +            }
 106.596 +          }
 106.597 +        }
 106.598 +        if ((*_active)[target]) {
 106.599 +          deactivate(target);
 106.600 +        }
 106.601 +
 106.602 +        _highest = _sets.back().begin();
 106.603 +        while (_highest != _sets.back().end() &&
 106.604 +               !(*_active)[_first[*_highest]]) {
 106.605 +          ++_highest;
 106.606 +        }
 106.607 +      }
 106.608 +
 106.609 +
 106.610 +      while (true) {
 106.611 +        while (_highest != _sets.back().end()) {
 106.612 +          Node n = _first[*_highest];
 106.613 +          Value excess = (*_excess)[n];
 106.614 +          int next_bucket = _node_num;
 106.615 +
 106.616 +          int under_bucket;
 106.617 +          if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
 106.618 +            under_bucket = -1;
 106.619 +          } else {
 106.620 +            under_bucket = *(++std::list<int>::iterator(_highest));
 106.621 +          }
 106.622 +
 106.623 +          for (InArcIt a(_graph, n); a != INVALID; ++a) {
 106.624 +            Node v = _graph.source(a);
 106.625 +            if (_dormant[(*_bucket)[v]]) continue;
 106.626 +            Value rem = (*_capacity)[a] - (*_flow)[a];
 106.627 +            if (!_tolerance.positive(rem)) continue;
 106.628 +            if ((*_bucket)[v] == under_bucket) {
 106.629 +              if (!(*_active)[v] && v != target) {
 106.630 +                activate(v);
 106.631 +              }
 106.632 +              if (!_tolerance.less(rem, excess)) {
 106.633 +                (*_flow)[a] += excess;
 106.634 +                (*_excess)[v] += excess;
 106.635 +                excess = 0;
 106.636 +                goto no_more_push;
 106.637 +              } else {
 106.638 +                excess -= rem;
 106.639 +                (*_excess)[v] += rem;
 106.640 +                (*_flow)[a] = (*_capacity)[a];
 106.641 +              }
 106.642 +            } else if (next_bucket > (*_bucket)[v]) {
 106.643 +              next_bucket = (*_bucket)[v];
 106.644 +            }
 106.645 +          }
 106.646 +
 106.647 +          for (OutArcIt a(_graph, n); a != INVALID; ++a) {
 106.648 +            Node v = _graph.target(a);
 106.649 +            if (_dormant[(*_bucket)[v]]) continue;
 106.650 +            Value rem = (*_flow)[a];
 106.651 +            if (!_tolerance.positive(rem)) continue;
 106.652 +            if ((*_bucket)[v] == under_bucket) {
 106.653 +              if (!(*_active)[v] && v != target) {
 106.654 +                activate(v);
 106.655 +              }
 106.656 +              if (!_tolerance.less(rem, excess)) {
 106.657 +                (*_flow)[a] -= excess;
 106.658 +                (*_excess)[v] += excess;
 106.659 +                excess = 0;
 106.660 +                goto no_more_push;
 106.661 +              } else {
 106.662 +                excess -= rem;
 106.663 +                (*_excess)[v] += rem;
 106.664 +                (*_flow)[a] = 0;
 106.665 +              }
 106.666 +            } else if (next_bucket > (*_bucket)[v]) {
 106.667 +              next_bucket = (*_bucket)[v];
 106.668 +            }
 106.669 +          }
 106.670 +
 106.671 +        no_more_push:
 106.672 +
 106.673 +          (*_excess)[n] = excess;
 106.674 +
 106.675 +          if (excess != 0) {
 106.676 +            if ((*_next)[n] == INVALID) {
 106.677 +              typename std::list<std::list<int> >::iterator new_set =
 106.678 +                _sets.insert(--_sets.end(), std::list<int>());
 106.679 +              new_set->splice(new_set->end(), _sets.back(),
 106.680 +                              _sets.back().begin(), ++_highest);
 106.681 +              for (std::list<int>::iterator it = new_set->begin();
 106.682 +                   it != new_set->end(); ++it) {
 106.683 +                _dormant[*it] = true;
 106.684 +              }
 106.685 +              while (_highest != _sets.back().end() &&
 106.686 +                     !(*_active)[_first[*_highest]]) {
 106.687 +                ++_highest;
 106.688 +              }
 106.689 +            } else if (next_bucket == _node_num) {
 106.690 +              _first[(*_bucket)[n]] = (*_next)[n];
 106.691 +              (*_prev)[(*_next)[n]] = INVALID;
 106.692 +
 106.693 +              std::list<std::list<int> >::iterator new_set =
 106.694 +                _sets.insert(--_sets.end(), std::list<int>());
 106.695 +
 106.696 +              new_set->push_front(bucket_num);
 106.697 +              (*_bucket)[n] = bucket_num;
 106.698 +              _first[bucket_num] = _last[bucket_num] = n;
 106.699 +              (*_next)[n] = INVALID;
 106.700 +              (*_prev)[n] = INVALID;
 106.701 +              _dormant[bucket_num] = true;
 106.702 +              ++bucket_num;
 106.703 +
 106.704 +              while (_highest != _sets.back().end() &&
 106.705 +                     !(*_active)[_first[*_highest]]) {
 106.706 +                ++_highest;
 106.707 +              }
 106.708 +            } else {
 106.709 +              _first[*_highest] = (*_next)[n];
 106.710 +              (*_prev)[(*_next)[n]] = INVALID;
 106.711 +
 106.712 +              while (next_bucket != *_highest) {
 106.713 +                --_highest;
 106.714 +              }
 106.715 +              if (_highest == _sets.back().begin()) {
 106.716 +                _sets.back().push_front(bucket_num);
 106.717 +                _dormant[bucket_num] = false;
 106.718 +                _first[bucket_num] = _last[bucket_num] = INVALID;
 106.719 +                ++bucket_num;
 106.720 +              }
 106.721 +              --_highest;
 106.722 +
 106.723 +              (*_bucket)[n] = *_highest;
 106.724 +              (*_next)[n] = _first[*_highest];
 106.725 +              if (_first[*_highest] != INVALID) {
 106.726 +                (*_prev)[_first[*_highest]] = n;
 106.727 +              } else {
 106.728 +                _last[*_highest] = n;
 106.729 +              }
 106.730 +              _first[*_highest] = n;
 106.731 +            }
 106.732 +          } else {
 106.733 +
 106.734 +            deactivate(n);
 106.735 +            if (!(*_active)[_first[*_highest]]) {
 106.736 +              ++_highest;
 106.737 +              if (_highest != _sets.back().end() &&
 106.738 +                  !(*_active)[_first[*_highest]]) {
 106.739 +                _highest = _sets.back().end();
 106.740 +              }
 106.741 +            }
 106.742 +          }
 106.743 +        }
 106.744 +
 106.745 +        if ((*_excess)[target] < _min_cut) {
 106.746 +          _min_cut = (*_excess)[target];
 106.747 +          for (NodeIt i(_graph); i != INVALID; ++i) {
 106.748 +            (*_min_cut_map)[i] = false;
 106.749 +          }
 106.750 +          for (std::list<int>::iterator it = _sets.back().begin();
 106.751 +               it != _sets.back().end(); ++it) {
 106.752 +            Node n = _first[*it];
 106.753 +            while (n != INVALID) {
 106.754 +              (*_min_cut_map)[n] = true;
 106.755 +              n = (*_next)[n];
 106.756 +            }
 106.757 +          }
 106.758 +        }
 106.759 +
 106.760 +        {
 106.761 +          Node new_target;
 106.762 +          if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
 106.763 +            if ((*_next)[target] == INVALID) {
 106.764 +              _last[(*_bucket)[target]] = (*_prev)[target];
 106.765 +              new_target = (*_prev)[target];
 106.766 +            } else {
 106.767 +              (*_prev)[(*_next)[target]] = (*_prev)[target];
 106.768 +              new_target = (*_next)[target];
 106.769 +            }
 106.770 +            if ((*_prev)[target] == INVALID) {
 106.771 +              _first[(*_bucket)[target]] = (*_next)[target];
 106.772 +            } else {
 106.773 +              (*_next)[(*_prev)[target]] = (*_next)[target];
 106.774 +            }
 106.775 +          } else {
 106.776 +            _sets.back().pop_back();
 106.777 +            if (_sets.back().empty()) {
 106.778 +              _sets.pop_back();
 106.779 +              if (_sets.empty())
 106.780 +                break;
 106.781 +              for (std::list<int>::iterator it = _sets.back().begin();
 106.782 +                   it != _sets.back().end(); ++it) {
 106.783 +                _dormant[*it] = false;
 106.784 +              }
 106.785 +            }
 106.786 +            new_target = _last[_sets.back().back()];
 106.787 +          }
 106.788 +
 106.789 +          (*_bucket)[target] = 0;
 106.790 +
 106.791 +          (*_source_set)[target] = true;
 106.792 +          for (InArcIt a(_graph, target); a != INVALID; ++a) {
 106.793 +            Value rem = (*_capacity)[a] - (*_flow)[a];
 106.794 +            if (!_tolerance.positive(rem)) continue;
 106.795 +            Node v = _graph.source(a);
 106.796 +            if (!(*_active)[v] && !(*_source_set)[v]) {
 106.797 +              activate(v);
 106.798 +            }
 106.799 +            (*_excess)[v] += rem;
 106.800 +            (*_flow)[a] = (*_capacity)[a];
 106.801 +          }
 106.802 +
 106.803 +          for (OutArcIt a(_graph, target); a != INVALID; ++a) {
 106.804 +            Value rem = (*_flow)[a];
 106.805 +            if (!_tolerance.positive(rem)) continue;
 106.806 +            Node v = _graph.target(a);
 106.807 +            if (!(*_active)[v] && !(*_source_set)[v]) {
 106.808 +              activate(v);
 106.809 +            }
 106.810 +            (*_excess)[v] += rem;
 106.811 +            (*_flow)[a] = 0;
 106.812 +          }
 106.813 +
 106.814 +          target = new_target;
 106.815 +          if ((*_active)[target]) {
 106.816 +            deactivate(target);
 106.817 +          }
 106.818 +
 106.819 +          _highest = _sets.back().begin();
 106.820 +          while (_highest != _sets.back().end() &&
 106.821 +                 !(*_active)[_first[*_highest]]) {
 106.822 +            ++_highest;
 106.823 +          }
 106.824 +        }
 106.825 +      }
 106.826 +    }
 106.827 +
 106.828 +  public:
 106.829 +
 106.830 +    /// \name Execution Control
 106.831 +    /// The simplest way to execute the algorithm is to use
 106.832 +    /// one of the member functions called \ref run().
 106.833 +    /// \n
 106.834 +    /// If you need better control on the execution,
 106.835 +    /// you have to call one of the \ref init() functions first, then
 106.836 +    /// \ref calculateOut() and/or \ref calculateIn().
 106.837 +
 106.838 +    /// @{
 106.839 +
 106.840 +    /// \brief Initialize the internal data structures.
 106.841 +    ///
 106.842 +    /// This function initializes the internal data structures. It creates
 106.843 +    /// the maps and some bucket structures for the algorithm.
 106.844 +    /// The first node is used as the source node for the push-relabel
 106.845 +    /// algorithm.
 106.846 +    void init() {
 106.847 +      init(NodeIt(_graph));
 106.848 +    }
 106.849 +
 106.850 +    /// \brief Initialize the internal data structures.
 106.851 +    ///
 106.852 +    /// This function initializes the internal data structures. It creates
 106.853 +    /// the maps and some bucket structures for the algorithm. 
 106.854 +    /// The given node is used as the source node for the push-relabel
 106.855 +    /// algorithm.
 106.856 +    void init(const Node& source) {
 106.857 +      _source = source;
 106.858 +
 106.859 +      _node_num = countNodes(_graph);
 106.860 +
 106.861 +      _first.resize(_node_num);
 106.862 +      _last.resize(_node_num);
 106.863 +
 106.864 +      _dormant.resize(_node_num);
 106.865 +
 106.866 +      if (!_flow) {
 106.867 +        _flow = new FlowMap(_graph);
 106.868 +      }
 106.869 +      if (!_next) {
 106.870 +        _next = new typename Digraph::template NodeMap<Node>(_graph);
 106.871 +      }
 106.872 +      if (!_prev) {
 106.873 +        _prev = new typename Digraph::template NodeMap<Node>(_graph);
 106.874 +      }
 106.875 +      if (!_active) {
 106.876 +        _active = new typename Digraph::template NodeMap<bool>(_graph);
 106.877 +      }
 106.878 +      if (!_bucket) {
 106.879 +        _bucket = new typename Digraph::template NodeMap<int>(_graph);
 106.880 +      }
 106.881 +      if (!_excess) {
 106.882 +        _excess = new ExcessMap(_graph);
 106.883 +      }
 106.884 +      if (!_source_set) {
 106.885 +        _source_set = new SourceSetMap(_graph);
 106.886 +      }
 106.887 +      if (!_min_cut_map) {
 106.888 +        _min_cut_map = new MinCutMap(_graph);
 106.889 +      }
 106.890 +
 106.891 +      _min_cut = std::numeric_limits<Value>::max();
 106.892 +    }
 106.893 +
 106.894 +
 106.895 +    /// \brief Calculate a minimum cut with \f$ source \f$ on the
 106.896 +    /// source-side.
 106.897 +    ///
 106.898 +    /// This function calculates a minimum cut with \f$ source \f$ on the
 106.899 +    /// source-side (i.e. a set \f$ X\subsetneq V \f$ with
 106.900 +    /// \f$ source \in X \f$ and minimal outgoing capacity).
 106.901 +    ///
 106.902 +    /// \pre \ref init() must be called before using this function.
 106.903 +    void calculateOut() {
 106.904 +      findMinCutOut();
 106.905 +    }
 106.906 +
 106.907 +    /// \brief Calculate a minimum cut with \f$ source \f$ on the
 106.908 +    /// sink-side.
 106.909 +    ///
 106.910 +    /// This function calculates a minimum cut with \f$ source \f$ on the
 106.911 +    /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with
 106.912 +    /// \f$ source \notin X \f$ and minimal outgoing capacity).
 106.913 +    ///
 106.914 +    /// \pre \ref init() must be called before using this function.
 106.915 +    void calculateIn() {
 106.916 +      findMinCutIn();
 106.917 +    }
 106.918 +
 106.919 +
 106.920 +    /// \brief Run the algorithm.
 106.921 +    ///
 106.922 +    /// This function runs the algorithm. It finds nodes \c source and
 106.923 +    /// \c target arbitrarily and then calls \ref init(), \ref calculateOut()
 106.924 +    /// and \ref calculateIn().
 106.925 +    void run() {
 106.926 +      init();
 106.927 +      calculateOut();
 106.928 +      calculateIn();
 106.929 +    }
 106.930 +
 106.931 +    /// \brief Run the algorithm.
 106.932 +    ///
 106.933 +    /// This function runs the algorithm. It uses the given \c source node, 
 106.934 +    /// finds a proper \c target node and then calls the \ref init(),
 106.935 +    /// \ref calculateOut() and \ref calculateIn().
 106.936 +    void run(const Node& s) {
 106.937 +      init(s);
 106.938 +      calculateOut();
 106.939 +      calculateIn();
 106.940 +    }
 106.941 +
 106.942 +    /// @}
 106.943 +
 106.944 +    /// \name Query Functions
 106.945 +    /// The result of the %HaoOrlin algorithm
 106.946 +    /// can be obtained using these functions.\n
 106.947 +    /// \ref run(), \ref calculateOut() or \ref calculateIn() 
 106.948 +    /// should be called before using them.
 106.949 +
 106.950 +    /// @{
 106.951 +
 106.952 +    /// \brief Return the value of the minimum cut.
 106.953 +    ///
 106.954 +    /// This function returns the value of the minimum cut.
 106.955 +    ///
 106.956 +    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 
 106.957 +    /// must be called before using this function.
 106.958 +    Value minCutValue() const {
 106.959 +      return _min_cut;
 106.960 +    }
 106.961 +
 106.962 +
 106.963 +    /// \brief Return a minimum cut.
 106.964 +    ///
 106.965 +    /// This function sets \c cutMap to the characteristic vector of a
 106.966 +    /// minimum value cut: it will give a non-empty set \f$ X\subsetneq V \f$
 106.967 +    /// with minimal outgoing capacity (i.e. \c cutMap will be \c true exactly
 106.968 +    /// for the nodes of \f$ X \f$).
 106.969 +    ///
 106.970 +    /// \param cutMap A \ref concepts::WriteMap "writable" node map with
 106.971 +    /// \c bool (or convertible) value type.
 106.972 +    ///
 106.973 +    /// \return The value of the minimum cut.
 106.974 +    ///
 106.975 +    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 
 106.976 +    /// must be called before using this function.
 106.977 +    template <typename CutMap>
 106.978 +    Value minCutMap(CutMap& cutMap) const {
 106.979 +      for (NodeIt it(_graph); it != INVALID; ++it) {
 106.980 +        cutMap.set(it, (*_min_cut_map)[it]);
 106.981 +      }
 106.982 +      return _min_cut;
 106.983 +    }
 106.984 +
 106.985 +    /// @}
 106.986 +
 106.987 +  }; //class HaoOrlin
 106.988 +
 106.989 +} //namespace lemon
 106.990 +
 106.991 +#endif //LEMON_HAO_ORLIN_H
   107.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   107.2 +++ b/lemon/hartmann_orlin.h	Thu Nov 05 15:50:01 2009 +0100
   107.3 @@ -0,0 +1,640 @@
   107.4 +/* -*- C++ -*-
   107.5 + *
   107.6 + * This file is a part of LEMON, a generic C++ optimization library
   107.7 + *
   107.8 + * Copyright (C) 2003-2008
   107.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  107.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  107.11 + *
  107.12 + * Permission to use, modify and distribute this software is granted
  107.13 + * provided that this copyright notice appears in all copies. For
  107.14 + * precise terms see the accompanying LICENSE file.
  107.15 + *
  107.16 + * This software is provided "AS IS" with no warranty of any kind,
  107.17 + * express or implied, and with no claim as to its suitability for any
  107.18 + * purpose.
  107.19 + *
  107.20 + */
  107.21 +
  107.22 +#ifndef LEMON_HARTMANN_ORLIN_H
  107.23 +#define LEMON_HARTMANN_ORLIN_H
  107.24 +
  107.25 +/// \ingroup min_mean_cycle
  107.26 +///
  107.27 +/// \file
  107.28 +/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
  107.29 +
  107.30 +#include <vector>
  107.31 +#include <limits>
  107.32 +#include <lemon/core.h>
  107.33 +#include <lemon/path.h>
  107.34 +#include <lemon/tolerance.h>
  107.35 +#include <lemon/connectivity.h>
  107.36 +
  107.37 +namespace lemon {
  107.38 +
  107.39 +  /// \brief Default traits class of HartmannOrlin algorithm.
  107.40 +  ///
  107.41 +  /// Default traits class of HartmannOrlin algorithm.
  107.42 +  /// \tparam GR The type of the digraph.
  107.43 +  /// \tparam LEN The type of the length map.
  107.44 +  /// It must conform to the \ref concepts::Rea_data "Rea_data" concept.
  107.45 +#ifdef DOXYGEN
  107.46 +  template <typename GR, typename LEN>
  107.47 +#else
  107.48 +  template <typename GR, typename LEN,
  107.49 +    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
  107.50 +#endif
  107.51 +  struct HartmannOrlinDefaultTraits
  107.52 +  {
  107.53 +    /// The type of the digraph
  107.54 +    typedef GR Digraph;
  107.55 +    /// The type of the length map
  107.56 +    typedef LEN LengthMap;
  107.57 +    /// The type of the arc lengths
  107.58 +    typedef typename LengthMap::Value Value;
  107.59 +
  107.60 +    /// \brief The large value type used for internal computations
  107.61 +    ///
  107.62 +    /// The large value type used for internal computations.
  107.63 +    /// It is \c long \c long if the \c Value type is integer,
  107.64 +    /// otherwise it is \c double.
  107.65 +    /// \c Value must be convertible to \c LargeValue.
  107.66 +    typedef double LargeValue;
  107.67 +
  107.68 +    /// The tolerance type used for internal computations
  107.69 +    typedef lemon::Tolerance<LargeValue> Tolerance;
  107.70 +
  107.71 +    /// \brief The path type of the found cycles
  107.72 +    ///
  107.73 +    /// The path type of the found cycles.
  107.74 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
  107.75 +    /// and it must have an \c addFront() function.
  107.76 +    typedef lemon::Path<Digraph> Path;
  107.77 +  };
  107.78 +
  107.79 +  // Default traits class for integer value types
  107.80 +  template <typename GR, typename LEN>
  107.81 +  struct HartmannOrlinDefaultTraits<GR, LEN, true>
  107.82 +  {
  107.83 +    typedef GR Digraph;
  107.84 +    typedef LEN LengthMap;
  107.85 +    typedef typename LengthMap::Value Value;
  107.86 +#ifdef LEMON_HAVE_LONG_LONG
  107.87 +    typedef long long LargeValue;
  107.88 +#else
  107.89 +    typedef long LargeValue;
  107.90 +#endif
  107.91 +    typedef lemon::Tolerance<LargeValue> Tolerance;
  107.92 +    typedef lemon::Path<Digraph> Path;
  107.93 +  };
  107.94 +
  107.95 +
  107.96 +  /// \addtogroup min_mean_cycle
  107.97 +  /// @{
  107.98 +
  107.99 +  /// \brief Implementation of the Hartmann-Orlin algorithm for finding
 107.100 +  /// a minimum mean cycle.
 107.101 +  ///
 107.102 +  /// This class implements the Hartmann-Orlin algorithm for finding
 107.103 +  /// a directed cycle of minimum mean length (cost) in a digraph
 107.104 +  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
 107.105 +  /// It is an improved version of \ref Karp "Karp"'s original algorithm,
 107.106 +  /// it applies an efficient early termination scheme.
 107.107 +  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
 107.108 +  ///
 107.109 +  /// \tparam GR The type of the digraph the algorithm runs on.
 107.110 +  /// \tparam LEN The type of the length map. The default
 107.111 +  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
 107.112 +#ifdef DOXYGEN
 107.113 +  template <typename GR, typename LEN, typename TR>
 107.114 +#else
 107.115 +  template < typename GR,
 107.116 +             typename LEN = typename GR::template ArcMap<int>,
 107.117 +             typename TR = HartmannOrlinDefaultTraits<GR, LEN> >
 107.118 +#endif
 107.119 +  class HartmannOrlin
 107.120 +  {
 107.121 +  public:
 107.122 +
 107.123 +    /// The type of the digraph
 107.124 +    typedef typename TR::Digraph Digraph;
 107.125 +    /// The type of the length map
 107.126 +    typedef typename TR::LengthMap LengthMap;
 107.127 +    /// The type of the arc lengths
 107.128 +    typedef typename TR::Value Value;
 107.129 +
 107.130 +    /// \brief The large value type
 107.131 +    ///
 107.132 +    /// The large value type used for internal computations.
 107.133 +    /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
 107.134 +    /// it is \c long \c long if the \c Value type is integer,
 107.135 +    /// otherwise it is \c double.
 107.136 +    typedef typename TR::LargeValue LargeValue;
 107.137 +
 107.138 +    /// The tolerance type
 107.139 +    typedef typename TR::Tolerance Tolerance;
 107.140 +
 107.141 +    /// \brief The path type of the found cycles
 107.142 +    ///
 107.143 +    /// The path type of the found cycles.
 107.144 +    /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
 107.145 +    /// it is \ref lemon::Path "Path<Digraph>".
 107.146 +    typedef typename TR::Path Path;
 107.147 +
 107.148 +    /// The \ref HartmannOrlinDefaultTraits "traits class" of the algorithm
 107.149 +    typedef TR Traits;
 107.150 +
 107.151 +  private:
 107.152 +
 107.153 +    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 107.154 +
 107.155 +    // Data sturcture for path data
 107.156 +    struct PathData
 107.157 +    {
 107.158 +      LargeValue dist;
 107.159 +      Arc pred;
 107.160 +      PathData(LargeValue d, Arc p = INVALID) :
 107.161 +        dist(d), pred(p) {}
 107.162 +    };
 107.163 +
 107.164 +    typedef typename Digraph::template NodeMap<std::vector<PathData> >
 107.165 +      PathDataNodeMap;
 107.166 +
 107.167 +  private:
 107.168 +
 107.169 +    // The digraph the algorithm runs on
 107.170 +    const Digraph &_gr;
 107.171 +    // The length of the arcs
 107.172 +    const LengthMap &_length;
 107.173 +
 107.174 +    // Data for storing the strongly connected components
 107.175 +    int _comp_num;
 107.176 +    typename Digraph::template NodeMap<int> _comp;
 107.177 +    std::vector<std::vector<Node> > _comp_nodes;
 107.178 +    std::vector<Node>* _nodes;
 107.179 +    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
 107.180 +
 107.181 +    // Data for the found cycles
 107.182 +    bool _curr_found, _best_found;
 107.183 +    LargeValue _curr_length, _best_length;
 107.184 +    int _curr_size, _best_size;
 107.185 +    Node _curr_node, _best_node;
 107.186 +    int _curr_level, _best_level;
 107.187 +
 107.188 +    Path *_cycle_path;
 107.189 +    bool _local_path;
 107.190 +
 107.191 +    // Node map for storing path data
 107.192 +    PathDataNodeMap _data;
 107.193 +    // The processed nodes in the last round
 107.194 +    std::vector<Node> _process;
 107.195 +
 107.196 +    Tolerance _tolerance;
 107.197 +
 107.198 +    // Infinite constant
 107.199 +    const LargeValue INF;
 107.200 +
 107.201 +  public:
 107.202 +
 107.203 +    /// \name Named Template Parameters
 107.204 +    /// @{
 107.205 +
 107.206 +    template <typename T>
 107.207 +    struct SetLargeValueTraits : public Traits {
 107.208 +      typedef T LargeValue;
 107.209 +      typedef lemon::Tolerance<T> Tolerance;
 107.210 +    };
 107.211 +
 107.212 +    /// \brief \ref named-templ-param "Named parameter" for setting
 107.213 +    /// \c LargeValue type.
 107.214 +    ///
 107.215 +    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
 107.216 +    /// type. It is used for internal computations in the algorithm.
 107.217 +    template <typename T>
 107.218 +    struct SetLargeValue
 107.219 +      : public HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > {
 107.220 +      typedef HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > Create;
 107.221 +    };
 107.222 +
 107.223 +    template <typename T>
 107.224 +    struct SetPathTraits : public Traits {
 107.225 +      typedef T Path;
 107.226 +    };
 107.227 +
 107.228 +    /// \brief \ref named-templ-param "Named parameter" for setting
 107.229 +    /// \c %Path type.
 107.230 +    ///
 107.231 +    /// \ref named-templ-param "Named parameter" for setting the \c %Path
 107.232 +    /// type of the found cycles.
 107.233 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
 107.234 +    /// and it must have an \c addFront() function.
 107.235 +    template <typename T>
 107.236 +    struct SetPath
 107.237 +      : public HartmannOrlin<GR, LEN, SetPathTraits<T> > {
 107.238 +      typedef HartmannOrlin<GR, LEN, SetPathTraits<T> > Create;
 107.239 +    };
 107.240 +
 107.241 +    /// @}
 107.242 +
 107.243 +  public:
 107.244 +
 107.245 +    /// \brief Constructor.
 107.246 +    ///
 107.247 +    /// The constructor of the class.
 107.248 +    ///
 107.249 +    /// \param digraph The digraph the algorithm runs on.
 107.250 +    /// \param length The lengths (costs) of the arcs.
 107.251 +    HartmannOrlin( const Digraph &digraph,
 107.252 +                   const LengthMap &length ) :
 107.253 +      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
 107.254 +      _best_found(false), _best_length(0), _best_size(1),
 107.255 +      _cycle_path(NULL), _local_path(false), _data(digraph),
 107.256 +      INF(std::numeric_limits<LargeValue>::has_infinity ?
 107.257 +          std::numeric_limits<LargeValue>::infinity() :
 107.258 +          std::numeric_limits<LargeValue>::max())
 107.259 +    {}
 107.260 +
 107.261 +    /// Destructor.
 107.262 +    ~HartmannOrlin() {
 107.263 +      if (_local_path) delete _cycle_path;
 107.264 +    }
 107.265 +
 107.266 +    /// \brief Set the path structure for storing the found cycle.
 107.267 +    ///
 107.268 +    /// This function sets an external path structure for storing the
 107.269 +    /// found cycle.
 107.270 +    ///
 107.271 +    /// If you don't call this function before calling \ref run() or
 107.272 +    /// \ref findMinMean(), it will allocate a local \ref Path "path"
 107.273 +    /// structure. The destuctor deallocates this automatically
 107.274 +    /// allocated object, of course.
 107.275 +    ///
 107.276 +    /// \note The algorithm calls only the \ref lemon::Path::addFront()
 107.277 +    /// "addFront()" function of the given path structure.
 107.278 +    ///
 107.279 +    /// \return <tt>(*this)</tt>
 107.280 +    HartmannOrlin& cycle(Path &path) {
 107.281 +      if (_local_path) {
 107.282 +        delete _cycle_path;
 107.283 +        _local_path = false;
 107.284 +      }
 107.285 +      _cycle_path = &path;
 107.286 +      return *this;
 107.287 +    }
 107.288 +
 107.289 +    /// \brief Set the tolerance used by the algorithm.
 107.290 +    ///
 107.291 +    /// This function sets the tolerance object used by the algorithm.
 107.292 +    ///
 107.293 +    /// \return <tt>(*this)</tt>
 107.294 +    HartmannOrlin& tolerance(const Tolerance& tolerance) {
 107.295 +      _tolerance = tolerance;
 107.296 +      return *this;
 107.297 +    }
 107.298 +
 107.299 +    /// \brief Return a const reference to the tolerance.
 107.300 +    ///
 107.301 +    /// This function returns a const reference to the tolerance object
 107.302 +    /// used by the algorithm.
 107.303 +    const Tolerance& tolerance() const {
 107.304 +      return _tolerance;
 107.305 +    }
 107.306 +
 107.307 +    /// \name Execution control
 107.308 +    /// The simplest way to execute the algorithm is to call the \ref run()
 107.309 +    /// function.\n
 107.310 +    /// If you only need the minimum mean length, you may call
 107.311 +    /// \ref findMinMean().
 107.312 +
 107.313 +    /// @{
 107.314 +
 107.315 +    /// \brief Run the algorithm.
 107.316 +    ///
 107.317 +    /// This function runs the algorithm.
 107.318 +    /// It can be called more than once (e.g. if the underlying digraph
 107.319 +    /// and/or the arc lengths have been modified).
 107.320 +    ///
 107.321 +    /// \return \c true if a directed cycle exists in the digraph.
 107.322 +    ///
 107.323 +    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
 107.324 +    /// \code
 107.325 +    ///   return mmc.findMinMean() && mmc.findCycle();
 107.326 +    /// \endcode
 107.327 +    bool run() {
 107.328 +      return findMinMean() && findCycle();
 107.329 +    }
 107.330 +
 107.331 +    /// \brief Find the minimum cycle mean.
 107.332 +    ///
 107.333 +    /// This function finds the minimum mean length of the directed
 107.334 +    /// cycles in the digraph.
 107.335 +    ///
 107.336 +    /// \return \c true if a directed cycle exists in the digraph.
 107.337 +    bool findMinMean() {
 107.338 +      // Initialization and find strongly connected components
 107.339 +      init();
 107.340 +      findComponents();
 107.341 +      
 107.342 +      // Find the minimum cycle mean in the components
 107.343 +      for (int comp = 0; comp < _comp_num; ++comp) {
 107.344 +        if (!initComponent(comp)) continue;
 107.345 +        processRounds();
 107.346 +        
 107.347 +        // Update the best cycle (global minimum mean cycle)
 107.348 +        if ( _curr_found && (!_best_found || 
 107.349 +             _curr_length * _best_size < _best_length * _curr_size) ) {
 107.350 +          _best_found = true;
 107.351 +          _best_length = _curr_length;
 107.352 +          _best_size = _curr_size;
 107.353 +          _best_node = _curr_node;
 107.354 +          _best_level = _curr_level;
 107.355 +        }
 107.356 +      }
 107.357 +      return _best_found;
 107.358 +    }
 107.359 +
 107.360 +    /// \brief Find a minimum mean directed cycle.
 107.361 +    ///
 107.362 +    /// This function finds a directed cycle of minimum mean length
 107.363 +    /// in the digraph using the data computed by findMinMean().
 107.364 +    ///
 107.365 +    /// \return \c true if a directed cycle exists in the digraph.
 107.366 +    ///
 107.367 +    /// \pre \ref findMinMean() must be called before using this function.
 107.368 +    bool findCycle() {
 107.369 +      if (!_best_found) return false;
 107.370 +      IntNodeMap reached(_gr, -1);
 107.371 +      int r = _best_level + 1;
 107.372 +      Node u = _best_node;
 107.373 +      while (reached[u] < 0) {
 107.374 +        reached[u] = --r;
 107.375 +        u = _gr.source(_data[u][r].pred);
 107.376 +      }
 107.377 +      r = reached[u];
 107.378 +      Arc e = _data[u][r].pred;
 107.379 +      _cycle_path->addFront(e);
 107.380 +      _best_length = _length[e];
 107.381 +      _best_size = 1;
 107.382 +      Node v;
 107.383 +      while ((v = _gr.source(e)) != u) {
 107.384 +        e = _data[v][--r].pred;
 107.385 +        _cycle_path->addFront(e);
 107.386 +        _best_length += _length[e];
 107.387 +        ++_best_size;
 107.388 +      }
 107.389 +      return true;
 107.390 +    }
 107.391 +
 107.392 +    /// @}
 107.393 +
 107.394 +    /// \name Query Functions
 107.395 +    /// The results of the algorithm can be obtained using these
 107.396 +    /// functions.\n
 107.397 +    /// The algorithm should be executed before using them.
 107.398 +
 107.399 +    /// @{
 107.400 +
 107.401 +    /// \brief Return the total length of the found cycle.
 107.402 +    ///
 107.403 +    /// This function returns the total length of the found cycle.
 107.404 +    ///
 107.405 +    /// \pre \ref run() or \ref findMinMean() must be called before
 107.406 +    /// using this function.
 107.407 +    LargeValue cycleLength() const {
 107.408 +      return _best_length;
 107.409 +    }
 107.410 +
 107.411 +    /// \brief Return the number of arcs on the found cycle.
 107.412 +    ///
 107.413 +    /// This function returns the number of arcs on the found cycle.
 107.414 +    ///
 107.415 +    /// \pre \ref run() or \ref findMinMean() must be called before
 107.416 +    /// using this function.
 107.417 +    int cycleArcNum() const {
 107.418 +      return _best_size;
 107.419 +    }
 107.420 +
 107.421 +    /// \brief Return the mean length of the found cycle.
 107.422 +    ///
 107.423 +    /// This function returns the mean length of the found cycle.
 107.424 +    ///
 107.425 +    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
 107.426 +    /// following code.
 107.427 +    /// \code
 107.428 +    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
 107.429 +    /// \endcode
 107.430 +    ///
 107.431 +    /// \pre \ref run() or \ref findMinMean() must be called before
 107.432 +    /// using this function.
 107.433 +    double cycleMean() const {
 107.434 +      return static_cast<double>(_best_length) / _best_size;
 107.435 +    }
 107.436 +
 107.437 +    /// \brief Return the found cycle.
 107.438 +    ///
 107.439 +    /// This function returns a const reference to the path structure
 107.440 +    /// storing the found cycle.
 107.441 +    ///
 107.442 +    /// \pre \ref run() or \ref findCycle() must be called before using
 107.443 +    /// this function.
 107.444 +    const Path& cycle() const {
 107.445 +      return *_cycle_path;
 107.446 +    }
 107.447 +
 107.448 +    ///@}
 107.449 +
 107.450 +  private:
 107.451 +
 107.452 +    // Initialization
 107.453 +    void init() {
 107.454 +      if (!_cycle_path) {
 107.455 +        _local_path = true;
 107.456 +        _cycle_path = new Path;
 107.457 +      }
 107.458 +      _cycle_path->clear();
 107.459 +      _best_found = false;
 107.460 +      _best_length = 0;
 107.461 +      _best_size = 1;
 107.462 +      _cycle_path->clear();
 107.463 +      for (NodeIt u(_gr); u != INVALID; ++u)
 107.464 +        _data[u].clear();
 107.465 +    }
 107.466 +
 107.467 +    // Find strongly connected components and initialize _comp_nodes
 107.468 +    // and _out_arcs
 107.469 +    void findComponents() {
 107.470 +      _comp_num = stronglyConnectedComponents(_gr, _comp);
 107.471 +      _comp_nodes.resize(_comp_num);
 107.472 +      if (_comp_num == 1) {
 107.473 +        _comp_nodes[0].clear();
 107.474 +        for (NodeIt n(_gr); n != INVALID; ++n) {
 107.475 +          _comp_nodes[0].push_back(n);
 107.476 +          _out_arcs[n].clear();
 107.477 +          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
 107.478 +            _out_arcs[n].push_back(a);
 107.479 +          }
 107.480 +        }
 107.481 +      } else {
 107.482 +        for (int i = 0; i < _comp_num; ++i)
 107.483 +          _comp_nodes[i].clear();
 107.484 +        for (NodeIt n(_gr); n != INVALID; ++n) {
 107.485 +          int k = _comp[n];
 107.486 +          _comp_nodes[k].push_back(n);
 107.487 +          _out_arcs[n].clear();
 107.488 +          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
 107.489 +            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
 107.490 +          }
 107.491 +        }
 107.492 +      }
 107.493 +    }
 107.494 +
 107.495 +    // Initialize path data for the current component
 107.496 +    bool initComponent(int comp) {
 107.497 +      _nodes = &(_comp_nodes[comp]);
 107.498 +      int n = _nodes->size();
 107.499 +      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
 107.500 +        return false;
 107.501 +      }      
 107.502 +      for (int i = 0; i < n; ++i) {
 107.503 +        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
 107.504 +      }
 107.505 +      return true;
 107.506 +    }
 107.507 +
 107.508 +    // Process all rounds of computing path data for the current component.
 107.509 +    // _data[v][k] is the length of a shortest directed walk from the root
 107.510 +    // node to node v containing exactly k arcs.
 107.511 +    void processRounds() {
 107.512 +      Node start = (*_nodes)[0];
 107.513 +      _data[start][0] = PathData(0);
 107.514 +      _process.clear();
 107.515 +      _process.push_back(start);
 107.516 +
 107.517 +      int k, n = _nodes->size();
 107.518 +      int next_check = 4;
 107.519 +      bool terminate = false;
 107.520 +      for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
 107.521 +        processNextBuildRound(k);
 107.522 +        if (k == next_check || k == n) {
 107.523 +          terminate = checkTermination(k);
 107.524 +          next_check = next_check * 3 / 2;
 107.525 +        }
 107.526 +      }
 107.527 +      for ( ; k <= n && !terminate; ++k) {
 107.528 +        processNextFullRound(k);
 107.529 +        if (k == next_check || k == n) {
 107.530 +          terminate = checkTermination(k);
 107.531 +          next_check = next_check * 3 / 2;
 107.532 +        }
 107.533 +      }
 107.534 +    }
 107.535 +
 107.536 +    // Process one round and rebuild _process
 107.537 +    void processNextBuildRound(int k) {
 107.538 +      std::vector<Node> next;
 107.539 +      Node u, v;
 107.540 +      Arc e;
 107.541 +      LargeValue d;
 107.542 +      for (int i = 0; i < int(_process.size()); ++i) {
 107.543 +        u = _process[i];
 107.544 +        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
 107.545 +          e = _out_arcs[u][j];
 107.546 +          v = _gr.target(e);
 107.547 +          d = _data[u][k-1].dist + _length[e];
 107.548 +          if (_tolerance.less(d, _data[v][k].dist)) {
 107.549 +            if (_data[v][k].dist == INF) next.push_back(v);
 107.550 +            _data[v][k] = PathData(d, e);
 107.551 +          }
 107.552 +        }
 107.553 +      }
 107.554 +      _process.swap(next);
 107.555 +    }
 107.556 +
 107.557 +    // Process one round using _nodes instead of _process
 107.558 +    void processNextFullRound(int k) {
 107.559 +      Node u, v;
 107.560 +      Arc e;
 107.561 +      LargeValue d;
 107.562 +      for (int i = 0; i < int(_nodes->size()); ++i) {
 107.563 +        u = (*_nodes)[i];
 107.564 +        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
 107.565 +          e = _out_arcs[u][j];
 107.566 +          v = _gr.target(e);
 107.567 +          d = _data[u][k-1].dist + _length[e];
 107.568 +          if (_tolerance.less(d, _data[v][k].dist)) {
 107.569 +            _data[v][k] = PathData(d, e);
 107.570 +          }
 107.571 +        }
 107.572 +      }
 107.573 +    }
 107.574 +    
 107.575 +    // Check early termination
 107.576 +    bool checkTermination(int k) {
 107.577 +      typedef std::pair<int, int> Pair;
 107.578 +      typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
 107.579 +      typename GR::template NodeMap<LargeValue> pi(_gr);
 107.580 +      int n = _nodes->size();
 107.581 +      LargeValue length;
 107.582 +      int size;
 107.583 +      Node u;
 107.584 +      
 107.585 +      // Search for cycles that are already found
 107.586 +      _curr_found = false;
 107.587 +      for (int i = 0; i < n; ++i) {
 107.588 +        u = (*_nodes)[i];
 107.589 +        if (_data[u][k].dist == INF) continue;
 107.590 +        for (int j = k; j >= 0; --j) {
 107.591 +          if (level[u].first == i && level[u].second > 0) {
 107.592 +            // A cycle is found
 107.593 +            length = _data[u][level[u].second].dist - _data[u][j].dist;
 107.594 +            size = level[u].second - j;
 107.595 +            if (!_curr_found || length * _curr_size < _curr_length * size) {
 107.596 +              _curr_length = length;
 107.597 +              _curr_size = size;
 107.598 +              _curr_node = u;
 107.599 +              _curr_level = level[u].second;
 107.600 +              _curr_found = true;
 107.601 +            }
 107.602 +          }
 107.603 +          level[u] = Pair(i, j);
 107.604 +          u = _gr.source(_data[u][j].pred);
 107.605 +        }
 107.606 +      }
 107.607 +
 107.608 +      // If at least one cycle is found, check the optimality condition
 107.609 +      LargeValue d;
 107.610 +      if (_curr_found && k < n) {
 107.611 +        // Find node potentials
 107.612 +        for (int i = 0; i < n; ++i) {
 107.613 +          u = (*_nodes)[i];
 107.614 +          pi[u] = INF;
 107.615 +          for (int j = 0; j <= k; ++j) {
 107.616 +            if (_data[u][j].dist < INF) {
 107.617 +              d = _data[u][j].dist * _curr_size - j * _curr_length;
 107.618 +              if (_tolerance.less(d, pi[u])) pi[u] = d;
 107.619 +            }
 107.620 +          }
 107.621 +        }
 107.622 +
 107.623 +        // Check the optimality condition for all arcs
 107.624 +        bool done = true;
 107.625 +        for (ArcIt a(_gr); a != INVALID; ++a) {
 107.626 +          if (_tolerance.less(_length[a] * _curr_size - _curr_length,
 107.627 +                              pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
 107.628 +            done = false;
 107.629 +            break;
 107.630 +          }
 107.631 +        }
 107.632 +        return done;
 107.633 +      }
 107.634 +      return (k == n);
 107.635 +    }
 107.636 +
 107.637 +  }; //class HartmannOrlin
 107.638 +
 107.639 +  ///@}
 107.640 +
 107.641 +} //namespace lemon
 107.642 +
 107.643 +#endif //LEMON_HARTMANN_ORLIN_H
   108.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   108.2 +++ b/lemon/howard.h	Thu Nov 05 15:50:01 2009 +0100
   108.3 @@ -0,0 +1,597 @@
   108.4 +/* -*- C++ -*-
   108.5 + *
   108.6 + * This file is a part of LEMON, a generic C++ optimization library
   108.7 + *
   108.8 + * Copyright (C) 2003-2008
   108.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  108.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  108.11 + *
  108.12 + * Permission to use, modify and distribute this software is granted
  108.13 + * provided that this copyright notice appears in all copies. For
  108.14 + * precise terms see the accompanying LICENSE file.
  108.15 + *
  108.16 + * This software is provided "AS IS" with no warranty of any kind,
  108.17 + * express or implied, and with no claim as to its suitability for any
  108.18 + * purpose.
  108.19 + *
  108.20 + */
  108.21 +
  108.22 +#ifndef LEMON_HOWARD_H
  108.23 +#define LEMON_HOWARD_H
  108.24 +
  108.25 +/// \ingroup min_mean_cycle
  108.26 +///
  108.27 +/// \file
  108.28 +/// \brief Howard's algorithm for finding a minimum mean cycle.
  108.29 +
  108.30 +#include <vector>
  108.31 +#include <limits>
  108.32 +#include <lemon/core.h>
  108.33 +#include <lemon/path.h>
  108.34 +#include <lemon/tolerance.h>
  108.35 +#include <lemon/connectivity.h>
  108.36 +
  108.37 +namespace lemon {
  108.38 +
  108.39 +  /// \brief Default traits class of Howard class.
  108.40 +  ///
  108.41 +  /// Default traits class of Howard class.
  108.42 +  /// \tparam GR The type of the digraph.
  108.43 +  /// \tparam LEN The type of the length map.
  108.44 +  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
  108.45 +#ifdef DOXYGEN
  108.46 +  template <typename GR, typename LEN>
  108.47 +#else
  108.48 +  template <typename GR, typename LEN,
  108.49 +    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
  108.50 +#endif
  108.51 +  struct HowardDefaultTraits
  108.52 +  {
  108.53 +    /// The type of the digraph
  108.54 +    typedef GR Digraph;
  108.55 +    /// The type of the length map
  108.56 +    typedef LEN LengthMap;
  108.57 +    /// The type of the arc lengths
  108.58 +    typedef typename LengthMap::Value Value;
  108.59 +
  108.60 +    /// \brief The large value type used for internal computations
  108.61 +    ///
  108.62 +    /// The large value type used for internal computations.
  108.63 +    /// It is \c long \c long if the \c Value type is integer,
  108.64 +    /// otherwise it is \c double.
  108.65 +    /// \c Value must be convertible to \c LargeValue.
  108.66 +    typedef double LargeValue;
  108.67 +
  108.68 +    /// The tolerance type used for internal computations
  108.69 +    typedef lemon::Tolerance<LargeValue> Tolerance;
  108.70 +
  108.71 +    /// \brief The path type of the found cycles
  108.72 +    ///
  108.73 +    /// The path type of the found cycles.
  108.74 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
  108.75 +    /// and it must have an \c addBack() function.
  108.76 +    typedef lemon::Path<Digraph> Path;
  108.77 +  };
  108.78 +
  108.79 +  // Default traits class for integer value types
  108.80 +  template <typename GR, typename LEN>
  108.81 +  struct HowardDefaultTraits<GR, LEN, true>
  108.82 +  {
  108.83 +    typedef GR Digraph;
  108.84 +    typedef LEN LengthMap;
  108.85 +    typedef typename LengthMap::Value Value;
  108.86 +#ifdef LEMON_HAVE_LONG_LONG
  108.87 +    typedef long long LargeValue;
  108.88 +#else
  108.89 +    typedef long LargeValue;
  108.90 +#endif
  108.91 +    typedef lemon::Tolerance<LargeValue> Tolerance;
  108.92 +    typedef lemon::Path<Digraph> Path;
  108.93 +  };
  108.94 +
  108.95 +
  108.96 +  /// \addtogroup min_mean_cycle
  108.97 +  /// @{
  108.98 +
  108.99 +  /// \brief Implementation of Howard's algorithm for finding a minimum
 108.100 +  /// mean cycle.
 108.101 +  ///
 108.102 +  /// This class implements Howard's policy iteration algorithm for finding
 108.103 +  /// a directed cycle of minimum mean length (cost) in a digraph
 108.104 +  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
 108.105 +  /// This class provides the most efficient algorithm for the
 108.106 +  /// minimum mean cycle problem, though the best known theoretical
 108.107 +  /// bound on its running time is exponential.
 108.108 +  ///
 108.109 +  /// \tparam GR The type of the digraph the algorithm runs on.
 108.110 +  /// \tparam LEN The type of the length map. The default
 108.111 +  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
 108.112 +#ifdef DOXYGEN
 108.113 +  template <typename GR, typename LEN, typename TR>
 108.114 +#else
 108.115 +  template < typename GR,
 108.116 +             typename LEN = typename GR::template ArcMap<int>,
 108.117 +             typename TR = HowardDefaultTraits<GR, LEN> >
 108.118 +#endif
 108.119 +  class Howard
 108.120 +  {
 108.121 +  public:
 108.122 +  
 108.123 +    /// The type of the digraph
 108.124 +    typedef typename TR::Digraph Digraph;
 108.125 +    /// The type of the length map
 108.126 +    typedef typename TR::LengthMap LengthMap;
 108.127 +    /// The type of the arc lengths
 108.128 +    typedef typename TR::Value Value;
 108.129 +
 108.130 +    /// \brief The large value type
 108.131 +    ///
 108.132 +    /// The large value type used for internal computations.
 108.133 +    /// Using the \ref HowardDefaultTraits "default traits class",
 108.134 +    /// it is \c long \c long if the \c Value type is integer,
 108.135 +    /// otherwise it is \c double.
 108.136 +    typedef typename TR::LargeValue LargeValue;
 108.137 +
 108.138 +    /// The tolerance type
 108.139 +    typedef typename TR::Tolerance Tolerance;
 108.140 +
 108.141 +    /// \brief The path type of the found cycles
 108.142 +    ///
 108.143 +    /// The path type of the found cycles.
 108.144 +    /// Using the \ref HowardDefaultTraits "default traits class",
 108.145 +    /// it is \ref lemon::Path "Path<Digraph>".
 108.146 +    typedef typename TR::Path Path;
 108.147 +
 108.148 +    /// The \ref HowardDefaultTraits "traits class" of the algorithm
 108.149 +    typedef TR Traits;
 108.150 +
 108.151 +  private:
 108.152 +
 108.153 +    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 108.154 +  
 108.155 +    // The digraph the algorithm runs on
 108.156 +    const Digraph &_gr;
 108.157 +    // The length of the arcs
 108.158 +    const LengthMap &_length;
 108.159 +
 108.160 +    // Data for the found cycles
 108.161 +    bool _curr_found, _best_found;
 108.162 +    LargeValue _curr_length, _best_length;
 108.163 +    int _curr_size, _best_size;
 108.164 +    Node _curr_node, _best_node;
 108.165 +
 108.166 +    Path *_cycle_path;
 108.167 +    bool _local_path;
 108.168 +
 108.169 +    // Internal data used by the algorithm
 108.170 +    typename Digraph::template NodeMap<Arc> _policy;
 108.171 +    typename Digraph::template NodeMap<bool> _reached;
 108.172 +    typename Digraph::template NodeMap<int> _level;
 108.173 +    typename Digraph::template NodeMap<LargeValue> _dist;
 108.174 +
 108.175 +    // Data for storing the strongly connected components
 108.176 +    int _comp_num;
 108.177 +    typename Digraph::template NodeMap<int> _comp;
 108.178 +    std::vector<std::vector<Node> > _comp_nodes;
 108.179 +    std::vector<Node>* _nodes;
 108.180 +    typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
 108.181 +    
 108.182 +    // Queue used for BFS search
 108.183 +    std::vector<Node> _queue;
 108.184 +    int _qfront, _qback;
 108.185 +
 108.186 +    Tolerance _tolerance;
 108.187 +  
 108.188 +    // Infinite constant
 108.189 +    const LargeValue INF;
 108.190 +
 108.191 +  public:
 108.192 +  
 108.193 +    /// \name Named Template Parameters
 108.194 +    /// @{
 108.195 +
 108.196 +    template <typename T>
 108.197 +    struct SetLargeValueTraits : public Traits {
 108.198 +      typedef T LargeValue;
 108.199 +      typedef lemon::Tolerance<T> Tolerance;
 108.200 +    };
 108.201 +
 108.202 +    /// \brief \ref named-templ-param "Named parameter" for setting
 108.203 +    /// \c LargeValue type.
 108.204 +    ///
 108.205 +    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
 108.206 +    /// type. It is used for internal computations in the algorithm.
 108.207 +    template <typename T>
 108.208 +    struct SetLargeValue
 108.209 +      : public Howard<GR, LEN, SetLargeValueTraits<T> > {
 108.210 +      typedef Howard<GR, LEN, SetLargeValueTraits<T> > Create;
 108.211 +    };
 108.212 +
 108.213 +    template <typename T>
 108.214 +    struct SetPathTraits : public Traits {
 108.215 +      typedef T Path;
 108.216 +    };
 108.217 +
 108.218 +    /// \brief \ref named-templ-param "Named parameter" for setting
 108.219 +    /// \c %Path type.
 108.220 +    ///
 108.221 +    /// \ref named-templ-param "Named parameter" for setting the \c %Path
 108.222 +    /// type of the found cycles.
 108.223 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
 108.224 +    /// and it must have an \c addBack() function.
 108.225 +    template <typename T>
 108.226 +    struct SetPath
 108.227 +      : public Howard<GR, LEN, SetPathTraits<T> > {
 108.228 +      typedef Howard<GR, LEN, SetPathTraits<T> > Create;
 108.229 +    };
 108.230 +    
 108.231 +    /// @}
 108.232 +
 108.233 +  public:
 108.234 +
 108.235 +    /// \brief Constructor.
 108.236 +    ///
 108.237 +    /// The constructor of the class.
 108.238 +    ///
 108.239 +    /// \param digraph The digraph the algorithm runs on.
 108.240 +    /// \param length The lengths (costs) of the arcs.
 108.241 +    Howard( const Digraph &digraph,
 108.242 +            const LengthMap &length ) :
 108.243 +      _gr(digraph), _length(length), _best_found(false),
 108.244 +      _best_length(0), _best_size(1), _cycle_path(NULL), _local_path(false),
 108.245 +      _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
 108.246 +      _comp(digraph), _in_arcs(digraph),
 108.247 +      INF(std::numeric_limits<LargeValue>::has_infinity ?
 108.248 +          std::numeric_limits<LargeValue>::infinity() :
 108.249 +          std::numeric_limits<LargeValue>::max())
 108.250 +    {}
 108.251 +
 108.252 +    /// Destructor.
 108.253 +    ~Howard() {
 108.254 +      if (_local_path) delete _cycle_path;
 108.255 +    }
 108.256 +
 108.257 +    /// \brief Set the path structure for storing the found cycle.
 108.258 +    ///
 108.259 +    /// This function sets an external path structure for storing the
 108.260 +    /// found cycle.
 108.261 +    ///
 108.262 +    /// If you don't call this function before calling \ref run() or
 108.263 +    /// \ref findMinMean(), it will allocate a local \ref Path "path"
 108.264 +    /// structure. The destuctor deallocates this automatically
 108.265 +    /// allocated object, of course.
 108.266 +    ///
 108.267 +    /// \note The algorithm calls only the \ref lemon::Path::addBack()
 108.268 +    /// "addBack()" function of the given path structure.
 108.269 +    ///
 108.270 +    /// \return <tt>(*this)</tt>
 108.271 +    Howard& cycle(Path &path) {
 108.272 +      if (_local_path) {
 108.273 +        delete _cycle_path;
 108.274 +        _local_path = false;
 108.275 +      }
 108.276 +      _cycle_path = &path;
 108.277 +      return *this;
 108.278 +    }
 108.279 +
 108.280 +    /// \brief Set the tolerance used by the algorithm.
 108.281 +    ///
 108.282 +    /// This function sets the tolerance object used by the algorithm.
 108.283 +    ///
 108.284 +    /// \return <tt>(*this)</tt>
 108.285 +    Howard& tolerance(const Tolerance& tolerance) {
 108.286 +      _tolerance = tolerance;
 108.287 +      return *this;
 108.288 +    }
 108.289 +
 108.290 +    /// \brief Return a const reference to the tolerance.
 108.291 +    ///
 108.292 +    /// This function returns a const reference to the tolerance object
 108.293 +    /// used by the algorithm.
 108.294 +    const Tolerance& tolerance() const {
 108.295 +      return _tolerance;
 108.296 +    }
 108.297 +
 108.298 +    /// \name Execution control
 108.299 +    /// The simplest way to execute the algorithm is to call the \ref run()
 108.300 +    /// function.\n
 108.301 +    /// If you only need the minimum mean length, you may call
 108.302 +    /// \ref findMinMean().
 108.303 +
 108.304 +    /// @{
 108.305 +
 108.306 +    /// \brief Run the algorithm.
 108.307 +    ///
 108.308 +    /// This function runs the algorithm.
 108.309 +    /// It can be called more than once (e.g. if the underlying digraph
 108.310 +    /// and/or the arc lengths have been modified).
 108.311 +    ///
 108.312 +    /// \return \c true if a directed cycle exists in the digraph.
 108.313 +    ///
 108.314 +    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
 108.315 +    /// \code
 108.316 +    ///   return mmc.findMinMean() && mmc.findCycle();
 108.317 +    /// \endcode
 108.318 +    bool run() {
 108.319 +      return findMinMean() && findCycle();
 108.320 +    }
 108.321 +
 108.322 +    /// \brief Find the minimum cycle mean.
 108.323 +    ///
 108.324 +    /// This function finds the minimum mean length of the directed
 108.325 +    /// cycles in the digraph.
 108.326 +    ///
 108.327 +    /// \return \c true if a directed cycle exists in the digraph.
 108.328 +    bool findMinMean() {
 108.329 +      // Initialize and find strongly connected components
 108.330 +      init();
 108.331 +      findComponents();
 108.332 +      
 108.333 +      // Find the minimum cycle mean in the components
 108.334 +      for (int comp = 0; comp < _comp_num; ++comp) {
 108.335 +        // Find the minimum mean cycle in the current component
 108.336 +        if (!buildPolicyGraph(comp)) continue;
 108.337 +        while (true) {
 108.338 +          findPolicyCycle();
 108.339 +          if (!computeNodeDistances()) break;
 108.340 +        }
 108.341 +        // Update the best cycle (global minimum mean cycle)
 108.342 +        if ( _curr_found && (!_best_found ||
 108.343 +             _curr_length * _best_size < _best_length * _curr_size) ) {
 108.344 +          _best_found = true;
 108.345 +          _best_length = _curr_length;
 108.346 +          _best_size = _curr_size;
 108.347 +          _best_node = _curr_node;
 108.348 +        }
 108.349 +      }
 108.350 +      return _best_found;
 108.351 +    }
 108.352 +
 108.353 +    /// \brief Find a minimum mean directed cycle.
 108.354 +    ///
 108.355 +    /// This function finds a directed cycle of minimum mean length
 108.356 +    /// in the digraph using the data computed by findMinMean().
 108.357 +    ///
 108.358 +    /// \return \c true if a directed cycle exists in the digraph.
 108.359 +    ///
 108.360 +    /// \pre \ref findMinMean() must be called before using this function.
 108.361 +    bool findCycle() {
 108.362 +      if (!_best_found) return false;
 108.363 +      _cycle_path->addBack(_policy[_best_node]);
 108.364 +      for ( Node v = _best_node;
 108.365 +            (v = _gr.target(_policy[v])) != _best_node; ) {
 108.366 +        _cycle_path->addBack(_policy[v]);
 108.367 +      }
 108.368 +      return true;
 108.369 +    }
 108.370 +
 108.371 +    /// @}
 108.372 +
 108.373 +    /// \name Query Functions
 108.374 +    /// The results of the algorithm can be obtained using these
 108.375 +    /// functions.\n
 108.376 +    /// The algorithm should be executed before using them.
 108.377 +
 108.378 +    /// @{
 108.379 +
 108.380 +    /// \brief Return the total length of the found cycle.
 108.381 +    ///
 108.382 +    /// This function returns the total length of the found cycle.
 108.383 +    ///
 108.384 +    /// \pre \ref run() or \ref findMinMean() must be called before
 108.385 +    /// using this function.
 108.386 +    LargeValue cycleLength() const {
 108.387 +      return _best_length;
 108.388 +    }
 108.389 +
 108.390 +    /// \brief Return the number of arcs on the found cycle.
 108.391 +    ///
 108.392 +    /// This function returns the number of arcs on the found cycle.
 108.393 +    ///
 108.394 +    /// \pre \ref run() or \ref findMinMean() must be called before
 108.395 +    /// using this function.
 108.396 +    int cycleArcNum() const {
 108.397 +      return _best_size;
 108.398 +    }
 108.399 +
 108.400 +    /// \brief Return the mean length of the found cycle.
 108.401 +    ///
 108.402 +    /// This function returns the mean length of the found cycle.
 108.403 +    ///
 108.404 +    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
 108.405 +    /// following code.
 108.406 +    /// \code
 108.407 +    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
 108.408 +    /// \endcode
 108.409 +    ///
 108.410 +    /// \pre \ref run() or \ref findMinMean() must be called before
 108.411 +    /// using this function.
 108.412 +    double cycleMean() const {
 108.413 +      return static_cast<double>(_best_length) / _best_size;
 108.414 +    }
 108.415 +
 108.416 +    /// \brief Return the found cycle.
 108.417 +    ///
 108.418 +    /// This function returns a const reference to the path structure
 108.419 +    /// storing the found cycle.
 108.420 +    ///
 108.421 +    /// \pre \ref run() or \ref findCycle() must be called before using
 108.422 +    /// this function.
 108.423 +    const Path& cycle() const {
 108.424 +      return *_cycle_path;
 108.425 +    }
 108.426 +
 108.427 +    ///@}
 108.428 +
 108.429 +  private:
 108.430 +
 108.431 +    // Initialize
 108.432 +    void init() {
 108.433 +      if (!_cycle_path) {
 108.434 +        _local_path = true;
 108.435 +        _cycle_path = new Path;
 108.436 +      }
 108.437 +      _queue.resize(countNodes(_gr));
 108.438 +      _best_found = false;
 108.439 +      _best_length = 0;
 108.440 +      _best_size = 1;
 108.441 +      _cycle_path->clear();
 108.442 +    }
 108.443 +    
 108.444 +    // Find strongly connected components and initialize _comp_nodes
 108.445 +    // and _in_arcs
 108.446 +    void findComponents() {
 108.447 +      _comp_num = stronglyConnectedComponents(_gr, _comp);
 108.448 +      _comp_nodes.resize(_comp_num);
 108.449 +      if (_comp_num == 1) {
 108.450 +        _comp_nodes[0].clear();
 108.451 +        for (NodeIt n(_gr); n != INVALID; ++n) {
 108.452 +          _comp_nodes[0].push_back(n);
 108.453 +          _in_arcs[n].clear();
 108.454 +          for (InArcIt a(_gr, n); a != INVALID; ++a) {
 108.455 +            _in_arcs[n].push_back(a);
 108.456 +          }
 108.457 +        }
 108.458 +      } else {
 108.459 +        for (int i = 0; i < _comp_num; ++i)
 108.460 +          _comp_nodes[i].clear();
 108.461 +        for (NodeIt n(_gr); n != INVALID; ++n) {
 108.462 +          int k = _comp[n];
 108.463 +          _comp_nodes[k].push_back(n);
 108.464 +          _in_arcs[n].clear();
 108.465 +          for (InArcIt a(_gr, n); a != INVALID; ++a) {
 108.466 +            if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
 108.467 +          }
 108.468 +        }
 108.469 +      }
 108.470 +    }
 108.471 +
 108.472 +    // Build the policy graph in the given strongly connected component
 108.473 +    // (the out-degree of every node is 1)
 108.474 +    bool buildPolicyGraph(int comp) {
 108.475 +      _nodes = &(_comp_nodes[comp]);
 108.476 +      if (_nodes->size() < 1 ||
 108.477 +          (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
 108.478 +        return false;
 108.479 +      }
 108.480 +      for (int i = 0; i < int(_nodes->size()); ++i) {
 108.481 +        _dist[(*_nodes)[i]] = INF;
 108.482 +      }
 108.483 +      Node u, v;
 108.484 +      Arc e;
 108.485 +      for (int i = 0; i < int(_nodes->size()); ++i) {
 108.486 +        v = (*_nodes)[i];
 108.487 +        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
 108.488 +          e = _in_arcs[v][j];
 108.489 +          u = _gr.source(e);
 108.490 +          if (_length[e] < _dist[u]) {
 108.491 +            _dist[u] = _length[e];
 108.492 +            _policy[u] = e;
 108.493 +          }
 108.494 +        }
 108.495 +      }
 108.496 +      return true;
 108.497 +    }
 108.498 +
 108.499 +    // Find the minimum mean cycle in the policy graph
 108.500 +    void findPolicyCycle() {
 108.501 +      for (int i = 0; i < int(_nodes->size()); ++i) {
 108.502 +        _level[(*_nodes)[i]] = -1;
 108.503 +      }
 108.504 +      LargeValue clength;
 108.505 +      int csize;
 108.506 +      Node u, v;
 108.507 +      _curr_found = false;
 108.508 +      for (int i = 0; i < int(_nodes->size()); ++i) {
 108.509 +        u = (*_nodes)[i];
 108.510 +        if (_level[u] >= 0) continue;
 108.511 +        for (; _level[u] < 0; u = _gr.target(_policy[u])) {
 108.512 +          _level[u] = i;
 108.513 +        }
 108.514 +        if (_level[u] == i) {
 108.515 +          // A cycle is found
 108.516 +          clength = _length[_policy[u]];
 108.517 +          csize = 1;
 108.518 +          for (v = u; (v = _gr.target(_policy[v])) != u; ) {
 108.519 +            clength += _length[_policy[v]];
 108.520 +            ++csize;
 108.521 +          }
 108.522 +          if ( !_curr_found ||
 108.523 +               (clength * _curr_size < _curr_length * csize) ) {
 108.524 +            _curr_found = true;
 108.525 +            _curr_length = clength;
 108.526 +            _curr_size = csize;
 108.527 +            _curr_node = u;
 108.528 +          }
 108.529 +        }
 108.530 +      }
 108.531 +    }
 108.532 +
 108.533 +    // Contract the policy graph and compute node distances
 108.534 +    bool computeNodeDistances() {
 108.535 +      // Find the component of the main cycle and compute node distances
 108.536 +      // using reverse BFS
 108.537 +      for (int i = 0; i < int(_nodes->size()); ++i) {
 108.538 +        _reached[(*_nodes)[i]] = false;
 108.539 +      }
 108.540 +      _qfront = _qback = 0;
 108.541 +      _queue[0] = _curr_node;
 108.542 +      _reached[_curr_node] = true;
 108.543 +      _dist[_curr_node] = 0;
 108.544 +      Node u, v;
 108.545 +      Arc e;
 108.546 +      while (_qfront <= _qback) {
 108.547 +        v = _queue[_qfront++];
 108.548 +        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
 108.549 +          e = _in_arcs[v][j];
 108.550 +          u = _gr.source(e);
 108.551 +          if (_policy[u] == e && !_reached[u]) {
 108.552 +            _reached[u] = true;
 108.553 +            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
 108.554 +            _queue[++_qback] = u;
 108.555 +          }
 108.556 +        }
 108.557 +      }
 108.558 +
 108.559 +      // Connect all other nodes to this component and compute node
 108.560 +      // distances using reverse BFS
 108.561 +      _qfront = 0;
 108.562 +      while (_qback < int(_nodes->size())-1) {
 108.563 +        v = _queue[_qfront++];
 108.564 +        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
 108.565 +          e = _in_arcs[v][j];
 108.566 +          u = _gr.source(e);
 108.567 +          if (!_reached[u]) {
 108.568 +            _reached[u] = true;
 108.569 +            _policy[u] = e;
 108.570 +            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
 108.571 +            _queue[++_qback] = u;
 108.572 +          }
 108.573 +        }
 108.574 +      }
 108.575 +
 108.576 +      // Improve node distances
 108.577 +      bool improved = false;
 108.578 +      for (int i = 0; i < int(_nodes->size()); ++i) {
 108.579 +        v = (*_nodes)[i];
 108.580 +        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
 108.581 +          e = _in_arcs[v][j];
 108.582 +          u = _gr.source(e);
 108.583 +          LargeValue delta = _dist[v] + _length[e] * _curr_size - _curr_length;
 108.584 +          if (_tolerance.less(delta, _dist[u])) {
 108.585 +            _dist[u] = delta;
 108.586 +            _policy[u] = e;
 108.587 +            improved = true;
 108.588 +          }
 108.589 +        }
 108.590 +      }
 108.591 +      return improved;
 108.592 +    }
 108.593 +
 108.594 +  }; //class Howard
 108.595 +
 108.596 +  ///@}
 108.597 +
 108.598 +} //namespace lemon
 108.599 +
 108.600 +#endif //LEMON_HOWARD_H
   109.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   109.2 +++ b/lemon/hypercube_graph.h	Thu Nov 05 15:50:01 2009 +0100
   109.3 @@ -0,0 +1,457 @@
   109.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   109.5 + *
   109.6 + * This file is a part of LEMON, a generic C++ optimization library.
   109.7 + *
   109.8 + * Copyright (C) 2003-2009
   109.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  109.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  109.11 + *
  109.12 + * Permission to use, modify and distribute this software is granted
  109.13 + * provided that this copyright notice appears in all copies. For
  109.14 + * precise terms see the accompanying LICENSE file.
  109.15 + *
  109.16 + * This software is provided "AS IS" with no warranty of any kind,
  109.17 + * express or implied, and with no claim as to its suitability for any
  109.18 + * purpose.
  109.19 + *
  109.20 + */
  109.21 +
  109.22 +#ifndef HYPERCUBE_GRAPH_H
  109.23 +#define HYPERCUBE_GRAPH_H
  109.24 +
  109.25 +#include <vector>
  109.26 +#include <lemon/core.h>
  109.27 +#include <lemon/assert.h>
  109.28 +#include <lemon/bits/graph_extender.h>
  109.29 +
  109.30 +///\ingroup graphs
  109.31 +///\file
  109.32 +///\brief HypercubeGraph class.
  109.33 +
  109.34 +namespace lemon {
  109.35 +
  109.36 +  class HypercubeGraphBase {
  109.37 +
  109.38 +  public:
  109.39 +
  109.40 +    typedef HypercubeGraphBase Graph;
  109.41 +
  109.42 +    class Node;
  109.43 +    class Edge;
  109.44 +    class Arc;
  109.45 +
  109.46 +  public:
  109.47 +
  109.48 +    HypercubeGraphBase() {}
  109.49 +
  109.50 +  protected:
  109.51 +
  109.52 +    void construct(int dim) {
  109.53 +      LEMON_ASSERT(dim >= 1, "The number of dimensions must be at least 1.");
  109.54 +      _dim = dim;
  109.55 +      _node_num = 1 << dim;
  109.56 +      _edge_num = dim * (1 << (dim-1));
  109.57 +    }
  109.58 +
  109.59 +  public:
  109.60 +
  109.61 +    typedef True NodeNumTag;
  109.62 +    typedef True EdgeNumTag;
  109.63 +    typedef True ArcNumTag;
  109.64 +
  109.65 +    int nodeNum() const { return _node_num; }
  109.66 +    int edgeNum() const { return _edge_num; }
  109.67 +    int arcNum() const { return 2 * _edge_num; }
  109.68 +
  109.69 +    int maxNodeId() const { return _node_num - 1; }
  109.70 +    int maxEdgeId() const { return _edge_num - 1; }
  109.71 +    int maxArcId() const { return 2 * _edge_num - 1; }
  109.72 +
  109.73 +    static Node nodeFromId(int id) { return Node(id); }
  109.74 +    static Edge edgeFromId(int id) { return Edge(id); }
  109.75 +    static Arc arcFromId(int id) { return Arc(id); }
  109.76 +
  109.77 +    static int id(Node node) { return node._id; }
  109.78 +    static int id(Edge edge) { return edge._id; }
  109.79 +    static int id(Arc arc) { return arc._id; }
  109.80 +
  109.81 +    Node u(Edge edge) const {
  109.82 +      int base = edge._id & ((1 << (_dim-1)) - 1);
  109.83 +      int k = edge._id >> (_dim-1);
  109.84 +      return ((base >> k) << (k+1)) | (base & ((1 << k) - 1));
  109.85 +    }
  109.86 +
  109.87 +    Node v(Edge edge) const {
  109.88 +      int base = edge._id & ((1 << (_dim-1)) - 1);
  109.89 +      int k = edge._id >> (_dim-1);
  109.90 +      return ((base >> k) << (k+1)) | (base & ((1 << k) - 1)) | (1 << k);
  109.91 +    }
  109.92 +
  109.93 +    Node source(Arc arc) const {
  109.94 +      return (arc._id & 1) == 1 ? u(arc) : v(arc);
  109.95 +    }
  109.96 +
  109.97 +    Node target(Arc arc) const {
  109.98 +      return (arc._id & 1) == 1 ? v(arc) : u(arc);
  109.99 +    }
 109.100 +
 109.101 +    typedef True FindEdgeTag;
 109.102 +    typedef True FindArcTag;
 109.103 +
 109.104 +    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
 109.105 +      if (prev != INVALID) return INVALID;
 109.106 +      int d = u._id ^ v._id;
 109.107 +      int k = 0;
 109.108 +      if (d == 0) return INVALID;
 109.109 +      for ( ; (d & 1) == 0; d >>= 1) ++k;
 109.110 +      if (d >> 1 != 0) return INVALID;
 109.111 +      return (k << (_dim-1)) | ((u._id >> (k+1)) << k) |
 109.112 +        (u._id & ((1 << k) - 1));
 109.113 +    }
 109.114 +
 109.115 +    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
 109.116 +      Edge edge = findEdge(u, v, prev);
 109.117 +      if (edge == INVALID) return INVALID;
 109.118 +      int k = edge._id >> (_dim-1);
 109.119 +      return ((u._id >> k) & 1) == 1 ? edge._id << 1 : (edge._id << 1) | 1;
 109.120 +    }
 109.121 +
 109.122 +    class Node {
 109.123 +      friend class HypercubeGraphBase;
 109.124 +
 109.125 +    protected:
 109.126 +      int _id;
 109.127 +      Node(int id) : _id(id) {}
 109.128 +    public:
 109.129 +      Node() {}
 109.130 +      Node (Invalid) : _id(-1) {}
 109.131 +      bool operator==(const Node node) const {return _id == node._id;}
 109.132 +      bool operator!=(const Node node) const {return _id != node._id;}
 109.133 +      bool operator<(const Node node) const {return _id < node._id;}
 109.134 +    };
 109.135 +
 109.136 +    class Edge {
 109.137 +      friend class HypercubeGraphBase;
 109.138 +      friend class Arc;
 109.139 +
 109.140 +    protected:
 109.141 +      int _id;
 109.142 +
 109.143 +      Edge(int id) : _id(id) {}
 109.144 +
 109.145 +    public:
 109.146 +      Edge() {}
 109.147 +      Edge (Invalid) : _id(-1) {}
 109.148 +      bool operator==(const Edge edge) const {return _id == edge._id;}
 109.149 +      bool operator!=(const Edge edge) const {return _id != edge._id;}
 109.150 +      bool operator<(const Edge edge) const {return _id < edge._id;}
 109.151 +    };
 109.152 +
 109.153 +    class Arc {
 109.154 +      friend class HypercubeGraphBase;
 109.155 +
 109.156 +    protected:
 109.157 +      int _id;
 109.158 +
 109.159 +      Arc(int id) : _id(id) {}
 109.160 +
 109.161 +    public:
 109.162 +      Arc() {}
 109.163 +      Arc (Invalid) : _id(-1) {}
 109.164 +      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
 109.165 +      bool operator==(const Arc arc) const {return _id == arc._id;}
 109.166 +      bool operator!=(const Arc arc) const {return _id != arc._id;}
 109.167 +      bool operator<(const Arc arc) const {return _id < arc._id;}
 109.168 +    };
 109.169 +
 109.170 +    void first(Node& node) const {
 109.171 +      node._id = _node_num - 1;
 109.172 +    }
 109.173 +
 109.174 +    static void next(Node& node) {
 109.175 +      --node._id;
 109.176 +    }
 109.177 +
 109.178 +    void first(Edge& edge) const {
 109.179 +      edge._id = _edge_num - 1;
 109.180 +    }
 109.181 +
 109.182 +    static void next(Edge& edge) {
 109.183 +      --edge._id;
 109.184 +    }
 109.185 +
 109.186 +    void first(Arc& arc) const {
 109.187 +      arc._id = 2 * _edge_num - 1;
 109.188 +    }
 109.189 +
 109.190 +    static void next(Arc& arc) {
 109.191 +      --arc._id;
 109.192 +    }
 109.193 +
 109.194 +    void firstInc(Edge& edge, bool& dir, const Node& node) const {
 109.195 +      edge._id = node._id >> 1;
 109.196 +      dir = (node._id & 1) == 0;
 109.197 +    }
 109.198 +
 109.199 +    void nextInc(Edge& edge, bool& dir) const {
 109.200 +      Node n = dir ? u(edge) : v(edge);
 109.201 +      int k = (edge._id >> (_dim-1)) + 1;
 109.202 +      if (k < _dim) {
 109.203 +        edge._id = (k << (_dim-1)) |
 109.204 +          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
 109.205 +        dir = ((n._id >> k) & 1) == 0;
 109.206 +      } else {
 109.207 +        edge._id = -1;
 109.208 +        dir = true;
 109.209 +      }
 109.210 +    }
 109.211 +
 109.212 +    void firstOut(Arc& arc, const Node& node) const {
 109.213 +      arc._id = ((node._id >> 1) << 1) | (~node._id & 1);
 109.214 +    }
 109.215 +
 109.216 +    void nextOut(Arc& arc) const {
 109.217 +      Node n = (arc._id & 1) == 1 ? u(arc) : v(arc);
 109.218 +      int k = (arc._id >> _dim) + 1;
 109.219 +      if (k < _dim) {
 109.220 +        arc._id = (k << (_dim-1)) |
 109.221 +          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
 109.222 +        arc._id = (arc._id << 1) | (~(n._id >> k) & 1);
 109.223 +      } else {
 109.224 +        arc._id = -1;
 109.225 +      }
 109.226 +    }
 109.227 +
 109.228 +    void firstIn(Arc& arc, const Node& node) const {
 109.229 +      arc._id = ((node._id >> 1) << 1) | (node._id & 1);
 109.230 +    }
 109.231 +
 109.232 +    void nextIn(Arc& arc) const {
 109.233 +      Node n = (arc._id & 1) == 1 ? v(arc) : u(arc);
 109.234 +      int k = (arc._id >> _dim) + 1;
 109.235 +      if (k < _dim) {
 109.236 +        arc._id = (k << (_dim-1)) |
 109.237 +          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
 109.238 +        arc._id = (arc._id << 1) | ((n._id >> k) & 1);
 109.239 +      } else {
 109.240 +        arc._id = -1;
 109.241 +      }
 109.242 +    }
 109.243 +
 109.244 +    static bool direction(Arc arc) {
 109.245 +      return (arc._id & 1) == 1;
 109.246 +    }
 109.247 +
 109.248 +    static Arc direct(Edge edge, bool dir) {
 109.249 +      return Arc((edge._id << 1) | (dir ? 1 : 0));
 109.250 +    }
 109.251 +
 109.252 +    int dimension() const {
 109.253 +      return _dim;
 109.254 +    }
 109.255 +
 109.256 +    bool projection(Node node, int n) const {
 109.257 +      return static_cast<bool>(node._id & (1 << n));
 109.258 +    }
 109.259 +
 109.260 +    int dimension(Edge edge) const {
 109.261 +      return edge._id >> (_dim-1);
 109.262 +    }
 109.263 +
 109.264 +    int dimension(Arc arc) const {
 109.265 +      return arc._id >> _dim;
 109.266 +    }
 109.267 +
 109.268 +    static int index(Node node) {
 109.269 +      return node._id;
 109.270 +    }
 109.271 +
 109.272 +    Node operator()(int ix) const {
 109.273 +      return Node(ix);
 109.274 +    }
 109.275 +
 109.276 +  private:
 109.277 +    int _dim;
 109.278 +    int _node_num, _edge_num;
 109.279 +  };
 109.280 +
 109.281 +
 109.282 +  typedef GraphExtender<HypercubeGraphBase> ExtendedHypercubeGraphBase;
 109.283 +
 109.284 +  /// \ingroup graphs
 109.285 +  ///
 109.286 +  /// \brief Hypercube graph class
 109.287 +  ///
 109.288 +  /// HypercubeGraph implements a special graph type. The nodes of the
 109.289 +  /// graph are indexed with integers having at most \c dim binary digits.
 109.290 +  /// Two nodes are connected in the graph if and only if their indices
 109.291 +  /// differ only on one position in the binary form.
 109.292 +  /// This class is completely static and it needs constant memory space.
 109.293 +  /// Thus you can neither add nor delete nodes or edges, however 
 109.294 +  /// the structure can be resized using resize().
 109.295 +  ///
 109.296 +  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
 109.297 +  /// Most of its member functions and nested classes are documented
 109.298 +  /// only in the concept class.
 109.299 +  ///
 109.300 +  /// \note The type of the indices is chosen to \c int for efficiency
 109.301 +  /// reasons. Thus the maximum dimension of this implementation is 26
 109.302 +  /// (assuming that the size of \c int is 32 bit).
 109.303 +  class HypercubeGraph : public ExtendedHypercubeGraphBase {
 109.304 +    typedef ExtendedHypercubeGraphBase Parent;
 109.305 +
 109.306 +  public:
 109.307 +
 109.308 +    /// \brief Constructs a hypercube graph with \c dim dimensions.
 109.309 +    ///
 109.310 +    /// Constructs a hypercube graph with \c dim dimensions.
 109.311 +    HypercubeGraph(int dim) { construct(dim); }
 109.312 +
 109.313 +    /// \brief Resizes the graph
 109.314 +    ///
 109.315 +    /// This function resizes the graph. It fully destroys and
 109.316 +    /// rebuilds the structure, therefore the maps of the graph will be
 109.317 +    /// reallocated automatically and the previous values will be lost.
 109.318 +    void resize(int dim) {
 109.319 +      Parent::notifier(Arc()).clear();
 109.320 +      Parent::notifier(Edge()).clear();
 109.321 +      Parent::notifier(Node()).clear();
 109.322 +      construct(dim);
 109.323 +      Parent::notifier(Node()).build();
 109.324 +      Parent::notifier(Edge()).build();
 109.325 +      Parent::notifier(Arc()).build();
 109.326 +    }
 109.327 +
 109.328 +    /// \brief The number of dimensions.
 109.329 +    ///
 109.330 +    /// Gives back the number of dimensions.
 109.331 +    int dimension() const {
 109.332 +      return Parent::dimension();
 109.333 +    }
 109.334 +
 109.335 +    /// \brief Returns \c true if the n'th bit of the node is one.
 109.336 +    ///
 109.337 +    /// Returns \c true if the n'th bit of the node is one.
 109.338 +    bool projection(Node node, int n) const {
 109.339 +      return Parent::projection(node, n);
 109.340 +    }
 109.341 +
 109.342 +    /// \brief The dimension id of an edge.
 109.343 +    ///
 109.344 +    /// Gives back the dimension id of the given edge.
 109.345 +    /// It is in the range <tt>[0..dim-1]</tt>.
 109.346 +    int dimension(Edge edge) const {
 109.347 +      return Parent::dimension(edge);
 109.348 +    }
 109.349 +
 109.350 +    /// \brief The dimension id of an arc.
 109.351 +    ///
 109.352 +    /// Gives back the dimension id of the given arc.
 109.353 +    /// It is in the range <tt>[0..dim-1]</tt>.
 109.354 +    int dimension(Arc arc) const {
 109.355 +      return Parent::dimension(arc);
 109.356 +    }
 109.357 +
 109.358 +    /// \brief The index of a node.
 109.359 +    ///
 109.360 +    /// Gives back the index of the given node.
 109.361 +    /// The lower bits of the integer describes the node.
 109.362 +    static int index(Node node) {
 109.363 +      return Parent::index(node);
 109.364 +    }
 109.365 +
 109.366 +    /// \brief Gives back a node by its index.
 109.367 +    ///
 109.368 +    /// Gives back a node by its index.
 109.369 +    Node operator()(int ix) const {
 109.370 +      return Parent::operator()(ix);
 109.371 +    }
 109.372 +
 109.373 +    /// \brief Number of nodes.
 109.374 +    int nodeNum() const { return Parent::nodeNum(); }
 109.375 +    /// \brief Number of edges.
 109.376 +    int edgeNum() const { return Parent::edgeNum(); }
 109.377 +    /// \brief Number of arcs.
 109.378 +    int arcNum() const { return Parent::arcNum(); }
 109.379 +
 109.380 +    /// \brief Linear combination map.
 109.381 +    ///
 109.382 +    /// This map makes possible to give back a linear combination
 109.383 +    /// for each node. It works like the \c std::accumulate function,
 109.384 +    /// so it accumulates the \c bf binary function with the \c fv first
 109.385 +    /// value. The map accumulates only on that positions (dimensions)
 109.386 +    /// where the index of the node is one. The values that have to be
 109.387 +    /// accumulated should be given by the \c begin and \c end iterators
 109.388 +    /// and the length of this range should be equal to the dimension
 109.389 +    /// number of the graph.
 109.390 +    ///
 109.391 +    ///\code
 109.392 +    /// const int DIM = 3;
 109.393 +    /// HypercubeGraph graph(DIM);
 109.394 +    /// dim2::Point<double> base[DIM];
 109.395 +    /// for (int k = 0; k < DIM; ++k) {
 109.396 +    ///   base[k].x = rnd();
 109.397 +    ///   base[k].y = rnd();
 109.398 +    /// }
 109.399 +    /// HypercubeGraph::HyperMap<dim2::Point<double> >
 109.400 +    ///   pos(graph, base, base + DIM, dim2::Point<double>(0.0, 0.0));
 109.401 +    ///\endcode
 109.402 +    ///
 109.403 +    /// \see HypercubeGraph
 109.404 +    template <typename T, typename BF = std::plus<T> >
 109.405 +    class HyperMap {
 109.406 +    public:
 109.407 +
 109.408 +      /// \brief The key type of the map
 109.409 +      typedef Node Key;
 109.410 +      /// \brief The value type of the map
 109.411 +      typedef T Value;
 109.412 +
 109.413 +      /// \brief Constructor for HyperMap.
 109.414 +      ///
 109.415 +      /// Construct a HyperMap for the given graph. The values that have
 109.416 +      /// to be accumulated should be given by the \c begin and \c end
 109.417 +      /// iterators and the length of this range should be equal to the
 109.418 +      /// dimension number of the graph.
 109.419 +      ///
 109.420 +      /// This map accumulates the \c bf binary function with the \c fv
 109.421 +      /// first value on that positions (dimensions) where the index of
 109.422 +      /// the node is one.
 109.423 +      template <typename It>
 109.424 +      HyperMap(const Graph& graph, It begin, It end,
 109.425 +               T fv = 0, const BF& bf = BF())
 109.426 +        : _graph(graph), _values(begin, end), _first_value(fv), _bin_func(bf)
 109.427 +      {
 109.428 +        LEMON_ASSERT(_values.size() == graph.dimension(),
 109.429 +                     "Wrong size of range");
 109.430 +      }
 109.431 +
 109.432 +      /// \brief The partial accumulated value.
 109.433 +      ///
 109.434 +      /// Gives back the partial accumulated value.
 109.435 +      Value operator[](const Key& k) const {
 109.436 +        Value val = _first_value;
 109.437 +        int id = _graph.index(k);
 109.438 +        int n = 0;
 109.439 +        while (id != 0) {
 109.440 +          if (id & 1) {
 109.441 +            val = _bin_func(val, _values[n]);
 109.442 +          }
 109.443 +          id >>= 1;
 109.444 +          ++n;
 109.445 +        }
 109.446 +        return val;
 109.447 +      }
 109.448 +
 109.449 +    private:
 109.450 +      const Graph& _graph;
 109.451 +      std::vector<T> _values;
 109.452 +      T _first_value;
 109.453 +      BF _bin_func;
 109.454 +    };
 109.455 +
 109.456 +  };
 109.457 +
 109.458 +}
 109.459 +
 109.460 +#endif
   110.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   110.2 +++ b/lemon/karp.h	Thu Nov 05 15:50:01 2009 +0100
   110.3 @@ -0,0 +1,582 @@
   110.4 +/* -*- C++ -*-
   110.5 + *
   110.6 + * This file is a part of LEMON, a generic C++ optimization library
   110.7 + *
   110.8 + * Copyright (C) 2003-2008
   110.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  110.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  110.11 + *
  110.12 + * Permission to use, modify and distribute this software is granted
  110.13 + * provided that this copyright notice appears in all copies. For
  110.14 + * precise terms see the accompanying LICENSE file.
  110.15 + *
  110.16 + * This software is provided "AS IS" with no warranty of any kind,
  110.17 + * express or implied, and with no claim as to its suitability for any
  110.18 + * purpose.
  110.19 + *
  110.20 + */
  110.21 +
  110.22 +#ifndef LEMON_KARP_H
  110.23 +#define LEMON_KARP_H
  110.24 +
  110.25 +/// \ingroup min_mean_cycle
  110.26 +///
  110.27 +/// \file
  110.28 +/// \brief Karp's algorithm for finding a minimum mean cycle.
  110.29 +
  110.30 +#include <vector>
  110.31 +#include <limits>
  110.32 +#include <lemon/core.h>
  110.33 +#include <lemon/path.h>
  110.34 +#include <lemon/tolerance.h>
  110.35 +#include <lemon/connectivity.h>
  110.36 +
  110.37 +namespace lemon {
  110.38 +
  110.39 +  /// \brief Default traits class of Karp algorithm.
  110.40 +  ///
  110.41 +  /// Default traits class of Karp algorithm.
  110.42 +  /// \tparam GR The type of the digraph.
  110.43 +  /// \tparam LEN The type of the length map.
  110.44 +  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
  110.45 +#ifdef DOXYGEN
  110.46 +  template <typename GR, typename LEN>
  110.47 +#else
  110.48 +  template <typename GR, typename LEN,
  110.49 +    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
  110.50 +#endif
  110.51 +  struct KarpDefaultTraits
  110.52 +  {
  110.53 +    /// The type of the digraph
  110.54 +    typedef GR Digraph;
  110.55 +    /// The type of the length map
  110.56 +    typedef LEN LengthMap;
  110.57 +    /// The type of the arc lengths
  110.58 +    typedef typename LengthMap::Value Value;
  110.59 +
  110.60 +    /// \brief The large value type used for internal computations
  110.61 +    ///
  110.62 +    /// The large value type used for internal computations.
  110.63 +    /// It is \c long \c long if the \c Value type is integer,
  110.64 +    /// otherwise it is \c double.
  110.65 +    /// \c Value must be convertible to \c LargeValue.
  110.66 +    typedef double LargeValue;
  110.67 +
  110.68 +    /// The tolerance type used for internal computations
  110.69 +    typedef lemon::Tolerance<LargeValue> Tolerance;
  110.70 +
  110.71 +    /// \brief The path type of the found cycles
  110.72 +    ///
  110.73 +    /// The path type of the found cycles.
  110.74 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
  110.75 +    /// and it must have an \c addFront() function.
  110.76 +    typedef lemon::Path<Digraph> Path;
  110.77 +  };
  110.78 +
  110.79 +  // Default traits class for integer value types
  110.80 +  template <typename GR, typename LEN>
  110.81 +  struct KarpDefaultTraits<GR, LEN, true>
  110.82 +  {
  110.83 +    typedef GR Digraph;
  110.84 +    typedef LEN LengthMap;
  110.85 +    typedef typename LengthMap::Value Value;
  110.86 +#ifdef LEMON_HAVE_LONG_LONG
  110.87 +    typedef long long LargeValue;
  110.88 +#else
  110.89 +    typedef long LargeValue;
  110.90 +#endif
  110.91 +    typedef lemon::Tolerance<LargeValue> Tolerance;
  110.92 +    typedef lemon::Path<Digraph> Path;
  110.93 +  };
  110.94 +
  110.95 +
  110.96 +  /// \addtogroup min_mean_cycle
  110.97 +  /// @{
  110.98 +
  110.99 +  /// \brief Implementation of Karp's algorithm for finding a minimum
 110.100 +  /// mean cycle.
 110.101 +  ///
 110.102 +  /// This class implements Karp's algorithm for finding a directed
 110.103 +  /// cycle of minimum mean length (cost) in a digraph
 110.104 +  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
 110.105 +  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
 110.106 +  ///
 110.107 +  /// \tparam GR The type of the digraph the algorithm runs on.
 110.108 +  /// \tparam LEN The type of the length map. The default
 110.109 +  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
 110.110 +#ifdef DOXYGEN
 110.111 +  template <typename GR, typename LEN, typename TR>
 110.112 +#else
 110.113 +  template < typename GR,
 110.114 +             typename LEN = typename GR::template ArcMap<int>,
 110.115 +             typename TR = KarpDefaultTraits<GR, LEN> >
 110.116 +#endif
 110.117 +  class Karp
 110.118 +  {
 110.119 +  public:
 110.120 +
 110.121 +    /// The type of the digraph
 110.122 +    typedef typename TR::Digraph Digraph;
 110.123 +    /// The type of the length map
 110.124 +    typedef typename TR::LengthMap LengthMap;
 110.125 +    /// The type of the arc lengths
 110.126 +    typedef typename TR::Value Value;
 110.127 +
 110.128 +    /// \brief The large value type
 110.129 +    ///
 110.130 +    /// The large value type used for internal computations.
 110.131 +    /// Using the \ref KarpDefaultTraits "default traits class",
 110.132 +    /// it is \c long \c long if the \c Value type is integer,
 110.133 +    /// otherwise it is \c double.
 110.134 +    typedef typename TR::LargeValue LargeValue;
 110.135 +
 110.136 +    /// The tolerance type
 110.137 +    typedef typename TR::Tolerance Tolerance;
 110.138 +
 110.139 +    /// \brief The path type of the found cycles
 110.140 +    ///
 110.141 +    /// The path type of the found cycles.
 110.142 +    /// Using the \ref KarpDefaultTraits "default traits class",
 110.143 +    /// it is \ref lemon::Path "Path<Digraph>".
 110.144 +    typedef typename TR::Path Path;
 110.145 +
 110.146 +    /// The \ref KarpDefaultTraits "traits class" of the algorithm
 110.147 +    typedef TR Traits;
 110.148 +
 110.149 +  private:
 110.150 +
 110.151 +    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 110.152 +
 110.153 +    // Data sturcture for path data
 110.154 +    struct PathData
 110.155 +    {
 110.156 +      LargeValue dist;
 110.157 +      Arc pred;
 110.158 +      PathData(LargeValue d, Arc p = INVALID) :
 110.159 +        dist(d), pred(p) {}
 110.160 +    };
 110.161 +
 110.162 +    typedef typename Digraph::template NodeMap<std::vector<PathData> >
 110.163 +      PathDataNodeMap;
 110.164 +
 110.165 +  private:
 110.166 +
 110.167 +    // The digraph the algorithm runs on
 110.168 +    const Digraph &_gr;
 110.169 +    // The length of the arcs
 110.170 +    const LengthMap &_length;
 110.171 +
 110.172 +    // Data for storing the strongly connected components
 110.173 +    int _comp_num;
 110.174 +    typename Digraph::template NodeMap<int> _comp;
 110.175 +    std::vector<std::vector<Node> > _comp_nodes;
 110.176 +    std::vector<Node>* _nodes;
 110.177 +    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
 110.178 +
 110.179 +    // Data for the found cycle
 110.180 +    LargeValue _cycle_length;
 110.181 +    int _cycle_size;
 110.182 +    Node _cycle_node;
 110.183 +
 110.184 +    Path *_cycle_path;
 110.185 +    bool _local_path;
 110.186 +
 110.187 +    // Node map for storing path data
 110.188 +    PathDataNodeMap _data;
 110.189 +    // The processed nodes in the last round
 110.190 +    std::vector<Node> _process;
 110.191 +
 110.192 +    Tolerance _tolerance;
 110.193 +    
 110.194 +    // Infinite constant
 110.195 +    const LargeValue INF;
 110.196 +
 110.197 +  public:
 110.198 +
 110.199 +    /// \name Named Template Parameters
 110.200 +    /// @{
 110.201 +
 110.202 +    template <typename T>
 110.203 +    struct SetLargeValueTraits : public Traits {
 110.204 +      typedef T LargeValue;
 110.205 +      typedef lemon::Tolerance<T> Tolerance;
 110.206 +    };
 110.207 +
 110.208 +    /// \brief \ref named-templ-param "Named parameter" for setting
 110.209 +    /// \c LargeValue type.
 110.210 +    ///
 110.211 +    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
 110.212 +    /// type. It is used for internal computations in the algorithm.
 110.213 +    template <typename T>
 110.214 +    struct SetLargeValue
 110.215 +      : public Karp<GR, LEN, SetLargeValueTraits<T> > {
 110.216 +      typedef Karp<GR, LEN, SetLargeValueTraits<T> > Create;
 110.217 +    };
 110.218 +
 110.219 +    template <typename T>
 110.220 +    struct SetPathTraits : public Traits {
 110.221 +      typedef T Path;
 110.222 +    };
 110.223 +
 110.224 +    /// \brief \ref named-templ-param "Named parameter" for setting
 110.225 +    /// \c %Path type.
 110.226 +    ///
 110.227 +    /// \ref named-templ-param "Named parameter" for setting the \c %Path
 110.228 +    /// type of the found cycles.
 110.229 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
 110.230 +    /// and it must have an \c addFront() function.
 110.231 +    template <typename T>
 110.232 +    struct SetPath
 110.233 +      : public Karp<GR, LEN, SetPathTraits<T> > {
 110.234 +      typedef Karp<GR, LEN, SetPathTraits<T> > Create;
 110.235 +    };
 110.236 +
 110.237 +    /// @}
 110.238 +
 110.239 +  public:
 110.240 +
 110.241 +    /// \brief Constructor.
 110.242 +    ///
 110.243 +    /// The constructor of the class.
 110.244 +    ///
 110.245 +    /// \param digraph The digraph the algorithm runs on.
 110.246 +    /// \param length The lengths (costs) of the arcs.
 110.247 +    Karp( const Digraph &digraph,
 110.248 +          const LengthMap &length ) :
 110.249 +      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
 110.250 +      _cycle_length(0), _cycle_size(1), _cycle_node(INVALID),
 110.251 +      _cycle_path(NULL), _local_path(false), _data(digraph),
 110.252 +      INF(std::numeric_limits<LargeValue>::has_infinity ?
 110.253 +          std::numeric_limits<LargeValue>::infinity() :
 110.254 +          std::numeric_limits<LargeValue>::max())
 110.255 +    {}
 110.256 +
 110.257 +    /// Destructor.
 110.258 +    ~Karp() {
 110.259 +      if (_local_path) delete _cycle_path;
 110.260 +    }
 110.261 +
 110.262 +    /// \brief Set the path structure for storing the found cycle.
 110.263 +    ///
 110.264 +    /// This function sets an external path structure for storing the
 110.265 +    /// found cycle.
 110.266 +    ///
 110.267 +    /// If you don't call this function before calling \ref run() or
 110.268 +    /// \ref findMinMean(), it will allocate a local \ref Path "path"
 110.269 +    /// structure. The destuctor deallocates this automatically
 110.270 +    /// allocated object, of course.
 110.271 +    ///
 110.272 +    /// \note The algorithm calls only the \ref lemon::Path::addFront()
 110.273 +    /// "addFront()" function of the given path structure.
 110.274 +    ///
 110.275 +    /// \return <tt>(*this)</tt>
 110.276 +    Karp& cycle(Path &path) {
 110.277 +      if (_local_path) {
 110.278 +        delete _cycle_path;
 110.279 +        _local_path = false;
 110.280 +      }
 110.281 +      _cycle_path = &path;
 110.282 +      return *this;
 110.283 +    }
 110.284 +
 110.285 +    /// \brief Set the tolerance used by the algorithm.
 110.286 +    ///
 110.287 +    /// This function sets the tolerance object used by the algorithm.
 110.288 +    ///
 110.289 +    /// \return <tt>(*this)</tt>
 110.290 +    Karp& tolerance(const Tolerance& tolerance) {
 110.291 +      _tolerance = tolerance;
 110.292 +      return *this;
 110.293 +    }
 110.294 +
 110.295 +    /// \brief Return a const reference to the tolerance.
 110.296 +    ///
 110.297 +    /// This function returns a const reference to the tolerance object
 110.298 +    /// used by the algorithm.
 110.299 +    const Tolerance& tolerance() const {
 110.300 +      return _tolerance;
 110.301 +    }
 110.302 +
 110.303 +    /// \name Execution control
 110.304 +    /// The simplest way to execute the algorithm is to call the \ref run()
 110.305 +    /// function.\n
 110.306 +    /// If you only need the minimum mean length, you may call
 110.307 +    /// \ref findMinMean().
 110.308 +
 110.309 +    /// @{
 110.310 +
 110.311 +    /// \brief Run the algorithm.
 110.312 +    ///
 110.313 +    /// This function runs the algorithm.
 110.314 +    /// It can be called more than once (e.g. if the underlying digraph
 110.315 +    /// and/or the arc lengths have been modified).
 110.316 +    ///
 110.317 +    /// \return \c true if a directed cycle exists in the digraph.
 110.318 +    ///
 110.319 +    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
 110.320 +    /// \code
 110.321 +    ///   return mmc.findMinMean() && mmc.findCycle();
 110.322 +    /// \endcode
 110.323 +    bool run() {
 110.324 +      return findMinMean() && findCycle();
 110.325 +    }
 110.326 +
 110.327 +    /// \brief Find the minimum cycle mean.
 110.328 +    ///
 110.329 +    /// This function finds the minimum mean length of the directed
 110.330 +    /// cycles in the digraph.
 110.331 +    ///
 110.332 +    /// \return \c true if a directed cycle exists in the digraph.
 110.333 +    bool findMinMean() {
 110.334 +      // Initialization and find strongly connected components
 110.335 +      init();
 110.336 +      findComponents();
 110.337 +      
 110.338 +      // Find the minimum cycle mean in the components
 110.339 +      for (int comp = 0; comp < _comp_num; ++comp) {
 110.340 +        if (!initComponent(comp)) continue;
 110.341 +        processRounds();
 110.342 +        updateMinMean();
 110.343 +      }
 110.344 +      return (_cycle_node != INVALID);
 110.345 +    }
 110.346 +
 110.347 +    /// \brief Find a minimum mean directed cycle.
 110.348 +    ///
 110.349 +    /// This function finds a directed cycle of minimum mean length
 110.350 +    /// in the digraph using the data computed by findMinMean().
 110.351 +    ///
 110.352 +    /// \return \c true if a directed cycle exists in the digraph.
 110.353 +    ///
 110.354 +    /// \pre \ref findMinMean() must be called before using this function.
 110.355 +    bool findCycle() {
 110.356 +      if (_cycle_node == INVALID) return false;
 110.357 +      IntNodeMap reached(_gr, -1);
 110.358 +      int r = _data[_cycle_node].size();
 110.359 +      Node u = _cycle_node;
 110.360 +      while (reached[u] < 0) {
 110.361 +        reached[u] = --r;
 110.362 +        u = _gr.source(_data[u][r].pred);
 110.363 +      }
 110.364 +      r = reached[u];
 110.365 +      Arc e = _data[u][r].pred;
 110.366 +      _cycle_path->addFront(e);
 110.367 +      _cycle_length = _length[e];
 110.368 +      _cycle_size = 1;
 110.369 +      Node v;
 110.370 +      while ((v = _gr.source(e)) != u) {
 110.371 +        e = _data[v][--r].pred;
 110.372 +        _cycle_path->addFront(e);
 110.373 +        _cycle_length += _length[e];
 110.374 +        ++_cycle_size;
 110.375 +      }
 110.376 +      return true;
 110.377 +    }
 110.378 +
 110.379 +    /// @}
 110.380 +
 110.381 +    /// \name Query Functions
 110.382 +    /// The results of the algorithm can be obtained using these
 110.383 +    /// functions.\n
 110.384 +    /// The algorithm should be executed before using them.
 110.385 +
 110.386 +    /// @{
 110.387 +
 110.388 +    /// \brief Return the total length of the found cycle.
 110.389 +    ///
 110.390 +    /// This function returns the total length of the found cycle.
 110.391 +    ///
 110.392 +    /// \pre \ref run() or \ref findMinMean() must be called before
 110.393 +    /// using this function.
 110.394 +    LargeValue cycleLength() const {
 110.395 +      return _cycle_length;
 110.396 +    }
 110.397 +
 110.398 +    /// \brief Return the number of arcs on the found cycle.
 110.399 +    ///
 110.400 +    /// This function returns the number of arcs on the found cycle.
 110.401 +    ///
 110.402 +    /// \pre \ref run() or \ref findMinMean() must be called before
 110.403 +    /// using this function.
 110.404 +    int cycleArcNum() const {
 110.405 +      return _cycle_size;
 110.406 +    }
 110.407 +
 110.408 +    /// \brief Return the mean length of the found cycle.
 110.409 +    ///
 110.410 +    /// This function returns the mean length of the found cycle.
 110.411 +    ///
 110.412 +    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
 110.413 +    /// following code.
 110.414 +    /// \code
 110.415 +    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
 110.416 +    /// \endcode
 110.417 +    ///
 110.418 +    /// \pre \ref run() or \ref findMinMean() must be called before
 110.419 +    /// using this function.
 110.420 +    double cycleMean() const {
 110.421 +      return static_cast<double>(_cycle_length) / _cycle_size;
 110.422 +    }
 110.423 +
 110.424 +    /// \brief Return the found cycle.
 110.425 +    ///
 110.426 +    /// This function returns a const reference to the path structure
 110.427 +    /// storing the found cycle.
 110.428 +    ///
 110.429 +    /// \pre \ref run() or \ref findCycle() must be called before using
 110.430 +    /// this function.
 110.431 +    const Path& cycle() const {
 110.432 +      return *_cycle_path;
 110.433 +    }
 110.434 +
 110.435 +    ///@}
 110.436 +
 110.437 +  private:
 110.438 +
 110.439 +    // Initialization
 110.440 +    void init() {
 110.441 +      if (!_cycle_path) {
 110.442 +        _local_path = true;
 110.443 +        _cycle_path = new Path;
 110.444 +      }
 110.445 +      _cycle_path->clear();
 110.446 +      _cycle_length = 0;
 110.447 +      _cycle_size = 1;
 110.448 +      _cycle_node = INVALID;
 110.449 +      for (NodeIt u(_gr); u != INVALID; ++u)
 110.450 +        _data[u].clear();
 110.451 +    }
 110.452 +
 110.453 +    // Find strongly connected components and initialize _comp_nodes
 110.454 +    // and _out_arcs
 110.455 +    void findComponents() {
 110.456 +      _comp_num = stronglyConnectedComponents(_gr, _comp);
 110.457 +      _comp_nodes.resize(_comp_num);
 110.458 +      if (_comp_num == 1) {
 110.459 +        _comp_nodes[0].clear();
 110.460 +        for (NodeIt n(_gr); n != INVALID; ++n) {
 110.461 +          _comp_nodes[0].push_back(n);
 110.462 +          _out_arcs[n].clear();
 110.463 +          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
 110.464 +            _out_arcs[n].push_back(a);
 110.465 +          }
 110.466 +        }
 110.467 +      } else {
 110.468 +        for (int i = 0; i < _comp_num; ++i)
 110.469 +          _comp_nodes[i].clear();
 110.470 +        for (NodeIt n(_gr); n != INVALID; ++n) {
 110.471 +          int k = _comp[n];
 110.472 +          _comp_nodes[k].push_back(n);
 110.473 +          _out_arcs[n].clear();
 110.474 +          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
 110.475 +            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
 110.476 +          }
 110.477 +        }
 110.478 +      }
 110.479 +    }
 110.480 +
 110.481 +    // Initialize path data for the current component
 110.482 +    bool initComponent(int comp) {
 110.483 +      _nodes = &(_comp_nodes[comp]);
 110.484 +      int n = _nodes->size();
 110.485 +      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
 110.486 +        return false;
 110.487 +      }      
 110.488 +      for (int i = 0; i < n; ++i) {
 110.489 +        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
 110.490 +      }
 110.491 +      return true;
 110.492 +    }
 110.493 +
 110.494 +    // Process all rounds of computing path data for the current component.
 110.495 +    // _data[v][k] is the length of a shortest directed walk from the root
 110.496 +    // node to node v containing exactly k arcs.
 110.497 +    void processRounds() {
 110.498 +      Node start = (*_nodes)[0];
 110.499 +      _data[start][0] = PathData(0);
 110.500 +      _process.clear();
 110.501 +      _process.push_back(start);
 110.502 +
 110.503 +      int k, n = _nodes->size();
 110.504 +      for (k = 1; k <= n && int(_process.size()) < n; ++k) {
 110.505 +        processNextBuildRound(k);
 110.506 +      }
 110.507 +      for ( ; k <= n; ++k) {
 110.508 +        processNextFullRound(k);
 110.509 +      }
 110.510 +    }
 110.511 +
 110.512 +    // Process one round and rebuild _process
 110.513 +    void processNextBuildRound(int k) {
 110.514 +      std::vector<Node> next;
 110.515 +      Node u, v;
 110.516 +      Arc e;
 110.517 +      LargeValue d;
 110.518 +      for (int i = 0; i < int(_process.size()); ++i) {
 110.519 +        u = _process[i];
 110.520 +        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
 110.521 +          e = _out_arcs[u][j];
 110.522 +          v = _gr.target(e);
 110.523 +          d = _data[u][k-1].dist + _length[e];
 110.524 +          if (_tolerance.less(d, _data[v][k].dist)) {
 110.525 +            if (_data[v][k].dist == INF) next.push_back(v);
 110.526 +            _data[v][k] = PathData(d, e);
 110.527 +          }
 110.528 +        }
 110.529 +      }
 110.530 +      _process.swap(next);
 110.531 +    }
 110.532 +
 110.533 +    // Process one round using _nodes instead of _process
 110.534 +    void processNextFullRound(int k) {
 110.535 +      Node u, v;
 110.536 +      Arc e;
 110.537 +      LargeValue d;
 110.538 +      for (int i = 0; i < int(_nodes->size()); ++i) {
 110.539 +        u = (*_nodes)[i];
 110.540 +        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
 110.541 +          e = _out_arcs[u][j];
 110.542 +          v = _gr.target(e);
 110.543 +          d = _data[u][k-1].dist + _length[e];
 110.544 +          if (_tolerance.less(d, _data[v][k].dist)) {
 110.545 +            _data[v][k] = PathData(d, e);
 110.546 +          }
 110.547 +        }
 110.548 +      }
 110.549 +    }
 110.550 +
 110.551 +    // Update the minimum cycle mean
 110.552 +    void updateMinMean() {
 110.553 +      int n = _nodes->size();
 110.554 +      for (int i = 0; i < n; ++i) {
 110.555 +        Node u = (*_nodes)[i];
 110.556 +        if (_data[u][n].dist == INF) continue;
 110.557 +        LargeValue length, max_length = 0;
 110.558 +        int size, max_size = 1;
 110.559 +        bool found_curr = false;
 110.560 +        for (int k = 0; k < n; ++k) {
 110.561 +          if (_data[u][k].dist == INF) continue;
 110.562 +          length = _data[u][n].dist - _data[u][k].dist;
 110.563 +          size = n - k;
 110.564 +          if (!found_curr || length * max_size > max_length * size) {
 110.565 +            found_curr = true;
 110.566 +            max_length = length;
 110.567 +            max_size = size;
 110.568 +          }
 110.569 +        }
 110.570 +        if ( found_curr && (_cycle_node == INVALID ||
 110.571 +             max_length * _cycle_size < _cycle_length * max_size) ) {
 110.572 +          _cycle_length = max_length;
 110.573 +          _cycle_size = max_size;
 110.574 +          _cycle_node = u;
 110.575 +        }
 110.576 +      }
 110.577 +    }
 110.578 +
 110.579 +  }; //class Karp
 110.580 +
 110.581 +  ///@}
 110.582 +
 110.583 +} //namespace lemon
 110.584 +
 110.585 +#endif //LEMON_KARP_H
   111.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   111.2 +++ b/lemon/kary_heap.h	Thu Nov 05 15:50:01 2009 +0100
   111.3 @@ -0,0 +1,352 @@
   111.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   111.5 + *
   111.6 + * This file is a part of LEMON, a generic C++ optimization library.
   111.7 + *
   111.8 + * Copyright (C) 2003-2009
   111.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  111.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  111.11 + *
  111.12 + * Permission to use, modify and distribute this software is granted
  111.13 + * provided that this copyright notice appears in all copies. For
  111.14 + * precise terms see the accompanying LICENSE file.
  111.15 + *
  111.16 + * This software is provided "AS IS" with no warranty of any kind,
  111.17 + * express or implied, and with no claim as to its suitability for any
  111.18 + * purpose.
  111.19 + *
  111.20 + */
  111.21 +
  111.22 +#ifndef LEMON_KARY_HEAP_H
  111.23 +#define LEMON_KARY_HEAP_H
  111.24 +
  111.25 +///\ingroup heaps
  111.26 +///\file
  111.27 +///\brief Fourary heap implementation.
  111.28 +
  111.29 +#include <vector>
  111.30 +#include <utility>
  111.31 +#include <functional>
  111.32 +
  111.33 +namespace lemon {
  111.34 +
  111.35 +  /// \ingroup heaps
  111.36 +  ///
  111.37 +  ///\brief K-ary heap data structure.
  111.38 +  ///
  111.39 +  /// This class implements the \e K-ary \e heap data structure.
  111.40 +  /// It fully conforms to the \ref concepts::Heap "heap concept".
  111.41 +  ///
  111.42 +  /// The \ref KaryHeap "K-ary heap" is a generalization of the
  111.43 +  /// \ref BinHeap "binary heap" structure, its nodes have at most
  111.44 +  /// \c K children, instead of two.
  111.45 +  /// \ref BinHeap and \ref FouraryHeap are specialized implementations
  111.46 +  /// of this structure for <tt>K=2</tt> and <tt>K=4</tt>, respectively.
  111.47 +  ///
  111.48 +  /// \tparam PR Type of the priorities of the items.
  111.49 +  /// \tparam IM A read-writable item map with \c int values, used
  111.50 +  /// internally to handle the cross references.
  111.51 +  /// \tparam K The degree of the heap, each node have at most \e K
  111.52 +  /// children. The default is 16. Powers of two are suggested to use
  111.53 +  /// so that the multiplications and divisions needed to traverse the
  111.54 +  /// nodes of the heap could be performed faster.
  111.55 +  /// \tparam CMP A functor class for comparing the priorities.
  111.56 +  /// The default is \c std::less<PR>.
  111.57 +  ///
  111.58 +  ///\sa BinHeap
  111.59 +  ///\sa FouraryHeap
  111.60 +#ifdef DOXYGEN
  111.61 +  template <typename PR, typename IM, int K, typename CMP>
  111.62 +#else
  111.63 +  template <typename PR, typename IM, int K = 16,
  111.64 +            typename CMP = std::less<PR> >
  111.65 +#endif
  111.66 +  class KaryHeap {
  111.67 +  public:
  111.68 +    /// Type of the item-int map.
  111.69 +    typedef IM ItemIntMap;
  111.70 +    /// Type of the priorities.
  111.71 +    typedef PR Prio;
  111.72 +    /// Type of the items stored in the heap.
  111.73 +    typedef typename ItemIntMap::Key Item;
  111.74 +    /// Type of the item-priority pairs.
  111.75 +    typedef std::pair<Item,Prio> Pair;
  111.76 +    /// Functor type for comparing the priorities.
  111.77 +    typedef CMP Compare;
  111.78 +
  111.79 +    /// \brief Type to represent the states of the items.
  111.80 +    ///
  111.81 +    /// Each item has a state associated to it. It can be "in heap",
  111.82 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
  111.83 +    /// heap's point of view, but may be useful to the user.
  111.84 +    ///
  111.85 +    /// The item-int map must be initialized in such way that it assigns
  111.86 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
  111.87 +    enum State {
  111.88 +      IN_HEAP = 0,    ///< = 0.
  111.89 +      PRE_HEAP = -1,  ///< = -1.
  111.90 +      POST_HEAP = -2  ///< = -2.
  111.91 +    };
  111.92 +
  111.93 +  private:
  111.94 +    std::vector<Pair> _data;
  111.95 +    Compare _comp;
  111.96 +    ItemIntMap &_iim;
  111.97 +
  111.98 +  public:
  111.99 +    /// \brief Constructor.
 111.100 +    ///
 111.101 +    /// Constructor.
 111.102 +    /// \param map A map that assigns \c int values to the items.
 111.103 +    /// It is used internally to handle the cross references.
 111.104 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
 111.105 +    explicit KaryHeap(ItemIntMap &map) : _iim(map) {}
 111.106 +
 111.107 +    /// \brief Constructor.
 111.108 +    ///
 111.109 +    /// Constructor.
 111.110 +    /// \param map A map that assigns \c int values to the items.
 111.111 +    /// It is used internally to handle the cross references.
 111.112 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
 111.113 +    /// \param comp The function object used for comparing the priorities.
 111.114 +    KaryHeap(ItemIntMap &map, const Compare &comp)
 111.115 +      : _iim(map), _comp(comp) {}
 111.116 +
 111.117 +    /// \brief The number of items stored in the heap.
 111.118 +    ///
 111.119 +    /// This function returns the number of items stored in the heap.
 111.120 +    int size() const { return _data.size(); }
 111.121 +
 111.122 +    /// \brief Check if the heap is empty.
 111.123 +    ///
 111.124 +    /// This function returns \c true if the heap is empty.
 111.125 +    bool empty() const { return _data.empty(); }
 111.126 +
 111.127 +    /// \brief Make the heap empty.
 111.128 +    ///
 111.129 +    /// This functon makes the heap empty.
 111.130 +    /// It does not change the cross reference map. If you want to reuse
 111.131 +    /// a heap that is not surely empty, you should first clear it and
 111.132 +    /// then you should set the cross reference map to \c PRE_HEAP
 111.133 +    /// for each item.
 111.134 +    void clear() { _data.clear(); }
 111.135 +
 111.136 +  private:
 111.137 +    int parent(int i) { return (i-1)/K; }
 111.138 +    int firstChild(int i) { return K*i+1; }
 111.139 +
 111.140 +    bool less(const Pair &p1, const Pair &p2) const {
 111.141 +      return _comp(p1.second, p2.second);
 111.142 +    }
 111.143 +
 111.144 +    void bubbleUp(int hole, Pair p) {
 111.145 +      int par = parent(hole);
 111.146 +      while( hole>0 && less(p,_data[par]) ) {
 111.147 +        move(_data[par],hole);
 111.148 +        hole = par;
 111.149 +        par = parent(hole);
 111.150 +      }
 111.151 +      move(p, hole);
 111.152 +    }
 111.153 +
 111.154 +    void bubbleDown(int hole, Pair p, int length) {
 111.155 +      if( length>1 ) {
 111.156 +        int child = firstChild(hole);
 111.157 +        while( child+K<=length ) {
 111.158 +          int min=child;
 111.159 +          for (int i=1; i<K; ++i) {
 111.160 +            if( less(_data[child+i], _data[min]) )
 111.161 +              min=child+i;
 111.162 +          }
 111.163 +          if( !less(_data[min], p) )
 111.164 +            goto ok;
 111.165 +          move(_data[min], hole);
 111.166 +          hole = min;
 111.167 +          child = firstChild(hole);
 111.168 +        }
 111.169 +        if ( child<length ) {
 111.170 +          int min = child;
 111.171 +          while (++child < length) {
 111.172 +            if( less(_data[child], _data[min]) )
 111.173 +              min=child;
 111.174 +          }
 111.175 +          if( less(_data[min], p) ) {
 111.176 +            move(_data[min], hole);
 111.177 +            hole = min;
 111.178 +          }
 111.179 +        }
 111.180 +      }
 111.181 +    ok:
 111.182 +      move(p, hole);
 111.183 +    }
 111.184 +
 111.185 +    void move(const Pair &p, int i) {
 111.186 +      _data[i] = p;
 111.187 +      _iim.set(p.first, i);
 111.188 +    }
 111.189 +
 111.190 +  public:
 111.191 +    /// \brief Insert a pair of item and priority into the heap.
 111.192 +    ///
 111.193 +    /// This function inserts \c p.first to the heap with priority
 111.194 +    /// \c p.second.
 111.195 +    /// \param p The pair to insert.
 111.196 +    /// \pre \c p.first must not be stored in the heap.
 111.197 +    void push(const Pair &p) {
 111.198 +      int n = _data.size();
 111.199 +      _data.resize(n+1);
 111.200 +      bubbleUp(n, p);
 111.201 +    }
 111.202 +
 111.203 +    /// \brief Insert an item into the heap with the given priority.
 111.204 +    ///
 111.205 +    /// This function inserts the given item into the heap with the
 111.206 +    /// given priority.
 111.207 +    /// \param i The item to insert.
 111.208 +    /// \param p The priority of the item.
 111.209 +    /// \pre \e i must not be stored in the heap.
 111.210 +    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
 111.211 +
 111.212 +    /// \brief Return the item having minimum priority.
 111.213 +    ///
 111.214 +    /// This function returns the item having minimum priority.
 111.215 +    /// \pre The heap must be non-empty.
 111.216 +    Item top() const { return _data[0].first; }
 111.217 +
 111.218 +    /// \brief The minimum priority.
 111.219 +    ///
 111.220 +    /// This function returns the minimum priority.
 111.221 +    /// \pre The heap must be non-empty.
 111.222 +    Prio prio() const { return _data[0].second; }
 111.223 +
 111.224 +    /// \brief Remove the item having minimum priority.
 111.225 +    ///
 111.226 +    /// This function removes the item having minimum priority.
 111.227 +    /// \pre The heap must be non-empty.
 111.228 +    void pop() {
 111.229 +      int n = _data.size()-1;
 111.230 +      _iim.set(_data[0].first, POST_HEAP);
 111.231 +      if (n>0) bubbleDown(0, _data[n], n);
 111.232 +      _data.pop_back();
 111.233 +    }
 111.234 +
 111.235 +    /// \brief Remove the given item from the heap.
 111.236 +    ///
 111.237 +    /// This function removes the given item from the heap if it is
 111.238 +    /// already stored.
 111.239 +    /// \param i The item to delete.
 111.240 +    /// \pre \e i must be in the heap.
 111.241 +    void erase(const Item &i) {
 111.242 +      int h = _iim[i];
 111.243 +      int n = _data.size()-1;
 111.244 +      _iim.set(_data[h].first, POST_HEAP);
 111.245 +      if( h<n ) {
 111.246 +        if( less(_data[parent(h)], _data[n]) )
 111.247 +          bubbleDown(h, _data[n], n);
 111.248 +        else
 111.249 +          bubbleUp(h, _data[n]);
 111.250 +      }
 111.251 +      _data.pop_back();
 111.252 +    }
 111.253 +
 111.254 +    /// \brief The priority of the given item.
 111.255 +    ///
 111.256 +    /// This function returns the priority of the given item.
 111.257 +    /// \param i The item.
 111.258 +    /// \pre \e i must be in the heap.
 111.259 +    Prio operator[](const Item &i) const {
 111.260 +      int idx = _iim[i];
 111.261 +      return _data[idx].second;
 111.262 +    }
 111.263 +
 111.264 +    /// \brief Set the priority of an item or insert it, if it is
 111.265 +    /// not stored in the heap.
 111.266 +    ///
 111.267 +    /// This method sets the priority of the given item if it is
 111.268 +    /// already stored in the heap. Otherwise it inserts the given
 111.269 +    /// item into the heap with the given priority.
 111.270 +    /// \param i The item.
 111.271 +    /// \param p The priority.
 111.272 +    void set(const Item &i, const Prio &p) {
 111.273 +      int idx = _iim[i];
 111.274 +      if( idx<0 )
 111.275 +        push(i,p);
 111.276 +      else if( _comp(p, _data[idx].second) )
 111.277 +        bubbleUp(idx, Pair(i,p));
 111.278 +      else
 111.279 +        bubbleDown(idx, Pair(i,p), _data.size());
 111.280 +    }
 111.281 +
 111.282 +    /// \brief Decrease the priority of an item to the given value.
 111.283 +    ///
 111.284 +    /// This function decreases the priority of an item to the given value.
 111.285 +    /// \param i The item.
 111.286 +    /// \param p The priority.
 111.287 +    /// \pre \e i must be stored in the heap with priority at least \e p.
 111.288 +    void decrease(const Item &i, const Prio &p) {
 111.289 +      int idx = _iim[i];
 111.290 +      bubbleUp(idx, Pair(i,p));
 111.291 +    }
 111.292 +
 111.293 +    /// \brief Increase the priority of an item to the given value.
 111.294 +    ///
 111.295 +    /// This function increases the priority of an item to the given value.
 111.296 +    /// \param i The item.
 111.297 +    /// \param p The priority.
 111.298 +    /// \pre \e i must be stored in the heap with priority at most \e p.
 111.299 +    void increase(const Item &i, const Prio &p) {
 111.300 +      int idx = _iim[i];
 111.301 +      bubbleDown(idx, Pair(i,p), _data.size());
 111.302 +    }
 111.303 +
 111.304 +    /// \brief Return the state of an item.
 111.305 +    ///
 111.306 +    /// This method returns \c PRE_HEAP if the given item has never
 111.307 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
 111.308 +    /// and \c POST_HEAP otherwise.
 111.309 +    /// In the latter case it is possible that the item will get back
 111.310 +    /// to the heap again.
 111.311 +    /// \param i The item.
 111.312 +    State state(const Item &i) const {
 111.313 +      int s = _iim[i];
 111.314 +      if (s>=0) s=0;
 111.315 +      return State(s);
 111.316 +    }
 111.317 +
 111.318 +    /// \brief Set the state of an item in the heap.
 111.319 +    ///
 111.320 +    /// This function sets the state of the given item in the heap.
 111.321 +    /// It can be used to manually clear the heap when it is important
 111.322 +    /// to achive better time complexity.
 111.323 +    /// \param i The item.
 111.324 +    /// \param st The state. It should not be \c IN_HEAP.
 111.325 +    void state(const Item& i, State st) {
 111.326 +      switch (st) {
 111.327 +        case POST_HEAP:
 111.328 +        case PRE_HEAP:
 111.329 +          if (state(i) == IN_HEAP) erase(i);
 111.330 +          _iim[i] = st;
 111.331 +          break;
 111.332 +        case IN_HEAP:
 111.333 +          break;
 111.334 +      }
 111.335 +    }
 111.336 +
 111.337 +    /// \brief Replace an item in the heap.
 111.338 +    ///
 111.339 +    /// This function replaces item \c i with item \c j.
 111.340 +    /// Item \c i must be in the heap, while \c j must be out of the heap.
 111.341 +    /// After calling this method, item \c i will be out of the
 111.342 +    /// heap and \c j will be in the heap with the same prioriority
 111.343 +    /// as item \c i had before.
 111.344 +    void replace(const Item& i, const Item& j) {
 111.345 +      int idx=_iim[i];
 111.346 +      _iim.set(i, _iim[j]);
 111.347 +      _iim.set(j, idx);
 111.348 +      _data[idx].first=j;
 111.349 +    }
 111.350 +
 111.351 +  }; // class KaryHeap
 111.352 +
 111.353 +} // namespace lemon
 111.354 +
 111.355 +#endif // LEMON_KARY_HEAP_H
   112.1 --- a/lemon/kruskal.h	Fri Oct 16 10:21:37 2009 +0200
   112.2 +++ b/lemon/kruskal.h	Thu Nov 05 15:50:01 2009 +0100
   112.3 @@ -2,7 +2,7 @@
   112.4   *
   112.5   * This file is a part of LEMON, a generic C++ optimization library.
   112.6   *
   112.7 - * Copyright (C) 2003-2008
   112.8 + * Copyright (C) 2003-2009
   112.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  112.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  112.11   *
  112.12 @@ -248,11 +248,11 @@
  112.13  
  112.14    /// \ingroup spantree
  112.15    ///
  112.16 -  /// \brief Kruskal algorithm to find a minimum cost spanning tree of
  112.17 +  /// \brief Kruskal's algorithm for finding a minimum cost spanning tree of
  112.18    /// a graph.
  112.19    ///
  112.20    /// This function runs Kruskal's algorithm to find a minimum cost
  112.21 -  /// spanning tree.
  112.22 +  /// spanning tree of a graph.
  112.23    /// Due to some C++ hacking, it accepts various input and output types.
  112.24    ///
  112.25    /// \param g The graph the algorithm runs on.
  112.26 @@ -264,17 +264,17 @@
  112.27    /// \param in This object is used to describe the arc/edge costs.
  112.28    /// It can be one of the following choices.
  112.29    /// - An STL compatible 'Forward Container' with
  112.30 -  /// <tt>std::pair<GR::Arc,X></tt> or
  112.31 -  /// <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, where
  112.32 -  /// \c X is the type of the costs. The pairs indicates the arcs/edges
  112.33 +  /// <tt>std::pair<GR::Arc,C></tt> or
  112.34 +  /// <tt>std::pair<GR::Edge,C></tt> as its <tt>value_type</tt>, where
  112.35 +  /// \c C is the type of the costs. The pairs indicates the arcs/edges
  112.36    /// along with the assigned cost. <em>They must be in a
  112.37    /// cost-ascending order.</em>
  112.38    /// - Any readable arc/edge map. The values of the map indicate the
  112.39    /// arc/edge costs.
  112.40    ///
  112.41    /// \retval out Here we also have a choice.
  112.42 -  /// - It can be a writable \c bool arc/edge map. After running the
  112.43 -  /// algorithm it will contain the found minimum cost spanning
  112.44 +  /// - It can be a writable arc/edge map with \c bool value type. After
  112.45 +  /// running the algorithm it will contain the found minimum cost spanning
  112.46    /// tree: the value of an arc/edge will be set to \c true if it belongs
  112.47    /// to the tree, otherwise it will be set to \c false. The value of
  112.48    /// each arc/edge will be set exactly once.
  112.49 @@ -301,8 +301,8 @@
  112.50    /// forest is calculated instead of a spanning tree.
  112.51  
  112.52  #ifdef DOXYGEN
  112.53 -  template <class Graph, class In, class Out>
  112.54 -  Value kruskal(GR const& g, const In& in, Out& out)
  112.55 +  template <typename Graph, typename In, typename Out>
  112.56 +  Value kruskal(const Graph& g, const In& in, Out& out)
  112.57  #else
  112.58    template <class Graph, class In, class Out>
  112.59    inline typename _kruskal_bits::KruskalValueSelector<In>::Value
  112.60 @@ -314,8 +314,6 @@
  112.61    }
  112.62  
  112.63  
  112.64 -
  112.65 -
  112.66    template <class Graph, class In, class Out>
  112.67    inline typename _kruskal_bits::KruskalValueSelector<In>::Value
  112.68    kruskal(const Graph& graph, const In& in, const Out& out)
   113.1 --- a/lemon/lemon.pc.in	Fri Oct 16 10:21:37 2009 +0200
   113.2 +++ b/lemon/lemon.pc.in	Thu Nov 05 15:50:01 2009 +0100
   113.3 @@ -4,7 +4,7 @@
   113.4  includedir=@includedir@
   113.5  
   113.6  Name: @PACKAGE_NAME@
   113.7 -Description: Library of Efficient Models and Optimization in Networks
   113.8 +Description: Library for Efficient Modeling and Optimization in Networks
   113.9  Version: @PACKAGE_VERSION@
  113.10 -Libs: -L${libdir} -lemon
  113.11 +Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@
  113.12  Cflags: -I${includedir}
   114.1 --- a/lemon/lgf_reader.h	Fri Oct 16 10:21:37 2009 +0200
   114.2 +++ b/lemon/lgf_reader.h	Thu Nov 05 15:50:01 2009 +0100
   114.3 @@ -2,7 +2,7 @@
   114.4   *
   114.5   * This file is a part of LEMON, a generic C++ optimization library.
   114.6   *
   114.7 - * Copyright (C) 2003-2008
   114.8 + * Copyright (C) 2003-2009
   114.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  114.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  114.11   *
  114.12 @@ -101,23 +101,23 @@
  114.13        }
  114.14      };
  114.15  
  114.16 -    template <typename _Graph, bool _dir, typename _Map,
  114.17 +    template <typename _GR, bool _dir, typename _Map,
  114.18                typename _Converter = DefaultConverter<typename _Map::Value> >
  114.19 -    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
  114.20 +    class GraphArcMapStorage : public MapStorageBase<typename _GR::Edge> {
  114.21      public:
  114.22        typedef _Map Map;
  114.23        typedef _Converter Converter;
  114.24 -      typedef _Graph Graph;
  114.25 -      typedef typename Graph::Edge Item;
  114.26 +      typedef _GR GR;
  114.27 +      typedef typename GR::Edge Item;
  114.28        static const bool dir = _dir;
  114.29  
  114.30      private:
  114.31 -      const Graph& _graph;
  114.32 +      const GR& _graph;
  114.33        Map& _map;
  114.34        Converter _converter;
  114.35  
  114.36      public:
  114.37 -      GraphArcMapStorage(const Graph& graph, Map& map,
  114.38 +      GraphArcMapStorage(const GR& graph, Map& map,
  114.39                           const Converter& converter = Converter())
  114.40          : _graph(graph), _map(map), _converter(converter) {}
  114.41        virtual ~GraphArcMapStorage() {}
  114.42 @@ -173,21 +173,21 @@
  114.43        }
  114.44      };
  114.45  
  114.46 -    template <typename Graph>
  114.47 +    template <typename GR>
  114.48      struct GraphArcLookUpConverter {
  114.49 -      const Graph& _graph;
  114.50 -      const std::map<std::string, typename Graph::Edge>& _map;
  114.51 -
  114.52 -      GraphArcLookUpConverter(const Graph& graph,
  114.53 +      const GR& _graph;
  114.54 +      const std::map<std::string, typename GR::Edge>& _map;
  114.55 +
  114.56 +      GraphArcLookUpConverter(const GR& graph,
  114.57                                const std::map<std::string,
  114.58 -                                             typename Graph::Edge>& map)
  114.59 +                                             typename GR::Edge>& map)
  114.60          : _graph(graph), _map(map) {}
  114.61  
  114.62 -      typename Graph::Arc operator()(const std::string& str) {
  114.63 +      typename GR::Arc operator()(const std::string& str) {
  114.64          if (str.empty() || (str[0] != '+' && str[0] != '-')) {
  114.65            throw FormatError("Item must start with '+' or '-'");
  114.66          }
  114.67 -        typename std::map<std::string, typename Graph::Edge>
  114.68 +        typename std::map<std::string, typename GR::Edge>
  114.69            ::const_iterator it = _map.find(str.substr(1));
  114.70          if (it == _map.end()) {
  114.71            throw FormatError("Item not found");
  114.72 @@ -387,16 +387,15 @@
  114.73  
  114.74    }
  114.75  
  114.76 -  template <typename Digraph>
  114.77 +  template <typename DGR>
  114.78    class DigraphReader;
  114.79  
  114.80 -  template <typename Digraph>
  114.81 -  DigraphReader<Digraph> digraphReader(Digraph& digraph, 
  114.82 -                                       std::istream& is = std::cin);
  114.83 -  template <typename Digraph>
  114.84 -  DigraphReader<Digraph> digraphReader(Digraph& digraph, const std::string& fn);
  114.85 -  template <typename Digraph>
  114.86 -  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char *fn);
  114.87 +  template <typename TDGR>
  114.88 +  DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is = std::cin);
  114.89 +  template <typename TDGR>
  114.90 +  DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn);
  114.91 +  template <typename TDGR>
  114.92 +  DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
  114.93  
  114.94    /// \ingroup lemon_io
  114.95    ///
  114.96 @@ -419,7 +418,7 @@
  114.97    /// rules.
  114.98    ///
  114.99    ///\code
 114.100 -  /// DigraphReader<Digraph>(digraph, std::cin).
 114.101 +  /// DigraphReader<DGR>(digraph, std::cin).
 114.102    ///   nodeMap("coordinates", coord_map).
 114.103    ///   arcMap("capacity", cap_map).
 114.104    ///   node("source", src).
 114.105 @@ -448,21 +447,21 @@
 114.106    /// It is impossible to read this in
 114.107    /// a single pass, because the arcs are not constructed when the node
 114.108    /// maps are read.
 114.109 -  template <typename _Digraph>
 114.110 +  template <typename DGR>
 114.111    class DigraphReader {
 114.112    public:
 114.113  
 114.114 -    typedef _Digraph Digraph;
 114.115 -    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 114.116 +    typedef DGR Digraph;
 114.117  
 114.118    private:
 114.119  
 114.120 +    TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
 114.121  
 114.122      std::istream* _is;
 114.123      bool local_is;
 114.124      std::string _filename;
 114.125  
 114.126 -    Digraph& _digraph;
 114.127 +    DGR& _digraph;
 114.128  
 114.129      std::string _nodes_caption;
 114.130      std::string _arcs_caption;
 114.131 @@ -500,7 +499,7 @@
 114.132      ///
 114.133      /// Construct a directed graph reader, which reads from the given
 114.134      /// input stream.
 114.135 -    DigraphReader(Digraph& digraph, std::istream& is = std::cin)
 114.136 +    DigraphReader(DGR& digraph, std::istream& is = std::cin)
 114.137        : _is(&is), local_is(false), _digraph(digraph),
 114.138          _use_nodes(false), _use_arcs(false),
 114.139          _skip_nodes(false), _skip_arcs(false) {}
 114.140 @@ -509,7 +508,7 @@
 114.141      ///
 114.142      /// Construct a directed graph reader, which reads from the given
 114.143      /// file.
 114.144 -    DigraphReader(Digraph& digraph, const std::string& fn)
 114.145 +    DigraphReader(DGR& digraph, const std::string& fn)
 114.146        : _is(new std::ifstream(fn.c_str())), local_is(true),
 114.147          _filename(fn), _digraph(digraph),
 114.148          _use_nodes(false), _use_arcs(false),
 114.149 @@ -524,7 +523,7 @@
 114.150      ///
 114.151      /// Construct a directed graph reader, which reads from the given
 114.152      /// file.
 114.153 -    DigraphReader(Digraph& digraph, const char* fn)
 114.154 +    DigraphReader(DGR& digraph, const char* fn)
 114.155        : _is(new std::ifstream(fn)), local_is(true),
 114.156          _filename(fn), _digraph(digraph),
 114.157          _use_nodes(false), _use_arcs(false),
 114.158 @@ -560,13 +559,13 @@
 114.159  
 114.160    private:
 114.161  
 114.162 -    template <typename DGR>
 114.163 -    friend DigraphReader<DGR> digraphReader(DGR& digraph, std::istream& is);
 114.164 -    template <typename DGR>
 114.165 -    friend DigraphReader<DGR> digraphReader(DGR& digraph, 
 114.166 -                                            const std::string& fn);
 114.167 -    template <typename DGR>
 114.168 -    friend DigraphReader<DGR> digraphReader(DGR& digraph, const char *fn);
 114.169 +    template <typename TDGR>
 114.170 +    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is);
 114.171 +    template <typename TDGR>
 114.172 +    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, 
 114.173 +                                             const std::string& fn);
 114.174 +    template <typename TDGR>
 114.175 +    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
 114.176  
 114.177      DigraphReader(DigraphReader& other)
 114.178        : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
 114.179 @@ -593,7 +592,7 @@
 114.180  
 114.181    public:
 114.182  
 114.183 -    /// \name Reading rules
 114.184 +    /// \name Reading Rules
 114.185      /// @{
 114.186  
 114.187      /// \brief Node map reading rule
 114.188 @@ -698,7 +697,7 @@
 114.189  
 114.190      /// @}
 114.191  
 114.192 -    /// \name Select section by name
 114.193 +    /// \name Select Section by Name
 114.194      /// @{
 114.195  
 114.196      /// \brief Set \c \@nodes section to be read
 114.197 @@ -727,7 +726,7 @@
 114.198  
 114.199      /// @}
 114.200  
 114.201 -    /// \name Using previously constructed node or arc set
 114.202 +    /// \name Using Previously Constructed Node or Arc Set
 114.203      /// @{
 114.204  
 114.205      /// \brief Use previously constructed node set
 114.206 @@ -847,7 +846,9 @@
 114.207        while (readSuccess() && line >> c && c != '@') {
 114.208          readLine();
 114.209        }
 114.210 -      line.putback(c);
 114.211 +      if (readSuccess()) {
 114.212 +        line.putback(c);
 114.213 +      }
 114.214      }
 114.215  
 114.216      void readNodes() {
 114.217 @@ -1114,7 +1115,7 @@
 114.218  
 114.219    public:
 114.220  
 114.221 -    /// \name Execution of the reader
 114.222 +    /// \name Execution of the Reader
 114.223      /// @{
 114.224  
 114.225      /// \brief Start the batch processing
 114.226 @@ -1186,14 +1187,52 @@
 114.227      /// @}
 114.228  
 114.229    };
 114.230 +  
 114.231 +  /// \ingroup lemon_io
 114.232 +  ///
 114.233 +  /// \brief Return a \ref DigraphReader class
 114.234 +  ///
 114.235 +  /// This function just returns a \ref DigraphReader class.
 114.236 +  ///
 114.237 +  /// With this function a digraph can be read from an 
 114.238 +  /// \ref lgf-format "LGF" file or input stream with several maps and
 114.239 +  /// attributes. For example, there is network flow problem on a
 114.240 +  /// digraph, i.e. a digraph with a \e capacity map on the arcs and
 114.241 +  /// \e source and \e target nodes. This digraph can be read with the
 114.242 +  /// following code:
 114.243 +  ///
 114.244 +  ///\code
 114.245 +  ///ListDigraph digraph;
 114.246 +  ///ListDigraph::ArcMap<int> cm(digraph);
 114.247 +  ///ListDigraph::Node src, trg;
 114.248 +  ///digraphReader(digraph, std::cin).
 114.249 +  ///  arcMap("capacity", cap).
 114.250 +  ///  node("source", src).
 114.251 +  ///  node("target", trg).
 114.252 +  ///  run();
 114.253 +  ///\endcode
 114.254 +  ///
 114.255 +  /// For a complete documentation, please see the \ref DigraphReader
 114.256 +  /// class documentation.
 114.257 +  /// \warning Don't forget to put the \ref DigraphReader::run() "run()"
 114.258 +  /// to the end of the parameter list.
 114.259 +  /// \relates DigraphReader
 114.260 +  /// \sa digraphReader(TDGR& digraph, const std::string& fn)
 114.261 +  /// \sa digraphReader(TDGR& digraph, const char* fn)
 114.262 +  template <typename TDGR>
 114.263 +  DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is) {
 114.264 +    DigraphReader<TDGR> tmp(digraph, is);
 114.265 +    return tmp;
 114.266 +  }
 114.267  
 114.268    /// \brief Return a \ref DigraphReader class
 114.269    ///
 114.270    /// This function just returns a \ref DigraphReader class.
 114.271    /// \relates DigraphReader
 114.272 -  template <typename Digraph>
 114.273 -  DigraphReader<Digraph> digraphReader(Digraph& digraph, std::istream& is) {
 114.274 -    DigraphReader<Digraph> tmp(digraph, is);
 114.275 +  /// \sa digraphReader(TDGR& digraph, std::istream& is)
 114.276 +  template <typename TDGR>
 114.277 +  DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn) {
 114.278 +    DigraphReader<TDGR> tmp(digraph, fn);
 114.279      return tmp;
 114.280    }
 114.281  
 114.282 @@ -1201,33 +1240,22 @@
 114.283    ///
 114.284    /// This function just returns a \ref DigraphReader class.
 114.285    /// \relates DigraphReader
 114.286 -  template <typename Digraph>
 114.287 -  DigraphReader<Digraph> digraphReader(Digraph& digraph,
 114.288 -                                       const std::string& fn) {
 114.289 -    DigraphReader<Digraph> tmp(digraph, fn);
 114.290 +  /// \sa digraphReader(TDGR& digraph, std::istream& is)
 114.291 +  template <typename TDGR>
 114.292 +  DigraphReader<TDGR> digraphReader(TDGR& digraph, const char* fn) {
 114.293 +    DigraphReader<TDGR> tmp(digraph, fn);
 114.294      return tmp;
 114.295    }
 114.296  
 114.297 -  /// \brief Return a \ref DigraphReader class
 114.298 -  ///
 114.299 -  /// This function just returns a \ref DigraphReader class.
 114.300 -  /// \relates DigraphReader
 114.301 -  template <typename Digraph>
 114.302 -  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
 114.303 -    DigraphReader<Digraph> tmp(digraph, fn);
 114.304 -    return tmp;
 114.305 -  }
 114.306 -
 114.307 -  template <typename Graph>
 114.308 +  template <typename GR>
 114.309    class GraphReader;
 114.310   
 114.311 -  template <typename Graph>
 114.312 -  GraphReader<Graph> graphReader(Graph& graph, 
 114.313 -                                 std::istream& is = std::cin);
 114.314 -  template <typename Graph>
 114.315 -  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn);
 114.316 -  template <typename Graph>
 114.317 -  GraphReader<Graph> graphReader(Graph& graph, const char *fn);
 114.318 +  template <typename TGR>
 114.319 +  GraphReader<TGR> graphReader(TGR& graph, std::istream& is = std::cin);
 114.320 +  template <typename TGR>
 114.321 +  GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
 114.322 +  template <typename TGR>
 114.323 +  GraphReader<TGR> graphReader(TGR& graph, const char *fn);
 114.324  
 114.325    /// \ingroup lemon_io
 114.326    ///
 114.327 @@ -1244,20 +1272,21 @@
 114.328    /// prefixed with \c '+' and \c '-', then these can be read into an
 114.329    /// arc map.  Similarly, an attribute can be read into an arc, if
 114.330    /// it's value is an edge label prefixed with \c '+' or \c '-'.
 114.331 -  template <typename _Graph>
 114.332 +  template <typename GR>
 114.333    class GraphReader {
 114.334    public:
 114.335  
 114.336 -    typedef _Graph Graph;
 114.337 -    TEMPLATE_GRAPH_TYPEDEFS(Graph);
 114.338 +    typedef GR Graph;
 114.339  
 114.340    private:
 114.341  
 114.342 +    TEMPLATE_GRAPH_TYPEDEFS(GR);
 114.343 +
 114.344      std::istream* _is;
 114.345      bool local_is;
 114.346      std::string _filename;
 114.347  
 114.348 -    Graph& _graph;
 114.349 +    GR& _graph;
 114.350  
 114.351      std::string _nodes_caption;
 114.352      std::string _edges_caption;
 114.353 @@ -1295,7 +1324,7 @@
 114.354      ///
 114.355      /// Construct an undirected graph reader, which reads from the given
 114.356      /// input stream.
 114.357 -    GraphReader(Graph& graph, std::istream& is = std::cin)
 114.358 +    GraphReader(GR& graph, std::istream& is = std::cin)
 114.359        : _is(&is), local_is(false), _graph(graph),
 114.360          _use_nodes(false), _use_edges(false),
 114.361          _skip_nodes(false), _skip_edges(false) {}
 114.362 @@ -1304,7 +1333,7 @@
 114.363      ///
 114.364      /// Construct an undirected graph reader, which reads from the given
 114.365      /// file.
 114.366 -    GraphReader(Graph& graph, const std::string& fn)
 114.367 +    GraphReader(GR& graph, const std::string& fn)
 114.368        : _is(new std::ifstream(fn.c_str())), local_is(true),
 114.369          _filename(fn), _graph(graph),
 114.370          _use_nodes(false), _use_edges(false),
 114.371 @@ -1319,7 +1348,7 @@
 114.372      ///
 114.373      /// Construct an undirected graph reader, which reads from the given
 114.374      /// file.
 114.375 -    GraphReader(Graph& graph, const char* fn)
 114.376 +    GraphReader(GR& graph, const char* fn)
 114.377        : _is(new std::ifstream(fn)), local_is(true),
 114.378          _filename(fn), _graph(graph),
 114.379          _use_nodes(false), _use_edges(false),
 114.380 @@ -1354,12 +1383,12 @@
 114.381      }
 114.382  
 114.383    private:
 114.384 -    template <typename GR>
 114.385 -    friend GraphReader<GR> graphReader(GR& graph, std::istream& is);
 114.386 -    template <typename GR>
 114.387 -    friend GraphReader<GR> graphReader(GR& graph, const std::string& fn); 
 114.388 -    template <typename GR>
 114.389 -    friend GraphReader<GR> graphReader(GR& graph, const char *fn);
 114.390 +    template <typename TGR>
 114.391 +    friend GraphReader<TGR> graphReader(TGR& graph, std::istream& is);
 114.392 +    template <typename TGR>
 114.393 +    friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn); 
 114.394 +    template <typename TGR>
 114.395 +    friend GraphReader<TGR> graphReader(TGR& graph, const char *fn);
 114.396  
 114.397      GraphReader(GraphReader& other)
 114.398        : _is(other._is), local_is(other.local_is), _graph(other._graph),
 114.399 @@ -1386,7 +1415,7 @@
 114.400  
 114.401    public:
 114.402  
 114.403 -    /// \name Reading rules
 114.404 +    /// \name Reading Rules
 114.405      /// @{
 114.406  
 114.407      /// \brief Node map reading rule
 114.408 @@ -1451,7 +1480,7 @@
 114.409          new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
 114.410        _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
 114.411        _reader_bits::MapStorageBase<Edge>* backward_storage =
 114.412 -        new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
 114.413 +        new _reader_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
 114.414        _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
 114.415        return *this;
 114.416      }
 114.417 @@ -1465,11 +1494,11 @@
 114.418                            const Converter& converter = Converter()) {
 114.419        checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
 114.420        _reader_bits::MapStorageBase<Edge>* forward_storage =
 114.421 -        new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
 114.422 +        new _reader_bits::GraphArcMapStorage<GR, true, Map, Converter>
 114.423          (_graph, map, converter);
 114.424        _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
 114.425        _reader_bits::MapStorageBase<Edge>* backward_storage =
 114.426 -        new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
 114.427 +        new _reader_bits::GraphArcMapStorage<GR, false, Map, Converter>
 114.428          (_graph, map, converter);
 114.429        _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
 114.430        return *this;
 114.431 @@ -1527,7 +1556,7 @@
 114.432      ///
 114.433      /// Add an arc reading rule to reader.
 114.434      GraphReader& arc(const std::string& caption, Arc& arc) {
 114.435 -      typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
 114.436 +      typedef _reader_bits::GraphArcLookUpConverter<GR> Converter;
 114.437        Converter converter(_graph, _edge_index);
 114.438        _reader_bits::ValueStorageBase* storage =
 114.439          new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
 114.440 @@ -1537,7 +1566,7 @@
 114.441  
 114.442      /// @}
 114.443  
 114.444 -    /// \name Select section by name
 114.445 +    /// \name Select Section by Name
 114.446      /// @{
 114.447  
 114.448      /// \brief Set \c \@nodes section to be read
 114.449 @@ -1566,7 +1595,7 @@
 114.450  
 114.451      /// @}
 114.452  
 114.453 -    /// \name Using previously constructed node or edge set
 114.454 +    /// \name Using Previously Constructed Node or Edge Set
 114.455      /// @{
 114.456  
 114.457      /// \brief Use previously constructed node set
 114.458 @@ -1687,7 +1716,9 @@
 114.459        while (readSuccess() && line >> c && c != '@') {
 114.460          readLine();
 114.461        }
 114.462 -      line.putback(c);
 114.463 +      if (readSuccess()) {
 114.464 +        line.putback(c);
 114.465 +      }
 114.466      }
 114.467  
 114.468      void readNodes() {
 114.469 @@ -1954,7 +1985,7 @@
 114.470  
 114.471    public:
 114.472  
 114.473 -    /// \name Execution of the reader
 114.474 +    /// \name Execution of the Reader
 114.475      /// @{
 114.476  
 114.477      /// \brief Start the batch processing
 114.478 @@ -2028,13 +2059,47 @@
 114.479  
 114.480    };
 114.481  
 114.482 +  /// \ingroup lemon_io
 114.483 +  ///
 114.484 +  /// \brief Return a \ref GraphReader class
 114.485 +  ///
 114.486 +  /// This function just returns a \ref GraphReader class. 
 114.487 +  ///
 114.488 +  /// With this function a graph can be read from an 
 114.489 +  /// \ref lgf-format "LGF" file or input stream with several maps and
 114.490 +  /// attributes. For example, there is weighted matching problem on a
 114.491 +  /// graph, i.e. a graph with a \e weight map on the edges. This
 114.492 +  /// graph can be read with the following code:
 114.493 +  ///
 114.494 +  ///\code
 114.495 +  ///ListGraph graph;
 114.496 +  ///ListGraph::EdgeMap<int> weight(graph);
 114.497 +  ///graphReader(graph, std::cin).
 114.498 +  ///  edgeMap("weight", weight).
 114.499 +  ///  run();
 114.500 +  ///\endcode
 114.501 +  ///
 114.502 +  /// For a complete documentation, please see the \ref GraphReader
 114.503 +  /// class documentation.
 114.504 +  /// \warning Don't forget to put the \ref GraphReader::run() "run()"
 114.505 +  /// to the end of the parameter list.
 114.506 +  /// \relates GraphReader
 114.507 +  /// \sa graphReader(TGR& graph, const std::string& fn)
 114.508 +  /// \sa graphReader(TGR& graph, const char* fn)
 114.509 +  template <typename TGR>
 114.510 +  GraphReader<TGR> graphReader(TGR& graph, std::istream& is) {
 114.511 +    GraphReader<TGR> tmp(graph, is);
 114.512 +    return tmp;
 114.513 +  }
 114.514 +
 114.515    /// \brief Return a \ref GraphReader class
 114.516    ///
 114.517    /// This function just returns a \ref GraphReader class.
 114.518    /// \relates GraphReader
 114.519 -  template <typename Graph>
 114.520 -  GraphReader<Graph> graphReader(Graph& graph, std::istream& is) {
 114.521 -    GraphReader<Graph> tmp(graph, is);
 114.522 +  /// \sa graphReader(TGR& graph, std::istream& is)
 114.523 +  template <typename TGR>
 114.524 +  GraphReader<TGR> graphReader(TGR& graph, const std::string& fn) {
 114.525 +    GraphReader<TGR> tmp(graph, fn);
 114.526      return tmp;
 114.527    }
 114.528  
 114.529 @@ -2042,19 +2107,10 @@
 114.530    ///
 114.531    /// This function just returns a \ref GraphReader class.
 114.532    /// \relates GraphReader
 114.533 -  template <typename Graph>
 114.534 -  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
 114.535 -    GraphReader<Graph> tmp(graph, fn);
 114.536 -    return tmp;
 114.537 -  }
 114.538 -
 114.539 -  /// \brief Return a \ref GraphReader class
 114.540 -  ///
 114.541 -  /// This function just returns a \ref GraphReader class.
 114.542 -  /// \relates GraphReader
 114.543 -  template <typename Graph>
 114.544 -  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
 114.545 -    GraphReader<Graph> tmp(graph, fn);
 114.546 +  /// \sa graphReader(TGR& graph, std::istream& is)
 114.547 +  template <typename TGR>
 114.548 +  GraphReader<TGR> graphReader(TGR& graph, const char* fn) {
 114.549 +    GraphReader<TGR> tmp(graph, fn);
 114.550      return tmp;
 114.551    }
 114.552  
 114.553 @@ -2153,7 +2209,7 @@
 114.554  
 114.555    public:
 114.556  
 114.557 -    /// \name Section readers
 114.558 +    /// \name Section Readers
 114.559      /// @{
 114.560  
 114.561      /// \brief Add a section processor with line oriented reading
 114.562 @@ -2244,13 +2300,15 @@
 114.563        while (readSuccess() && line >> c && c != '@') {
 114.564          readLine();
 114.565        }
 114.566 -      line.putback(c);
 114.567 +      if (readSuccess()) {
 114.568 +        line.putback(c);
 114.569 +      }
 114.570      }
 114.571  
 114.572    public:
 114.573  
 114.574  
 114.575 -    /// \name Execution of the reader
 114.576 +    /// \name Execution of the Reader
 114.577      /// @{
 114.578  
 114.579      /// \brief Start the batch processing
 114.580 @@ -2309,12 +2367,30 @@
 114.581  
 114.582    };
 114.583  
 114.584 +  /// \ingroup lemon_io
 114.585 +  ///
 114.586 +  /// \brief Return a \ref SectionReader class
 114.587 +  ///
 114.588 +  /// This function just returns a \ref SectionReader class.
 114.589 +  ///
 114.590 +  /// Please see SectionReader documentation about the custom section
 114.591 +  /// input.
 114.592 +  ///
 114.593 +  /// \relates SectionReader
 114.594 +  /// \sa sectionReader(const std::string& fn)
 114.595 +  /// \sa sectionReader(const char *fn)
 114.596 +  inline SectionReader sectionReader(std::istream& is) {
 114.597 +    SectionReader tmp(is);
 114.598 +    return tmp;
 114.599 +  }
 114.600 +
 114.601    /// \brief Return a \ref SectionReader class
 114.602    ///
 114.603    /// This function just returns a \ref SectionReader class.
 114.604    /// \relates SectionReader
 114.605 -  inline SectionReader sectionReader(std::istream& is) {
 114.606 -    SectionReader tmp(is);
 114.607 +  /// \sa sectionReader(std::istream& is)
 114.608 +  inline SectionReader sectionReader(const std::string& fn) {
 114.609 +    SectionReader tmp(fn);
 114.610      return tmp;
 114.611    }
 114.612  
 114.613 @@ -2322,15 +2398,7 @@
 114.614    ///
 114.615    /// This function just returns a \ref SectionReader class.
 114.616    /// \relates SectionReader
 114.617 -  inline SectionReader sectionReader(const std::string& fn) {
 114.618 -    SectionReader tmp(fn);
 114.619 -    return tmp;
 114.620 -  }
 114.621 -
 114.622 -  /// \brief Return a \ref SectionReader class
 114.623 -  ///
 114.624 -  /// This function just returns a \ref SectionReader class.
 114.625 -  /// \relates SectionReader
 114.626 +  /// \sa sectionReader(std::istream& is)
 114.627    inline SectionReader sectionReader(const char* fn) {
 114.628      SectionReader tmp(fn);
 114.629      return tmp;
 114.630 @@ -2432,7 +2500,7 @@
 114.631    public:
 114.632  
 114.633  
 114.634 -    /// \name Node sections
 114.635 +    /// \name Node Sections
 114.636      /// @{
 114.637  
 114.638      /// \brief Gives back the number of node sections in the file.
 114.639 @@ -2458,7 +2526,7 @@
 114.640  
 114.641      /// @}
 114.642  
 114.643 -    /// \name Arc/Edge sections
 114.644 +    /// \name Arc/Edge Sections
 114.645      /// @{
 114.646  
 114.647      /// \brief Gives back the number of arc/edge sections in the file.
 114.648 @@ -2516,7 +2584,7 @@
 114.649  
 114.650      /// @}
 114.651  
 114.652 -    /// \name Attribute sections
 114.653 +    /// \name Attribute Sections
 114.654      /// @{
 114.655  
 114.656      /// \brief Gives back the number of attribute sections in the file.
 114.657 @@ -2542,7 +2610,7 @@
 114.658  
 114.659      /// @}
 114.660  
 114.661 -    /// \name Extra sections
 114.662 +    /// \name Extra Sections
 114.663      /// @{
 114.664  
 114.665      /// \brief Gives back the number of extra sections in the file.
 114.666 @@ -2585,7 +2653,9 @@
 114.667        while (readSuccess() && line >> c && c != '@') {
 114.668          readLine();
 114.669        }
 114.670 -      line.putback(c);
 114.671 +      if (readSuccess()) {
 114.672 +        line.putback(c);
 114.673 +      }
 114.674      }
 114.675  
 114.676      void readMaps(std::vector<std::string>& maps) {
 114.677 @@ -2616,7 +2686,7 @@
 114.678  
 114.679    public:
 114.680  
 114.681 -    /// \name Execution of the contents reader
 114.682 +    /// \name Execution of the Contents Reader
 114.683      /// @{
 114.684  
 114.685      /// \brief Starts the reading
   115.1 --- a/lemon/lgf_writer.h	Fri Oct 16 10:21:37 2009 +0200
   115.2 +++ b/lemon/lgf_writer.h	Thu Nov 05 15:50:01 2009 +0100
   115.3 @@ -2,7 +2,7 @@
   115.4   *
   115.5   * This file is a part of LEMON, a generic C++ optimization library.
   115.6   *
   115.7 - * Copyright (C) 2003-2008
   115.8 + * Copyright (C) 2003-2009
   115.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  115.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  115.11   *
  115.12 @@ -347,19 +347,17 @@
  115.13  
  115.14    }
  115.15  
  115.16 -  template <typename Digraph>
  115.17 +  template <typename DGR>
  115.18    class DigraphWriter;
  115.19  
  115.20 -  template <typename Digraph>
  115.21 -  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
  115.22 -                                       std::ostream& os = std::cout);
  115.23 -  template <typename Digraph>
  115.24 -  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
  115.25 -                                       const std::string& fn);
  115.26 +  template <typename TDGR>
  115.27 +  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
  115.28 +                                   std::ostream& os = std::cout);
  115.29 +  template <typename TDGR>
  115.30 +  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const std::string& fn);
  115.31  
  115.32 -  template <typename Digraph>
  115.33 -  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
  115.34 -                                       const char* fn);
  115.35 +  template <typename TDGR>
  115.36 +  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn);
  115.37  
  115.38  
  115.39    /// \ingroup lemon_io
  115.40 @@ -381,7 +379,7 @@
  115.41    /// arc() functions are used to add attribute writing rules.
  115.42    ///
  115.43    ///\code
  115.44 -  /// DigraphWriter<Digraph>(digraph, std::cout).
  115.45 +  /// DigraphWriter<DGR>(digraph, std::cout).
  115.46    ///   nodeMap("coordinates", coord_map).
  115.47    ///   nodeMap("size", size).
  115.48    ///   nodeMap("title", title).
  115.49 @@ -406,12 +404,12 @@
  115.50    /// section to the stream. The output stream can be retrieved with
  115.51    /// the \c ostream() function, hence the second pass can append its
  115.52    /// output to the output of the first pass.
  115.53 -  template <typename _Digraph>
  115.54 +  template <typename DGR>
  115.55    class DigraphWriter {
  115.56    public:
  115.57  
  115.58 -    typedef _Digraph Digraph;
  115.59 -    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
  115.60 +    typedef DGR Digraph;
  115.61 +    TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
  115.62  
  115.63    private:
  115.64  
  115.65 @@ -419,7 +417,7 @@
  115.66      std::ostream* _os;
  115.67      bool local_os;
  115.68  
  115.69 -    const Digraph& _digraph;
  115.70 +    const DGR& _digraph;
  115.71  
  115.72      std::string _nodes_caption;
  115.73      std::string _arcs_caption;
  115.74 @@ -451,7 +449,7 @@
  115.75      ///
  115.76      /// Construct a directed graph writer, which writes to the given
  115.77      /// output stream.
  115.78 -    DigraphWriter(const Digraph& digraph, std::ostream& os = std::cout)
  115.79 +    DigraphWriter(const DGR& digraph, std::ostream& os = std::cout)
  115.80        : _os(&os), local_os(false), _digraph(digraph),
  115.81          _skip_nodes(false), _skip_arcs(false) {}
  115.82  
  115.83 @@ -459,7 +457,7 @@
  115.84      ///
  115.85      /// Construct a directed graph writer, which writes to the given
  115.86      /// output file.
  115.87 -    DigraphWriter(const Digraph& digraph, const std::string& fn)
  115.88 +    DigraphWriter(const DGR& digraph, const std::string& fn)
  115.89        : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
  115.90          _skip_nodes(false), _skip_arcs(false) {
  115.91        if (!(*_os)) {
  115.92 @@ -472,7 +470,7 @@
  115.93      ///
  115.94      /// Construct a directed graph writer, which writes to the given
  115.95      /// output file.
  115.96 -    DigraphWriter(const Digraph& digraph, const char* fn)
  115.97 +    DigraphWriter(const DGR& digraph, const char* fn)
  115.98        : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
  115.99          _skip_nodes(false), _skip_arcs(false) {
 115.100        if (!(*_os)) {
 115.101 @@ -505,15 +503,15 @@
 115.102  
 115.103    private:
 115.104  
 115.105 -    template <typename DGR>
 115.106 -    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph, 
 115.107 -                                            std::ostream& os);
 115.108 -    template <typename DGR>
 115.109 -    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
 115.110 -                                            const std::string& fn);
 115.111 -    template <typename DGR>
 115.112 -    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
 115.113 -                                            const char *fn);
 115.114 +    template <typename TDGR>
 115.115 +    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
 115.116 +                                             std::ostream& os);
 115.117 +    template <typename TDGR>
 115.118 +    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
 115.119 +                                             const std::string& fn);
 115.120 +    template <typename TDGR>
 115.121 +    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
 115.122 +                                             const char *fn);
 115.123  
 115.124      DigraphWriter(DigraphWriter& other)
 115.125        : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
 115.126 @@ -538,7 +536,7 @@
 115.127  
 115.128    public:
 115.129  
 115.130 -    /// \name Writing rules
 115.131 +    /// \name Writing Rules
 115.132      /// @{
 115.133  
 115.134      /// \brief Node map writing rule
 115.135 @@ -641,7 +639,7 @@
 115.136        return *this;
 115.137      }
 115.138  
 115.139 -    /// \name Section captions
 115.140 +    /// \name Section Captions
 115.141      /// @{
 115.142  
 115.143      /// \brief Add an additional caption to the \c \@nodes section
 115.144 @@ -668,7 +666,7 @@
 115.145        return *this;
 115.146      }
 115.147  
 115.148 -    /// \name Skipping section
 115.149 +    /// \name Skipping Section
 115.150      /// @{
 115.151  
 115.152      /// \brief Skip writing the node set
 115.153 @@ -724,8 +722,8 @@
 115.154        }
 115.155  
 115.156        if (label == 0) {
 115.157 -        IdMap<Digraph, Node> id_map(_digraph);
 115.158 -        _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
 115.159 +        IdMap<DGR, Node> id_map(_digraph);
 115.160 +        _writer_bits::MapLess<IdMap<DGR, Node> > id_less(id_map);
 115.161          std::sort(nodes.begin(), nodes.end(), id_less);
 115.162        } else {
 115.163          label->sort(nodes);
 115.164 @@ -809,8 +807,8 @@
 115.165        }
 115.166  
 115.167        if (label == 0) {
 115.168 -        IdMap<Digraph, Arc> id_map(_digraph);
 115.169 -        _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
 115.170 +        IdMap<DGR, Arc> id_map(_digraph);
 115.171 +        _writer_bits::MapLess<IdMap<DGR, Arc> > id_less(id_map);
 115.172          std::sort(arcs.begin(), arcs.end(), id_less);
 115.173        } else {
 115.174          label->sort(arcs);
 115.175 @@ -885,7 +883,7 @@
 115.176  
 115.177    public:
 115.178  
 115.179 -    /// \name Execution of the writer
 115.180 +    /// \name Execution of the Writer
 115.181      /// @{
 115.182  
 115.183      /// \brief Start the batch processing
 115.184 @@ -915,14 +913,41 @@
 115.185      /// @}
 115.186    };
 115.187  
 115.188 +  /// \ingroup lemon_io
 115.189 +  ///
 115.190    /// \brief Return a \ref DigraphWriter class
 115.191    ///
 115.192 -  /// This function just returns a \ref DigraphWriter class.
 115.193 +  /// This function just returns a \ref DigraphWriter class. 
 115.194 +  ///
 115.195 +  /// With this function a digraph can be write to a file or output
 115.196 +  /// stream in \ref lgf-format "LGF" format with several maps and
 115.197 +  /// attributes. For example, with the following code a network flow
 115.198 +  /// problem can be written to the standard output, i.e. a digraph
 115.199 +  /// with a \e capacity map on the arcs and \e source and \e target
 115.200 +  /// nodes:
 115.201 +  ///
 115.202 +  ///\code
 115.203 +  ///ListDigraph digraph;
 115.204 +  ///ListDigraph::ArcMap<int> cap(digraph);
 115.205 +  ///ListDigraph::Node src, trg;
 115.206 +  ///  // Setting the capacity map and source and target nodes
 115.207 +  ///digraphWriter(digraph, std::cout).
 115.208 +  ///  arcMap("capacity", cap).
 115.209 +  ///  node("source", src).
 115.210 +  ///  node("target", trg).
 115.211 +  ///  run();
 115.212 +  ///\endcode
 115.213 +  ///
 115.214 +  /// For a complete documentation, please see the \ref DigraphWriter
 115.215 +  /// class documentation.
 115.216 +  /// \warning Don't forget to put the \ref DigraphWriter::run() "run()"
 115.217 +  /// to the end of the parameter list.
 115.218    /// \relates DigraphWriter
 115.219 -  template <typename Digraph>
 115.220 -  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
 115.221 -                                       std::ostream& os) {
 115.222 -    DigraphWriter<Digraph> tmp(digraph, os);
 115.223 +  /// \sa digraphWriter(const TDGR& digraph, const std::string& fn)
 115.224 +  /// \sa digraphWriter(const TDGR& digraph, const char* fn)
 115.225 +  template <typename TDGR>
 115.226 +  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, std::ostream& os) {
 115.227 +    DigraphWriter<TDGR> tmp(digraph, os);
 115.228      return tmp;
 115.229    }
 115.230  
 115.231 @@ -930,10 +955,11 @@
 115.232    ///
 115.233    /// This function just returns a \ref DigraphWriter class.
 115.234    /// \relates DigraphWriter
 115.235 -  template <typename Digraph>
 115.236 -  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
 115.237 -                                       const std::string& fn) {
 115.238 -    DigraphWriter<Digraph> tmp(digraph, fn);
 115.239 +  /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
 115.240 +  template <typename TDGR>
 115.241 +  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
 115.242 +                                    const std::string& fn) {
 115.243 +    DigraphWriter<TDGR> tmp(digraph, fn);
 115.244      return tmp;
 115.245    }
 115.246  
 115.247 @@ -941,23 +967,22 @@
 115.248    ///
 115.249    /// This function just returns a \ref DigraphWriter class.
 115.250    /// \relates DigraphWriter
 115.251 -  template <typename Digraph>
 115.252 -  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
 115.253 -                                       const char* fn) {
 115.254 -    DigraphWriter<Digraph> tmp(digraph, fn);
 115.255 +  /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
 115.256 +  template <typename TDGR>
 115.257 +  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn) {
 115.258 +    DigraphWriter<TDGR> tmp(digraph, fn);
 115.259      return tmp;
 115.260    }
 115.261  
 115.262 -  template <typename Graph>
 115.263 +  template <typename GR>
 115.264    class GraphWriter;
 115.265  
 115.266 -  template <typename Graph>
 115.267 -  GraphWriter<Graph> graphWriter(const Graph& graph,
 115.268 -                                 std::ostream& os = std::cout);
 115.269 -  template <typename Graph>
 115.270 -  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn);
 115.271 -  template <typename Graph>
 115.272 -  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn);
 115.273 +  template <typename TGR>
 115.274 +  GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os = std::cout);
 115.275 +  template <typename TGR>
 115.276 +  GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn);
 115.277 +  template <typename TGR>
 115.278 +  GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn);
 115.279  
 115.280    /// \ingroup lemon_io
 115.281    ///
 115.282 @@ -974,12 +999,12 @@
 115.283    /// '+' and \c '-'. The arcs are written into the \c \@attributes
 115.284    /// section as a \c '+' or a \c '-' prefix (depends on the direction
 115.285    /// of the arc) and the label of corresponding edge.
 115.286 -  template <typename _Graph>
 115.287 +  template <typename GR>
 115.288    class GraphWriter {
 115.289    public:
 115.290  
 115.291 -    typedef _Graph Graph;
 115.292 -    TEMPLATE_GRAPH_TYPEDEFS(Graph);
 115.293 +    typedef GR Graph;
 115.294 +    TEMPLATE_GRAPH_TYPEDEFS(GR);
 115.295  
 115.296    private:
 115.297  
 115.298 @@ -987,7 +1012,7 @@
 115.299      std::ostream* _os;
 115.300      bool local_os;
 115.301  
 115.302 -    const Graph& _graph;
 115.303 +    const GR& _graph;
 115.304  
 115.305      std::string _nodes_caption;
 115.306      std::string _edges_caption;
 115.307 @@ -1019,7 +1044,7 @@
 115.308      ///
 115.309      /// Construct a directed graph writer, which writes to the given
 115.310      /// output stream.
 115.311 -    GraphWriter(const Graph& graph, std::ostream& os = std::cout)
 115.312 +    GraphWriter(const GR& graph, std::ostream& os = std::cout)
 115.313        : _os(&os), local_os(false), _graph(graph),
 115.314          _skip_nodes(false), _skip_edges(false) {}
 115.315  
 115.316 @@ -1027,7 +1052,7 @@
 115.317      ///
 115.318      /// Construct a directed graph writer, which writes to the given
 115.319      /// output file.
 115.320 -    GraphWriter(const Graph& graph, const std::string& fn)
 115.321 +    GraphWriter(const GR& graph, const std::string& fn)
 115.322        : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
 115.323          _skip_nodes(false), _skip_edges(false) {
 115.324        if (!(*_os)) {
 115.325 @@ -1040,7 +1065,7 @@
 115.326      ///
 115.327      /// Construct a directed graph writer, which writes to the given
 115.328      /// output file.
 115.329 -    GraphWriter(const Graph& graph, const char* fn)
 115.330 +    GraphWriter(const GR& graph, const char* fn)
 115.331        : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
 115.332          _skip_nodes(false), _skip_edges(false) {
 115.333        if (!(*_os)) {
 115.334 @@ -1073,15 +1098,13 @@
 115.335  
 115.336    private:
 115.337  
 115.338 -    template <typename GR>
 115.339 -    friend GraphWriter<GR> graphWriter(const GR& graph,
 115.340 -                                       std::ostream& os);
 115.341 -    template <typename GR>
 115.342 -    friend GraphWriter<GR> graphWriter(const GR& graph,
 115.343 -                                       const std::string& fn);
 115.344 -    template <typename GR>
 115.345 -    friend GraphWriter<GR> graphWriter(const GR& graph,
 115.346 -                                       const char *fn);
 115.347 +    template <typename TGR>
 115.348 +    friend GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os);
 115.349 +    template <typename TGR>
 115.350 +    friend GraphWriter<TGR> graphWriter(const TGR& graph, 
 115.351 +                                        const std::string& fn);
 115.352 +    template <typename TGR>
 115.353 +    friend GraphWriter<TGR> graphWriter(const TGR& graph, const char *fn);
 115.354      
 115.355      GraphWriter(GraphWriter& other)
 115.356        : _os(other._os), local_os(other.local_os), _graph(other._graph),
 115.357 @@ -1106,7 +1129,7 @@
 115.358  
 115.359    public:
 115.360  
 115.361 -    /// \name Writing rules
 115.362 +    /// \name Writing Rules
 115.363      /// @{
 115.364  
 115.365      /// \brief Node map writing rule
 115.366 @@ -1168,10 +1191,10 @@
 115.367      GraphWriter& arcMap(const std::string& caption, const Map& map) {
 115.368        checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
 115.369        _writer_bits::MapStorageBase<Edge>* forward_storage =
 115.370 -        new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
 115.371 +        new _writer_bits::GraphArcMapStorage<GR, true, Map>(_graph, map);
 115.372        _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
 115.373        _writer_bits::MapStorageBase<Edge>* backward_storage =
 115.374 -        new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
 115.375 +        new _writer_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
 115.376        _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
 115.377        return *this;
 115.378      }
 115.379 @@ -1185,11 +1208,11 @@
 115.380                            const Converter& converter = Converter()) {
 115.381        checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
 115.382        _writer_bits::MapStorageBase<Edge>* forward_storage =
 115.383 -        new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
 115.384 +        new _writer_bits::GraphArcMapStorage<GR, true, Map, Converter>
 115.385          (_graph, map, converter);
 115.386        _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
 115.387        _writer_bits::MapStorageBase<Edge>* backward_storage =
 115.388 -        new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
 115.389 +        new _writer_bits::GraphArcMapStorage<GR, false, Map, Converter>
 115.390          (_graph, map, converter);
 115.391        _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
 115.392        return *this;
 115.393 @@ -1247,7 +1270,7 @@
 115.394      ///
 115.395      /// Add an arc writing rule to writer.
 115.396      GraphWriter& arc(const std::string& caption, const Arc& arc) {
 115.397 -      typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
 115.398 +      typedef _writer_bits::GraphArcLookUpConverter<GR> Converter;
 115.399        Converter converter(_graph, _edge_index);
 115.400        _writer_bits::ValueStorageBase* storage =
 115.401          new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
 115.402 @@ -1255,7 +1278,7 @@
 115.403        return *this;
 115.404      }
 115.405  
 115.406 -    /// \name Section captions
 115.407 +    /// \name Section Captions
 115.408      /// @{
 115.409  
 115.410      /// \brief Add an additional caption to the \c \@nodes section
 115.411 @@ -1282,7 +1305,7 @@
 115.412        return *this;
 115.413      }
 115.414  
 115.415 -    /// \name Skipping section
 115.416 +    /// \name Skipping Section
 115.417      /// @{
 115.418  
 115.419      /// \brief Skip writing the node set
 115.420 @@ -1338,8 +1361,8 @@
 115.421        }
 115.422  
 115.423        if (label == 0) {
 115.424 -        IdMap<Graph, Node> id_map(_graph);
 115.425 -        _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
 115.426 +        IdMap<GR, Node> id_map(_graph);
 115.427 +        _writer_bits::MapLess<IdMap<GR, Node> > id_less(id_map);
 115.428          std::sort(nodes.begin(), nodes.end(), id_less);
 115.429        } else {
 115.430          label->sort(nodes);
 115.431 @@ -1423,8 +1446,8 @@
 115.432        }
 115.433  
 115.434        if (label == 0) {
 115.435 -        IdMap<Graph, Edge> id_map(_graph);
 115.436 -        _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
 115.437 +        IdMap<GR, Edge> id_map(_graph);
 115.438 +        _writer_bits::MapLess<IdMap<GR, Edge> > id_less(id_map);
 115.439          std::sort(edges.begin(), edges.end(), id_less);
 115.440        } else {
 115.441          label->sort(edges);
 115.442 @@ -1499,7 +1522,7 @@
 115.443  
 115.444    public:
 115.445  
 115.446 -    /// \name Execution of the writer
 115.447 +    /// \name Execution of the Writer
 115.448      /// @{
 115.449  
 115.450      /// \brief Start the batch processing
 115.451 @@ -1529,14 +1552,37 @@
 115.452      /// @}
 115.453    };
 115.454  
 115.455 +  /// \ingroup lemon_io
 115.456 +  ///
 115.457    /// \brief Return a \ref GraphWriter class
 115.458    ///
 115.459 -  /// This function just returns a \ref GraphWriter class.
 115.460 +  /// This function just returns a \ref GraphWriter class. 
 115.461 +  ///
 115.462 +  /// With this function a graph can be write to a file or output
 115.463 +  /// stream in \ref lgf-format "LGF" format with several maps and
 115.464 +  /// attributes. For example, with the following code a weighted
 115.465 +  /// matching problem can be written to the standard output, i.e. a
 115.466 +  /// graph with a \e weight map on the edges:
 115.467 +  ///
 115.468 +  ///\code
 115.469 +  ///ListGraph graph;
 115.470 +  ///ListGraph::EdgeMap<int> weight(graph);
 115.471 +  ///  // Setting the weight map
 115.472 +  ///graphWriter(graph, std::cout).
 115.473 +  ///  edgeMap("weight", weight).
 115.474 +  ///  run();
 115.475 +  ///\endcode
 115.476 +  ///
 115.477 +  /// For a complete documentation, please see the \ref GraphWriter
 115.478 +  /// class documentation.
 115.479 +  /// \warning Don't forget to put the \ref GraphWriter::run() "run()"
 115.480 +  /// to the end of the parameter list.
 115.481    /// \relates GraphWriter
 115.482 -  template <typename Graph>
 115.483 -  GraphWriter<Graph> graphWriter(const Graph& graph,
 115.484 -                                 std::ostream& os) {
 115.485 -    GraphWriter<Graph> tmp(graph, os);
 115.486 +  /// \sa graphWriter(const TGR& graph, const std::string& fn)
 115.487 +  /// \sa graphWriter(const TGR& graph, const char* fn)
 115.488 +  template <typename TGR>
 115.489 +  GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os) {
 115.490 +    GraphWriter<TGR> tmp(graph, os);
 115.491      return tmp;
 115.492    }
 115.493  
 115.494 @@ -1544,9 +1590,10 @@
 115.495    ///
 115.496    /// This function just returns a \ref GraphWriter class.
 115.497    /// \relates GraphWriter
 115.498 -  template <typename Graph>
 115.499 -  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
 115.500 -    GraphWriter<Graph> tmp(graph, fn);
 115.501 +  /// \sa graphWriter(const TGR& graph, std::ostream& os)
 115.502 +  template <typename TGR>
 115.503 +  GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn) {
 115.504 +    GraphWriter<TGR> tmp(graph, fn);
 115.505      return tmp;
 115.506    }
 115.507  
 115.508 @@ -1554,9 +1601,10 @@
 115.509    ///
 115.510    /// This function just returns a \ref GraphWriter class.
 115.511    /// \relates GraphWriter
 115.512 -  template <typename Graph>
 115.513 -  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
 115.514 -    GraphWriter<Graph> tmp(graph, fn);
 115.515 +  /// \sa graphWriter(const TGR& graph, std::ostream& os)
 115.516 +  template <typename TGR>
 115.517 +  GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) {
 115.518 +    GraphWriter<TGR> tmp(graph, fn);
 115.519      return tmp;
 115.520    }
 115.521  
 115.522 @@ -1651,7 +1699,7 @@
 115.523  
 115.524    public:
 115.525  
 115.526 -    /// \name Section writers
 115.527 +    /// \name Section Writers
 115.528      /// @{
 115.529  
 115.530      /// \brief Add a section writer with line oriented writing
 115.531 @@ -1718,7 +1766,7 @@
 115.532    public:
 115.533  
 115.534  
 115.535 -    /// \name Execution of the writer
 115.536 +    /// \name Execution of the Writer
 115.537      /// @{
 115.538  
 115.539      /// \brief Start the batch processing
 115.540 @@ -1746,10 +1794,18 @@
 115.541  
 115.542    };
 115.543  
 115.544 +  /// \ingroup lemon_io
 115.545 +  ///
 115.546    /// \brief Return a \ref SectionWriter class
 115.547    ///
 115.548    /// This function just returns a \ref SectionWriter class.
 115.549 +  ///
 115.550 +  /// Please see SectionWriter documentation about the custom section
 115.551 +  /// output.
 115.552 +  ///
 115.553    /// \relates SectionWriter
 115.554 +  /// \sa sectionWriter(const std::string& fn)
 115.555 +  /// \sa sectionWriter(const char *fn)
 115.556    inline SectionWriter sectionWriter(std::ostream& os) {
 115.557      SectionWriter tmp(os);
 115.558      return tmp;
 115.559 @@ -1759,6 +1815,7 @@
 115.560    ///
 115.561    /// This function just returns a \ref SectionWriter class.
 115.562    /// \relates SectionWriter
 115.563 +  /// \sa sectionWriter(std::ostream& os)
 115.564    inline SectionWriter sectionWriter(const std::string& fn) {
 115.565      SectionWriter tmp(fn);
 115.566      return tmp;
 115.567 @@ -1768,6 +1825,7 @@
 115.568    ///
 115.569    /// This function just returns a \ref SectionWriter class.
 115.570    /// \relates SectionWriter
 115.571 +  /// \sa sectionWriter(std::ostream& os)
 115.572    inline SectionWriter sectionWriter(const char* fn) {
 115.573      SectionWriter tmp(fn);
 115.574      return tmp;
   116.1 --- a/lemon/list_graph.h	Fri Oct 16 10:21:37 2009 +0200
   116.2 +++ b/lemon/list_graph.h	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   116.8 + * Copyright (C) 2003-2009
   116.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  116.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  116.11   *
  116.12 @@ -21,7 +21,7 @@
  116.13  
  116.14  ///\ingroup graphs
  116.15  ///\file
  116.16 -///\brief ListDigraph, ListGraph classes.
  116.17 +///\brief ListDigraph and ListGraph classes.
  116.18  
  116.19  #include <lemon/core.h>
  116.20  #include <lemon/error.h>
  116.21 @@ -32,6 +32,8 @@
  116.22  
  116.23  namespace lemon {
  116.24  
  116.25 +  class ListDigraph;
  116.26 +
  116.27    class ListDigraphBase {
  116.28  
  116.29    protected:
  116.30 @@ -62,6 +64,7 @@
  116.31  
  116.32      class Node {
  116.33        friend class ListDigraphBase;
  116.34 +      friend class ListDigraph;
  116.35      protected:
  116.36  
  116.37        int id;
  116.38 @@ -77,6 +80,7 @@
  116.39  
  116.40      class Arc {
  116.41        friend class ListDigraphBase;
  116.42 +      friend class ListDigraph;
  116.43      protected:
  116.44  
  116.45        int id;
  116.46 @@ -116,20 +120,20 @@
  116.47      void first(Arc& arc) const {
  116.48        int n;
  116.49        for(n = first_node;
  116.50 -          n!=-1 && nodes[n].first_in == -1;
  116.51 +          n != -1 && nodes[n].first_out == -1;
  116.52            n = nodes[n].next) {}
  116.53 -      arc.id = (n == -1) ? -1 : nodes[n].first_in;
  116.54 +      arc.id = (n == -1) ? -1 : nodes[n].first_out;
  116.55      }
  116.56  
  116.57      void next(Arc& arc) const {
  116.58 -      if (arcs[arc.id].next_in != -1) {
  116.59 -        arc.id = arcs[arc.id].next_in;
  116.60 +      if (arcs[arc.id].next_out != -1) {
  116.61 +        arc.id = arcs[arc.id].next_out;
  116.62        } else {
  116.63          int n;
  116.64 -        for(n = nodes[arcs[arc.id].target].next;
  116.65 -            n!=-1 && nodes[n].first_in == -1;
  116.66 +        for(n = nodes[arcs[arc.id].source].next;
  116.67 +            n != -1 && nodes[n].first_out == -1;
  116.68              n = nodes[n].next) {}
  116.69 -        arc.id = (n == -1) ? -1 : nodes[n].first_in;
  116.70 +        arc.id = (n == -1) ? -1 : nodes[n].first_out;
  116.71        }
  116.72      }
  116.73  
  116.74 @@ -311,37 +315,28 @@
  116.75  
  116.76    ///A general directed graph structure.
  116.77  
  116.78 -  ///\ref ListDigraph is a simple and fast <em>directed graph</em>
  116.79 -  ///implementation based on static linked lists that are stored in
  116.80 +  ///\ref ListDigraph is a versatile and fast directed graph
  116.81 +  ///implementation based on linked lists that are stored in
  116.82    ///\c std::vector structures.
  116.83    ///
  116.84 -  ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
  116.85 -  ///also provides several useful additional functionalities.
  116.86 -  ///Most of the member functions and nested classes are documented
  116.87 +  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
  116.88 +  ///and it also provides several useful additional functionalities.
  116.89 +  ///Most of its member functions and nested classes are documented
  116.90    ///only in the concept class.
  116.91    ///
  116.92 -  ///An important extra feature of this digraph implementation is that
  116.93 -  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
  116.94 -  ///
  116.95    ///\sa concepts::Digraph
  116.96 +  ///\sa ListGraph
  116.97 +  class ListDigraph : public ExtendedListDigraphBase {
  116.98 +    typedef ExtendedListDigraphBase Parent;
  116.99  
 116.100 -  class ListDigraph : public ExtendedListDigraphBase {
 116.101    private:
 116.102 -    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
 116.103 -
 116.104 -    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
 116.105 -    ///
 116.106 +    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
 116.107      ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
 116.108 -    ///\brief Assignment of ListDigraph to another one is \e not allowed.
 116.109 -    ///Use copyDigraph() instead.
 116.110 -
 116.111 -    ///Assignment of ListDigraph to another one is \e not allowed.
 116.112 -    ///Use copyDigraph() instead.
 116.113 +    /// \brief Assignment of a digraph to another one is \e not allowed.
 116.114 +    /// Use DigraphCopy instead.
 116.115      void operator=(const ListDigraph &) {}
 116.116    public:
 116.117  
 116.118 -    typedef ExtendedListDigraphBase Parent;
 116.119 -
 116.120      /// Constructor
 116.121  
 116.122      /// Constructor.
 116.123 @@ -350,71 +345,65 @@
 116.124  
 116.125      ///Add a new node to the digraph.
 116.126  
 116.127 -    ///Add a new node to the digraph.
 116.128 -    ///\return the new node.
 116.129 +    ///This function adds a new node to the digraph.
 116.130 +    ///\return The new node.
 116.131      Node addNode() { return Parent::addNode(); }
 116.132  
 116.133      ///Add a new arc to the digraph.
 116.134  
 116.135 -    ///Add a new arc to the digraph with source node \c s
 116.136 +    ///This function adds a new arc to the digraph with source node \c s
 116.137      ///and target node \c t.
 116.138 -    ///\return the new arc.
 116.139 -    Arc addArc(const Node& s, const Node& t) {
 116.140 +    ///\return The new arc.
 116.141 +    Arc addArc(Node s, Node t) {
 116.142        return Parent::addArc(s, t);
 116.143      }
 116.144  
 116.145      ///\brief Erase a node from the digraph.
 116.146      ///
 116.147 -    ///Erase a node from the digraph.
 116.148 -    ///
 116.149 -    void erase(const Node& n) { Parent::erase(n); }
 116.150 +    ///This function erases the given node from the digraph.
 116.151 +    void erase(Node n) { Parent::erase(n); }
 116.152  
 116.153      ///\brief Erase an arc from the digraph.
 116.154      ///
 116.155 -    ///Erase an arc from the digraph.
 116.156 -    ///
 116.157 -    void erase(const Arc& a) { Parent::erase(a); }
 116.158 +    ///This function erases the given arc from the digraph.
 116.159 +    void erase(Arc a) { Parent::erase(a); }
 116.160  
 116.161      /// Node validity check
 116.162  
 116.163 -    /// This function gives back true if the given node is valid,
 116.164 -    /// ie. it is a real node of the graph.
 116.165 +    /// This function gives back \c true if the given node is valid,
 116.166 +    /// i.e. it is a real node of the digraph.
 116.167      ///
 116.168 -    /// \warning A Node pointing to a removed item
 116.169 -    /// could become valid again later if new nodes are
 116.170 -    /// added to the graph.
 116.171 +    /// \warning A removed node could become valid again if new nodes are
 116.172 +    /// added to the digraph.
 116.173      bool valid(Node n) const { return Parent::valid(n); }
 116.174  
 116.175      /// Arc validity check
 116.176  
 116.177 -    /// This function gives back true if the given arc is valid,
 116.178 -    /// ie. it is a real arc of the graph.
 116.179 +    /// This function gives back \c true if the given arc is valid,
 116.180 +    /// i.e. it is a real arc of the digraph.
 116.181      ///
 116.182 -    /// \warning An Arc pointing to a removed item
 116.183 -    /// could become valid again later if new nodes are
 116.184 -    /// added to the graph.
 116.185 +    /// \warning A removed arc could become valid again if new arcs are
 116.186 +    /// added to the digraph.
 116.187      bool valid(Arc a) const { return Parent::valid(a); }
 116.188  
 116.189 -    /// Change the target of \c a to \c n
 116.190 +    /// Change the target node of an arc
 116.191  
 116.192 -    /// Change the target of \c a to \c n
 116.193 +    /// This function changes the target node of the given arc \c a to \c n.
 116.194      ///
 116.195 -    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
 116.196 -    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
 116.197 -    ///invalidated.
 116.198 +    ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
 116.199 +    ///arc remain valid, however \c InArcIt iterators are invalidated.
 116.200      ///
 116.201      ///\warning This functionality cannot be used together with the Snapshot
 116.202      ///feature.
 116.203      void changeTarget(Arc a, Node n) {
 116.204        Parent::changeTarget(a,n);
 116.205      }
 116.206 -    /// Change the source of \c a to \c n
 116.207 +    /// Change the source node of an arc
 116.208  
 116.209 -    /// Change the source of \c a to \c n
 116.210 +    /// This function changes the source node of the given arc \c a to \c n.
 116.211      ///
 116.212 -    ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
 116.213 -    ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
 116.214 -    ///invalidated.
 116.215 +    ///\note \c InArcIt iterators referencing the changed arc remain
 116.216 +    ///valid, however \c ArcIt and \c OutArcIt iterators are invalidated.
 116.217      ///
 116.218      ///\warning This functionality cannot be used together with the Snapshot
 116.219      ///feature.
 116.220 @@ -422,94 +411,76 @@
 116.221        Parent::changeSource(a,n);
 116.222      }
 116.223  
 116.224 -    /// Invert the direction of an arc.
 116.225 +    /// Reverse the direction of an arc.
 116.226  
 116.227 -    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
 116.228 -    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
 116.229 -    ///invalidated.
 116.230 +    /// This function reverses the direction of the given arc.
 116.231 +    ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
 116.232 +    ///the changed arc are invalidated.
 116.233      ///
 116.234      ///\warning This functionality cannot be used together with the Snapshot
 116.235      ///feature.
 116.236 -    void reverseArc(Arc e) {
 116.237 -      Node t=target(e);
 116.238 -      changeTarget(e,source(e));
 116.239 -      changeSource(e,t);
 116.240 +    void reverseArc(Arc a) {
 116.241 +      Node t=target(a);
 116.242 +      changeTarget(a,source(a));
 116.243 +      changeSource(a,t);
 116.244      }
 116.245  
 116.246 -    /// Reserve memory for nodes.
 116.247 -
 116.248 -    /// Using this function it is possible to avoid the superfluous memory
 116.249 -    /// allocation: if you know that the digraph you want to build will
 116.250 -    /// be very large (e.g. it will contain millions of nodes and/or arcs)
 116.251 -    /// then it is worth reserving space for this amount before starting
 116.252 -    /// to build the digraph.
 116.253 -    /// \sa reserveArc
 116.254 -    void reserveNode(int n) { nodes.reserve(n); };
 116.255 -
 116.256 -    /// Reserve memory for arcs.
 116.257 -
 116.258 -    /// Using this function it is possible to avoid the superfluous memory
 116.259 -    /// allocation: if you know that the digraph you want to build will
 116.260 -    /// be very large (e.g. it will contain millions of nodes and/or arcs)
 116.261 -    /// then it is worth reserving space for this amount before starting
 116.262 -    /// to build the digraph.
 116.263 -    /// \sa reserveNode
 116.264 -    void reserveArc(int m) { arcs.reserve(m); };
 116.265 -
 116.266      ///Contract two nodes.
 116.267  
 116.268 -    ///This function contracts two nodes.
 116.269 -    ///Node \p b will be removed but instead of deleting
 116.270 -    ///incident arcs, they will be joined to \p a.
 116.271 -    ///The last parameter \p r controls whether to remove loops. \c true
 116.272 -    ///means that loops will be removed.
 116.273 +    ///This function contracts the given two nodes.
 116.274 +    ///Node \c v is removed, but instead of deleting its
 116.275 +    ///incident arcs, they are joined to node \c u.
 116.276 +    ///If the last parameter \c r is \c true (this is the default value),
 116.277 +    ///then the newly created loops are removed.
 116.278      ///
 116.279 -    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
 116.280 -    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
 116.281 -    ///may be invalidated.
 116.282 +    ///\note The moved arcs are joined to node \c u using changeSource()
 116.283 +    ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
 116.284 +    ///invalidated for the outgoing arcs of node \c v and \c InArcIt
 116.285 +    ///iterators are invalidated for the incomming arcs of \c v.
 116.286 +    ///Moreover all iterators referencing node \c v or the removed 
 116.287 +    ///loops are also invalidated. Other iterators remain valid.
 116.288      ///
 116.289      ///\warning This functionality cannot be used together with the Snapshot
 116.290      ///feature.
 116.291 -    void contract(Node a, Node b, bool r = true)
 116.292 +    void contract(Node u, Node v, bool r = true)
 116.293      {
 116.294 -      for(OutArcIt e(*this,b);e!=INVALID;) {
 116.295 +      for(OutArcIt e(*this,v);e!=INVALID;) {
 116.296          OutArcIt f=e;
 116.297          ++f;
 116.298 -        if(r && target(e)==a) erase(e);
 116.299 -        else changeSource(e,a);
 116.300 +        if(r && target(e)==u) erase(e);
 116.301 +        else changeSource(e,u);
 116.302          e=f;
 116.303        }
 116.304 -      for(InArcIt e(*this,b);e!=INVALID;) {
 116.305 +      for(InArcIt e(*this,v);e!=INVALID;) {
 116.306          InArcIt f=e;
 116.307          ++f;
 116.308 -        if(r && source(e)==a) erase(e);
 116.309 -        else changeTarget(e,a);
 116.310 +        if(r && source(e)==u) erase(e);
 116.311 +        else changeTarget(e,u);
 116.312          e=f;
 116.313        }
 116.314 -      erase(b);
 116.315 +      erase(v);
 116.316      }
 116.317  
 116.318      ///Split a node.
 116.319  
 116.320 -    ///This function splits a node. First a new node is added to the digraph,
 116.321 -    ///then the source of each outgoing arc of \c n is moved to this new node.
 116.322 -    ///If \c connect is \c true (this is the default value), then a new arc
 116.323 -    ///from \c n to the newly created node is also added.
 116.324 +    ///This function splits the given node. First, a new node is added
 116.325 +    ///to the digraph, then the source of each outgoing arc of node \c n
 116.326 +    ///is moved to this new node.
 116.327 +    ///If the second parameter \c connect is \c true (this is the default
 116.328 +    ///value), then a new arc from node \c n to the newly created node
 116.329 +    ///is also added.
 116.330      ///\return The newly created node.
 116.331      ///
 116.332 -    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
 116.333 -    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
 116.334 -    ///be invalidated.
 116.335 +    ///\note All iterators remain valid.
 116.336      ///
 116.337 -    ///\warning This functionality cannot be used in conjunction with the
 116.338 +    ///\warning This functionality cannot be used together with the
 116.339      ///Snapshot feature.
 116.340      Node split(Node n, bool connect = true) {
 116.341        Node b = addNode();
 116.342 -      for(OutArcIt e(*this,n);e!=INVALID;) {
 116.343 -        OutArcIt f=e;
 116.344 -        ++f;
 116.345 -        changeSource(e,b);
 116.346 -        e=f;
 116.347 +      nodes[b.id].first_out=nodes[n.id].first_out;
 116.348 +      nodes[n.id].first_out=-1;
 116.349 +      for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {
 116.350 +        arcs[i].source=b.id;
 116.351        }
 116.352        if (connect) addArc(n,b);
 116.353        return b;
 116.354 @@ -517,21 +488,52 @@
 116.355  
 116.356      ///Split an arc.
 116.357  
 116.358 -    ///This function splits an arc. First a new node \c b is added to
 116.359 -    ///the digraph, then the original arc is re-targeted to \c
 116.360 -    ///b. Finally an arc from \c b to the original target is added.
 116.361 +    ///This function splits the given arc. First, a new node \c v is
 116.362 +    ///added to the digraph, then the target node of the original arc
 116.363 +    ///is set to \c v. Finally, an arc from \c v to the original target
 116.364 +    ///is added.
 116.365 +    ///\return The newly created node.
 116.366      ///
 116.367 -    ///\return The newly created node.
 116.368 +    ///\note \c InArcIt iterators referencing the original arc are
 116.369 +    ///invalidated. Other iterators remain valid.
 116.370      ///
 116.371      ///\warning This functionality cannot be used together with the
 116.372      ///Snapshot feature.
 116.373 -    Node split(Arc e) {
 116.374 -      Node b = addNode();
 116.375 -      addArc(b,target(e));
 116.376 -      changeTarget(e,b);
 116.377 -      return b;
 116.378 +    Node split(Arc a) {
 116.379 +      Node v = addNode();
 116.380 +      addArc(v,target(a));
 116.381 +      changeTarget(a,v);
 116.382 +      return v;
 116.383      }
 116.384  
 116.385 +    ///Clear the digraph.
 116.386 +
 116.387 +    ///This function erases all nodes and arcs from the digraph.
 116.388 +    ///
 116.389 +    void clear() {
 116.390 +      Parent::clear();
 116.391 +    }
 116.392 +
 116.393 +    /// Reserve memory for nodes.
 116.394 +
 116.395 +    /// Using this function, it is possible to avoid superfluous memory
 116.396 +    /// allocation: if you know that the digraph you want to build will
 116.397 +    /// be large (e.g. it will contain millions of nodes and/or arcs),
 116.398 +    /// then it is worth reserving space for this amount before starting
 116.399 +    /// to build the digraph.
 116.400 +    /// \sa reserveArc()
 116.401 +    void reserveNode(int n) { nodes.reserve(n); };
 116.402 +
 116.403 +    /// Reserve memory for arcs.
 116.404 +
 116.405 +    /// Using this function, it is possible to avoid superfluous memory
 116.406 +    /// allocation: if you know that the digraph you want to build will
 116.407 +    /// be large (e.g. it will contain millions of nodes and/or arcs),
 116.408 +    /// then it is worth reserving space for this amount before starting
 116.409 +    /// to build the digraph.
 116.410 +    /// \sa reserveNode()
 116.411 +    void reserveArc(int m) { arcs.reserve(m); };
 116.412 +
 116.413      /// \brief Class to make a snapshot of the digraph and restore
 116.414      /// it later.
 116.415      ///
 116.416 @@ -540,9 +542,15 @@
 116.417      /// The newly added nodes and arcs can be removed using the
 116.418      /// restore() function.
 116.419      ///
 116.420 -    /// \warning Arc and node deletions and other modifications (e.g.
 116.421 -    /// contracting, splitting, reversing arcs or nodes) cannot be
 116.422 +    /// \note After a state is restored, you cannot restore a later state, 
 116.423 +    /// i.e. you cannot add the removed nodes and arcs again using
 116.424 +    /// another Snapshot instance.
 116.425 +    ///
 116.426 +    /// \warning Node and arc deletions and other modifications (e.g.
 116.427 +    /// reversing, contracting, splitting arcs or nodes) cannot be
 116.428      /// restored. These events invalidate the snapshot.
 116.429 +    /// However the arcs and nodes that were added to the digraph after
 116.430 +    /// making the current snapshot can be removed without invalidating it.
 116.431      class Snapshot {
 116.432      protected:
 116.433  
 116.434 @@ -712,39 +720,40 @@
 116.435        /// \brief Default constructor.
 116.436        ///
 116.437        /// Default constructor.
 116.438 -      /// To actually make a snapshot you must call save().
 116.439 +      /// You have to call save() to actually make a snapshot.
 116.440        Snapshot()
 116.441          : digraph(0), node_observer_proxy(*this),
 116.442            arc_observer_proxy(*this) {}
 116.443  
 116.444        /// \brief Constructor that immediately makes a snapshot.
 116.445        ///
 116.446 -      /// This constructor immediately makes a snapshot of the digraph.
 116.447 -      /// \param _digraph The digraph we make a snapshot of.
 116.448 -      Snapshot(ListDigraph &_digraph)
 116.449 +      /// This constructor immediately makes a snapshot of the given digraph.
 116.450 +      Snapshot(ListDigraph &gr)
 116.451          : node_observer_proxy(*this),
 116.452            arc_observer_proxy(*this) {
 116.453 -        attach(_digraph);
 116.454 +        attach(gr);
 116.455        }
 116.456  
 116.457        /// \brief Make a snapshot.
 116.458        ///
 116.459 -      /// Make a snapshot of the digraph.
 116.460 -      ///
 116.461 -      /// This function can be called more than once. In case of a repeated
 116.462 +      /// This function makes a snapshot of the given digraph.
 116.463 +      /// It can be called more than once. In case of a repeated
 116.464        /// call, the previous snapshot gets lost.
 116.465 -      /// \param _digraph The digraph we make the snapshot of.
 116.466 -      void save(ListDigraph &_digraph) {
 116.467 +      void save(ListDigraph &gr) {
 116.468          if (attached()) {
 116.469            detach();
 116.470            clear();
 116.471          }
 116.472 -        attach(_digraph);
 116.473 +        attach(gr);
 116.474        }
 116.475  
 116.476        /// \brief Undo the changes until the last snapshot.
 116.477 -      //
 116.478 -      /// Undo the changes until the last snapshot created by save().
 116.479 +      ///
 116.480 +      /// This function undos the changes until the last snapshot
 116.481 +      /// created by save() or Snapshot(ListDigraph&).
 116.482 +      ///
 116.483 +      /// \warning This method invalidates the snapshot, i.e. repeated
 116.484 +      /// restoring is not supported unless you call save() again.
 116.485        void restore() {
 116.486          detach();
 116.487          for(std::list<Arc>::iterator it = added_arcs.begin();
 116.488 @@ -758,9 +767,9 @@
 116.489          clear();
 116.490        }
 116.491  
 116.492 -      /// \brief Gives back true when the snapshot is valid.
 116.493 +      /// \brief Returns \c true if the snapshot is valid.
 116.494        ///
 116.495 -      /// Gives back true when the snapshot is valid.
 116.496 +      /// This function returns \c true if the snapshot is valid.
 116.497        bool valid() const {
 116.498          return attached();
 116.499        }
 116.500 @@ -796,11 +805,7 @@
 116.501  
 116.502    public:
 116.503  
 116.504 -    typedef ListGraphBase Digraph;
 116.505 -
 116.506 -    class Node;
 116.507 -    class Arc;
 116.508 -    class Edge;
 116.509 +    typedef ListGraphBase Graph;
 116.510  
 116.511      class Node {
 116.512        friend class ListGraphBase;
 116.513 @@ -840,8 +845,8 @@
 116.514        explicit Arc(int pid) { id = pid;}
 116.515  
 116.516      public:
 116.517 -      operator Edge() const { 
 116.518 -        return id != -1 ? edgeFromId(id / 2) : INVALID; 
 116.519 +      operator Edge() const {
 116.520 +        return id != -1 ? edgeFromId(id / 2) : INVALID;
 116.521        }
 116.522  
 116.523        Arc() {}
 116.524 @@ -851,8 +856,6 @@
 116.525        bool operator<(const Arc& arc) const {return id < arc.id;}
 116.526      };
 116.527  
 116.528 -
 116.529 -
 116.530      ListGraphBase()
 116.531        : nodes(), first_node(-1),
 116.532          first_free_node(-1), arcs(), first_free_arc(-1) {}
 116.533 @@ -1167,32 +1170,25 @@
 116.534  
 116.535    ///A general undirected graph structure.
 116.536  
 116.537 -  ///\ref ListGraph is a simple and fast <em>undirected graph</em>
 116.538 -  ///implementation based on static linked lists that are stored in
 116.539 +  ///\ref ListGraph is a versatile and fast undirected graph
 116.540 +  ///implementation based on linked lists that are stored in
 116.541    ///\c std::vector structures.
 116.542    ///
 116.543 -  ///It conforms to the \ref concepts::Graph "Graph concept" and it
 116.544 -  ///also provides several useful additional functionalities.
 116.545 -  ///Most of the member functions and nested classes are documented
 116.546 +  ///This type fully conforms to the \ref concepts::Graph "Graph concept"
 116.547 +  ///and it also provides several useful additional functionalities.
 116.548 +  ///Most of its member functions and nested classes are documented
 116.549    ///only in the concept class.
 116.550    ///
 116.551 -  ///An important extra feature of this graph implementation is that
 116.552 -  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
 116.553 -  ///
 116.554    ///\sa concepts::Graph
 116.555 +  ///\sa ListDigraph
 116.556 +  class ListGraph : public ExtendedListGraphBase {
 116.557 +    typedef ExtendedListGraphBase Parent;
 116.558  
 116.559 -  class ListGraph : public ExtendedListGraphBase {
 116.560    private:
 116.561 -    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
 116.562 -
 116.563 -    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
 116.564 -    ///
 116.565 +    /// Graphs are \e not copy constructible. Use GraphCopy instead.
 116.566      ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
 116.567 -    ///\brief Assignment of ListGraph to another one is \e not allowed.
 116.568 -    ///Use copyGraph() instead.
 116.569 -
 116.570 -    ///Assignment of ListGraph to another one is \e not allowed.
 116.571 -    ///Use copyGraph() instead.
 116.572 +    /// \brief Assignment of a graph to another one is \e not allowed.
 116.573 +    /// Use GraphCopy instead.
 116.574      void operator=(const ListGraph &) {}
 116.575    public:
 116.576      /// Constructor
 116.577 @@ -1201,100 +1197,99 @@
 116.578      ///
 116.579      ListGraph() {}
 116.580  
 116.581 -    typedef ExtendedListGraphBase Parent;
 116.582 -
 116.583      typedef Parent::OutArcIt IncEdgeIt;
 116.584  
 116.585      /// \brief Add a new node to the graph.
 116.586      ///
 116.587 -    /// Add a new node to the graph.
 116.588 -    /// \return the new node.
 116.589 +    /// This function adds a new node to the graph.
 116.590 +    /// \return The new node.
 116.591      Node addNode() { return Parent::addNode(); }
 116.592  
 116.593      /// \brief Add a new edge to the graph.
 116.594      ///
 116.595 -    /// Add a new edge to the graph with source node \c s
 116.596 -    /// and target node \c t.
 116.597 -    /// \return the new edge.
 116.598 -    Edge addEdge(const Node& s, const Node& t) {
 116.599 -      return Parent::addEdge(s, t);
 116.600 +    /// This function adds a new edge to the graph between nodes
 116.601 +    /// \c u and \c v with inherent orientation from node \c u to
 116.602 +    /// node \c v.
 116.603 +    /// \return The new edge.
 116.604 +    Edge addEdge(Node u, Node v) {
 116.605 +      return Parent::addEdge(u, v);
 116.606      }
 116.607  
 116.608 -    /// \brief Erase a node from the graph.
 116.609 +    ///\brief Erase a node from the graph.
 116.610      ///
 116.611 -    /// Erase a node from the graph.
 116.612 +    /// This function erases the given node from the graph.
 116.613 +    void erase(Node n) { Parent::erase(n); }
 116.614 +
 116.615 +    ///\brief Erase an edge from the graph.
 116.616      ///
 116.617 -    void erase(const Node& n) { Parent::erase(n); }
 116.618 -
 116.619 -    /// \brief Erase an edge from the graph.
 116.620 -    ///
 116.621 -    /// Erase an edge from the graph.
 116.622 -    ///
 116.623 -    void erase(const Edge& e) { Parent::erase(e); }
 116.624 +    /// This function erases the given edge from the graph.
 116.625 +    void erase(Edge e) { Parent::erase(e); }
 116.626      /// Node validity check
 116.627  
 116.628 -    /// This function gives back true if the given node is valid,
 116.629 -    /// ie. it is a real node of the graph.
 116.630 +    /// This function gives back \c true if the given node is valid,
 116.631 +    /// i.e. it is a real node of the graph.
 116.632      ///
 116.633 -    /// \warning A Node pointing to a removed item
 116.634 -    /// could become valid again later if new nodes are
 116.635 +    /// \warning A removed node could become valid again if new nodes are
 116.636      /// added to the graph.
 116.637      bool valid(Node n) const { return Parent::valid(n); }
 116.638 +    /// Edge validity check
 116.639 +
 116.640 +    /// This function gives back \c true if the given edge is valid,
 116.641 +    /// i.e. it is a real edge of the graph.
 116.642 +    ///
 116.643 +    /// \warning A removed edge could become valid again if new edges are
 116.644 +    /// added to the graph.
 116.645 +    bool valid(Edge e) const { return Parent::valid(e); }
 116.646      /// Arc validity check
 116.647  
 116.648 -    /// This function gives back true if the given arc is valid,
 116.649 -    /// ie. it is a real arc of the graph.
 116.650 +    /// This function gives back \c true if the given arc is valid,
 116.651 +    /// i.e. it is a real arc of the graph.
 116.652      ///
 116.653 -    /// \warning An Arc pointing to a removed item
 116.654 -    /// could become valid again later if new edges are
 116.655 +    /// \warning A removed arc could become valid again if new edges are
 116.656      /// added to the graph.
 116.657      bool valid(Arc a) const { return Parent::valid(a); }
 116.658 -    /// Edge validity check
 116.659  
 116.660 -    /// This function gives back true if the given edge is valid,
 116.661 -    /// ie. it is a real arc of the graph.
 116.662 +    /// \brief Change the first node of an edge.
 116.663      ///
 116.664 -    /// \warning A Edge pointing to a removed item
 116.665 -    /// could become valid again later if new edges are
 116.666 -    /// added to the graph.
 116.667 -    bool valid(Edge e) const { return Parent::valid(e); }
 116.668 -    /// \brief Change the end \c u of \c e to \c n
 116.669 +    /// This function changes the first node of the given edge \c e to \c n.
 116.670      ///
 116.671 -    /// This function changes the end \c u of \c e to node \c n.
 116.672 -    ///
 116.673 -    ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
 116.674 -    ///changed edge are invalidated and if the changed node is the
 116.675 -    ///base node of an iterator then this iterator is also
 116.676 -    ///invalidated.
 116.677 +    ///\note \c EdgeIt and \c ArcIt iterators referencing the
 116.678 +    ///changed edge are invalidated and all other iterators whose
 116.679 +    ///base node is the changed node are also invalidated.
 116.680      ///
 116.681      ///\warning This functionality cannot be used together with the
 116.682      ///Snapshot feature.
 116.683      void changeU(Edge e, Node n) {
 116.684        Parent::changeU(e,n);
 116.685      }
 116.686 -    /// \brief Change the end \c v of \c e to \c n
 116.687 +    /// \brief Change the second node of an edge.
 116.688      ///
 116.689 -    /// This function changes the end \c v of \c e to \c n.
 116.690 +    /// This function changes the second node of the given edge \c e to \c n.
 116.691      ///
 116.692 -    ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
 116.693 -    ///valid, however <tt>ArcIt</tt>s and if the changed node is the
 116.694 -    ///base node of an iterator then this iterator is invalidated.
 116.695 +    ///\note \c EdgeIt iterators referencing the changed edge remain
 116.696 +    ///valid, however \c ArcIt iterators referencing the changed edge and
 116.697 +    ///all other iterators whose base node is the changed node are also
 116.698 +    ///invalidated.
 116.699      ///
 116.700      ///\warning This functionality cannot be used together with the
 116.701      ///Snapshot feature.
 116.702      void changeV(Edge e, Node n) {
 116.703        Parent::changeV(e,n);
 116.704      }
 116.705 +
 116.706      /// \brief Contract two nodes.
 116.707      ///
 116.708 -    /// This function contracts two nodes.
 116.709 -    /// Node \p b will be removed but instead of deleting
 116.710 -    /// its neighboring arcs, they will be joined to \p a.
 116.711 -    /// The last parameter \p r controls whether to remove loops. \c true
 116.712 -    /// means that loops will be removed.
 116.713 +    /// This function contracts the given two nodes.
 116.714 +    /// Node \c b is removed, but instead of deleting
 116.715 +    /// its incident edges, they are joined to node \c a.
 116.716 +    /// If the last parameter \c r is \c true (this is the default value),
 116.717 +    /// then the newly created loops are removed.
 116.718      ///
 116.719 -    /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
 116.720 -    /// valid.
 116.721 +    /// \note The moved edges are joined to node \c a using changeU()
 116.722 +    /// or changeV(), thus all edge and arc iterators whose base node is
 116.723 +    /// \c b are invalidated.
 116.724 +    /// Moreover all iterators referencing node \c b or the removed 
 116.725 +    /// loops are also invalidated. Other iterators remain valid.
 116.726      ///
 116.727      ///\warning This functionality cannot be used together with the
 116.728      ///Snapshot feature.
 116.729 @@ -1313,6 +1308,33 @@
 116.730        erase(b);
 116.731      }
 116.732  
 116.733 +    ///Clear the graph.
 116.734 +
 116.735 +    ///This function erases all nodes and arcs from the graph.
 116.736 +    ///
 116.737 +    void clear() {
 116.738 +      Parent::clear();
 116.739 +    }
 116.740 +
 116.741 +    /// Reserve memory for nodes.
 116.742 +
 116.743 +    /// Using this function, it is possible to avoid superfluous memory
 116.744 +    /// allocation: if you know that the graph you want to build will
 116.745 +    /// be large (e.g. it will contain millions of nodes and/or edges),
 116.746 +    /// then it is worth reserving space for this amount before starting
 116.747 +    /// to build the graph.
 116.748 +    /// \sa reserveEdge()
 116.749 +    void reserveNode(int n) { nodes.reserve(n); };
 116.750 +
 116.751 +    /// Reserve memory for edges.
 116.752 +
 116.753 +    /// Using this function, it is possible to avoid superfluous memory
 116.754 +    /// allocation: if you know that the graph you want to build will
 116.755 +    /// be large (e.g. it will contain millions of nodes and/or edges),
 116.756 +    /// then it is worth reserving space for this amount before starting
 116.757 +    /// to build the graph.
 116.758 +    /// \sa reserveNode()
 116.759 +    void reserveEdge(int m) { arcs.reserve(2 * m); };
 116.760  
 116.761      /// \brief Class to make a snapshot of the graph and restore
 116.762      /// it later.
 116.763 @@ -1322,9 +1344,15 @@
 116.764      /// The newly added nodes and edges can be removed
 116.765      /// using the restore() function.
 116.766      ///
 116.767 -    /// \warning Edge and node deletions and other modifications
 116.768 -    /// (e.g. changing nodes of edges, contracting nodes) cannot be
 116.769 -    /// restored. These events invalidate the snapshot.
 116.770 +    /// \note After a state is restored, you cannot restore a later state, 
 116.771 +    /// i.e. you cannot add the removed nodes and edges again using
 116.772 +    /// another Snapshot instance.
 116.773 +    ///
 116.774 +    /// \warning Node and edge deletions and other modifications
 116.775 +    /// (e.g. changing the end-nodes of edges or contracting nodes)
 116.776 +    /// cannot be restored. These events invalidate the snapshot.
 116.777 +    /// However the edges and nodes that were added to the graph after
 116.778 +    /// making the current snapshot can be removed without invalidating it.
 116.779      class Snapshot {
 116.780      protected:
 116.781  
 116.782 @@ -1494,39 +1522,40 @@
 116.783        /// \brief Default constructor.
 116.784        ///
 116.785        /// Default constructor.
 116.786 -      /// To actually make a snapshot you must call save().
 116.787 +      /// You have to call save() to actually make a snapshot.
 116.788        Snapshot()
 116.789          : graph(0), node_observer_proxy(*this),
 116.790            edge_observer_proxy(*this) {}
 116.791  
 116.792        /// \brief Constructor that immediately makes a snapshot.
 116.793        ///
 116.794 -      /// This constructor immediately makes a snapshot of the graph.
 116.795 -      /// \param _graph The graph we make a snapshot of.
 116.796 -      Snapshot(ListGraph &_graph)
 116.797 +      /// This constructor immediately makes a snapshot of the given graph.
 116.798 +      Snapshot(ListGraph &gr)
 116.799          : node_observer_proxy(*this),
 116.800            edge_observer_proxy(*this) {
 116.801 -        attach(_graph);
 116.802 +        attach(gr);
 116.803        }
 116.804  
 116.805        /// \brief Make a snapshot.
 116.806        ///
 116.807 -      /// Make a snapshot of the graph.
 116.808 -      ///
 116.809 -      /// This function can be called more than once. In case of a repeated
 116.810 +      /// This function makes a snapshot of the given graph.
 116.811 +      /// It can be called more than once. In case of a repeated
 116.812        /// call, the previous snapshot gets lost.
 116.813 -      /// \param _graph The graph we make the snapshot of.
 116.814 -      void save(ListGraph &_graph) {
 116.815 +      void save(ListGraph &gr) {
 116.816          if (attached()) {
 116.817            detach();
 116.818            clear();
 116.819          }
 116.820 -        attach(_graph);
 116.821 +        attach(gr);
 116.822        }
 116.823  
 116.824        /// \brief Undo the changes until the last snapshot.
 116.825 -      //
 116.826 -      /// Undo the changes until the last snapshot created by save().
 116.827 +      ///
 116.828 +      /// This function undos the changes until the last snapshot
 116.829 +      /// created by save() or Snapshot(ListGraph&).
 116.830 +      ///
 116.831 +      /// \warning This method invalidates the snapshot, i.e. repeated
 116.832 +      /// restoring is not supported unless you call save() again.
 116.833        void restore() {
 116.834          detach();
 116.835          for(std::list<Edge>::iterator it = added_edges.begin();
 116.836 @@ -1540,9 +1569,9 @@
 116.837          clear();
 116.838        }
 116.839  
 116.840 -      /// \brief Gives back true when the snapshot is valid.
 116.841 +      /// \brief Returns \c true if the snapshot is valid.
 116.842        ///
 116.843 -      /// Gives back true when the snapshot is valid.
 116.844 +      /// This function returns \c true if the snapshot is valid.
 116.845        bool valid() const {
 116.846          return attached();
 116.847        }
   117.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   117.2 +++ b/lemon/lp.h	Thu Nov 05 15:50:01 2009 +0100
   117.3 @@ -0,0 +1,93 @@
   117.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   117.5 + *
   117.6 + * This file is a part of LEMON, a generic C++ optimization library.
   117.7 + *
   117.8 + * Copyright (C) 2003-2008
   117.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  117.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  117.11 + *
  117.12 + * Permission to use, modify and distribute this software is granted
  117.13 + * provided that this copyright notice appears in all copies. For
  117.14 + * precise terms see the accompanying LICENSE file.
  117.15 + *
  117.16 + * This software is provided "AS IS" with no warranty of any kind,
  117.17 + * express or implied, and with no claim as to its suitability for any
  117.18 + * purpose.
  117.19 + *
  117.20 + */
  117.21 +
  117.22 +#ifndef LEMON_LP_H
  117.23 +#define LEMON_LP_H
  117.24 +
  117.25 +#include<lemon/config.h>
  117.26 +
  117.27 +
  117.28 +#ifdef LEMON_HAVE_GLPK
  117.29 +#include <lemon/glpk.h>
  117.30 +#elif LEMON_HAVE_CPLEX
  117.31 +#include <lemon/cplex.h>
  117.32 +#elif LEMON_HAVE_SOPLEX
  117.33 +#include <lemon/soplex.h>
  117.34 +#elif LEMON_HAVE_CLP
  117.35 +#include <lemon/clp.h>
  117.36 +#endif
  117.37 +
  117.38 +///\file
  117.39 +///\brief Defines a default LP solver
  117.40 +///\ingroup lp_group
  117.41 +namespace lemon {
  117.42 +
  117.43 +#ifdef DOXYGEN
  117.44 +  ///The default LP solver identifier
  117.45 +
  117.46 +  ///The default LP solver identifier.
  117.47 +  ///\ingroup lp_group
  117.48 +  ///
  117.49 +  ///Currently, the possible values are \c GLPK, \c CPLEX,
  117.50 +  ///\c SOPLEX or \c CLP
  117.51 +#define LEMON_DEFAULT_LP SOLVER
  117.52 +  ///The default LP solver
  117.53 +
  117.54 +  ///The default LP solver.
  117.55 +  ///\ingroup lp_group
  117.56 +  ///
  117.57 +  ///Currently, it is either \c GlpkLp, \c CplexLp, \c SoplexLp or \c ClpLp
  117.58 +  typedef GlpkLp Lp;
  117.59 +
  117.60 +  ///The default MIP solver identifier
  117.61 +
  117.62 +  ///The default MIP solver identifier.
  117.63 +  ///\ingroup lp_group
  117.64 +  ///
  117.65 +  ///Currently, the possible values are \c GLPK or \c CPLEX
  117.66 +#define LEMON_DEFAULT_MIP SOLVER
  117.67 +  ///The default MIP solver.
  117.68 +
  117.69 +  ///The default MIP solver.
  117.70 +  ///\ingroup lp_group
  117.71 +  ///
  117.72 +  ///Currently, it is either \c GlpkMip or \c CplexMip
  117.73 +  typedef GlpkMip Mip;
  117.74 +#else
  117.75 +#ifdef LEMON_HAVE_GLPK
  117.76 +# define LEMON_DEFAULT_LP GLPK
  117.77 +  typedef GlpkLp Lp;
  117.78 +# define LEMON_DEFAULT_MIP GLPK
  117.79 +  typedef GlpkMip Mip;
  117.80 +#elif LEMON_HAVE_CPLEX
  117.81 +# define LEMON_DEFAULT_LP CPLEX
  117.82 +  typedef CplexLp Lp;
  117.83 +# define LEMON_DEFAULT_MIP CPLEX
  117.84 +  typedef CplexMip Mip;
  117.85 +#elif LEMON_HAVE_SOPLEX
  117.86 +# define DEFAULT_LP SOPLEX
  117.87 +  typedef SoplexLp Lp;
  117.88 +#elif LEMON_HAVE_CLP
  117.89 +# define DEFAULT_LP CLP
  117.90 +  typedef ClpLp Lp;  
  117.91 +#endif
  117.92 +#endif
  117.93 +
  117.94 +} //namespace lemon
  117.95 +
  117.96 +#endif //LEMON_LP_H
   118.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   118.2 +++ b/lemon/lp_base.cc	Thu Nov 05 15:50:01 2009 +0100
   118.3 @@ -0,0 +1,30 @@
   118.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   118.5 + *
   118.6 + * This file is a part of LEMON, a generic C++ optimization library.
   118.7 + *
   118.8 + * Copyright (C) 2003-2008
   118.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  118.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  118.11 + *
  118.12 + * Permission to use, modify and distribute this software is granted
  118.13 + * provided that this copyright notice appears in all copies. For
  118.14 + * precise terms see the accompanying LICENSE file.
  118.15 + *
  118.16 + * This software is provided "AS IS" with no warranty of any kind,
  118.17 + * express or implied, and with no claim as to its suitability for any
  118.18 + * purpose.
  118.19 + *
  118.20 + */
  118.21 +
  118.22 +///\file
  118.23 +///\brief The implementation of the LP solver interface.
  118.24 +
  118.25 +#include <lemon/lp_base.h>
  118.26 +namespace lemon {
  118.27 +
  118.28 +  const LpBase::Value LpBase::INF =
  118.29 +    std::numeric_limits<LpBase::Value>::infinity();
  118.30 +  const LpBase::Value LpBase::NaN =
  118.31 +    std::numeric_limits<LpBase::Value>::quiet_NaN();
  118.32 +
  118.33 +} //namespace lemon
   119.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   119.2 +++ b/lemon/lp_base.h	Thu Nov 05 15:50:01 2009 +0100
   119.3 @@ -0,0 +1,2102 @@
   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-2008
   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_LP_BASE_H
  119.23 +#define LEMON_LP_BASE_H
  119.24 +
  119.25 +#include<iostream>
  119.26 +#include<vector>
  119.27 +#include<map>
  119.28 +#include<limits>
  119.29 +#include<lemon/math.h>
  119.30 +
  119.31 +#include<lemon/error.h>
  119.32 +#include<lemon/assert.h>
  119.33 +
  119.34 +#include<lemon/core.h>
  119.35 +#include<lemon/bits/solver_bits.h>
  119.36 +
  119.37 +///\file
  119.38 +///\brief The interface of the LP solver interface.
  119.39 +///\ingroup lp_group
  119.40 +namespace lemon {
  119.41 +
  119.42 +  ///Common base class for LP and MIP solvers
  119.43 +
  119.44 +  ///Usually this class is not used directly, please use one of the concrete
  119.45 +  ///implementations of the solver interface.
  119.46 +  ///\ingroup lp_group
  119.47 +  class LpBase {
  119.48 +
  119.49 +  protected:
  119.50 +
  119.51 +    _solver_bits::VarIndex rows;
  119.52 +    _solver_bits::VarIndex cols;
  119.53 +
  119.54 +  public:
  119.55 +
  119.56 +    ///Possible outcomes of an LP solving procedure
  119.57 +    enum SolveExitStatus {
  119.58 +      /// = 0. It means that the problem has been successfully solved: either
  119.59 +      ///an optimal solution has been found or infeasibility/unboundedness
  119.60 +      ///has been proved.
  119.61 +      SOLVED = 0,
  119.62 +      /// = 1. Any other case (including the case when some user specified
  119.63 +      ///limit has been exceeded).
  119.64 +      UNSOLVED = 1
  119.65 +    };
  119.66 +
  119.67 +    ///Direction of the optimization
  119.68 +    enum Sense {
  119.69 +      /// Minimization
  119.70 +      MIN,
  119.71 +      /// Maximization
  119.72 +      MAX
  119.73 +    };
  119.74 +
  119.75 +    ///Enum for \c messageLevel() parameter
  119.76 +    enum MessageLevel {
  119.77 +      /// No output (default value).
  119.78 +      MESSAGE_NOTHING,
  119.79 +      /// Error messages only.
  119.80 +      MESSAGE_ERROR,
  119.81 +      /// Warnings.
  119.82 +      MESSAGE_WARNING,
  119.83 +      /// Normal output.
  119.84 +      MESSAGE_NORMAL,
  119.85 +      /// Verbose output.
  119.86 +      MESSAGE_VERBOSE
  119.87 +    };
  119.88 +    
  119.89 +
  119.90 +    ///The floating point type used by the solver
  119.91 +    typedef double Value;
  119.92 +    ///The infinity constant
  119.93 +    static const Value INF;
  119.94 +    ///The not a number constant
  119.95 +    static const Value NaN;
  119.96 +
  119.97 +    friend class Col;
  119.98 +    friend class ColIt;
  119.99 +    friend class Row;
 119.100 +    friend class RowIt;
 119.101 +
 119.102 +    ///Refer to a column of the LP.
 119.103 +
 119.104 +    ///This type is used to refer to a column of the LP.
 119.105 +    ///
 119.106 +    ///Its value remains valid and correct even after the addition or erase of
 119.107 +    ///other columns.
 119.108 +    ///
 119.109 +    ///\note This class is similar to other Item types in LEMON, like
 119.110 +    ///Node and Arc types in digraph.
 119.111 +    class Col {
 119.112 +      friend class LpBase;
 119.113 +    protected:
 119.114 +      int _id;
 119.115 +      explicit Col(int id) : _id(id) {}
 119.116 +    public:
 119.117 +      typedef Value ExprValue;
 119.118 +      typedef True LpCol;
 119.119 +      /// Default constructor
 119.120 +      
 119.121 +      /// \warning The default constructor sets the Col to an
 119.122 +      /// undefined value.
 119.123 +      Col() {}
 119.124 +      /// Invalid constructor \& conversion.
 119.125 +      
 119.126 +      /// This constructor initializes the Col to be invalid.
 119.127 +      /// \sa Invalid for more details.      
 119.128 +      Col(const Invalid&) : _id(-1) {}
 119.129 +      /// Equality operator
 119.130 +
 119.131 +      /// Two \ref Col "Col"s are equal if and only if they point to
 119.132 +      /// the same LP column or both are invalid.
 119.133 +      bool operator==(Col c) const  {return _id == c._id;}
 119.134 +      /// Inequality operator
 119.135 +
 119.136 +      /// \sa operator==(Col c)
 119.137 +      ///
 119.138 +      bool operator!=(Col c) const  {return _id != c._id;}
 119.139 +      /// Artificial ordering operator.
 119.140 +
 119.141 +      /// To allow the use of this object in std::map or similar
 119.142 +      /// associative container we require this.
 119.143 +      ///
 119.144 +      /// \note This operator only have to define some strict ordering of
 119.145 +      /// the items; this order has nothing to do with the iteration
 119.146 +      /// ordering of the items.
 119.147 +      bool operator<(Col c) const  {return _id < c._id;}
 119.148 +    };
 119.149 +
 119.150 +    ///Iterator for iterate over the columns of an LP problem
 119.151 +
 119.152 +    /// Its usage is quite simple, for example you can count the number
 119.153 +    /// of columns in an LP \c lp:
 119.154 +    ///\code
 119.155 +    /// int count=0;
 119.156 +    /// for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
 119.157 +    ///\endcode
 119.158 +    class ColIt : public Col {
 119.159 +      const LpBase *_solver;
 119.160 +    public:
 119.161 +      /// Default constructor
 119.162 +      
 119.163 +      /// \warning The default constructor sets the iterator
 119.164 +      /// to an undefined value.
 119.165 +      ColIt() {}
 119.166 +      /// Sets the iterator to the first Col
 119.167 +      
 119.168 +      /// Sets the iterator to the first Col.
 119.169 +      ///
 119.170 +      ColIt(const LpBase &solver) : _solver(&solver)
 119.171 +      {
 119.172 +        _solver->cols.firstItem(_id);
 119.173 +      }
 119.174 +      /// Invalid constructor \& conversion
 119.175 +      
 119.176 +      /// Initialize the iterator to be invalid.
 119.177 +      /// \sa Invalid for more details.
 119.178 +      ColIt(const Invalid&) : Col(INVALID) {}
 119.179 +      /// Next column
 119.180 +      
 119.181 +      /// Assign the iterator to the next column.
 119.182 +      ///
 119.183 +      ColIt &operator++()
 119.184 +      {
 119.185 +        _solver->cols.nextItem(_id);
 119.186 +        return *this;
 119.187 +      }
 119.188 +    };
 119.189 +
 119.190 +    /// \brief Returns the ID of the column.
 119.191 +    static int id(const Col& col) { return col._id; }
 119.192 +    /// \brief Returns the column with the given ID.
 119.193 +    ///
 119.194 +    /// \pre The argument should be a valid column ID in the LP problem.
 119.195 +    static Col colFromId(int id) { return Col(id); }
 119.196 +
 119.197 +    ///Refer to a row of the LP.
 119.198 +
 119.199 +    ///This type is used to refer to a row of the LP.
 119.200 +    ///
 119.201 +    ///Its value remains valid and correct even after the addition or erase of
 119.202 +    ///other rows.
 119.203 +    ///
 119.204 +    ///\note This class is similar to other Item types in LEMON, like
 119.205 +    ///Node and Arc types in digraph.
 119.206 +    class Row {
 119.207 +      friend class LpBase;
 119.208 +    protected:
 119.209 +      int _id;
 119.210 +      explicit Row(int id) : _id(id) {}
 119.211 +    public:
 119.212 +      typedef Value ExprValue;
 119.213 +      typedef True LpRow;
 119.214 +      /// Default constructor
 119.215 +      
 119.216 +      /// \warning The default constructor sets the Row to an
 119.217 +      /// undefined value.
 119.218 +      Row() {}
 119.219 +      /// Invalid constructor \& conversion.
 119.220 +      
 119.221 +      /// This constructor initializes the Row to be invalid.
 119.222 +      /// \sa Invalid for more details.      
 119.223 +      Row(const Invalid&) : _id(-1) {}
 119.224 +      /// Equality operator
 119.225 +
 119.226 +      /// Two \ref Row "Row"s are equal if and only if they point to
 119.227 +      /// the same LP row or both are invalid.
 119.228 +      bool operator==(Row r) const  {return _id == r._id;}
 119.229 +      /// Inequality operator
 119.230 +      
 119.231 +      /// \sa operator==(Row r)
 119.232 +      ///
 119.233 +      bool operator!=(Row r) const  {return _id != r._id;}
 119.234 +      /// Artificial ordering operator.
 119.235 +
 119.236 +      /// To allow the use of this object in std::map or similar
 119.237 +      /// associative container we require this.
 119.238 +      ///
 119.239 +      /// \note This operator only have to define some strict ordering of
 119.240 +      /// the items; this order has nothing to do with the iteration
 119.241 +      /// ordering of the items.
 119.242 +      bool operator<(Row r) const  {return _id < r._id;}
 119.243 +    };
 119.244 +
 119.245 +    ///Iterator for iterate over the rows of an LP problem
 119.246 +
 119.247 +    /// Its usage is quite simple, for example you can count the number
 119.248 +    /// of rows in an LP \c lp:
 119.249 +    ///\code
 119.250 +    /// int count=0;
 119.251 +    /// for (LpBase::RowIt c(lp); c!=INVALID; ++c) ++count;
 119.252 +    ///\endcode
 119.253 +    class RowIt : public Row {
 119.254 +      const LpBase *_solver;
 119.255 +    public:
 119.256 +      /// Default constructor
 119.257 +      
 119.258 +      /// \warning The default constructor sets the iterator
 119.259 +      /// to an undefined value.
 119.260 +      RowIt() {}
 119.261 +      /// Sets the iterator to the first Row
 119.262 +      
 119.263 +      /// Sets the iterator to the first Row.
 119.264 +      ///
 119.265 +      RowIt(const LpBase &solver) : _solver(&solver)
 119.266 +      {
 119.267 +        _solver->rows.firstItem(_id);
 119.268 +      }
 119.269 +      /// Invalid constructor \& conversion
 119.270 +      
 119.271 +      /// Initialize the iterator to be invalid.
 119.272 +      /// \sa Invalid for more details.
 119.273 +      RowIt(const Invalid&) : Row(INVALID) {}
 119.274 +      /// Next row
 119.275 +      
 119.276 +      /// Assign the iterator to the next row.
 119.277 +      ///
 119.278 +      RowIt &operator++()
 119.279 +      {
 119.280 +        _solver->rows.nextItem(_id);
 119.281 +        return *this;
 119.282 +      }
 119.283 +    };
 119.284 +
 119.285 +    /// \brief Returns the ID of the row.
 119.286 +    static int id(const Row& row) { return row._id; }
 119.287 +    /// \brief Returns the row with the given ID.
 119.288 +    ///
 119.289 +    /// \pre The argument should be a valid row ID in the LP problem.
 119.290 +    static Row rowFromId(int id) { return Row(id); }
 119.291 +
 119.292 +  public:
 119.293 +
 119.294 +    ///Linear expression of variables and a constant component
 119.295 +
 119.296 +    ///This data structure stores a linear expression of the variables
 119.297 +    ///(\ref Col "Col"s) and also has a constant component.
 119.298 +    ///
 119.299 +    ///There are several ways to access and modify the contents of this
 119.300 +    ///container.
 119.301 +    ///\code
 119.302 +    ///e[v]=5;
 119.303 +    ///e[v]+=12;
 119.304 +    ///e.erase(v);
 119.305 +    ///\endcode
 119.306 +    ///or you can also iterate through its elements.
 119.307 +    ///\code
 119.308 +    ///double s=0;
 119.309 +    ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
 119.310 +    ///  s+=*i * primal(i);
 119.311 +    ///\endcode
 119.312 +    ///(This code computes the primal value of the expression).
 119.313 +    ///- Numbers (<tt>double</tt>'s)
 119.314 +    ///and variables (\ref Col "Col"s) directly convert to an
 119.315 +    ///\ref Expr and the usual linear operations are defined, so
 119.316 +    ///\code
 119.317 +    ///v+w
 119.318 +    ///2*v-3.12*(v-w/2)+2
 119.319 +    ///v*2.1+(3*v+(v*12+w+6)*3)/2
 119.320 +    ///\endcode
 119.321 +    ///are valid expressions.
 119.322 +    ///The usual assignment operations are also defined.
 119.323 +    ///\code
 119.324 +    ///e=v+w;
 119.325 +    ///e+=2*v-3.12*(v-w/2)+2;
 119.326 +    ///e*=3.4;
 119.327 +    ///e/=5;
 119.328 +    ///\endcode
 119.329 +    ///- The constant member can be set and read by dereference
 119.330 +    ///  operator (unary *)
 119.331 +    ///
 119.332 +    ///\code
 119.333 +    ///*e=12;
 119.334 +    ///double c=*e;
 119.335 +    ///\endcode
 119.336 +    ///
 119.337 +    ///\sa Constr
 119.338 +    class Expr {
 119.339 +      friend class LpBase;
 119.340 +    public:
 119.341 +      /// The key type of the expression
 119.342 +      typedef LpBase::Col Key;
 119.343 +      /// The value type of the expression
 119.344 +      typedef LpBase::Value Value;
 119.345 +
 119.346 +    protected:
 119.347 +      Value const_comp;
 119.348 +      std::map<int, Value> comps;
 119.349 +
 119.350 +    public:
 119.351 +      typedef True SolverExpr;
 119.352 +      /// Default constructor
 119.353 +      
 119.354 +      /// Construct an empty expression, the coefficients and
 119.355 +      /// the constant component are initialized to zero.
 119.356 +      Expr() : const_comp(0) {}
 119.357 +      /// Construct an expression from a column
 119.358 +
 119.359 +      /// Construct an expression, which has a term with \c c variable
 119.360 +      /// and 1.0 coefficient.
 119.361 +      Expr(const Col &c) : const_comp(0) {
 119.362 +        typedef std::map<int, Value>::value_type pair_type;
 119.363 +        comps.insert(pair_type(id(c), 1));
 119.364 +      }
 119.365 +      /// Construct an expression from a constant
 119.366 +
 119.367 +      /// Construct an expression, which's constant component is \c v.
 119.368 +      ///
 119.369 +      Expr(const Value &v) : const_comp(v) {}
 119.370 +      /// Returns the coefficient of the column
 119.371 +      Value operator[](const Col& c) const {
 119.372 +        std::map<int, Value>::const_iterator it=comps.find(id(c));
 119.373 +        if (it != comps.end()) {
 119.374 +          return it->second;
 119.375 +        } else {
 119.376 +          return 0;
 119.377 +        }
 119.378 +      }
 119.379 +      /// Returns the coefficient of the column
 119.380 +      Value& operator[](const Col& c) {
 119.381 +        return comps[id(c)];
 119.382 +      }
 119.383 +      /// Sets the coefficient of the column
 119.384 +      void set(const Col &c, const Value &v) {
 119.385 +        if (v != 0.0) {
 119.386 +          typedef std::map<int, Value>::value_type pair_type;
 119.387 +          comps.insert(pair_type(id(c), v));
 119.388 +        } else {
 119.389 +          comps.erase(id(c));
 119.390 +        }
 119.391 +      }
 119.392 +      /// Returns the constant component of the expression
 119.393 +      Value& operator*() { return const_comp; }
 119.394 +      /// Returns the constant component of the expression
 119.395 +      const Value& operator*() const { return const_comp; }
 119.396 +      /// \brief Removes the coefficients which's absolute value does
 119.397 +      /// not exceed \c epsilon. It also sets to zero the constant
 119.398 +      /// component, if it does not exceed epsilon in absolute value.
 119.399 +      void simplify(Value epsilon = 0.0) {
 119.400 +        std::map<int, Value>::iterator it=comps.begin();
 119.401 +        while (it != comps.end()) {
 119.402 +          std::map<int, Value>::iterator jt=it;
 119.403 +          ++jt;
 119.404 +          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
 119.405 +          it=jt;
 119.406 +        }
 119.407 +        if (std::fabs(const_comp) <= epsilon) const_comp = 0;
 119.408 +      }
 119.409 +
 119.410 +      void simplify(Value epsilon = 0.0) const {
 119.411 +        const_cast<Expr*>(this)->simplify(epsilon);
 119.412 +      }
 119.413 +
 119.414 +      ///Sets all coefficients and the constant component to 0.
 119.415 +      void clear() {
 119.416 +        comps.clear();
 119.417 +        const_comp=0;
 119.418 +      }
 119.419 +
 119.420 +      ///Compound assignment
 119.421 +      Expr &operator+=(const Expr &e) {
 119.422 +        for (std::map<int, Value>::const_iterator it=e.comps.begin();
 119.423 +             it!=e.comps.end(); ++it)
 119.424 +          comps[it->first]+=it->second;
 119.425 +        const_comp+=e.const_comp;
 119.426 +        return *this;
 119.427 +      }
 119.428 +      ///Compound assignment
 119.429 +      Expr &operator-=(const Expr &e) {
 119.430 +        for (std::map<int, Value>::const_iterator it=e.comps.begin();
 119.431 +             it!=e.comps.end(); ++it)
 119.432 +          comps[it->first]-=it->second;
 119.433 +        const_comp-=e.const_comp;
 119.434 +        return *this;
 119.435 +      }
 119.436 +      ///Multiply with a constant
 119.437 +      Expr &operator*=(const Value &v) {
 119.438 +        for (std::map<int, Value>::iterator it=comps.begin();
 119.439 +             it!=comps.end(); ++it)
 119.440 +          it->second*=v;
 119.441 +        const_comp*=v;
 119.442 +        return *this;
 119.443 +      }
 119.444 +      ///Division with a constant
 119.445 +      Expr &operator/=(const Value &c) {
 119.446 +        for (std::map<int, Value>::iterator it=comps.begin();
 119.447 +             it!=comps.end(); ++it)
 119.448 +          it->second/=c;
 119.449 +        const_comp/=c;
 119.450 +        return *this;
 119.451 +      }
 119.452 +
 119.453 +      ///Iterator over the expression
 119.454 +      
 119.455 +      ///The iterator iterates over the terms of the expression. 
 119.456 +      /// 
 119.457 +      ///\code
 119.458 +      ///double s=0;
 119.459 +      ///for(LpBase::Expr::CoeffIt i(e);i!=INVALID;++i)
 119.460 +      ///  s+= *i * primal(i);
 119.461 +      ///\endcode
 119.462 +      class CoeffIt {
 119.463 +      private:
 119.464 +
 119.465 +        std::map<int, Value>::iterator _it, _end;
 119.466 +
 119.467 +      public:
 119.468 +
 119.469 +        /// Sets the iterator to the first term
 119.470 +        
 119.471 +        /// Sets the iterator to the first term of the expression.
 119.472 +        ///
 119.473 +        CoeffIt(Expr& e)
 119.474 +          : _it(e.comps.begin()), _end(e.comps.end()){}
 119.475 +
 119.476 +        /// Convert the iterator to the column of the term
 119.477 +        operator Col() const {
 119.478 +          return colFromId(_it->first);
 119.479 +        }
 119.480 +
 119.481 +        /// Returns the coefficient of the term
 119.482 +        Value& operator*() { return _it->second; }
 119.483 +
 119.484 +        /// Returns the coefficient of the term
 119.485 +        const Value& operator*() const { return _it->second; }
 119.486 +        /// Next term
 119.487 +        
 119.488 +        /// Assign the iterator to the next term.
 119.489 +        ///
 119.490 +        CoeffIt& operator++() { ++_it; return *this; }
 119.491 +
 119.492 +        /// Equality operator
 119.493 +        bool operator==(Invalid) const { return _it == _end; }
 119.494 +        /// Inequality operator
 119.495 +        bool operator!=(Invalid) const { return _it != _end; }
 119.496 +      };
 119.497 +
 119.498 +      /// Const iterator over the expression
 119.499 +      
 119.500 +      ///The iterator iterates over the terms of the expression. 
 119.501 +      /// 
 119.502 +      ///\code
 119.503 +      ///double s=0;
 119.504 +      ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
 119.505 +      ///  s+=*i * primal(i);
 119.506 +      ///\endcode
 119.507 +      class ConstCoeffIt {
 119.508 +      private:
 119.509 +
 119.510 +        std::map<int, Value>::const_iterator _it, _end;
 119.511 +
 119.512 +      public:
 119.513 +
 119.514 +        /// Sets the iterator to the first term
 119.515 +        
 119.516 +        /// Sets the iterator to the first term of the expression.
 119.517 +        ///
 119.518 +        ConstCoeffIt(const Expr& e)
 119.519 +          : _it(e.comps.begin()), _end(e.comps.end()){}
 119.520 +
 119.521 +        /// Convert the iterator to the column of the term
 119.522 +        operator Col() const {
 119.523 +          return colFromId(_it->first);
 119.524 +        }
 119.525 +
 119.526 +        /// Returns the coefficient of the term
 119.527 +        const Value& operator*() const { return _it->second; }
 119.528 +
 119.529 +        /// Next term
 119.530 +        
 119.531 +        /// Assign the iterator to the next term.
 119.532 +        ///
 119.533 +        ConstCoeffIt& operator++() { ++_it; return *this; }
 119.534 +
 119.535 +        /// Equality operator
 119.536 +        bool operator==(Invalid) const { return _it == _end; }
 119.537 +        /// Inequality operator
 119.538 +        bool operator!=(Invalid) const { return _it != _end; }
 119.539 +      };
 119.540 +
 119.541 +    };
 119.542 +
 119.543 +    ///Linear constraint
 119.544 +
 119.545 +    ///This data stucture represents a linear constraint in the LP.
 119.546 +    ///Basically it is a linear expression with a lower or an upper bound
 119.547 +    ///(or both). These parts of the constraint can be obtained by the member
 119.548 +    ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
 119.549 +    ///respectively.
 119.550 +    ///There are two ways to construct a constraint.
 119.551 +    ///- You can set the linear expression and the bounds directly
 119.552 +    ///  by the functions above.
 119.553 +    ///- The operators <tt>\<=</tt>, <tt>==</tt> and  <tt>\>=</tt>
 119.554 +    ///  are defined between expressions, or even between constraints whenever
 119.555 +    ///  it makes sense. Therefore if \c e and \c f are linear expressions and
 119.556 +    ///  \c s and \c t are numbers, then the followings are valid expressions
 119.557 +    ///  and thus they can be used directly e.g. in \ref addRow() whenever
 119.558 +    ///  it makes sense.
 119.559 +    ///\code
 119.560 +    ///  e<=s
 119.561 +    ///  e<=f
 119.562 +    ///  e==f
 119.563 +    ///  s<=e<=t
 119.564 +    ///  e>=t
 119.565 +    ///\endcode
 119.566 +    ///\warning The validity of a constraint is checked only at run
 119.567 +    ///time, so e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will
 119.568 +    ///compile, but will fail an assertion.
 119.569 +    class Constr
 119.570 +    {
 119.571 +    public:
 119.572 +      typedef LpBase::Expr Expr;
 119.573 +      typedef Expr::Key Key;
 119.574 +      typedef Expr::Value Value;
 119.575 +
 119.576 +    protected:
 119.577 +      Expr _expr;
 119.578 +      Value _lb,_ub;
 119.579 +    public:
 119.580 +      ///\e
 119.581 +      Constr() : _expr(), _lb(NaN), _ub(NaN) {}
 119.582 +      ///\e
 119.583 +      Constr(Value lb, const Expr &e, Value ub) :
 119.584 +        _expr(e), _lb(lb), _ub(ub) {}
 119.585 +      Constr(const Expr &e) :
 119.586 +        _expr(e), _lb(NaN), _ub(NaN) {}
 119.587 +      ///\e
 119.588 +      void clear()
 119.589 +      {
 119.590 +        _expr.clear();
 119.591 +        _lb=_ub=NaN;
 119.592 +      }
 119.593 +
 119.594 +      ///Reference to the linear expression
 119.595 +      Expr &expr() { return _expr; }
 119.596 +      ///Cont reference to the linear expression
 119.597 +      const Expr &expr() const { return _expr; }
 119.598 +      ///Reference to the lower bound.
 119.599 +
 119.600 +      ///\return
 119.601 +      ///- \ref INF "INF": the constraint is lower unbounded.
 119.602 +      ///- \ref NaN "NaN": lower bound has not been set.
 119.603 +      ///- finite number: the lower bound
 119.604 +      Value &lowerBound() { return _lb; }
 119.605 +      ///The const version of \ref lowerBound()
 119.606 +      const Value &lowerBound() const { return _lb; }
 119.607 +      ///Reference to the upper bound.
 119.608 +
 119.609 +      ///\return
 119.610 +      ///- \ref INF "INF": the constraint is upper unbounded.
 119.611 +      ///- \ref NaN "NaN": upper bound has not been set.
 119.612 +      ///- finite number: the upper bound
 119.613 +      Value &upperBound() { return _ub; }
 119.614 +      ///The const version of \ref upperBound()
 119.615 +      const Value &upperBound() const { return _ub; }
 119.616 +      ///Is the constraint lower bounded?
 119.617 +      bool lowerBounded() const {
 119.618 +        return _lb != -INF && !isNaN(_lb);
 119.619 +      }
 119.620 +      ///Is the constraint upper bounded?
 119.621 +      bool upperBounded() const {
 119.622 +        return _ub != INF && !isNaN(_ub);
 119.623 +      }
 119.624 +
 119.625 +    };
 119.626 +
 119.627 +    ///Linear expression of rows
 119.628 +
 119.629 +    ///This data structure represents a column of the matrix,
 119.630 +    ///thas is it strores a linear expression of the dual variables
 119.631 +    ///(\ref Row "Row"s).
 119.632 +    ///
 119.633 +    ///There are several ways to access and modify the contents of this
 119.634 +    ///container.
 119.635 +    ///\code
 119.636 +    ///e[v]=5;
 119.637 +    ///e[v]+=12;
 119.638 +    ///e.erase(v);
 119.639 +    ///\endcode
 119.640 +    ///or you can also iterate through its elements.
 119.641 +    ///\code
 119.642 +    ///double s=0;
 119.643 +    ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
 119.644 +    ///  s+=*i;
 119.645 +    ///\endcode
 119.646 +    ///(This code computes the sum of all coefficients).
 119.647 +    ///- Numbers (<tt>double</tt>'s)
 119.648 +    ///and variables (\ref Row "Row"s) directly convert to an
 119.649 +    ///\ref DualExpr and the usual linear operations are defined, so
 119.650 +    ///\code
 119.651 +    ///v+w
 119.652 +    ///2*v-3.12*(v-w/2)
 119.653 +    ///v*2.1+(3*v+(v*12+w)*3)/2
 119.654 +    ///\endcode
 119.655 +    ///are valid \ref DualExpr dual expressions.
 119.656 +    ///The usual assignment operations are also defined.
 119.657 +    ///\code
 119.658 +    ///e=v+w;
 119.659 +    ///e+=2*v-3.12*(v-w/2);
 119.660 +    ///e*=3.4;
 119.661 +    ///e/=5;
 119.662 +    ///\endcode
 119.663 +    ///
 119.664 +    ///\sa Expr
 119.665 +    class DualExpr {
 119.666 +      friend class LpBase;
 119.667 +    public:
 119.668 +      /// The key type of the expression
 119.669 +      typedef LpBase::Row Key;
 119.670 +      /// The value type of the expression
 119.671 +      typedef LpBase::Value Value;
 119.672 +
 119.673 +    protected:
 119.674 +      std::map<int, Value> comps;
 119.675 +
 119.676 +    public:
 119.677 +      typedef True SolverExpr;
 119.678 +      /// Default constructor
 119.679 +      
 119.680 +      /// Construct an empty expression, the coefficients are
 119.681 +      /// initialized to zero.
 119.682 +      DualExpr() {}
 119.683 +      /// Construct an expression from a row
 119.684 +
 119.685 +      /// Construct an expression, which has a term with \c r dual
 119.686 +      /// variable and 1.0 coefficient.
 119.687 +      DualExpr(const Row &r) {
 119.688 +        typedef std::map<int, Value>::value_type pair_type;
 119.689 +        comps.insert(pair_type(id(r), 1));
 119.690 +      }
 119.691 +      /// Returns the coefficient of the row
 119.692 +      Value operator[](const Row& r) const {
 119.693 +        std::map<int, Value>::const_iterator it = comps.find(id(r));
 119.694 +        if (it != comps.end()) {
 119.695 +          return it->second;
 119.696 +        } else {
 119.697 +          return 0;
 119.698 +        }
 119.699 +      }
 119.700 +      /// Returns the coefficient of the row
 119.701 +      Value& operator[](const Row& r) {
 119.702 +        return comps[id(r)];
 119.703 +      }
 119.704 +      /// Sets the coefficient of the row
 119.705 +      void set(const Row &r, const Value &v) {
 119.706 +        if (v != 0.0) {
 119.707 +          typedef std::map<int, Value>::value_type pair_type;
 119.708 +          comps.insert(pair_type(id(r), v));
 119.709 +        } else {
 119.710 +          comps.erase(id(r));
 119.711 +        }
 119.712 +      }
 119.713 +      /// \brief Removes the coefficients which's absolute value does
 119.714 +      /// not exceed \c epsilon. 
 119.715 +      void simplify(Value epsilon = 0.0) {
 119.716 +        std::map<int, Value>::iterator it=comps.begin();
 119.717 +        while (it != comps.end()) {
 119.718 +          std::map<int, Value>::iterator jt=it;
 119.719 +          ++jt;
 119.720 +          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
 119.721 +          it=jt;
 119.722 +        }
 119.723 +      }
 119.724 +
 119.725 +      void simplify(Value epsilon = 0.0) const {
 119.726 +        const_cast<DualExpr*>(this)->simplify(epsilon);
 119.727 +      }
 119.728 +
 119.729 +      ///Sets all coefficients to 0.
 119.730 +      void clear() {
 119.731 +        comps.clear();
 119.732 +      }
 119.733 +      ///Compound assignment
 119.734 +      DualExpr &operator+=(const DualExpr &e) {
 119.735 +        for (std::map<int, Value>::const_iterator it=e.comps.begin();
 119.736 +             it!=e.comps.end(); ++it)
 119.737 +          comps[it->first]+=it->second;
 119.738 +        return *this;
 119.739 +      }
 119.740 +      ///Compound assignment
 119.741 +      DualExpr &operator-=(const DualExpr &e) {
 119.742 +        for (std::map<int, Value>::const_iterator it=e.comps.begin();
 119.743 +             it!=e.comps.end(); ++it)
 119.744 +          comps[it->first]-=it->second;
 119.745 +        return *this;
 119.746 +      }
 119.747 +      ///Multiply with a constant
 119.748 +      DualExpr &operator*=(const Value &v) {
 119.749 +        for (std::map<int, Value>::iterator it=comps.begin();
 119.750 +             it!=comps.end(); ++it)
 119.751 +          it->second*=v;
 119.752 +        return *this;
 119.753 +      }
 119.754 +      ///Division with a constant
 119.755 +      DualExpr &operator/=(const Value &v) {
 119.756 +        for (std::map<int, Value>::iterator it=comps.begin();
 119.757 +             it!=comps.end(); ++it)
 119.758 +          it->second/=v;
 119.759 +        return *this;
 119.760 +      }
 119.761 +
 119.762 +      ///Iterator over the expression
 119.763 +      
 119.764 +      ///The iterator iterates over the terms of the expression. 
 119.765 +      /// 
 119.766 +      ///\code
 119.767 +      ///double s=0;
 119.768 +      ///for(LpBase::DualExpr::CoeffIt i(e);i!=INVALID;++i)
 119.769 +      ///  s+= *i * dual(i);
 119.770 +      ///\endcode
 119.771 +      class CoeffIt {
 119.772 +      private:
 119.773 +
 119.774 +        std::map<int, Value>::iterator _it, _end;
 119.775 +
 119.776 +      public:
 119.777 +
 119.778 +        /// Sets the iterator to the first term
 119.779 +        
 119.780 +        /// Sets the iterator to the first term of the expression.
 119.781 +        ///
 119.782 +        CoeffIt(DualExpr& e)
 119.783 +          : _it(e.comps.begin()), _end(e.comps.end()){}
 119.784 +
 119.785 +        /// Convert the iterator to the row of the term
 119.786 +        operator Row() const {
 119.787 +          return rowFromId(_it->first);
 119.788 +        }
 119.789 +
 119.790 +        /// Returns the coefficient of the term
 119.791 +        Value& operator*() { return _it->second; }
 119.792 +
 119.793 +        /// Returns the coefficient of the term
 119.794 +        const Value& operator*() const { return _it->second; }
 119.795 +
 119.796 +        /// Next term
 119.797 +        
 119.798 +        /// Assign the iterator to the next term.
 119.799 +        ///
 119.800 +        CoeffIt& operator++() { ++_it; return *this; }
 119.801 +
 119.802 +        /// Equality operator
 119.803 +        bool operator==(Invalid) const { return _it == _end; }
 119.804 +        /// Inequality operator
 119.805 +        bool operator!=(Invalid) const { return _it != _end; }
 119.806 +      };
 119.807 +
 119.808 +      ///Iterator over the expression
 119.809 +      
 119.810 +      ///The iterator iterates over the terms of the expression. 
 119.811 +      /// 
 119.812 +      ///\code
 119.813 +      ///double s=0;
 119.814 +      ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
 119.815 +      ///  s+= *i * dual(i);
 119.816 +      ///\endcode
 119.817 +      class ConstCoeffIt {
 119.818 +      private:
 119.819 +
 119.820 +        std::map<int, Value>::const_iterator _it, _end;
 119.821 +
 119.822 +      public:
 119.823 +
 119.824 +        /// Sets the iterator to the first term
 119.825 +        
 119.826 +        /// Sets the iterator to the first term of the expression.
 119.827 +        ///
 119.828 +        ConstCoeffIt(const DualExpr& e)
 119.829 +          : _it(e.comps.begin()), _end(e.comps.end()){}
 119.830 +
 119.831 +        /// Convert the iterator to the row of the term
 119.832 +        operator Row() const {
 119.833 +          return rowFromId(_it->first);
 119.834 +        }
 119.835 +
 119.836 +        /// Returns the coefficient of the term
 119.837 +        const Value& operator*() const { return _it->second; }
 119.838 +
 119.839 +        /// Next term
 119.840 +        
 119.841 +        /// Assign the iterator to the next term.
 119.842 +        ///
 119.843 +        ConstCoeffIt& operator++() { ++_it; return *this; }
 119.844 +
 119.845 +        /// Equality operator
 119.846 +        bool operator==(Invalid) const { return _it == _end; }
 119.847 +        /// Inequality operator
 119.848 +        bool operator!=(Invalid) const { return _it != _end; }
 119.849 +      };
 119.850 +    };
 119.851 +
 119.852 +
 119.853 +  protected:
 119.854 +
 119.855 +    class InsertIterator {
 119.856 +    private:
 119.857 +
 119.858 +      std::map<int, Value>& _host;
 119.859 +      const _solver_bits::VarIndex& _index;
 119.860 +
 119.861 +    public:
 119.862 +
 119.863 +      typedef std::output_iterator_tag iterator_category;
 119.864 +      typedef void difference_type;
 119.865 +      typedef void value_type;
 119.866 +      typedef void reference;
 119.867 +      typedef void pointer;
 119.868 +
 119.869 +      InsertIterator(std::map<int, Value>& host,
 119.870 +                   const _solver_bits::VarIndex& index)
 119.871 +        : _host(host), _index(index) {}
 119.872 +
 119.873 +      InsertIterator& operator=(const std::pair<int, Value>& value) {
 119.874 +        typedef std::map<int, Value>::value_type pair_type;
 119.875 +        _host.insert(pair_type(_index[value.first], value.second));
 119.876 +        return *this;
 119.877 +      }
 119.878 +
 119.879 +      InsertIterator& operator*() { return *this; }
 119.880 +      InsertIterator& operator++() { return *this; }
 119.881 +      InsertIterator operator++(int) { return *this; }
 119.882 +
 119.883 +    };
 119.884 +
 119.885 +    class ExprIterator {
 119.886 +    private:
 119.887 +      std::map<int, Value>::const_iterator _host_it;
 119.888 +      const _solver_bits::VarIndex& _index;
 119.889 +    public:
 119.890 +
 119.891 +      typedef std::bidirectional_iterator_tag iterator_category;
 119.892 +      typedef std::ptrdiff_t difference_type;
 119.893 +      typedef const std::pair<int, Value> value_type;
 119.894 +      typedef value_type reference;
 119.895 +
 119.896 +      class pointer {
 119.897 +      public:
 119.898 +        pointer(value_type& _value) : value(_value) {}
 119.899 +        value_type* operator->() { return &value; }
 119.900 +      private:
 119.901 +        value_type value;
 119.902 +      };
 119.903 +
 119.904 +      ExprIterator(const std::map<int, Value>::const_iterator& host_it,
 119.905 +                   const _solver_bits::VarIndex& index)
 119.906 +        : _host_it(host_it), _index(index) {}
 119.907 +
 119.908 +      reference operator*() {
 119.909 +        return std::make_pair(_index(_host_it->first), _host_it->second);
 119.910 +      }
 119.911 +
 119.912 +      pointer operator->() {
 119.913 +        return pointer(operator*());
 119.914 +      }
 119.915 +
 119.916 +      ExprIterator& operator++() { ++_host_it; return *this; }
 119.917 +      ExprIterator operator++(int) {
 119.918 +        ExprIterator tmp(*this); ++_host_it; return tmp;
 119.919 +      }
 119.920 +
 119.921 +      ExprIterator& operator--() { --_host_it; return *this; }
 119.922 +      ExprIterator operator--(int) {
 119.923 +        ExprIterator tmp(*this); --_host_it; return tmp;
 119.924 +      }
 119.925 +
 119.926 +      bool operator==(const ExprIterator& it) const {
 119.927 +        return _host_it == it._host_it;
 119.928 +      }
 119.929 +
 119.930 +      bool operator!=(const ExprIterator& it) const {
 119.931 +        return _host_it != it._host_it;
 119.932 +      }
 119.933 +
 119.934 +    };
 119.935 +
 119.936 +  protected:
 119.937 +
 119.938 +    //Abstract virtual functions
 119.939 +
 119.940 +    virtual int _addColId(int col) { return cols.addIndex(col); }
 119.941 +    virtual int _addRowId(int row) { return rows.addIndex(row); }
 119.942 +
 119.943 +    virtual void _eraseColId(int col) { cols.eraseIndex(col); }
 119.944 +    virtual void _eraseRowId(int row) { rows.eraseIndex(row); }
 119.945 +
 119.946 +    virtual int _addCol() = 0;
 119.947 +    virtual int _addRow() = 0;
 119.948 +
 119.949 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
 119.950 +      int row = _addRow();
 119.951 +      _setRowCoeffs(row, b, e);
 119.952 +      _setRowLowerBound(row, l);
 119.953 +      _setRowUpperBound(row, u);
 119.954 +      return row;
 119.955 +    }
 119.956 +
 119.957 +    virtual void _eraseCol(int col) = 0;
 119.958 +    virtual void _eraseRow(int row) = 0;
 119.959 +
 119.960 +    virtual void _getColName(int col, std::string& name) const = 0;
 119.961 +    virtual void _setColName(int col, const std::string& name) = 0;
 119.962 +    virtual int _colByName(const std::string& name) const = 0;
 119.963 +
 119.964 +    virtual void _getRowName(int row, std::string& name) const = 0;
 119.965 +    virtual void _setRowName(int row, const std::string& name) = 0;
 119.966 +    virtual int _rowByName(const std::string& name) const = 0;
 119.967 +
 119.968 +    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
 119.969 +    virtual void _getRowCoeffs(int i, InsertIterator b) const = 0;
 119.970 +
 119.971 +    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
 119.972 +    virtual void _getColCoeffs(int i, InsertIterator b) const = 0;
 119.973 +
 119.974 +    virtual void _setCoeff(int row, int col, Value value) = 0;
 119.975 +    virtual Value _getCoeff(int row, int col) const = 0;
 119.976 +
 119.977 +    virtual void _setColLowerBound(int i, Value value) = 0;
 119.978 +    virtual Value _getColLowerBound(int i) const = 0;
 119.979 +
 119.980 +    virtual void _setColUpperBound(int i, Value value) = 0;
 119.981 +    virtual Value _getColUpperBound(int i) const = 0;
 119.982 +
 119.983 +    virtual void _setRowLowerBound(int i, Value value) = 0;
 119.984 +    virtual Value _getRowLowerBound(int i) const = 0;
 119.985 +
 119.986 +    virtual void _setRowUpperBound(int i, Value value) = 0;
 119.987 +    virtual Value _getRowUpperBound(int i) const = 0;
 119.988 +
 119.989 +    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0;
 119.990 +    virtual void _getObjCoeffs(InsertIterator b) const = 0;
 119.991 +
 119.992 +    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
 119.993 +    virtual Value _getObjCoeff(int i) const = 0;
 119.994 +
 119.995 +    virtual void _setSense(Sense) = 0;
 119.996 +    virtual Sense _getSense() const = 0;
 119.997 +
 119.998 +    virtual void _clear() = 0;
 119.999 +
119.1000 +    virtual const char* _solverName() const = 0;
119.1001 +
119.1002 +    virtual void _messageLevel(MessageLevel level) = 0;
119.1003 +
119.1004 +    //Own protected stuff
119.1005 +
119.1006 +    //Constant component of the objective function
119.1007 +    Value obj_const_comp;
119.1008 +
119.1009 +    LpBase() : rows(), cols(), obj_const_comp(0) {}
119.1010 +
119.1011 +  public:
119.1012 +
119.1013 +    /// Virtual destructor
119.1014 +    virtual ~LpBase() {}
119.1015 +
119.1016 +    ///Gives back the name of the solver.
119.1017 +    const char* solverName() const {return _solverName();}
119.1018 +
119.1019 +    ///\name Build Up and Modify the LP
119.1020 +
119.1021 +    ///@{
119.1022 +
119.1023 +    ///Add a new empty column (i.e a new variable) to the LP
119.1024 +    Col addCol() { Col c; c._id = _addColId(_addCol()); return c;}
119.1025 +
119.1026 +    ///\brief Adds several new columns (i.e variables) at once
119.1027 +    ///
119.1028 +    ///This magic function takes a container as its argument and fills
119.1029 +    ///its elements with new columns (i.e. variables)
119.1030 +    ///\param t can be
119.1031 +    ///- a standard STL compatible iterable container with
119.1032 +    ///\ref Col as its \c values_type like
119.1033 +    ///\code
119.1034 +    ///std::vector<LpBase::Col>
119.1035 +    ///std::list<LpBase::Col>
119.1036 +    ///\endcode
119.1037 +    ///- a standard STL compatible iterable container with
119.1038 +    ///\ref Col as its \c mapped_type like
119.1039 +    ///\code
119.1040 +    ///std::map<AnyType,LpBase::Col>
119.1041 +    ///\endcode
119.1042 +    ///- an iterable lemon \ref concepts::WriteMap "write map" like
119.1043 +    ///\code
119.1044 +    ///ListGraph::NodeMap<LpBase::Col>
119.1045 +    ///ListGraph::ArcMap<LpBase::Col>
119.1046 +    ///\endcode
119.1047 +    ///\return The number of the created column.
119.1048 +#ifdef DOXYGEN
119.1049 +    template<class T>
119.1050 +    int addColSet(T &t) { return 0;}
119.1051 +#else
119.1052 +    template<class T>
119.1053 +    typename enable_if<typename T::value_type::LpCol,int>::type
119.1054 +    addColSet(T &t,dummy<0> = 0) {
119.1055 +      int s=0;
119.1056 +      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
119.1057 +      return s;
119.1058 +    }
119.1059 +    template<class T>
119.1060 +    typename enable_if<typename T::value_type::second_type::LpCol,
119.1061 +                       int>::type
119.1062 +    addColSet(T &t,dummy<1> = 1) {
119.1063 +      int s=0;
119.1064 +      for(typename T::iterator i=t.begin();i!=t.end();++i) {
119.1065 +        i->second=addCol();
119.1066 +        s++;
119.1067 +      }
119.1068 +      return s;
119.1069 +    }
119.1070 +    template<class T>
119.1071 +    typename enable_if<typename T::MapIt::Value::LpCol,
119.1072 +                       int>::type
119.1073 +    addColSet(T &t,dummy<2> = 2) {
119.1074 +      int s=0;
119.1075 +      for(typename T::MapIt i(t); i!=INVALID; ++i)
119.1076 +        {
119.1077 +          i.set(addCol());
119.1078 +          s++;
119.1079 +        }
119.1080 +      return s;
119.1081 +    }
119.1082 +#endif
119.1083 +
119.1084 +    ///Set a column (i.e a dual constraint) of the LP
119.1085 +
119.1086 +    ///\param c is the column to be modified
119.1087 +    ///\param e is a dual linear expression (see \ref DualExpr)
119.1088 +    ///a better one.
119.1089 +    void col(Col c, const DualExpr &e) {
119.1090 +      e.simplify();
119.1091 +      _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), rows),
119.1092 +                    ExprIterator(e.comps.end(), rows));
119.1093 +    }
119.1094 +
119.1095 +    ///Get a column (i.e a dual constraint) of the LP
119.1096 +
119.1097 +    ///\param c is the column to get
119.1098 +    ///\return the dual expression associated to the column
119.1099 +    DualExpr col(Col c) const {
119.1100 +      DualExpr e;
119.1101 +      _getColCoeffs(cols(id(c)), InsertIterator(e.comps, rows));
119.1102 +      return e;
119.1103 +    }
119.1104 +
119.1105 +    ///Add a new column to the LP
119.1106 +
119.1107 +    ///\param e is a dual linear expression (see \ref DualExpr)
119.1108 +    ///\param o is the corresponding component of the objective
119.1109 +    ///function. It is 0 by default.
119.1110 +    ///\return The created column.
119.1111 +    Col addCol(const DualExpr &e, Value o = 0) {
119.1112 +      Col c=addCol();
119.1113 +      col(c,e);
119.1114 +      objCoeff(c,o);
119.1115 +      return c;
119.1116 +    }
119.1117 +
119.1118 +    ///Add a new empty row (i.e a new constraint) to the LP
119.1119 +
119.1120 +    ///This function adds a new empty row (i.e a new constraint) to the LP.
119.1121 +    ///\return The created row
119.1122 +    Row addRow() { Row r; r._id = _addRowId(_addRow()); return r;}
119.1123 +
119.1124 +    ///\brief Add several new rows (i.e constraints) at once
119.1125 +    ///
119.1126 +    ///This magic function takes a container as its argument and fills
119.1127 +    ///its elements with new row (i.e. variables)
119.1128 +    ///\param t can be
119.1129 +    ///- a standard STL compatible iterable container with
119.1130 +    ///\ref Row as its \c values_type like
119.1131 +    ///\code
119.1132 +    ///std::vector<LpBase::Row>
119.1133 +    ///std::list<LpBase::Row>
119.1134 +    ///\endcode
119.1135 +    ///- a standard STL compatible iterable container with
119.1136 +    ///\ref Row as its \c mapped_type like
119.1137 +    ///\code
119.1138 +    ///std::map<AnyType,LpBase::Row>
119.1139 +    ///\endcode
119.1140 +    ///- an iterable lemon \ref concepts::WriteMap "write map" like
119.1141 +    ///\code
119.1142 +    ///ListGraph::NodeMap<LpBase::Row>
119.1143 +    ///ListGraph::ArcMap<LpBase::Row>
119.1144 +    ///\endcode
119.1145 +    ///\return The number of rows created.
119.1146 +#ifdef DOXYGEN
119.1147 +    template<class T>
119.1148 +    int addRowSet(T &t) { return 0;}
119.1149 +#else
119.1150 +    template<class T>
119.1151 +    typename enable_if<typename T::value_type::LpRow,int>::type
119.1152 +    addRowSet(T &t, dummy<0> = 0) {
119.1153 +      int s=0;
119.1154 +      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
119.1155 +      return s;
119.1156 +    }
119.1157 +    template<class T>
119.1158 +    typename enable_if<typename T::value_type::second_type::LpRow, int>::type
119.1159 +    addRowSet(T &t, dummy<1> = 1) {
119.1160 +      int s=0;
119.1161 +      for(typename T::iterator i=t.begin();i!=t.end();++i) {
119.1162 +        i->second=addRow();
119.1163 +        s++;
119.1164 +      }
119.1165 +      return s;
119.1166 +    }
119.1167 +    template<class T>
119.1168 +    typename enable_if<typename T::MapIt::Value::LpRow, int>::type
119.1169 +    addRowSet(T &t, dummy<2> = 2) {
119.1170 +      int s=0;
119.1171 +      for(typename T::MapIt i(t); i!=INVALID; ++i)
119.1172 +        {
119.1173 +          i.set(addRow());
119.1174 +          s++;
119.1175 +        }
119.1176 +      return s;
119.1177 +    }
119.1178 +#endif
119.1179 +
119.1180 +    ///Set a row (i.e a constraint) of the LP
119.1181 +
119.1182 +    ///\param r is the row to be modified
119.1183 +    ///\param l is lower bound (-\ref INF means no bound)
119.1184 +    ///\param e is a linear expression (see \ref Expr)
119.1185 +    ///\param u is the upper bound (\ref INF means no bound)
119.1186 +    void row(Row r, Value l, const Expr &e, Value u) {
119.1187 +      e.simplify();
119.1188 +      _setRowCoeffs(rows(id(r)), ExprIterator(e.comps.begin(), cols),
119.1189 +                    ExprIterator(e.comps.end(), cols));
119.1190 +      _setRowLowerBound(rows(id(r)),l - *e);
119.1191 +      _setRowUpperBound(rows(id(r)),u - *e);
119.1192 +    }
119.1193 +
119.1194 +    ///Set a row (i.e a constraint) of the LP
119.1195 +
119.1196 +    ///\param r is the row to be modified
119.1197 +    ///\param c is a linear expression (see \ref Constr)
119.1198 +    void row(Row r, const Constr &c) {
119.1199 +      row(r, c.lowerBounded()?c.lowerBound():-INF,
119.1200 +          c.expr(), c.upperBounded()?c.upperBound():INF);
119.1201 +    }
119.1202 +
119.1203 +
119.1204 +    ///Get a row (i.e a constraint) of the LP
119.1205 +
119.1206 +    ///\param r is the row to get
119.1207 +    ///\return the expression associated to the row
119.1208 +    Expr row(Row r) const {
119.1209 +      Expr e;
119.1210 +      _getRowCoeffs(rows(id(r)), InsertIterator(e.comps, cols));
119.1211 +      return e;
119.1212 +    }
119.1213 +
119.1214 +    ///Add a new row (i.e a new constraint) to the LP
119.1215 +
119.1216 +    ///\param l is the lower bound (-\ref INF means no bound)
119.1217 +    ///\param e is a linear expression (see \ref Expr)
119.1218 +    ///\param u is the upper bound (\ref INF means no bound)
119.1219 +    ///\return The created row.
119.1220 +    Row addRow(Value l,const Expr &e, Value u) {
119.1221 +      Row r;
119.1222 +      e.simplify();
119.1223 +      r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols),
119.1224 +                                ExprIterator(e.comps.end(), cols), u - *e));
119.1225 +      return r;
119.1226 +    }
119.1227 +
119.1228 +    ///Add a new row (i.e a new constraint) to the LP
119.1229 +
119.1230 +    ///\param c is a linear expression (see \ref Constr)
119.1231 +    ///\return The created row.
119.1232 +    Row addRow(const Constr &c) {
119.1233 +      Row r;
119.1234 +      c.expr().simplify();
119.1235 +      r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound():-INF, 
119.1236 +                                ExprIterator(c.expr().comps.begin(), cols),
119.1237 +                                ExprIterator(c.expr().comps.end(), cols),
119.1238 +                                c.upperBounded()?c.upperBound():INF));
119.1239 +      return r;
119.1240 +    }
119.1241 +    ///Erase a column (i.e a variable) from the LP
119.1242 +
119.1243 +    ///\param c is the column to be deleted
119.1244 +    void erase(Col c) {
119.1245 +      _eraseCol(cols(id(c)));
119.1246 +      _eraseColId(cols(id(c)));
119.1247 +    }
119.1248 +    ///Erase a row (i.e a constraint) from the LP
119.1249 +
119.1250 +    ///\param r is the row to be deleted
119.1251 +    void erase(Row r) {
119.1252 +      _eraseRow(rows(id(r)));
119.1253 +      _eraseRowId(rows(id(r)));
119.1254 +    }
119.1255 +
119.1256 +    /// Get the name of a column
119.1257 +
119.1258 +    ///\param c is the coresponding column
119.1259 +    ///\return The name of the colunm
119.1260 +    std::string colName(Col c) const {
119.1261 +      std::string name;
119.1262 +      _getColName(cols(id(c)), name);
119.1263 +      return name;
119.1264 +    }
119.1265 +
119.1266 +    /// Set the name of a column
119.1267 +
119.1268 +    ///\param c is the coresponding column
119.1269 +    ///\param name The name to be given
119.1270 +    void colName(Col c, const std::string& name) {
119.1271 +      _setColName(cols(id(c)), name);
119.1272 +    }
119.1273 +
119.1274 +    /// Get the column by its name
119.1275 +
119.1276 +    ///\param name The name of the column
119.1277 +    ///\return the proper column or \c INVALID
119.1278 +    Col colByName(const std::string& name) const {
119.1279 +      int k = _colByName(name);
119.1280 +      return k != -1 ? Col(cols[k]) : Col(INVALID);
119.1281 +    }
119.1282 +
119.1283 +    /// Get the name of a row
119.1284 +
119.1285 +    ///\param r is the coresponding row
119.1286 +    ///\return The name of the row
119.1287 +    std::string rowName(Row r) const {
119.1288 +      std::string name;
119.1289 +      _getRowName(rows(id(r)), name);
119.1290 +      return name;
119.1291 +    }
119.1292 +
119.1293 +    /// Set the name of a row
119.1294 +
119.1295 +    ///\param r is the coresponding row
119.1296 +    ///\param name The name to be given
119.1297 +    void rowName(Row r, const std::string& name) {
119.1298 +      _setRowName(rows(id(r)), name);
119.1299 +    }
119.1300 +
119.1301 +    /// Get the row by its name
119.1302 +
119.1303 +    ///\param name The name of the row
119.1304 +    ///\return the proper row or \c INVALID
119.1305 +    Row rowByName(const std::string& name) const {
119.1306 +      int k = _rowByName(name);
119.1307 +      return k != -1 ? Row(rows[k]) : Row(INVALID);
119.1308 +    }
119.1309 +
119.1310 +    /// Set an element of the coefficient matrix of the LP
119.1311 +
119.1312 +    ///\param r is the row of the element to be modified
119.1313 +    ///\param c is the column of the element to be modified
119.1314 +    ///\param val is the new value of the coefficient
119.1315 +    void coeff(Row r, Col c, Value val) {
119.1316 +      _setCoeff(rows(id(r)),cols(id(c)), val);
119.1317 +    }
119.1318 +
119.1319 +    /// Get an element of the coefficient matrix of the LP
119.1320 +
119.1321 +    ///\param r is the row of the element
119.1322 +    ///\param c is the column of the element
119.1323 +    ///\return the corresponding coefficient
119.1324 +    Value coeff(Row r, Col c) const {
119.1325 +      return _getCoeff(rows(id(r)),cols(id(c)));
119.1326 +    }
119.1327 +
119.1328 +    /// Set the lower bound of a column (i.e a variable)
119.1329 +
119.1330 +    /// The lower bound of a variable (column) has to be given by an
119.1331 +    /// extended number of type Value, i.e. a finite number of type
119.1332 +    /// Value or -\ref INF.
119.1333 +    void colLowerBound(Col c, Value value) {
119.1334 +      _setColLowerBound(cols(id(c)),value);
119.1335 +    }
119.1336 +
119.1337 +    /// Get the lower bound of a column (i.e a variable)
119.1338 +
119.1339 +    /// This function returns the lower bound for column (variable) \c c
119.1340 +    /// (this might be -\ref INF as well).
119.1341 +    ///\return The lower bound for column \c c
119.1342 +    Value colLowerBound(Col c) const {
119.1343 +      return _getColLowerBound(cols(id(c)));
119.1344 +    }
119.1345 +
119.1346 +    ///\brief Set the lower bound of  several columns
119.1347 +    ///(i.e variables) at once
119.1348 +    ///
119.1349 +    ///This magic function takes a container as its argument
119.1350 +    ///and applies the function on all of its elements.
119.1351 +    ///The lower bound of a variable (column) has to be given by an
119.1352 +    ///extended number of type Value, i.e. a finite number of type
119.1353 +    ///Value or -\ref INF.
119.1354 +#ifdef DOXYGEN
119.1355 +    template<class T>
119.1356 +    void colLowerBound(T &t, Value value) { return 0;}
119.1357 +#else
119.1358 +    template<class T>
119.1359 +    typename enable_if<typename T::value_type::LpCol,void>::type
119.1360 +    colLowerBound(T &t, Value value,dummy<0> = 0) {
119.1361 +      for(typename T::iterator i=t.begin();i!=t.end();++i) {
119.1362 +        colLowerBound(*i, value);
119.1363 +      }
119.1364 +    }
119.1365 +    template<class T>
119.1366 +    typename enable_if<typename T::value_type::second_type::LpCol,
119.1367 +                       void>::type
119.1368 +    colLowerBound(T &t, Value value,dummy<1> = 1) {
119.1369 +      for(typename T::iterator i=t.begin();i!=t.end();++i) {
119.1370 +        colLowerBound(i->second, value);
119.1371 +      }
119.1372 +    }
119.1373 +    template<class T>
119.1374 +    typename enable_if<typename T::MapIt::Value::LpCol,
119.1375 +                       void>::type
119.1376 +    colLowerBound(T &t, Value value,dummy<2> = 2) {
119.1377 +      for(typename T::MapIt i(t); i!=INVALID; ++i){
119.1378 +        colLowerBound(*i, value);
119.1379 +      }
119.1380 +    }
119.1381 +#endif
119.1382 +
119.1383 +    /// Set the upper bound of a column (i.e a variable)
119.1384 +
119.1385 +    /// The upper bound of a variable (column) has to be given by an
119.1386 +    /// extended number of type Value, i.e. a finite number of type
119.1387 +    /// Value or \ref INF.
119.1388 +    void colUpperBound(Col c, Value value) {
119.1389 +      _setColUpperBound(cols(id(c)),value);
119.1390 +    };
119.1391 +
119.1392 +    /// Get the upper bound of a column (i.e a variable)
119.1393 +
119.1394 +    /// This function returns the upper bound for column (variable) \c c
119.1395 +    /// (this might be \ref INF as well).
119.1396 +    /// \return The upper bound for column \c c
119.1397 +    Value colUpperBound(Col c) const {
119.1398 +      return _getColUpperBound(cols(id(c)));
119.1399 +    }
119.1400 +
119.1401 +    ///\brief Set the upper bound of  several columns
119.1402 +    ///(i.e variables) at once
119.1403 +    ///
119.1404 +    ///This magic function takes a container as its argument
119.1405 +    ///and applies the function on all of its elements.
119.1406 +    ///The upper bound of a variable (column) has to be given by an
119.1407 +    ///extended number of type Value, i.e. a finite number of type
119.1408 +    ///Value or \ref INF.
119.1409 +#ifdef DOXYGEN
119.1410 +    template<class T>
119.1411 +    void colUpperBound(T &t, Value value) { return 0;}
119.1412 +#else
119.1413 +    template<class T1>
119.1414 +    typename enable_if<typename T1::value_type::LpCol,void>::type
119.1415 +    colUpperBound(T1 &t, Value value,dummy<0> = 0) {
119.1416 +      for(typename T1::iterator i=t.begin();i!=t.end();++i) {
119.1417 +        colUpperBound(*i, value);
119.1418 +      }
119.1419 +    }
119.1420 +    template<class T1>
119.1421 +    typename enable_if<typename T1::value_type::second_type::LpCol,
119.1422 +                       void>::type
119.1423 +    colUpperBound(T1 &t, Value value,dummy<1> = 1) {
119.1424 +      for(typename T1::iterator i=t.begin();i!=t.end();++i) {
119.1425 +        colUpperBound(i->second, value);
119.1426 +      }
119.1427 +    }
119.1428 +    template<class T1>
119.1429 +    typename enable_if<typename T1::MapIt::Value::LpCol,
119.1430 +                       void>::type
119.1431 +    colUpperBound(T1 &t, Value value,dummy<2> = 2) {
119.1432 +      for(typename T1::MapIt i(t); i!=INVALID; ++i){
119.1433 +        colUpperBound(*i, value);
119.1434 +      }
119.1435 +    }
119.1436 +#endif
119.1437 +
119.1438 +    /// Set the lower and the upper bounds of a column (i.e a variable)
119.1439 +
119.1440 +    /// The lower and the upper bounds of
119.1441 +    /// a variable (column) have to be given by an
119.1442 +    /// extended number of type Value, i.e. a finite number of type
119.1443 +    /// Value, -\ref INF or \ref INF.
119.1444 +    void colBounds(Col c, Value lower, Value upper) {
119.1445 +      _setColLowerBound(cols(id(c)),lower);
119.1446 +      _setColUpperBound(cols(id(c)),upper);
119.1447 +    }
119.1448 +
119.1449 +    ///\brief Set the lower and the upper bound of several columns
119.1450 +    ///(i.e variables) at once
119.1451 +    ///
119.1452 +    ///This magic function takes a container as its argument
119.1453 +    ///and applies the function on all of its elements.
119.1454 +    /// The lower and the upper bounds of
119.1455 +    /// a variable (column) have to be given by an
119.1456 +    /// extended number of type Value, i.e. a finite number of type
119.1457 +    /// Value, -\ref INF or \ref INF.
119.1458 +#ifdef DOXYGEN
119.1459 +    template<class T>
119.1460 +    void colBounds(T &t, Value lower, Value upper) { return 0;}
119.1461 +#else
119.1462 +    template<class T2>
119.1463 +    typename enable_if<typename T2::value_type::LpCol,void>::type
119.1464 +    colBounds(T2 &t, Value lower, Value upper,dummy<0> = 0) {
119.1465 +      for(typename T2::iterator i=t.begin();i!=t.end();++i) {
119.1466 +        colBounds(*i, lower, upper);
119.1467 +      }
119.1468 +    }
119.1469 +    template<class T2>
119.1470 +    typename enable_if<typename T2::value_type::second_type::LpCol, void>::type
119.1471 +    colBounds(T2 &t, Value lower, Value upper,dummy<1> = 1) {
119.1472 +      for(typename T2::iterator i=t.begin();i!=t.end();++i) {
119.1473 +        colBounds(i->second, lower, upper);
119.1474 +      }
119.1475 +    }
119.1476 +    template<class T2>
119.1477 +    typename enable_if<typename T2::MapIt::Value::LpCol, void>::type
119.1478 +    colBounds(T2 &t, Value lower, Value upper,dummy<2> = 2) {
119.1479 +      for(typename T2::MapIt i(t); i!=INVALID; ++i){
119.1480 +        colBounds(*i, lower, upper);
119.1481 +      }
119.1482 +    }
119.1483 +#endif
119.1484 +
119.1485 +    /// Set the lower bound of a row (i.e a constraint)
119.1486 +
119.1487 +    /// The lower bound of a constraint (row) has to be given by an
119.1488 +    /// extended number of type Value, i.e. a finite number of type
119.1489 +    /// Value or -\ref INF.
119.1490 +    void rowLowerBound(Row r, Value value) {
119.1491 +      _setRowLowerBound(rows(id(r)),value);
119.1492 +    }
119.1493 +
119.1494 +    /// Get the lower bound of a row (i.e a constraint)
119.1495 +
119.1496 +    /// This function returns the lower bound for row (constraint) \c c
119.1497 +    /// (this might be -\ref INF as well).
119.1498 +    ///\return The lower bound for row \c r
119.1499 +    Value rowLowerBound(Row r) const {
119.1500 +      return _getRowLowerBound(rows(id(r)));
119.1501 +    }
119.1502 +
119.1503 +    /// Set the upper bound of a row (i.e a constraint)
119.1504 +
119.1505 +    /// The upper bound of a constraint (row) has to be given by an
119.1506 +    /// extended number of type Value, i.e. a finite number of type
119.1507 +    /// Value or -\ref INF.
119.1508 +    void rowUpperBound(Row r, Value value) {
119.1509 +      _setRowUpperBound(rows(id(r)),value);
119.1510 +    }
119.1511 +
119.1512 +    /// Get the upper bound of a row (i.e a constraint)
119.1513 +
119.1514 +    /// This function returns the upper bound for row (constraint) \c c
119.1515 +    /// (this might be -\ref INF as well).
119.1516 +    ///\return The upper bound for row \c r
119.1517 +    Value rowUpperBound(Row r) const {
119.1518 +      return _getRowUpperBound(rows(id(r)));
119.1519 +    }
119.1520 +
119.1521 +    ///Set an element of the objective function
119.1522 +    void objCoeff(Col c, Value v) {_setObjCoeff(cols(id(c)),v); };
119.1523 +
119.1524 +    ///Get an element of the objective function
119.1525 +    Value objCoeff(Col c) const { return _getObjCoeff(cols(id(c))); };
119.1526 +
119.1527 +    ///Set the objective function
119.1528 +
119.1529 +    ///\param e is a linear expression of type \ref Expr.
119.1530 +    ///
119.1531 +    void obj(const Expr& e) {
119.1532 +      _setObjCoeffs(ExprIterator(e.comps.begin(), cols),
119.1533 +                    ExprIterator(e.comps.end(), cols));
119.1534 +      obj_const_comp = *e;
119.1535 +    }
119.1536 +
119.1537 +    ///Get the objective function
119.1538 +
119.1539 +    ///\return the objective function as a linear expression of type
119.1540 +    ///Expr.
119.1541 +    Expr obj() const {
119.1542 +      Expr e;
119.1543 +      _getObjCoeffs(InsertIterator(e.comps, cols));
119.1544 +      *e = obj_const_comp;
119.1545 +      return e;
119.1546 +    }
119.1547 +
119.1548 +
119.1549 +    ///Set the direction of optimization
119.1550 +    void sense(Sense sense) { _setSense(sense); }
119.1551 +
119.1552 +    ///Query the direction of the optimization
119.1553 +    Sense sense() const {return _getSense(); }
119.1554 +
119.1555 +    ///Set the sense to maximization
119.1556 +    void max() { _setSense(MAX); }
119.1557 +
119.1558 +    ///Set the sense to maximization
119.1559 +    void min() { _setSense(MIN); }
119.1560 +
119.1561 +    ///Clears the problem
119.1562 +    void clear() { _clear(); }
119.1563 +
119.1564 +    /// Sets the message level of the solver
119.1565 +    void messageLevel(MessageLevel level) { _messageLevel(level); }
119.1566 +
119.1567 +    ///@}
119.1568 +
119.1569 +  };
119.1570 +
119.1571 +  /// Addition
119.1572 +
119.1573 +  ///\relates LpBase::Expr
119.1574 +  ///
119.1575 +  inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) {
119.1576 +    LpBase::Expr tmp(a);
119.1577 +    tmp+=b;
119.1578 +    return tmp;
119.1579 +  }
119.1580 +  ///Substraction
119.1581 +
119.1582 +  ///\relates LpBase::Expr
119.1583 +  ///
119.1584 +  inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) {
119.1585 +    LpBase::Expr tmp(a);
119.1586 +    tmp-=b;
119.1587 +    return tmp;
119.1588 +  }
119.1589 +  ///Multiply with constant
119.1590 +
119.1591 +  ///\relates LpBase::Expr
119.1592 +  ///
119.1593 +  inline LpBase::Expr operator*(const LpBase::Expr &a, const LpBase::Value &b) {
119.1594 +    LpBase::Expr tmp(a);
119.1595 +    tmp*=b;
119.1596 +    return tmp;
119.1597 +  }
119.1598 +
119.1599 +  ///Multiply with constant
119.1600 +
119.1601 +  ///\relates LpBase::Expr
119.1602 +  ///
119.1603 +  inline LpBase::Expr operator*(const LpBase::Value &a, const LpBase::Expr &b) {
119.1604 +    LpBase::Expr tmp(b);
119.1605 +    tmp*=a;
119.1606 +    return tmp;
119.1607 +  }
119.1608 +  ///Divide with constant
119.1609 +
119.1610 +  ///\relates LpBase::Expr
119.1611 +  ///
119.1612 +  inline LpBase::Expr operator/(const LpBase::Expr &a, const LpBase::Value &b) {
119.1613 +    LpBase::Expr tmp(a);
119.1614 +    tmp/=b;
119.1615 +    return tmp;
119.1616 +  }
119.1617 +
119.1618 +  ///Create constraint
119.1619 +
119.1620 +  ///\relates LpBase::Constr
119.1621 +  ///
119.1622 +  inline LpBase::Constr operator<=(const LpBase::Expr &e,
119.1623 +                                   const LpBase::Expr &f) {
119.1624 +    return LpBase::Constr(0, f - e, LpBase::INF);
119.1625 +  }
119.1626 +
119.1627 +  ///Create constraint
119.1628 +
119.1629 +  ///\relates LpBase::Constr
119.1630 +  ///
119.1631 +  inline LpBase::Constr operator<=(const LpBase::Value &e,
119.1632 +                                   const LpBase::Expr &f) {
119.1633 +    return LpBase::Constr(e, f, LpBase::NaN);
119.1634 +  }
119.1635 +
119.1636 +  ///Create constraint
119.1637 +
119.1638 +  ///\relates LpBase::Constr
119.1639 +  ///
119.1640 +  inline LpBase::Constr operator<=(const LpBase::Expr &e,
119.1641 +                                   const LpBase::Value &f) {
119.1642 +    return LpBase::Constr(- LpBase::INF, e, f);
119.1643 +  }
119.1644 +
119.1645 +  ///Create constraint
119.1646 +
119.1647 +  ///\relates LpBase::Constr
119.1648 +  ///
119.1649 +  inline LpBase::Constr operator>=(const LpBase::Expr &e,
119.1650 +                                   const LpBase::Expr &f) {
119.1651 +    return LpBase::Constr(0, e - f, LpBase::INF);
119.1652 +  }
119.1653 +
119.1654 +
119.1655 +  ///Create constraint
119.1656 +
119.1657 +  ///\relates LpBase::Constr
119.1658 +  ///
119.1659 +  inline LpBase::Constr operator>=(const LpBase::Value &e,
119.1660 +                                   const LpBase::Expr &f) {
119.1661 +    return LpBase::Constr(LpBase::NaN, f, e);
119.1662 +  }
119.1663 +
119.1664 +
119.1665 +  ///Create constraint
119.1666 +
119.1667 +  ///\relates LpBase::Constr
119.1668 +  ///
119.1669 +  inline LpBase::Constr operator>=(const LpBase::Expr &e,
119.1670 +                                   const LpBase::Value &f) {
119.1671 +    return LpBase::Constr(f, e, LpBase::INF);
119.1672 +  }
119.1673 +
119.1674 +  ///Create constraint
119.1675 +
119.1676 +  ///\relates LpBase::Constr
119.1677 +  ///
119.1678 +  inline LpBase::Constr operator==(const LpBase::Expr &e,
119.1679 +                                   const LpBase::Value &f) {
119.1680 +    return LpBase::Constr(f, e, f);
119.1681 +  }
119.1682 +
119.1683 +  ///Create constraint
119.1684 +
119.1685 +  ///\relates LpBase::Constr
119.1686 +  ///
119.1687 +  inline LpBase::Constr operator==(const LpBase::Expr &e,
119.1688 +                                   const LpBase::Expr &f) {
119.1689 +    return LpBase::Constr(0, f - e, 0);
119.1690 +  }
119.1691 +
119.1692 +  ///Create constraint
119.1693 +
119.1694 +  ///\relates LpBase::Constr
119.1695 +  ///
119.1696 +  inline LpBase::Constr operator<=(const LpBase::Value &n,
119.1697 +                                   const LpBase::Constr &c) {
119.1698 +    LpBase::Constr tmp(c);
119.1699 +    LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
119.1700 +    tmp.lowerBound()=n;
119.1701 +    return tmp;
119.1702 +  }
119.1703 +  ///Create constraint
119.1704 +
119.1705 +  ///\relates LpBase::Constr
119.1706 +  ///
119.1707 +  inline LpBase::Constr operator<=(const LpBase::Constr &c,
119.1708 +                                   const LpBase::Value &n)
119.1709 +  {
119.1710 +    LpBase::Constr tmp(c);
119.1711 +    LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
119.1712 +    tmp.upperBound()=n;
119.1713 +    return tmp;
119.1714 +  }
119.1715 +
119.1716 +  ///Create constraint
119.1717 +
119.1718 +  ///\relates LpBase::Constr
119.1719 +  ///
119.1720 +  inline LpBase::Constr operator>=(const LpBase::Value &n,
119.1721 +                                   const LpBase::Constr &c) {
119.1722 +    LpBase::Constr tmp(c);
119.1723 +    LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
119.1724 +    tmp.upperBound()=n;
119.1725 +    return tmp;
119.1726 +  }
119.1727 +  ///Create constraint
119.1728 +
119.1729 +  ///\relates LpBase::Constr
119.1730 +  ///
119.1731 +  inline LpBase::Constr operator>=(const LpBase::Constr &c,
119.1732 +                                   const LpBase::Value &n)
119.1733 +  {
119.1734 +    LpBase::Constr tmp(c);
119.1735 +    LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
119.1736 +    tmp.lowerBound()=n;
119.1737 +    return tmp;
119.1738 +  }
119.1739 +
119.1740 +  ///Addition
119.1741 +
119.1742 +  ///\relates LpBase::DualExpr
119.1743 +  ///
119.1744 +  inline LpBase::DualExpr operator+(const LpBase::DualExpr &a,
119.1745 +                                    const LpBase::DualExpr &b) {
119.1746 +    LpBase::DualExpr tmp(a);
119.1747 +    tmp+=b;
119.1748 +    return tmp;
119.1749 +  }
119.1750 +  ///Substraction
119.1751 +
119.1752 +  ///\relates LpBase::DualExpr
119.1753 +  ///
119.1754 +  inline LpBase::DualExpr operator-(const LpBase::DualExpr &a,
119.1755 +                                    const LpBase::DualExpr &b) {
119.1756 +    LpBase::DualExpr tmp(a);
119.1757 +    tmp-=b;
119.1758 +    return tmp;
119.1759 +  }
119.1760 +  ///Multiply with constant
119.1761 +
119.1762 +  ///\relates LpBase::DualExpr
119.1763 +  ///
119.1764 +  inline LpBase::DualExpr operator*(const LpBase::DualExpr &a,
119.1765 +                                    const LpBase::Value &b) {
119.1766 +    LpBase::DualExpr tmp(a);
119.1767 +    tmp*=b;
119.1768 +    return tmp;
119.1769 +  }
119.1770 +
119.1771 +  ///Multiply with constant
119.1772 +
119.1773 +  ///\relates LpBase::DualExpr
119.1774 +  ///
119.1775 +  inline LpBase::DualExpr operator*(const LpBase::Value &a,
119.1776 +                                    const LpBase::DualExpr &b) {
119.1777 +    LpBase::DualExpr tmp(b);
119.1778 +    tmp*=a;
119.1779 +    return tmp;
119.1780 +  }
119.1781 +  ///Divide with constant
119.1782 +
119.1783 +  ///\relates LpBase::DualExpr
119.1784 +  ///
119.1785 +  inline LpBase::DualExpr operator/(const LpBase::DualExpr &a,
119.1786 +                                    const LpBase::Value &b) {
119.1787 +    LpBase::DualExpr tmp(a);
119.1788 +    tmp/=b;
119.1789 +    return tmp;
119.1790 +  }
119.1791 +
119.1792 +  /// \ingroup lp_group
119.1793 +  ///
119.1794 +  /// \brief Common base class for LP solvers
119.1795 +  ///
119.1796 +  /// This class is an abstract base class for LP solvers. This class
119.1797 +  /// provides a full interface for set and modify an LP problem,
119.1798 +  /// solve it and retrieve the solution. You can use one of the
119.1799 +  /// descendants as a concrete implementation, or the \c Lp
119.1800 +  /// default LP solver. However, if you would like to handle LP
119.1801 +  /// solvers as reference or pointer in a generic way, you can use
119.1802 +  /// this class directly.
119.1803 +  class LpSolver : virtual public LpBase {
119.1804 +  public:
119.1805 +
119.1806 +    /// The problem types for primal and dual problems
119.1807 +    enum ProblemType {
119.1808 +      /// = 0. Feasible solution hasn't been found (but may exist).
119.1809 +      UNDEFINED = 0,
119.1810 +      /// = 1. The problem has no feasible solution.
119.1811 +      INFEASIBLE = 1,
119.1812 +      /// = 2. Feasible solution found.
119.1813 +      FEASIBLE = 2,
119.1814 +      /// = 3. Optimal solution exists and found.
119.1815 +      OPTIMAL = 3,
119.1816 +      /// = 4. The cost function is unbounded.
119.1817 +      UNBOUNDED = 4
119.1818 +    };
119.1819 +
119.1820 +    ///The basis status of variables
119.1821 +    enum VarStatus {
119.1822 +      /// The variable is in the basis
119.1823 +      BASIC, 
119.1824 +      /// The variable is free, but not basic
119.1825 +      FREE,
119.1826 +      /// The variable has active lower bound 
119.1827 +      LOWER,
119.1828 +      /// The variable has active upper bound
119.1829 +      UPPER,
119.1830 +      /// The variable is non-basic and fixed
119.1831 +      FIXED
119.1832 +    };
119.1833 +
119.1834 +  protected:
119.1835 +
119.1836 +    virtual SolveExitStatus _solve() = 0;
119.1837 +
119.1838 +    virtual Value _getPrimal(int i) const = 0;
119.1839 +    virtual Value _getDual(int i) const = 0;
119.1840 +
119.1841 +    virtual Value _getPrimalRay(int i) const = 0;
119.1842 +    virtual Value _getDualRay(int i) const = 0;
119.1843 +
119.1844 +    virtual Value _getPrimalValue() const = 0;
119.1845 +
119.1846 +    virtual VarStatus _getColStatus(int i) const = 0;
119.1847 +    virtual VarStatus _getRowStatus(int i) const = 0;
119.1848 +
119.1849 +    virtual ProblemType _getPrimalType() const = 0;
119.1850 +    virtual ProblemType _getDualType() const = 0;
119.1851 +
119.1852 +  public:
119.1853 +
119.1854 +    ///Allocate a new LP problem instance
119.1855 +    virtual LpSolver* newSolver() const = 0;
119.1856 +    ///Make a copy of the LP problem
119.1857 +    virtual LpSolver* cloneSolver() const = 0;
119.1858 +
119.1859 +    ///\name Solve the LP
119.1860 +
119.1861 +    ///@{
119.1862 +
119.1863 +    ///\e Solve the LP problem at hand
119.1864 +    ///
119.1865 +    ///\return The result of the optimization procedure. Possible
119.1866 +    ///values and their meanings can be found in the documentation of
119.1867 +    ///\ref SolveExitStatus.
119.1868 +    SolveExitStatus solve() { return _solve(); }
119.1869 +
119.1870 +    ///@}
119.1871 +
119.1872 +    ///\name Obtain the Solution
119.1873 +
119.1874 +    ///@{
119.1875 +
119.1876 +    /// The type of the primal problem
119.1877 +    ProblemType primalType() const {
119.1878 +      return _getPrimalType();
119.1879 +    }
119.1880 +
119.1881 +    /// The type of the dual problem
119.1882 +    ProblemType dualType() const {
119.1883 +      return _getDualType();
119.1884 +    }
119.1885 +
119.1886 +    /// Return the primal value of the column
119.1887 +
119.1888 +    /// Return the primal value of the column.
119.1889 +    /// \pre The problem is solved.
119.1890 +    Value primal(Col c) const { return _getPrimal(cols(id(c))); }
119.1891 +
119.1892 +    /// Return the primal value of the expression
119.1893 +
119.1894 +    /// Return the primal value of the expression, i.e. the dot
119.1895 +    /// product of the primal solution and the expression.
119.1896 +    /// \pre The problem is solved.
119.1897 +    Value primal(const Expr& e) const {
119.1898 +      double res = *e;
119.1899 +      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
119.1900 +        res += *c * primal(c);
119.1901 +      }
119.1902 +      return res;
119.1903 +    }
119.1904 +    /// Returns a component of the primal ray
119.1905 +    
119.1906 +    /// The primal ray is solution of the modified primal problem,
119.1907 +    /// where we change each finite bound to 0, and we looking for a
119.1908 +    /// negative objective value in case of minimization, and positive
119.1909 +    /// objective value for maximization. If there is such solution,
119.1910 +    /// that proofs the unsolvability of the dual problem, and if a
119.1911 +    /// feasible primal solution exists, then the unboundness of
119.1912 +    /// primal problem.
119.1913 +    ///
119.1914 +    /// \pre The problem is solved and the dual problem is infeasible.
119.1915 +    /// \note Some solvers does not provide primal ray calculation
119.1916 +    /// functions.
119.1917 +    Value primalRay(Col c) const { return _getPrimalRay(cols(id(c))); }
119.1918 +
119.1919 +    /// Return the dual value of the row
119.1920 +
119.1921 +    /// Return the dual value of the row.
119.1922 +    /// \pre The problem is solved.
119.1923 +    Value dual(Row r) const { return _getDual(rows(id(r))); }
119.1924 +
119.1925 +    /// Return the dual value of the dual expression
119.1926 +
119.1927 +    /// Return the dual value of the dual expression, i.e. the dot
119.1928 +    /// product of the dual solution and the dual expression.
119.1929 +    /// \pre The problem is solved.
119.1930 +    Value dual(const DualExpr& e) const {
119.1931 +      double res = 0.0;
119.1932 +      for (DualExpr::ConstCoeffIt r(e); r != INVALID; ++r) {
119.1933 +        res += *r * dual(r);
119.1934 +      }
119.1935 +      return res;
119.1936 +    }
119.1937 +
119.1938 +    /// Returns a component of the dual ray
119.1939 +    
119.1940 +    /// The dual ray is solution of the modified primal problem, where
119.1941 +    /// we change each finite bound to 0 (i.e. the objective function
119.1942 +    /// coefficients in the primal problem), and we looking for a
119.1943 +    /// ositive objective value. If there is such solution, that
119.1944 +    /// proofs the unsolvability of the primal problem, and if a
119.1945 +    /// feasible dual solution exists, then the unboundness of
119.1946 +    /// dual problem.
119.1947 +    ///
119.1948 +    /// \pre The problem is solved and the primal problem is infeasible.
119.1949 +    /// \note Some solvers does not provide dual ray calculation
119.1950 +    /// functions.
119.1951 +    Value dualRay(Row r) const { return _getDualRay(rows(id(r))); }
119.1952 +
119.1953 +    /// Return the basis status of the column
119.1954 +
119.1955 +    /// \see VarStatus
119.1956 +    VarStatus colStatus(Col c) const { return _getColStatus(cols(id(c))); }
119.1957 +
119.1958 +    /// Return the basis status of the row
119.1959 +
119.1960 +    /// \see VarStatus
119.1961 +    VarStatus rowStatus(Row r) const { return _getRowStatus(rows(id(r))); }
119.1962 +
119.1963 +    ///The value of the objective function
119.1964 +
119.1965 +    ///\return
119.1966 +    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
119.1967 +    /// of the primal problem, depending on whether we minimize or maximize.
119.1968 +    ///- \ref NaN if no primal solution is found.
119.1969 +    ///- The (finite) objective value if an optimal solution is found.
119.1970 +    Value primal() const { return _getPrimalValue()+obj_const_comp;}
119.1971 +    ///@}
119.1972 +
119.1973 +  protected:
119.1974 +
119.1975 +  };
119.1976 +
119.1977 +
119.1978 +  /// \ingroup lp_group
119.1979 +  ///
119.1980 +  /// \brief Common base class for MIP solvers
119.1981 +  ///
119.1982 +  /// This class is an abstract base class for MIP solvers. This class
119.1983 +  /// provides a full interface for set and modify an MIP problem,
119.1984 +  /// solve it and retrieve the solution. You can use one of the
119.1985 +  /// descendants as a concrete implementation, or the \c Lp
119.1986 +  /// default MIP solver. However, if you would like to handle MIP
119.1987 +  /// solvers as reference or pointer in a generic way, you can use
119.1988 +  /// this class directly.
119.1989 +  class MipSolver : virtual public LpBase {
119.1990 +  public:
119.1991 +
119.1992 +    /// The problem types for MIP problems
119.1993 +    enum ProblemType {
119.1994 +      /// = 0. Feasible solution hasn't been found (but may exist).
119.1995 +      UNDEFINED = 0,
119.1996 +      /// = 1. The problem has no feasible solution.
119.1997 +      INFEASIBLE = 1,
119.1998 +      /// = 2. Feasible solution found.
119.1999 +      FEASIBLE = 2,
119.2000 +      /// = 3. Optimal solution exists and found.
119.2001 +      OPTIMAL = 3,
119.2002 +      /// = 4. The cost function is unbounded.
119.2003 +      ///The Mip or at least the relaxed problem is unbounded.
119.2004 +      UNBOUNDED = 4
119.2005 +    };
119.2006 +
119.2007 +    ///Allocate a new MIP problem instance
119.2008 +    virtual MipSolver* newSolver() const = 0;
119.2009 +    ///Make a copy of the MIP problem
119.2010 +    virtual MipSolver* cloneSolver() const = 0;
119.2011 +
119.2012 +    ///\name Solve the MIP
119.2013 +
119.2014 +    ///@{
119.2015 +
119.2016 +    /// Solve the MIP problem at hand
119.2017 +    ///
119.2018 +    ///\return The result of the optimization procedure. Possible
119.2019 +    ///values and their meanings can be found in the documentation of
119.2020 +    ///\ref SolveExitStatus.
119.2021 +    SolveExitStatus solve() { return _solve(); }
119.2022 +
119.2023 +    ///@}
119.2024 +
119.2025 +    ///\name Set Column Type
119.2026 +    ///@{
119.2027 +
119.2028 +    ///Possible variable (column) types (e.g. real, integer, binary etc.)
119.2029 +    enum ColTypes {
119.2030 +      /// = 0. Continuous variable (default).
119.2031 +      REAL = 0,
119.2032 +      /// = 1. Integer variable.
119.2033 +      INTEGER = 1
119.2034 +    };
119.2035 +
119.2036 +    ///Sets the type of the given column to the given type
119.2037 +
119.2038 +    ///Sets the type of the given column to the given type.
119.2039 +    ///
119.2040 +    void colType(Col c, ColTypes col_type) {
119.2041 +      _setColType(cols(id(c)),col_type);
119.2042 +    }
119.2043 +
119.2044 +    ///Gives back the type of the column.
119.2045 +
119.2046 +    ///Gives back the type of the column.
119.2047 +    ///
119.2048 +    ColTypes colType(Col c) const {
119.2049 +      return _getColType(cols(id(c)));
119.2050 +    }
119.2051 +    ///@}
119.2052 +
119.2053 +    ///\name Obtain the Solution
119.2054 +
119.2055 +    ///@{
119.2056 +
119.2057 +    /// The type of the MIP problem
119.2058 +    ProblemType type() const {
119.2059 +      return _getType();
119.2060 +    }
119.2061 +
119.2062 +    /// Return the value of the row in the solution
119.2063 +
119.2064 +    ///  Return the value of the row in the solution.
119.2065 +    /// \pre The problem is solved.
119.2066 +    Value sol(Col c) const { return _getSol(cols(id(c))); }
119.2067 +
119.2068 +    /// Return the value of the expression in the solution
119.2069 +
119.2070 +    /// Return the value of the expression in the solution, i.e. the
119.2071 +    /// dot product of the solution and the expression.
119.2072 +    /// \pre The problem is solved.
119.2073 +    Value sol(const Expr& e) const {
119.2074 +      double res = *e;
119.2075 +      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
119.2076 +        res += *c * sol(c);
119.2077 +      }
119.2078 +      return res;
119.2079 +    }
119.2080 +    ///The value of the objective function
119.2081 +    
119.2082 +    ///\return
119.2083 +    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
119.2084 +    /// of the problem, depending on whether we minimize or maximize.
119.2085 +    ///- \ref NaN if no primal solution is found.
119.2086 +    ///- The (finite) objective value if an optimal solution is found.
119.2087 +    Value solValue() const { return _getSolValue()+obj_const_comp;}
119.2088 +    ///@}
119.2089 +
119.2090 +  protected:
119.2091 +
119.2092 +    virtual SolveExitStatus _solve() = 0;
119.2093 +    virtual ColTypes _getColType(int col) const = 0;
119.2094 +    virtual void _setColType(int col, ColTypes col_type) = 0;
119.2095 +    virtual ProblemType _getType() const = 0;
119.2096 +    virtual Value _getSol(int i) const = 0;
119.2097 +    virtual Value _getSolValue() const = 0;
119.2098 +
119.2099 +  };
119.2100 +
119.2101 +
119.2102 +
119.2103 +} //namespace lemon
119.2104 +
119.2105 +#endif //LEMON_LP_BASE_H
   120.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   120.2 +++ b/lemon/lp_skeleton.cc	Thu Nov 05 15:50:01 2009 +0100
   120.3 @@ -0,0 +1,141 @@
   120.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   120.5 + *
   120.6 + * This file is a part of LEMON, a generic C++ optimization library.
   120.7 + *
   120.8 + * Copyright (C) 2003-2008
   120.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  120.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  120.11 + *
  120.12 + * Permission to use, modify and distribute this software is granted
  120.13 + * provided that this copyright notice appears in all copies. For
  120.14 + * precise terms see the accompanying LICENSE file.
  120.15 + *
  120.16 + * This software is provided "AS IS" with no warranty of any kind,
  120.17 + * express or implied, and with no claim as to its suitability for any
  120.18 + * purpose.
  120.19 + *
  120.20 + */
  120.21 +
  120.22 +#include <lemon/lp_skeleton.h>
  120.23 +
  120.24 +///\file
  120.25 +///\brief A skeleton file to implement LP solver interfaces
  120.26 +namespace lemon {
  120.27 +
  120.28 +  int SkeletonSolverBase::_addCol()
  120.29 +  {
  120.30 +    return ++col_num;
  120.31 +  }
  120.32 +
  120.33 +  int SkeletonSolverBase::_addRow()
  120.34 +  {
  120.35 +    return ++row_num;
  120.36 +  }
  120.37 +
  120.38 +  int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
  120.39 +  {
  120.40 +    return ++row_num;
  120.41 +  }
  120.42 +
  120.43 +  void SkeletonSolverBase::_eraseCol(int) {}
  120.44 +  void SkeletonSolverBase::_eraseRow(int) {}
  120.45 +
  120.46 +  void SkeletonSolverBase::_getColName(int, std::string &) const {}
  120.47 +  void SkeletonSolverBase::_setColName(int, const std::string &) {}
  120.48 +  int SkeletonSolverBase::_colByName(const std::string&) const { return -1; }
  120.49 +
  120.50 +  void SkeletonSolverBase::_getRowName(int, std::string &) const {}
  120.51 +  void SkeletonSolverBase::_setRowName(int, const std::string &) {}
  120.52 +  int SkeletonSolverBase::_rowByName(const std::string&) const { return -1; }
  120.53 +
  120.54 +  void SkeletonSolverBase::_setRowCoeffs(int, ExprIterator, ExprIterator) {}
  120.55 +  void SkeletonSolverBase::_getRowCoeffs(int, InsertIterator) const {}
  120.56 +
  120.57 +  void SkeletonSolverBase::_setColCoeffs(int, ExprIterator, ExprIterator) {}
  120.58 +  void SkeletonSolverBase::_getColCoeffs(int, InsertIterator) const {}
  120.59 +
  120.60 +  void SkeletonSolverBase::_setCoeff(int, int, Value) {}
  120.61 +  SkeletonSolverBase::Value SkeletonSolverBase::_getCoeff(int, int) const
  120.62 +  { return 0; }
  120.63 +
  120.64 +  void SkeletonSolverBase::_setColLowerBound(int, Value) {}
  120.65 +  SkeletonSolverBase::Value SkeletonSolverBase::_getColLowerBound(int) const
  120.66 +  {  return 0; }
  120.67 +
  120.68 +  void SkeletonSolverBase::_setColUpperBound(int, Value) {}
  120.69 +  SkeletonSolverBase::Value SkeletonSolverBase::_getColUpperBound(int) const
  120.70 +  {  return 0; }
  120.71 +
  120.72 +  void SkeletonSolverBase::_setRowLowerBound(int, Value) {}
  120.73 +  SkeletonSolverBase::Value SkeletonSolverBase::_getRowLowerBound(int) const
  120.74 +  {  return 0; }
  120.75 +
  120.76 +  void SkeletonSolverBase::_setRowUpperBound(int, Value) {}
  120.77 +  SkeletonSolverBase::Value SkeletonSolverBase::_getRowUpperBound(int) const
  120.78 +  {  return 0; }
  120.79 +
  120.80 +  void SkeletonSolverBase::_setObjCoeffs(ExprIterator, ExprIterator) {}
  120.81 +  void SkeletonSolverBase::_getObjCoeffs(InsertIterator) const {};
  120.82 +
  120.83 +  void SkeletonSolverBase::_setObjCoeff(int, Value) {}
  120.84 +  SkeletonSolverBase::Value SkeletonSolverBase::_getObjCoeff(int) const
  120.85 +  {  return 0; }
  120.86 +
  120.87 +  void SkeletonSolverBase::_setSense(Sense) {}
  120.88 +  SkeletonSolverBase::Sense SkeletonSolverBase::_getSense() const
  120.89 +  { return MIN; }
  120.90 +
  120.91 +  void SkeletonSolverBase::_clear() {
  120.92 +    row_num = col_num = 0;
  120.93 +  }
  120.94 +
  120.95 +  void SkeletonSolverBase::_messageLevel(MessageLevel) {}
  120.96 +
  120.97 +  LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
  120.98 +
  120.99 +  LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
 120.100 +  LpSkeleton::Value LpSkeleton::_getDual(int) const { return 0; }
 120.101 +  LpSkeleton::Value LpSkeleton::_getPrimalValue() const { return 0; }
 120.102 +
 120.103 +  LpSkeleton::Value LpSkeleton::_getPrimalRay(int) const { return 0; }
 120.104 +  LpSkeleton::Value LpSkeleton::_getDualRay(int) const { return 0; }
 120.105 +
 120.106 +  LpSkeleton::ProblemType LpSkeleton::_getPrimalType() const
 120.107 +  { return UNDEFINED; }
 120.108 +
 120.109 +  LpSkeleton::ProblemType LpSkeleton::_getDualType() const
 120.110 +  { return UNDEFINED; }
 120.111 +
 120.112 +  LpSkeleton::VarStatus LpSkeleton::_getColStatus(int) const
 120.113 +  { return BASIC; }
 120.114 +
 120.115 +  LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
 120.116 +  { return BASIC; }
 120.117 +
 120.118 +  LpSkeleton* LpSkeleton::newSolver() const
 120.119 +  { return static_cast<LpSkeleton*>(0); }
 120.120 +
 120.121 +  LpSkeleton* LpSkeleton::cloneSolver() const
 120.122 +  { return static_cast<LpSkeleton*>(0); }
 120.123 +
 120.124 +  const char* LpSkeleton::_solverName() const { return "LpSkeleton"; }
 120.125 +
 120.126 +  MipSkeleton::SolveExitStatus MipSkeleton::_solve()
 120.127 +  { return SOLVED; }
 120.128 +
 120.129 +  MipSkeleton::Value MipSkeleton::_getSol(int) const { return 0; }
 120.130 +  MipSkeleton::Value MipSkeleton::_getSolValue() const { return 0; }
 120.131 +
 120.132 +  MipSkeleton::ProblemType MipSkeleton::_getType() const
 120.133 +  { return UNDEFINED; }
 120.134 +
 120.135 +  MipSkeleton* MipSkeleton::newSolver() const
 120.136 +  { return static_cast<MipSkeleton*>(0); }
 120.137 +
 120.138 +  MipSkeleton* MipSkeleton::cloneSolver() const
 120.139 +  { return static_cast<MipSkeleton*>(0); }
 120.140 +
 120.141 +  const char* MipSkeleton::_solverName() const { return "MipSkeleton"; }
 120.142 +
 120.143 +} //namespace lemon
 120.144 +
   121.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   121.2 +++ b/lemon/lp_skeleton.h	Thu Nov 05 15:50:01 2009 +0100
   121.3 @@ -0,0 +1,229 @@
   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-2008
   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_LP_SKELETON_H
  121.23 +#define LEMON_LP_SKELETON_H
  121.24 +
  121.25 +#include <lemon/lp_base.h>
  121.26 +
  121.27 +///\file
  121.28 +///\brief Skeleton file to implement LP/MIP solver interfaces
  121.29 +///  
  121.30 +///The classes in this file do nothing, but they can serve as skeletons when
  121.31 +///implementing an interface to new solvers.
  121.32 +namespace lemon {
  121.33 +
  121.34 +  ///A skeleton class to implement LP/MIP solver base interface
  121.35 +  
  121.36 +  ///This class does nothing, but it can serve as a skeleton when
  121.37 +  ///implementing an interface to new solvers.
  121.38 +  class SkeletonSolverBase : public virtual LpBase {
  121.39 +    int col_num,row_num;
  121.40 +
  121.41 +  protected:
  121.42 +
  121.43 +    SkeletonSolverBase()
  121.44 +      : col_num(-1), row_num(-1) {}
  121.45 +
  121.46 +    /// \e
  121.47 +    virtual int _addCol();
  121.48 +    /// \e
  121.49 +    virtual int _addRow();
  121.50 +    /// \e
  121.51 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
  121.52 +    /// \e
  121.53 +    virtual void _eraseCol(int i);
  121.54 +    /// \e
  121.55 +    virtual void _eraseRow(int i);
  121.56 +
  121.57 +    /// \e
  121.58 +    virtual void _getColName(int col, std::string& name) const;
  121.59 +    /// \e
  121.60 +    virtual void _setColName(int col, const std::string& name);
  121.61 +    /// \e
  121.62 +    virtual int _colByName(const std::string& name) const;
  121.63 +
  121.64 +    /// \e
  121.65 +    virtual void _getRowName(int row, std::string& name) const;
  121.66 +    /// \e
  121.67 +    virtual void _setRowName(int row, const std::string& name);
  121.68 +    /// \e
  121.69 +    virtual int _rowByName(const std::string& name) const;
  121.70 +
  121.71 +    /// \e
  121.72 +    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
  121.73 +    /// \e
  121.74 +    virtual void _getRowCoeffs(int i, InsertIterator b) const;
  121.75 +    /// \e
  121.76 +    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
  121.77 +    /// \e
  121.78 +    virtual void _getColCoeffs(int i, InsertIterator b) const;
  121.79 +
  121.80 +    /// Set one element of the coefficient matrix
  121.81 +    virtual void _setCoeff(int row, int col, Value value);
  121.82 +
  121.83 +    /// Get one element of the coefficient matrix
  121.84 +    virtual Value _getCoeff(int row, int col) const;
  121.85 +
  121.86 +    /// The lower bound of a variable (column) have to be given by an
  121.87 +    /// extended number of type Value, i.e. a finite number of type
  121.88 +    /// Value or -\ref INF.
  121.89 +    virtual void _setColLowerBound(int i, Value value);
  121.90 +    /// \e
  121.91 +
  121.92 +    /// The lower bound of a variable (column) is an
  121.93 +    /// extended number of type Value, i.e. a finite number of type
  121.94 +    /// Value or -\ref INF.
  121.95 +    virtual Value _getColLowerBound(int i) const;
  121.96 +
  121.97 +    /// The upper bound of a variable (column) have to be given by an
  121.98 +    /// extended number of type Value, i.e. a finite number of type
  121.99 +    /// Value or \ref INF.
 121.100 +    virtual void _setColUpperBound(int i, Value value);
 121.101 +    /// \e
 121.102 +
 121.103 +    /// The upper bound of a variable (column) is an
 121.104 +    /// extended number of type Value, i.e. a finite number of type
 121.105 +    /// Value or \ref INF.
 121.106 +    virtual Value _getColUpperBound(int i) const;
 121.107 +
 121.108 +    /// The lower bound of a constraint (row) have to be given by an
 121.109 +    /// extended number of type Value, i.e. a finite number of type
 121.110 +    /// Value or -\ref INF.
 121.111 +    virtual void _setRowLowerBound(int i, Value value);
 121.112 +    /// \e
 121.113 +
 121.114 +    /// The lower bound of a constraint (row) is an
 121.115 +    /// extended number of type Value, i.e. a finite number of type
 121.116 +    /// Value or -\ref INF.
 121.117 +    virtual Value _getRowLowerBound(int i) const;
 121.118 +
 121.119 +    /// The upper bound of a constraint (row) have to be given by an
 121.120 +    /// extended number of type Value, i.e. a finite number of type
 121.121 +    /// Value or \ref INF.
 121.122 +    virtual void _setRowUpperBound(int i, Value value);
 121.123 +    /// \e
 121.124 +
 121.125 +    /// The upper bound of a constraint (row) is an
 121.126 +    /// extended number of type Value, i.e. a finite number of type
 121.127 +    /// Value or \ref INF.
 121.128 +    virtual Value _getRowUpperBound(int i) const;
 121.129 +
 121.130 +    /// \e
 121.131 +    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
 121.132 +    /// \e
 121.133 +    virtual void _getObjCoeffs(InsertIterator b) const;
 121.134 +
 121.135 +    /// \e
 121.136 +    virtual void _setObjCoeff(int i, Value obj_coef);
 121.137 +    /// \e
 121.138 +    virtual Value _getObjCoeff(int i) const;
 121.139 +
 121.140 +    ///\e
 121.141 +    virtual void _setSense(Sense);
 121.142 +    ///\e
 121.143 +    virtual Sense _getSense() const;
 121.144 +
 121.145 +    ///\e
 121.146 +    virtual void _clear();
 121.147 +
 121.148 +    ///\e
 121.149 +    virtual void _messageLevel(MessageLevel);
 121.150 +  };
 121.151 +
 121.152 +  /// \brief Skeleton class for an LP solver interface
 121.153 +  ///
 121.154 +  ///This class does nothing, but it can serve as a skeleton when
 121.155 +  ///implementing an interface to new solvers.
 121.156 +
 121.157 +  ///\ingroup lp_group
 121.158 +  class LpSkeleton : public LpSolver, public SkeletonSolverBase {
 121.159 +  public:
 121.160 +    ///\e
 121.161 +    LpSkeleton() : LpSolver(), SkeletonSolverBase() {}
 121.162 +    ///\e
 121.163 +    virtual LpSkeleton* newSolver() const;
 121.164 +    ///\e
 121.165 +    virtual LpSkeleton* cloneSolver() const;
 121.166 +  protected:
 121.167 +
 121.168 +    ///\e
 121.169 +    virtual SolveExitStatus _solve();
 121.170 +
 121.171 +    ///\e
 121.172 +    virtual Value _getPrimal(int i) const;
 121.173 +    ///\e
 121.174 +    virtual Value _getDual(int i) const;
 121.175 +
 121.176 +    ///\e
 121.177 +    virtual Value _getPrimalValue() const;
 121.178 +
 121.179 +    ///\e
 121.180 +    virtual Value _getPrimalRay(int i) const;
 121.181 +    ///\e
 121.182 +    virtual Value _getDualRay(int i) const;
 121.183 +
 121.184 +    ///\e
 121.185 +    virtual ProblemType _getPrimalType() const;
 121.186 +    ///\e
 121.187 +    virtual ProblemType _getDualType() const;
 121.188 +
 121.189 +    ///\e
 121.190 +    virtual VarStatus _getColStatus(int i) const;
 121.191 +    ///\e
 121.192 +    virtual VarStatus _getRowStatus(int i) const;
 121.193 +
 121.194 +    ///\e
 121.195 +    virtual const char* _solverName() const;
 121.196 +
 121.197 +  };
 121.198 +
 121.199 +  /// \brief Skeleton class for a MIP solver interface
 121.200 +  ///
 121.201 +  ///This class does nothing, but it can serve as a skeleton when
 121.202 +  ///implementing an interface to new solvers.
 121.203 +  ///\ingroup lp_group
 121.204 +  class MipSkeleton : public MipSolver, public SkeletonSolverBase {
 121.205 +  public:
 121.206 +    ///\e
 121.207 +    MipSkeleton() : MipSolver(), SkeletonSolverBase() {}
 121.208 +    ///\e
 121.209 +    virtual MipSkeleton* newSolver() const;
 121.210 +    ///\e
 121.211 +    virtual MipSkeleton* cloneSolver() const;
 121.212 +
 121.213 +  protected:
 121.214 +    ///\e
 121.215 +    virtual SolveExitStatus _solve();
 121.216 +
 121.217 +    ///\e
 121.218 +    virtual Value _getSol(int i) const;
 121.219 +
 121.220 +    ///\e
 121.221 +    virtual Value _getSolValue() const;
 121.222 +
 121.223 +    ///\e
 121.224 +    virtual ProblemType _getType() const;
 121.225 +
 121.226 +    ///\e
 121.227 +    virtual const char* _solverName() const;
 121.228 +  };
 121.229 +
 121.230 +} //namespace lemon
 121.231 +
 121.232 +#endif
   122.1 --- a/lemon/maps.h	Fri Oct 16 10:21:37 2009 +0200
   122.2 +++ b/lemon/maps.h	Thu Nov 05 15:50:01 2009 +0100
   122.3 @@ -2,7 +2,7 @@
   122.4   *
   122.5   * This file is a part of LEMON, a generic C++ optimization library.
   122.6   *
   122.7 - * Copyright (C) 2003-2008
   122.8 + * Copyright (C) 2003-2009
   122.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  122.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  122.11   *
  122.12 @@ -22,6 +22,7 @@
  122.13  #include <iterator>
  122.14  #include <functional>
  122.15  #include <vector>
  122.16 +#include <map>
  122.17  
  122.18  #include <lemon/core.h>
  122.19  
  122.20 @@ -29,8 +30,6 @@
  122.21  ///\ingroup maps
  122.22  ///\brief Miscellaneous property maps
  122.23  
  122.24 -#include <map>
  122.25 -
  122.26  namespace lemon {
  122.27  
  122.28    /// \addtogroup maps
  122.29 @@ -57,15 +56,16 @@
  122.30    /// its type definitions, or if you have to provide a writable map,
  122.31    /// but data written to it is not required (i.e. it will be sent to
  122.32    /// <tt>/dev/null</tt>).
  122.33 -  /// It conforms the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  122.34 +  /// It conforms to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  122.35    ///
  122.36    /// \sa ConstMap
  122.37    template<typename K, typename V>
  122.38    class NullMap : public MapBase<K, V> {
  122.39    public:
  122.40 -    typedef MapBase<K, V> Parent;
  122.41 -    typedef typename Parent::Key Key;
  122.42 -    typedef typename Parent::Value Value;
  122.43 +    ///\e
  122.44 +    typedef K Key;
  122.45 +    ///\e
  122.46 +    typedef V Value;
  122.47  
  122.48      /// Gives back a default constructed element.
  122.49      Value operator[](const Key&) const { return Value(); }
  122.50 @@ -89,7 +89,7 @@
  122.51    /// value to each key.
  122.52    ///
  122.53    /// In other aspects it is equivalent to \c NullMap.
  122.54 -  /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
  122.55 +  /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
  122.56    /// concept, but it absorbs the data written to it.
  122.57    ///
  122.58    /// The simplest way of using this map is through the constMap()
  122.59 @@ -102,9 +102,10 @@
  122.60    private:
  122.61      V _value;
  122.62    public:
  122.63 -    typedef MapBase<K, V> Parent;
  122.64 -    typedef typename Parent::Key Key;
  122.65 -    typedef typename Parent::Value Value;
  122.66 +    ///\e
  122.67 +    typedef K Key;
  122.68 +    ///\e
  122.69 +    typedef V Value;
  122.70  
  122.71      /// Default constructor
  122.72  
  122.73 @@ -157,7 +158,7 @@
  122.74    /// value to each key.
  122.75    ///
  122.76    /// In other aspects it is equivalent to \c NullMap.
  122.77 -  /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
  122.78 +  /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
  122.79    /// concept, but it absorbs the data written to it.
  122.80    ///
  122.81    /// The simplest way of using this map is through the constMap()
  122.82 @@ -168,9 +169,10 @@
  122.83    template<typename K, typename V, V v>
  122.84    class ConstMap<K, Const<V, v> > : public MapBase<K, V> {
  122.85    public:
  122.86 -    typedef MapBase<K, V> Parent;
  122.87 -    typedef typename Parent::Key Key;
  122.88 -    typedef typename Parent::Value Value;
  122.89 +    ///\e
  122.90 +    typedef K Key;
  122.91 +    ///\e
  122.92 +    typedef V Value;
  122.93  
  122.94      /// Constructor.
  122.95      ConstMap() {}
  122.96 @@ -202,9 +204,10 @@
  122.97    template <typename T>
  122.98    class IdentityMap : public MapBase<T, T> {
  122.99    public:
 122.100 -    typedef MapBase<T, T> Parent;
 122.101 -    typedef typename Parent::Key Key;
 122.102 -    typedef typename Parent::Value Value;
 122.103 +    ///\e
 122.104 +    typedef T Key;
 122.105 +    ///\e
 122.106 +    typedef T Value;
 122.107  
 122.108      /// Gives back the given value without any modification.
 122.109      Value operator[](const Key &k) const {
 122.110 @@ -229,7 +232,7 @@
 122.111    /// values to integer keys from the range <tt>[0..size-1]</tt>.
 122.112    /// It can be used with some data structures, for example
 122.113    /// \c UnionFind, \c BinHeap, when the used items are small
 122.114 -  /// integers. This map conforms the \ref concepts::ReferenceMap
 122.115 +  /// integers. This map conforms to the \ref concepts::ReferenceMap
 122.116    /// "ReferenceMap" concept.
 122.117    ///
 122.118    /// The simplest way of using this map is through the rangeMap()
 122.119 @@ -245,11 +248,10 @@
 122.120  
 122.121    public:
 122.122  
 122.123 -    typedef MapBase<int, V> Parent;
 122.124      /// Key type
 122.125 -    typedef typename Parent::Key Key;
 122.126 +    typedef int Key;
 122.127      /// Value type
 122.128 -    typedef typename Parent::Value Value;
 122.129 +    typedef V Value;
 122.130      /// Reference type
 122.131      typedef typename Vector::reference Reference;
 122.132      /// Const reference type
 122.133 @@ -338,7 +340,7 @@
 122.134    /// that you can specify a default value for the keys that are not
 122.135    /// stored actually. This value can be different from the default
 122.136    /// contructed value (i.e. \c %Value()).
 122.137 -  /// This type conforms the \ref concepts::ReferenceMap "ReferenceMap"
 122.138 +  /// This type conforms to the \ref concepts::ReferenceMap "ReferenceMap"
 122.139    /// concept.
 122.140    ///
 122.141    /// This map is useful if a default value should be assigned to most of
 122.142 @@ -353,17 +355,16 @@
 122.143    ///
 122.144    /// The simplest way of using this map is through the sparseMap()
 122.145    /// function.
 122.146 -  template <typename K, typename V, typename Compare = std::less<K> >
 122.147 +  template <typename K, typename V, typename Comp = std::less<K> >
 122.148    class SparseMap : public MapBase<K, V> {
 122.149      template <typename K1, typename V1, typename C1>
 122.150      friend class SparseMap;
 122.151    public:
 122.152  
 122.153 -    typedef MapBase<K, V> Parent;
 122.154      /// Key type
 122.155 -    typedef typename Parent::Key Key;
 122.156 +    typedef K Key;
 122.157      /// Value type
 122.158 -    typedef typename Parent::Value Value;
 122.159 +    typedef V Value;
 122.160      /// Reference type
 122.161      typedef Value& Reference;
 122.162      /// Const reference type
 122.163 @@ -373,7 +374,7 @@
 122.164  
 122.165    private:
 122.166  
 122.167 -    typedef std::map<K, V, Compare> Map;
 122.168 +    typedef std::map<K, V, Comp> Map;
 122.169      Map _map;
 122.170      Value _value;
 122.171  
 122.172 @@ -489,14 +490,15 @@
 122.173      const M1 &_m1;
 122.174      const M2 &_m2;
 122.175    public:
 122.176 -    typedef MapBase<typename M2::Key, typename M1::Value> Parent;
 122.177 -    typedef typename Parent::Key Key;
 122.178 -    typedef typename Parent::Value Value;
 122.179 +    ///\e
 122.180 +    typedef typename M2::Key Key;
 122.181 +    ///\e
 122.182 +    typedef typename M1::Value Value;
 122.183  
 122.184      /// Constructor
 122.185      ComposeMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
 122.186  
 122.187 -    /// \e
 122.188 +    ///\e
 122.189      typename MapTraits<M1>::ConstReturnValue
 122.190      operator[](const Key &k) const { return _m1[_m2[k]]; }
 122.191    };
 122.192 @@ -545,14 +547,15 @@
 122.193      const M2 &_m2;
 122.194      F _f;
 122.195    public:
 122.196 -    typedef MapBase<typename M1::Key, V> Parent;
 122.197 -    typedef typename Parent::Key Key;
 122.198 -    typedef typename Parent::Value Value;
 122.199 +    ///\e
 122.200 +    typedef typename M1::Key Key;
 122.201 +    ///\e
 122.202 +    typedef V Value;
 122.203  
 122.204      /// Constructor
 122.205      CombineMap(const M1 &m1, const M2 &m2, const F &f = F())
 122.206        : _m1(m1), _m2(m2), _f(f) {}
 122.207 -    /// \e
 122.208 +    ///\e
 122.209      Value operator[](const Key &k) const { return _f(_m1[k],_m2[k]); }
 122.210    };
 122.211  
 122.212 @@ -615,13 +618,14 @@
 122.213    class FunctorToMap : public MapBase<K, V> {
 122.214      F _f;
 122.215    public:
 122.216 -    typedef MapBase<K, V> Parent;
 122.217 -    typedef typename Parent::Key Key;
 122.218 -    typedef typename Parent::Value Value;
 122.219 +    ///\e
 122.220 +    typedef K Key;
 122.221 +    ///\e
 122.222 +    typedef V Value;
 122.223  
 122.224      /// Constructor
 122.225      FunctorToMap(const F &f = F()) : _f(f) {}
 122.226 -    /// \e
 122.227 +    ///\e
 122.228      Value operator[](const Key &k) const { return _f(k); }
 122.229    };
 122.230  
 122.231 @@ -669,18 +673,19 @@
 122.232    class MapToFunctor : public MapBase<typename M::Key, typename M::Value> {
 122.233      const M &_m;
 122.234    public:
 122.235 -    typedef MapBase<typename M::Key, typename M::Value> Parent;
 122.236 -    typedef typename Parent::Key Key;
 122.237 -    typedef typename Parent::Value Value;
 122.238 -
 122.239 -    typedef typename Parent::Key argument_type;
 122.240 -    typedef typename Parent::Value result_type;
 122.241 +    ///\e
 122.242 +    typedef typename M::Key Key;
 122.243 +    ///\e
 122.244 +    typedef typename M::Value Value;
 122.245 +
 122.246 +    typedef typename M::Key argument_type;
 122.247 +    typedef typename M::Value result_type;
 122.248  
 122.249      /// Constructor
 122.250      MapToFunctor(const M &m) : _m(m) {}
 122.251 -    /// \e
 122.252 +    ///\e
 122.253      Value operator()(const Key &k) const { return _m[k]; }
 122.254 -    /// \e
 122.255 +    ///\e
 122.256      Value operator[](const Key &k) const { return _m[k]; }
 122.257    };
 122.258  
 122.259 @@ -701,7 +706,7 @@
 122.260    /// "readable map" to another type using the default conversion.
 122.261    /// The \c Key type of it is inherited from \c M and the \c Value
 122.262    /// type is \c V.
 122.263 -  /// This type conforms the \ref concepts::ReadMap "ReadMap" concept.
 122.264 +  /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
 122.265    ///
 122.266    /// The simplest way of using this map is through the convertMap()
 122.267    /// function.
 122.268 @@ -709,9 +714,10 @@
 122.269    class ConvertMap : public MapBase<typename M::Key, V> {
 122.270      const M &_m;
 122.271    public:
 122.272 -    typedef MapBase<typename M::Key, V> Parent;
 122.273 -    typedef typename Parent::Key Key;
 122.274 -    typedef typename Parent::Value Value;
 122.275 +    ///\e
 122.276 +    typedef typename M::Key Key;
 122.277 +    ///\e
 122.278 +    typedef V Value;
 122.279  
 122.280      /// Constructor
 122.281  
 122.282 @@ -719,7 +725,7 @@
 122.283      /// \param m The underlying map.
 122.284      ConvertMap(const M &m) : _m(m) {}
 122.285  
 122.286 -    /// \e
 122.287 +    ///\e
 122.288      Value operator[](const Key &k) const { return _m[k]; }
 122.289    };
 122.290  
 122.291 @@ -751,9 +757,10 @@
 122.292      M1 &_m1;
 122.293      M2 &_m2;
 122.294    public:
 122.295 -    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
 122.296 -    typedef typename Parent::Key Key;
 122.297 -    typedef typename Parent::Value Value;
 122.298 +    ///\e
 122.299 +    typedef typename M1::Key Key;
 122.300 +    ///\e
 122.301 +    typedef typename M1::Value Value;
 122.302  
 122.303      /// Constructor
 122.304      ForkMap(M1 &m1, M2 &m2) : _m1(m1), _m2(m2) {}
 122.305 @@ -797,13 +804,14 @@
 122.306      const M1 &_m1;
 122.307      const M2 &_m2;
 122.308    public:
 122.309 -    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
 122.310 -    typedef typename Parent::Key Key;
 122.311 -    typedef typename Parent::Value Value;
 122.312 +    ///\e
 122.313 +    typedef typename M1::Key Key;
 122.314 +    ///\e
 122.315 +    typedef typename M1::Value Value;
 122.316  
 122.317      /// Constructor
 122.318      AddMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
 122.319 -    /// \e
 122.320 +    ///\e
 122.321      Value operator[](const Key &k) const { return _m1[k]+_m2[k]; }
 122.322    };
 122.323  
 122.324 @@ -845,13 +853,14 @@
 122.325      const M1 &_m1;
 122.326      const M2 &_m2;
 122.327    public:
 122.328 -    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
 122.329 -    typedef typename Parent::Key Key;
 122.330 -    typedef typename Parent::Value Value;
 122.331 +    ///\e
 122.332 +    typedef typename M1::Key Key;
 122.333 +    ///\e
 122.334 +    typedef typename M1::Value Value;
 122.335  
 122.336      /// Constructor
 122.337      SubMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
 122.338 -    /// \e
 122.339 +    ///\e
 122.340      Value operator[](const Key &k) const { return _m1[k]-_m2[k]; }
 122.341    };
 122.342  
 122.343 @@ -894,13 +903,14 @@
 122.344      const M1 &_m1;
 122.345      const M2 &_m2;
 122.346    public:
 122.347 -    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
 122.348 -    typedef typename Parent::Key Key;
 122.349 -    typedef typename Parent::Value Value;
 122.350 +    ///\e
 122.351 +    typedef typename M1::Key Key;
 122.352 +    ///\e
 122.353 +    typedef typename M1::Value Value;
 122.354  
 122.355      /// Constructor
 122.356      MulMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
 122.357 -    /// \e
 122.358 +    ///\e
 122.359      Value operator[](const Key &k) const { return _m1[k]*_m2[k]; }
 122.360    };
 122.361  
 122.362 @@ -942,13 +952,14 @@
 122.363      const M1 &_m1;
 122.364      const M2 &_m2;
 122.365    public:
 122.366 -    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
 122.367 -    typedef typename Parent::Key Key;
 122.368 -    typedef typename Parent::Value Value;
 122.369 +    ///\e
 122.370 +    typedef typename M1::Key Key;
 122.371 +    ///\e
 122.372 +    typedef typename M1::Value Value;
 122.373  
 122.374      /// Constructor
 122.375      DivMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
 122.376 -    /// \e
 122.377 +    ///\e
 122.378      Value operator[](const Key &k) const { return _m1[k]/_m2[k]; }
 122.379    };
 122.380  
 122.381 @@ -992,9 +1003,10 @@
 122.382      const M &_m;
 122.383      C _v;
 122.384    public:
 122.385 -    typedef MapBase<typename M::Key, typename M::Value> Parent;
 122.386 -    typedef typename Parent::Key Key;
 122.387 -    typedef typename Parent::Value Value;
 122.388 +    ///\e
 122.389 +    typedef typename M::Key Key;
 122.390 +    ///\e
 122.391 +    typedef typename M::Value Value;
 122.392  
 122.393      /// Constructor
 122.394  
 122.395 @@ -1002,7 +1014,7 @@
 122.396      /// \param m The undelying map.
 122.397      /// \param v The constant value.
 122.398      ShiftMap(const M &m, const C &v) : _m(m), _v(v) {}
 122.399 -    /// \e
 122.400 +    ///\e
 122.401      Value operator[](const Key &k) const { return _m[k]+_v; }
 122.402    };
 122.403  
 122.404 @@ -1022,9 +1034,10 @@
 122.405      M &_m;
 122.406      C _v;
 122.407    public:
 122.408 -    typedef MapBase<typename M::Key, typename M::Value> Parent;
 122.409 -    typedef typename Parent::Key Key;
 122.410 -    typedef typename Parent::Value Value;
 122.411 +    ///\e
 122.412 +    typedef typename M::Key Key;
 122.413 +    ///\e
 122.414 +    typedef typename M::Value Value;
 122.415  
 122.416      /// Constructor
 122.417  
 122.418 @@ -1032,9 +1045,9 @@
 122.419      /// \param m The undelying map.
 122.420      /// \param v The constant value.
 122.421      ShiftWriteMap(M &m, const C &v) : _m(m), _v(v) {}
 122.422 -    /// \e
 122.423 +    ///\e
 122.424      Value operator[](const Key &k) const { return _m[k]+_v; }
 122.425 -    /// \e
 122.426 +    ///\e
 122.427      void set(const Key &k, const Value &v) { _m.set(k, v-_v); }
 122.428    };
 122.429  
 122.430 @@ -1093,9 +1106,10 @@
 122.431      const M &_m;
 122.432      C _v;
 122.433    public:
 122.434 -    typedef MapBase<typename M::Key, typename M::Value> Parent;
 122.435 -    typedef typename Parent::Key Key;
 122.436 -    typedef typename Parent::Value Value;
 122.437 +    ///\e
 122.438 +    typedef typename M::Key Key;
 122.439 +    ///\e
 122.440 +    typedef typename M::Value Value;
 122.441  
 122.442      /// Constructor
 122.443  
 122.444 @@ -1103,7 +1117,7 @@
 122.445      /// \param m The undelying map.
 122.446      /// \param v The constant value.
 122.447      ScaleMap(const M &m, const C &v) : _m(m), _v(v) {}
 122.448 -    /// \e
 122.449 +    ///\e
 122.450      Value operator[](const Key &k) const { return _v*_m[k]; }
 122.451    };
 122.452  
 122.453 @@ -1124,9 +1138,10 @@
 122.454      M &_m;
 122.455      C _v;
 122.456    public:
 122.457 -    typedef MapBase<typename M::Key, typename M::Value> Parent;
 122.458 -    typedef typename Parent::Key Key;
 122.459 -    typedef typename Parent::Value Value;
 122.460 +    ///\e
 122.461 +    typedef typename M::Key Key;
 122.462 +    ///\e
 122.463 +    typedef typename M::Value Value;
 122.464  
 122.465      /// Constructor
 122.466  
 122.467 @@ -1134,9 +1149,9 @@
 122.468      /// \param m The undelying map.
 122.469      /// \param v The constant value.
 122.470      ScaleWriteMap(M &m, const C &v) : _m(m), _v(v) {}
 122.471 -    /// \e
 122.472 +    ///\e
 122.473      Value operator[](const Key &k) const { return _v*_m[k]; }
 122.474 -    /// \e
 122.475 +    ///\e
 122.476      void set(const Key &k, const Value &v) { _m.set(k, v/_v); }
 122.477    };
 122.478  
 122.479 @@ -1193,13 +1208,14 @@
 122.480    class NegMap : public MapBase<typename M::Key, typename M::Value> {
 122.481      const M& _m;
 122.482    public:
 122.483 -    typedef MapBase<typename M::Key, typename M::Value> Parent;
 122.484 -    typedef typename Parent::Key Key;
 122.485 -    typedef typename Parent::Value Value;
 122.486 +    ///\e
 122.487 +    typedef typename M::Key Key;
 122.488 +    ///\e
 122.489 +    typedef typename M::Value Value;
 122.490  
 122.491      /// Constructor
 122.492      NegMap(const M &m) : _m(m) {}
 122.493 -    /// \e
 122.494 +    ///\e
 122.495      Value operator[](const Key &k) const { return -_m[k]; }
 122.496    };
 122.497  
 122.498 @@ -1228,15 +1244,16 @@
 122.499    class NegWriteMap : public MapBase<typename M::Key, typename M::Value> {
 122.500      M &_m;
 122.501    public:
 122.502 -    typedef MapBase<typename M::Key, typename M::Value> Parent;
 122.503 -    typedef typename Parent::Key Key;
 122.504 -    typedef typename Parent::Value Value;
 122.505 +    ///\e
 122.506 +    typedef typename M::Key Key;
 122.507 +    ///\e
 122.508 +    typedef typename M::Value Value;
 122.509  
 122.510      /// Constructor
 122.511      NegWriteMap(M &m) : _m(m) {}
 122.512 -    /// \e
 122.513 +    ///\e
 122.514      Value operator[](const Key &k) const { return -_m[k]; }
 122.515 -    /// \e
 122.516 +    ///\e
 122.517      void set(const Key &k, const Value &v) { _m.set(k, -v); }
 122.518    };
 122.519  
 122.520 @@ -1282,13 +1299,14 @@
 122.521    class AbsMap : public MapBase<typename M::Key, typename M::Value> {
 122.522      const M &_m;
 122.523    public:
 122.524 -    typedef MapBase<typename M::Key, typename M::Value> Parent;
 122.525 -    typedef typename Parent::Key Key;
 122.526 -    typedef typename Parent::Value Value;
 122.527 +    ///\e
 122.528 +    typedef typename M::Key Key;
 122.529 +    ///\e
 122.530 +    typedef typename M::Value Value;
 122.531  
 122.532      /// Constructor
 122.533      AbsMap(const M &m) : _m(m) {}
 122.534 -    /// \e
 122.535 +    ///\e
 122.536      Value operator[](const Key &k) const {
 122.537        Value tmp = _m[k];
 122.538        return tmp >= 0 ? tmp : -tmp;
 122.539 @@ -1337,9 +1355,10 @@
 122.540    template <typename K>
 122.541    class TrueMap : public MapBase<K, bool> {
 122.542    public:
 122.543 -    typedef MapBase<K, bool> Parent;
 122.544 -    typedef typename Parent::Key Key;
 122.545 -    typedef typename Parent::Value Value;
 122.546 +    ///\e
 122.547 +    typedef K Key;
 122.548 +    ///\e
 122.549 +    typedef bool Value;
 122.550  
 122.551      /// Gives back \c true.
 122.552      Value operator[](const Key&) const { return true; }
 122.553 @@ -1374,9 +1393,10 @@
 122.554    template <typename K>
 122.555    class FalseMap : public MapBase<K, bool> {
 122.556    public:
 122.557 -    typedef MapBase<K, bool> Parent;
 122.558 -    typedef typename Parent::Key Key;
 122.559 -    typedef typename Parent::Value Value;
 122.560 +    ///\e
 122.561 +    typedef K Key;
 122.562 +    ///\e
 122.563 +    typedef bool Value;
 122.564  
 122.565      /// Gives back \c false.
 122.566      Value operator[](const Key&) const { return false; }
 122.567 @@ -1419,13 +1439,14 @@
 122.568      const M1 &_m1;
 122.569      const M2 &_m2;
 122.570    public:
 122.571 -    typedef MapBase<typename M1::Key, bool> Parent;
 122.572 -    typedef typename Parent::Key Key;
 122.573 -    typedef typename Parent::Value Value;
 122.574 +    ///\e
 122.575 +    typedef typename M1::Key Key;
 122.576 +    ///\e
 122.577 +    typedef bool Value;
 122.578  
 122.579      /// Constructor
 122.580      AndMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
 122.581 -    /// \e
 122.582 +    ///\e
 122.583      Value operator[](const Key &k) const { return _m1[k]&&_m2[k]; }
 122.584    };
 122.585  
 122.586 @@ -1467,13 +1488,14 @@
 122.587      const M1 &_m1;
 122.588      const M2 &_m2;
 122.589    public:
 122.590 -    typedef MapBase<typename M1::Key, bool> Parent;
 122.591 -    typedef typename Parent::Key Key;
 122.592 -    typedef typename Parent::Value Value;
 122.593 +    ///\e
 122.594 +    typedef typename M1::Key Key;
 122.595 +    ///\e
 122.596 +    typedef bool Value;
 122.597  
 122.598      /// Constructor
 122.599      OrMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
 122.600 -    /// \e
 122.601 +    ///\e
 122.602      Value operator[](const Key &k) const { return _m1[k]||_m2[k]; }
 122.603    };
 122.604  
 122.605 @@ -1506,13 +1528,14 @@
 122.606    class NotMap : public MapBase<typename M::Key, bool> {
 122.607      const M &_m;
 122.608    public:
 122.609 -    typedef MapBase<typename M::Key, bool> Parent;
 122.610 -    typedef typename Parent::Key Key;
 122.611 -    typedef typename Parent::Value Value;
 122.612 +    ///\e
 122.613 +    typedef typename M::Key Key;
 122.614 +    ///\e
 122.615 +    typedef bool Value;
 122.616  
 122.617      /// Constructor
 122.618      NotMap(const M &m) : _m(m) {}
 122.619 -    /// \e
 122.620 +    ///\e
 122.621      Value operator[](const Key &k) const { return !_m[k]; }
 122.622    };
 122.623  
 122.624 @@ -1532,15 +1555,16 @@
 122.625    class NotWriteMap : public MapBase<typename M::Key, bool> {
 122.626      M &_m;
 122.627    public:
 122.628 -    typedef MapBase<typename M::Key, bool> Parent;
 122.629 -    typedef typename Parent::Key Key;
 122.630 -    typedef typename Parent::Value Value;
 122.631 +    ///\e
 122.632 +    typedef typename M::Key Key;
 122.633 +    ///\e
 122.634 +    typedef bool Value;
 122.635  
 122.636      /// Constructor
 122.637      NotWriteMap(M &m) : _m(m) {}
 122.638 -    /// \e
 122.639 +    ///\e
 122.640      Value operator[](const Key &k) const { return !_m[k]; }
 122.641 -    /// \e
 122.642 +    ///\e
 122.643      void set(const Key &k, bool v) { _m.set(k, !v); }
 122.644    };
 122.645  
 122.646 @@ -1595,13 +1619,14 @@
 122.647      const M1 &_m1;
 122.648      const M2 &_m2;
 122.649    public:
 122.650 -    typedef MapBase<typename M1::Key, bool> Parent;
 122.651 -    typedef typename Parent::Key Key;
 122.652 -    typedef typename Parent::Value Value;
 122.653 +    ///\e
 122.654 +    typedef typename M1::Key Key;
 122.655 +    ///\e
 122.656 +    typedef bool Value;
 122.657  
 122.658      /// Constructor
 122.659      EqualMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
 122.660 -    /// \e
 122.661 +    ///\e
 122.662      Value operator[](const Key &k) const { return _m1[k]==_m2[k]; }
 122.663    };
 122.664  
 122.665 @@ -1643,13 +1668,14 @@
 122.666      const M1 &_m1;
 122.667      const M2 &_m2;
 122.668    public:
 122.669 -    typedef MapBase<typename M1::Key, bool> Parent;
 122.670 -    typedef typename Parent::Key Key;
 122.671 -    typedef typename Parent::Value Value;
 122.672 +    ///\e
 122.673 +    typedef typename M1::Key Key;
 122.674 +    ///\e
 122.675 +    typedef bool Value;
 122.676  
 122.677      /// Constructor
 122.678      LessMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
 122.679 -    /// \e
 122.680 +    ///\e
 122.681      Value operator[](const Key &k) const { return _m1[k]<_m2[k]; }
 122.682    };
 122.683  
 122.684 @@ -1705,24 +1731,27 @@
 122.685    /// The simplest way of using this map is through the loggerBoolMap()
 122.686    /// function.
 122.687    ///
 122.688 -  /// \tparam It The type of the iterator.
 122.689 -  /// \tparam Ke The key type of the map. The default value set
 122.690 +  /// \tparam IT The type of the iterator.
 122.691 +  /// \tparam KEY The key type of the map. The default value set
 122.692    /// according to the iterator type should work in most cases.
 122.693    ///
 122.694    /// \note The container of the iterator must contain enough space
 122.695    /// for the elements or the iterator should be an inserter iterator.
 122.696  #ifdef DOXYGEN
 122.697 -  template <typename It, typename Ke>
 122.698 +  template <typename IT, typename KEY>
 122.699  #else
 122.700 -  template <typename It,
 122.701 -            typename Ke=typename _maps_bits::IteratorTraits<It>::Value>
 122.702 +  template <typename IT,
 122.703 +            typename KEY = typename _maps_bits::IteratorTraits<IT>::Value>
 122.704  #endif
 122.705 -  class LoggerBoolMap {
 122.706 +  class LoggerBoolMap : public MapBase<KEY, bool> {
 122.707    public:
 122.708 -    typedef It Iterator;
 122.709 -
 122.710 -    typedef Ke Key;
 122.711 +
 122.712 +    ///\e
 122.713 +    typedef KEY Key;
 122.714 +    ///\e
 122.715      typedef bool Value;
 122.716 +    ///\e
 122.717 +    typedef IT Iterator;
 122.718  
 122.719      /// Constructor
 122.720      LoggerBoolMap(Iterator it)
 122.721 @@ -1760,11 +1789,11 @@
 122.722    /// order of Dfs algorithm, as the following examples show.
 122.723    /// \code
 122.724    ///   std::vector<Node> v;
 122.725 -  ///   dfs(g,s).processedMap(loggerBoolMap(std::back_inserter(v))).run();
 122.726 +  ///   dfs(g).processedMap(loggerBoolMap(std::back_inserter(v))).run(s);
 122.727    /// \endcode
 122.728    /// \code
 122.729    ///   std::vector<Node> v(countNodes(g));
 122.730 -  ///   dfs(g,s).processedMap(loggerBoolMap(v.begin())).run();
 122.731 +  ///   dfs(g).processedMap(loggerBoolMap(v.begin())).run(s);
 122.732    /// \endcode
 122.733    ///
 122.734    /// \note The container of the iterator must contain enough space
 122.735 @@ -1785,23 +1814,36 @@
 122.736    /// \addtogroup graph_maps
 122.737    /// @{
 122.738  
 122.739 -  /// Provides an immutable and unique id for each item in the graph.
 122.740 -
 122.741 -  /// The IdMap class provides a unique and immutable id for each item of the
 122.742 -  /// same type (e.g. node) in the graph. This id is <ul><li>\b unique:
 122.743 -  /// different items (nodes) get different ids <li>\b immutable: the id of an
 122.744 -  /// item (node) does not change (even if you delete other nodes).  </ul>
 122.745 -  /// Through this map you get access (i.e. can read) the inner id values of
 122.746 -  /// the items stored in the graph. This map can be inverted with its member
 122.747 -  /// class \c InverseMap or with the \c operator() member.
 122.748 +  /// \brief Provides an immutable and unique id for each item in a graph.
 122.749    ///
 122.750 -  template <typename _Graph, typename _Item>
 122.751 -  class IdMap {
 122.752 +  /// IdMap provides a unique and immutable id for each item of the
 122.753 +  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
 122.754 +  ///  - \b unique: different items get different ids,
 122.755 +  ///  - \b immutable: the id of an item does not change (even if you
 122.756 +  ///    delete other nodes).
 122.757 +  ///
 122.758 +  /// Using this map you get access (i.e. can read) the inner id values of
 122.759 +  /// the items stored in the graph, which is returned by the \c id()
 122.760 +  /// function of the graph. This map can be inverted with its member
 122.761 +  /// class \c InverseMap or with the \c operator()() member.
 122.762 +  ///
 122.763 +  /// \tparam GR The graph type.
 122.764 +  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
 122.765 +  /// \c GR::Edge).
 122.766 +  ///
 122.767 +  /// \see RangeIdMap
 122.768 +  template <typename GR, typename K>
 122.769 +  class IdMap : public MapBase<K, int> {
 122.770    public:
 122.771 -    typedef _Graph Graph;
 122.772 +    /// The graph type of IdMap.
 122.773 +    typedef GR Graph;
 122.774 +    typedef GR Digraph;
 122.775 +    /// The key type of IdMap (\c Node, \c Arc or \c Edge).
 122.776 +    typedef K Item;
 122.777 +    /// The key type of IdMap (\c Node, \c Arc or \c Edge).
 122.778 +    typedef K Key;
 122.779 +    /// The value type of IdMap.
 122.780      typedef int Value;
 122.781 -    typedef _Item Item;
 122.782 -    typedef _Item Key;
 122.783  
 122.784      /// \brief Constructor.
 122.785      ///
 122.786 @@ -1813,9 +1855,9 @@
 122.787      /// Gives back the immutable and unique \e id of the item.
 122.788      int operator[](const Item& item) const { return _graph->id(item);}
 122.789  
 122.790 -    /// \brief Gives back the item by its id.
 122.791 +    /// \brief Gives back the \e item by its id.
 122.792      ///
 122.793 -    /// Gives back the item by its id.
 122.794 +    /// Gives back the \e item by its id.
 122.795      Item operator()(int id) { return _graph->fromId(id, Item()); }
 122.796  
 122.797    private:
 122.798 @@ -1823,9 +1865,11 @@
 122.799  
 122.800    public:
 122.801  
 122.802 -    /// \brief The class represents the inverse of its owner (IdMap).
 122.803 +    /// \brief The inverse map type of IdMap.
 122.804      ///
 122.805 -    /// The class represents the inverse of its owner (IdMap).
 122.806 +    /// The inverse map type of IdMap. The subscript operator gives back
 122.807 +    /// an item by its id.
 122.808 +    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
 122.809      /// \see inverse()
 122.810      class InverseMap {
 122.811      public:
 122.812 @@ -1840,10 +1884,9 @@
 122.813        /// Constructor for creating an id-to-item map.
 122.814        explicit InverseMap(const IdMap& map) : _graph(map._graph) {}
 122.815  
 122.816 -      /// \brief Gives back the given item from its id.
 122.817 +      /// \brief Gives back an item by its id.
 122.818        ///
 122.819 -      /// Gives back the given item from its id.
 122.820 -      ///
 122.821 +      /// Gives back an item by its id.
 122.822        Item operator[](int id) const { return _graph->fromId(id, Item());}
 122.823  
 122.824      private:
 122.825 @@ -1854,165 +1897,220 @@
 122.826      ///
 122.827      /// Gives back the inverse of the IdMap.
 122.828      InverseMap inverse() const { return InverseMap(*_graph);}
 122.829 -
 122.830    };
 122.831  
 122.832 -
 122.833 -  /// \brief General invertable graph-map type.
 122.834 -
 122.835 -  /// This type provides simple invertable graph-maps.
 122.836 -  /// The InvertableMap wraps an arbitrary ReadWriteMap
 122.837 -  /// and if a key is set to a new value then store it
 122.838 -  /// in the inverse map.
 122.839 +  /// \brief Returns an \c IdMap class.
 122.840    ///
 122.841 -  /// The values of the map can be accessed
 122.842 -  /// with stl compatible forward iterator.
 122.843 +  /// This function just returns an \c IdMap class.
 122.844 +  /// \relates IdMap
 122.845 +  template <typename K, typename GR>
 122.846 +  inline IdMap<GR, K> idMap(const GR& graph) {
 122.847 +    return IdMap<GR, K>(graph);
 122.848 +  }
 122.849 +
 122.850 +  /// \brief General cross reference graph map type.
 122.851 +
 122.852 +  /// This class provides simple invertable graph maps.
 122.853 +  /// It wraps a standard graph map (\c NodeMap, \c ArcMap or \c EdgeMap)
 122.854 +  /// and if a key is set to a new value, then stores it in the inverse map.
 122.855 +  /// The graph items can be accessed by their values either using
 122.856 +  /// \c InverseMap or \c operator()(), and the values of the map can be
 122.857 +  /// accessed with an STL compatible forward iterator (\c ValueIt).
 122.858 +  /// 
 122.859 +  /// This map is intended to be used when all associated values are
 122.860 +  /// different (the map is actually invertable) or there are only a few
 122.861 +  /// items with the same value.
 122.862 +  /// Otherwise consider to use \c IterableValueMap, which is more 
 122.863 +  /// suitable and more efficient for such cases. It provides iterators
 122.864 +  /// to traverse the items with the same associated value, however
 122.865 +  /// it does not have \c InverseMap.
 122.866    ///
 122.867 -  /// \tparam _Graph The graph type.
 122.868 -  /// \tparam _Item The item type of the graph.
 122.869 -  /// \tparam _Value The value type of the map.
 122.870 +  /// This type is not reference map, so it cannot be modified with
 122.871 +  /// the subscript operator.
 122.872 +  ///
 122.873 +  /// \tparam GR The graph type.
 122.874 +  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
 122.875 +  /// \c GR::Edge).
 122.876 +  /// \tparam V The value type of the map.
 122.877    ///
 122.878    /// \see IterableValueMap
 122.879 -  template <typename _Graph, typename _Item, typename _Value>
 122.880 -  class InvertableMap
 122.881 -    : protected ItemSetTraits<_Graph, _Item>::template Map<_Value>::Type {
 122.882 +  template <typename GR, typename K, typename V>
 122.883 +  class CrossRefMap
 122.884 +    : protected ItemSetTraits<GR, K>::template Map<V>::Type {
 122.885    private:
 122.886  
 122.887 -    typedef typename ItemSetTraits<_Graph, _Item>::
 122.888 -    template Map<_Value>::Type Map;
 122.889 -    typedef _Graph Graph;
 122.890 -
 122.891 -    typedef std::map<_Value, _Item> Container;
 122.892 +    typedef typename ItemSetTraits<GR, K>::
 122.893 +      template Map<V>::Type Map;
 122.894 +
 122.895 +    typedef std::multimap<V, K> Container;
 122.896      Container _inv_map;
 122.897  
 122.898    public:
 122.899  
 122.900 -    /// The key type of InvertableMap (Node, Arc, Edge).
 122.901 -    typedef typename Map::Key Key;
 122.902 -    /// The value type of the InvertableMap.
 122.903 -    typedef typename Map::Value Value;
 122.904 +    /// The graph type of CrossRefMap.
 122.905 +    typedef GR Graph;
 122.906 +    typedef GR Digraph;
 122.907 +    /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
 122.908 +    typedef K Item;
 122.909 +    /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
 122.910 +    typedef K Key;
 122.911 +    /// The value type of CrossRefMap.
 122.912 +    typedef V Value;
 122.913  
 122.914      /// \brief Constructor.
 122.915      ///
 122.916 -    /// Construct a new InvertableMap for the graph.
 122.917 -    ///
 122.918 -    explicit InvertableMap(const Graph& graph) : Map(graph) {}
 122.919 +    /// Construct a new CrossRefMap for the given graph.
 122.920 +    explicit CrossRefMap(const Graph& graph) : Map(graph) {}
 122.921  
 122.922      /// \brief Forward iterator for values.
 122.923      ///
 122.924 -    /// This iterator is an stl compatible forward
 122.925 +    /// This iterator is an STL compatible forward
 122.926      /// iterator on the values of the map. The values can
 122.927 -    /// be accessed in the [beginValue, endValue) range.
 122.928 -    ///
 122.929 -    class ValueIterator
 122.930 +    /// be accessed in the <tt>[beginValue, endValue)</tt> range.
 122.931 +    /// They are considered with multiplicity, so each value is
 122.932 +    /// traversed for each item it is assigned to.
 122.933 +    class ValueIt
 122.934        : public std::iterator<std::forward_iterator_tag, Value> {
 122.935 -      friend class InvertableMap;
 122.936 +      friend class CrossRefMap;
 122.937      private:
 122.938 -      ValueIterator(typename Container::const_iterator _it)
 122.939 +      ValueIt(typename Container::const_iterator _it)
 122.940          : it(_it) {}
 122.941      public:
 122.942  
 122.943 -      ValueIterator() {}
 122.944 -
 122.945 -      ValueIterator& operator++() { ++it; return *this; }
 122.946 -      ValueIterator operator++(int) {
 122.947 -        ValueIterator tmp(*this);
 122.948 +      /// Constructor
 122.949 +      ValueIt() {}
 122.950 +
 122.951 +      /// \e
 122.952 +      ValueIt& operator++() { ++it; return *this; }
 122.953 +      /// \e
 122.954 +      ValueIt operator++(int) {
 122.955 +        ValueIt tmp(*this);
 122.956          operator++();
 122.957          return tmp;
 122.958        }
 122.959  
 122.960 +      /// \e
 122.961        const Value& operator*() const { return it->first; }
 122.962 +      /// \e
 122.963        const Value* operator->() const { return &(it->first); }
 122.964  
 122.965 -      bool operator==(ValueIterator jt) const { return it == jt.it; }
 122.966 -      bool operator!=(ValueIterator jt) const { return it != jt.it; }
 122.967 +      /// \e
 122.968 +      bool operator==(ValueIt jt) const { return it == jt.it; }
 122.969 +      /// \e
 122.970 +      bool operator!=(ValueIt jt) const { return it != jt.it; }
 122.971  
 122.972      private:
 122.973        typename Container::const_iterator it;
 122.974      };
 122.975 +    
 122.976 +    /// Alias for \c ValueIt
 122.977 +    typedef ValueIt ValueIterator;
 122.978  
 122.979      /// \brief Returns an iterator to the first value.
 122.980      ///
 122.981 -    /// Returns an stl compatible iterator to the
 122.982 +    /// Returns an STL compatible iterator to the
 122.983      /// first value of the map. The values of the
 122.984 -    /// map can be accessed in the [beginValue, endValue)
 122.985 +    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
 122.986      /// range.
 122.987 -    ValueIterator beginValue() const {
 122.988 -      return ValueIterator(_inv_map.begin());
 122.989 +    ValueIt beginValue() const {
 122.990 +      return ValueIt(_inv_map.begin());
 122.991      }
 122.992  
 122.993      /// \brief Returns an iterator after the last value.
 122.994      ///
 122.995 -    /// Returns an stl compatible iterator after the
 122.996 +    /// Returns an STL compatible iterator after the
 122.997      /// last value of the map. The values of the
 122.998 -    /// map can be accessed in the [beginValue, endValue)
 122.999 +    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
122.1000      /// range.
122.1001 -    ValueIterator endValue() const {
122.1002 -      return ValueIterator(_inv_map.end());
122.1003 +    ValueIt endValue() const {
122.1004 +      return ValueIt(_inv_map.end());
122.1005      }
122.1006  
122.1007 -    /// \brief The setter function of the map.
122.1008 +    /// \brief Sets the value associated with the given key.
122.1009      ///
122.1010 -    /// Sets the mapped value.
122.1011 +    /// Sets the value associated with the given key.
122.1012      void set(const Key& key, const Value& val) {
122.1013        Value oldval = Map::operator[](key);
122.1014 -      typename Container::iterator it = _inv_map.find(oldval);
122.1015 -      if (it != _inv_map.end() && it->second == key) {
122.1016 -        _inv_map.erase(it);
122.1017 +      typename Container::iterator it;
122.1018 +      for (it = _inv_map.equal_range(oldval).first;
122.1019 +           it != _inv_map.equal_range(oldval).second; ++it) {
122.1020 +        if (it->second == key) {
122.1021 +          _inv_map.erase(it);
122.1022 +          break;
122.1023 +        }
122.1024        }
122.1025 -      _inv_map.insert(make_pair(val, key));
122.1026 +      _inv_map.insert(std::make_pair(val, key));
122.1027        Map::set(key, val);
122.1028      }
122.1029  
122.1030 -    /// \brief The getter function of the map.
122.1031 +    /// \brief Returns the value associated with the given key.
122.1032      ///
122.1033 -    /// It gives back the value associated with the key.
122.1034 +    /// Returns the value associated with the given key.
122.1035      typename MapTraits<Map>::ConstReturnValue
122.1036      operator[](const Key& key) const {
122.1037        return Map::operator[](key);
122.1038      }
122.1039  
122.1040 -    /// \brief Gives back the item by its value.
122.1041 +    /// \brief Gives back an item by its value.
122.1042      ///
122.1043 -    /// Gives back the item by its value.
122.1044 -    Key operator()(const Value& key) const {
122.1045 -      typename Container::const_iterator it = _inv_map.find(key);
122.1046 +    /// This function gives back an item that is assigned to
122.1047 +    /// the given value or \c INVALID if no such item exists.
122.1048 +    /// If there are more items with the same associated value,
122.1049 +    /// only one of them is returned.
122.1050 +    Key operator()(const Value& val) const {
122.1051 +      typename Container::const_iterator it = _inv_map.find(val);
122.1052        return it != _inv_map.end() ? it->second : INVALID;
122.1053      }
122.1054 +    
122.1055 +    /// \brief Returns the number of items with the given value.
122.1056 +    ///
122.1057 +    /// This function returns the number of items with the given value
122.1058 +    /// associated with it.
122.1059 +    int count(const Value &val) const {
122.1060 +      return _inv_map.count(val);
122.1061 +    }
122.1062  
122.1063    protected:
122.1064  
122.1065 -    /// \brief Erase the key from the map.
122.1066 +    /// \brief Erase the key from the map and the inverse map.
122.1067      ///
122.1068 -    /// Erase the key to the map. It is called by the
122.1069 +    /// Erase the key from the map and the inverse map. It is called by the
122.1070      /// \c AlterationNotifier.
122.1071      virtual void erase(const Key& key) {
122.1072        Value val = Map::operator[](key);
122.1073 -      typename Container::iterator it = _inv_map.find(val);
122.1074 -      if (it != _inv_map.end() && it->second == key) {
122.1075 -        _inv_map.erase(it);
122.1076 +      typename Container::iterator it;
122.1077 +      for (it = _inv_map.equal_range(val).first;
122.1078 +           it != _inv_map.equal_range(val).second; ++it) {
122.1079 +        if (it->second == key) {
122.1080 +          _inv_map.erase(it);
122.1081 +          break;
122.1082 +        }
122.1083        }
122.1084        Map::erase(key);
122.1085      }
122.1086  
122.1087 -    /// \brief Erase more keys from the map.
122.1088 +    /// \brief Erase more keys from the map and the inverse map.
122.1089      ///
122.1090 -    /// Erase more keys from the map. It is called by the
122.1091 +    /// Erase more keys from the map and the inverse map. It is called by the
122.1092      /// \c AlterationNotifier.
122.1093      virtual void erase(const std::vector<Key>& keys) {
122.1094        for (int i = 0; i < int(keys.size()); ++i) {
122.1095          Value val = Map::operator[](keys[i]);
122.1096 -        typename Container::iterator it = _inv_map.find(val);
122.1097 -        if (it != _inv_map.end() && it->second == keys[i]) {
122.1098 -          _inv_map.erase(it);
122.1099 +        typename Container::iterator it;
122.1100 +        for (it = _inv_map.equal_range(val).first;
122.1101 +             it != _inv_map.equal_range(val).second; ++it) {
122.1102 +          if (it->second == keys[i]) {
122.1103 +            _inv_map.erase(it);
122.1104 +            break;
122.1105 +          }
122.1106          }
122.1107        }
122.1108        Map::erase(keys);
122.1109      }
122.1110  
122.1111 -    /// \brief Clear the keys from the map and inverse map.
122.1112 +    /// \brief Clear the keys from the map and the inverse map.
122.1113      ///
122.1114 -    /// Clear the keys from the map and inverse map. It is called by the
122.1115 +    /// Clear the keys from the map and the inverse map. It is called by the
122.1116      /// \c AlterationNotifier.
122.1117      virtual void clear() {
122.1118        _inv_map.clear();
122.1119 @@ -2021,79 +2119,90 @@
122.1120  
122.1121    public:
122.1122  
122.1123 -    /// \brief The inverse map type.
122.1124 +    /// \brief The inverse map type of CrossRefMap.
122.1125      ///
122.1126 -    /// The inverse of this map. The subscript operator of the map
122.1127 -    /// gives back always the item what was last assigned to the value.
122.1128 +    /// The inverse map type of CrossRefMap. The subscript operator gives
122.1129 +    /// back an item by its value.
122.1130 +    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
122.1131 +    /// \see inverse()
122.1132      class InverseMap {
122.1133      public:
122.1134 -      /// \brief Constructor of the InverseMap.
122.1135 +      /// \brief Constructor
122.1136        ///
122.1137        /// Constructor of the InverseMap.
122.1138 -      explicit InverseMap(const InvertableMap& inverted)
122.1139 +      explicit InverseMap(const CrossRefMap& inverted)
122.1140          : _inverted(inverted) {}
122.1141  
122.1142        /// The value type of the InverseMap.
122.1143 -      typedef typename InvertableMap::Key Value;
122.1144 +      typedef typename CrossRefMap::Key Value;
122.1145        /// The key type of the InverseMap.
122.1146 -      typedef typename InvertableMap::Value Key;
122.1147 +      typedef typename CrossRefMap::Value Key;
122.1148  
122.1149        /// \brief Subscript operator.
122.1150        ///
122.1151 -      /// Subscript operator. It gives back always the item
122.1152 -      /// what was last assigned to the value.
122.1153 +      /// Subscript operator. It gives back an item
122.1154 +      /// that is assigned to the given value or \c INVALID
122.1155 +      /// if no such item exists.
122.1156        Value operator[](const Key& key) const {
122.1157          return _inverted(key);
122.1158        }
122.1159  
122.1160      private:
122.1161 -      const InvertableMap& _inverted;
122.1162 +      const CrossRefMap& _inverted;
122.1163      };
122.1164  
122.1165 -    /// \brief It gives back the just readable inverse map.
122.1166 +    /// \brief Gives back the inverse of the map.
122.1167      ///
122.1168 -    /// It gives back the just readable inverse map.
122.1169 +    /// Gives back the inverse of the CrossRefMap.
122.1170      InverseMap inverse() const {
122.1171        return InverseMap(*this);
122.1172      }
122.1173  
122.1174    };
122.1175  
122.1176 -  /// \brief Provides a mutable, continuous and unique descriptor for each
122.1177 -  /// item in the graph.
122.1178 +  /// \brief Provides continuous and unique id for the
122.1179 +  /// items of a graph.
122.1180    ///
122.1181 -  /// The DescriptorMap class provides a unique and continuous (but mutable)
122.1182 -  /// descriptor (id) for each item of the same type (e.g. node) in the
122.1183 -  /// graph. This id is <ul><li>\b unique: different items (nodes) get
122.1184 -  /// different ids <li>\b continuous: the range of the ids is the set of
122.1185 -  /// integers between 0 and \c n-1, where \c n is the number of the items of
122.1186 -  /// this type (e.g. nodes) (so the id of a node can change if you delete an
122.1187 -  /// other node, i.e. this id is mutable).  </ul> This map can be inverted
122.1188 -  /// with its member class \c InverseMap, or with the \c operator() member.
122.1189 +  /// RangeIdMap provides a unique and continuous
122.1190 +  /// id for each item of a given type (\c Node, \c Arc or
122.1191 +  /// \c Edge) in a graph. This id is
122.1192 +  ///  - \b unique: different items get different ids,
122.1193 +  ///  - \b continuous: the range of the ids is the set of integers
122.1194 +  ///    between 0 and \c n-1, where \c n is the number of the items of
122.1195 +  ///    this type (\c Node, \c Arc or \c Edge).
122.1196 +  ///  - So, the ids can change when deleting an item of the same type.
122.1197    ///
122.1198 -  /// \tparam _Graph The graph class the \c DescriptorMap belongs to.
122.1199 -  /// \tparam _Item The Item is the Key of the Map. It may be Node, Arc or
122.1200 -  /// Edge.
122.1201 -  template <typename _Graph, typename _Item>
122.1202 -  class DescriptorMap
122.1203 -    : protected ItemSetTraits<_Graph, _Item>::template Map<int>::Type {
122.1204 -
122.1205 -    typedef _Item Item;
122.1206 -    typedef typename ItemSetTraits<_Graph, _Item>::template Map<int>::Type Map;
122.1207 +  /// Thus this id is not (necessarily) the same as what can get using
122.1208 +  /// the \c id() function of the graph or \ref IdMap.
122.1209 +  /// This map can be inverted with its member class \c InverseMap,
122.1210 +  /// or with the \c operator()() member.
122.1211 +  ///
122.1212 +  /// \tparam GR The graph type.
122.1213 +  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
122.1214 +  /// \c GR::Edge).
122.1215 +  ///
122.1216 +  /// \see IdMap
122.1217 +  template <typename GR, typename K>
122.1218 +  class RangeIdMap
122.1219 +    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
122.1220 +
122.1221 +    typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Map;
122.1222  
122.1223    public:
122.1224 -    /// The graph class of DescriptorMap.
122.1225 -    typedef _Graph Graph;
122.1226 -
122.1227 -    /// The key type of DescriptorMap (Node, Arc, Edge).
122.1228 -    typedef typename Map::Key Key;
122.1229 -    /// The value type of DescriptorMap.
122.1230 -    typedef typename Map::Value Value;
122.1231 +    /// The graph type of RangeIdMap.
122.1232 +    typedef GR Graph;
122.1233 +    typedef GR Digraph;
122.1234 +    /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
122.1235 +    typedef K Item;
122.1236 +    /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
122.1237 +    typedef K Key;
122.1238 +    /// The value type of RangeIdMap.
122.1239 +    typedef int Value;
122.1240  
122.1241      /// \brief Constructor.
122.1242      ///
122.1243 -    /// Constructor for descriptor map.
122.1244 -    explicit DescriptorMap(const Graph& _graph) : Map(_graph) {
122.1245 +    /// Constructor.
122.1246 +    explicit RangeIdMap(const Graph& gr) : Map(gr) {
122.1247        Item it;
122.1248        const typename Map::Notifier* nf = Map::notifier();
122.1249        for (nf->first(it); it != INVALID; nf->next(it)) {
122.1250 @@ -2104,7 +2213,7 @@
122.1251  
122.1252    protected:
122.1253  
122.1254 -    /// \brief Add a new key to the map.
122.1255 +    /// \brief Adds a new key to the map.
122.1256      ///
122.1257      /// Add a new key to the map. It is called by the
122.1258      /// \c AlterationNotifier.
122.1259 @@ -2194,16 +2303,16 @@
122.1260        _inv_map[pi] = q;
122.1261      }
122.1262  
122.1263 -    /// \brief Gives back the \e descriptor of the item.
122.1264 +    /// \brief Gives back the \e range \e id of the item
122.1265      ///
122.1266 -    /// Gives back the mutable and unique \e descriptor of the map.
122.1267 +    /// Gives back the \e range \e id of the item.
122.1268      int operator[](const Item& item) const {
122.1269        return Map::operator[](item);
122.1270      }
122.1271  
122.1272 -    /// \brief Gives back the item by its descriptor.
122.1273 +    /// \brief Gives back the item belonging to a \e range \e id
122.1274      ///
122.1275 -    /// Gives back th item by its descriptor.
122.1276 +    /// Gives back the item belonging to the given \e range \e id.
122.1277      Item operator()(int id) const {
122.1278        return _inv_map[id];
122.1279      }
122.1280 @@ -2214,27 +2323,30 @@
122.1281      Container _inv_map;
122.1282  
122.1283    public:
122.1284 -    /// \brief The inverse map type of DescriptorMap.
122.1285 +
122.1286 +    /// \brief The inverse map type of RangeIdMap.
122.1287      ///
122.1288 -    /// The inverse map type of DescriptorMap.
122.1289 +    /// The inverse map type of RangeIdMap. The subscript operator gives
122.1290 +    /// back an item by its \e range \e id.
122.1291 +    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
122.1292      class InverseMap {
122.1293      public:
122.1294 -      /// \brief Constructor of the InverseMap.
122.1295 +      /// \brief Constructor
122.1296        ///
122.1297        /// Constructor of the InverseMap.
122.1298 -      explicit InverseMap(const DescriptorMap& inverted)
122.1299 +      explicit InverseMap(const RangeIdMap& inverted)
122.1300          : _inverted(inverted) {}
122.1301  
122.1302  
122.1303        /// The value type of the InverseMap.
122.1304 -      typedef typename DescriptorMap::Key Value;
122.1305 +      typedef typename RangeIdMap::Key Value;
122.1306        /// The key type of the InverseMap.
122.1307 -      typedef typename DescriptorMap::Value Key;
122.1308 +      typedef typename RangeIdMap::Value Key;
122.1309  
122.1310        /// \brief Subscript operator.
122.1311        ///
122.1312        /// Subscript operator. It gives back the item
122.1313 -      /// that the descriptor belongs to currently.
122.1314 +      /// that the given \e range \e id currently belongs to.
122.1315        Value operator[](const Key& key) const {
122.1316          return _inverted(key);
122.1317        }
122.1318 @@ -2247,241 +2359,1134 @@
122.1319        }
122.1320  
122.1321      private:
122.1322 -      const DescriptorMap& _inverted;
122.1323 +      const RangeIdMap& _inverted;
122.1324      };
122.1325  
122.1326      /// \brief Gives back the inverse of the map.
122.1327      ///
122.1328 -    /// Gives back the inverse of the map.
122.1329 +    /// Gives back the inverse of the RangeIdMap.
122.1330      const InverseMap inverse() const {
122.1331        return InverseMap(*this);
122.1332      }
122.1333    };
122.1334  
122.1335 -  /// \brief Returns the source of the given arc.
122.1336 +  /// \brief Returns a \c RangeIdMap class.
122.1337    ///
122.1338 -  /// The SourceMap gives back the source Node of the given arc.
122.1339 +  /// This function just returns an \c RangeIdMap class.
122.1340 +  /// \relates RangeIdMap
122.1341 +  template <typename K, typename GR>
122.1342 +  inline RangeIdMap<GR, K> rangeIdMap(const GR& graph) {
122.1343 +    return RangeIdMap<GR, K>(graph);
122.1344 +  }
122.1345 +  
122.1346 +  /// \brief Dynamic iterable \c bool map.
122.1347 +  ///
122.1348 +  /// This class provides a special graph map type which can store a
122.1349 +  /// \c bool value for graph items (\c Node, \c Arc or \c Edge).
122.1350 +  /// For both \c true and \c false values it is possible to iterate on
122.1351 +  /// the keys mapped to the value.
122.1352 +  ///
122.1353 +  /// This type is a reference map, so it can be modified with the
122.1354 +  /// subscript operator.
122.1355 +  ///
122.1356 +  /// \tparam GR The graph type.
122.1357 +  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
122.1358 +  /// \c GR::Edge).
122.1359 +  ///
122.1360 +  /// \see IterableIntMap, IterableValueMap
122.1361 +  /// \see CrossRefMap
122.1362 +  template <typename GR, typename K>
122.1363 +  class IterableBoolMap
122.1364 +    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
122.1365 +  private:
122.1366 +    typedef GR Graph;
122.1367 +
122.1368 +    typedef typename ItemSetTraits<GR, K>::ItemIt KeyIt;
122.1369 +    typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Parent;
122.1370 +
122.1371 +    std::vector<K> _array;
122.1372 +    int _sep;
122.1373 +
122.1374 +  public:
122.1375 +
122.1376 +    /// Indicates that the map is reference map.
122.1377 +    typedef True ReferenceMapTag;
122.1378 +
122.1379 +    /// The key type
122.1380 +    typedef K Key;
122.1381 +    /// The value type
122.1382 +    typedef bool Value;
122.1383 +    /// The const reference type.
122.1384 +    typedef const Value& ConstReference;
122.1385 +
122.1386 +  private:
122.1387 +
122.1388 +    int position(const Key& key) const {
122.1389 +      return Parent::operator[](key);
122.1390 +    }
122.1391 +
122.1392 +  public:
122.1393 +
122.1394 +    /// \brief Reference to the value of the map.
122.1395 +    ///
122.1396 +    /// This class is similar to the \c bool type. It can be converted to
122.1397 +    /// \c bool and it provides the same operators.
122.1398 +    class Reference {
122.1399 +      friend class IterableBoolMap;
122.1400 +    private:
122.1401 +      Reference(IterableBoolMap& map, const Key& key)
122.1402 +        : _key(key), _map(map) {}
122.1403 +    public:
122.1404 +
122.1405 +      Reference& operator=(const Reference& value) {
122.1406 +        _map.set(_key, static_cast<bool>(value));
122.1407 +         return *this;
122.1408 +      }
122.1409 +
122.1410 +      operator bool() const {
122.1411 +        return static_cast<const IterableBoolMap&>(_map)[_key];
122.1412 +      }
122.1413 +
122.1414 +      Reference& operator=(bool value) {
122.1415 +        _map.set(_key, value);
122.1416 +        return *this;
122.1417 +      }
122.1418 +      Reference& operator&=(bool value) {
122.1419 +        _map.set(_key, _map[_key] & value);
122.1420 +        return *this;
122.1421 +      }
122.1422 +      Reference& operator|=(bool value) {
122.1423 +        _map.set(_key, _map[_key] | value);
122.1424 +        return *this;
122.1425 +      }
122.1426 +      Reference& operator^=(bool value) {
122.1427 +        _map.set(_key, _map[_key] ^ value);
122.1428 +        return *this;
122.1429 +      }
122.1430 +    private:
122.1431 +      Key _key;
122.1432 +      IterableBoolMap& _map;
122.1433 +    };
122.1434 +
122.1435 +    /// \brief Constructor of the map with a default value.
122.1436 +    ///
122.1437 +    /// Constructor of the map with a default value.
122.1438 +    explicit IterableBoolMap(const Graph& graph, bool def = false)
122.1439 +      : Parent(graph) {
122.1440 +      typename Parent::Notifier* nf = Parent::notifier();
122.1441 +      Key it;
122.1442 +      for (nf->first(it); it != INVALID; nf->next(it)) {
122.1443 +        Parent::set(it, _array.size());
122.1444 +        _array.push_back(it);
122.1445 +      }
122.1446 +      _sep = (def ? _array.size() : 0);
122.1447 +    }
122.1448 +
122.1449 +    /// \brief Const subscript operator of the map.
122.1450 +    ///
122.1451 +    /// Const subscript operator of the map.
122.1452 +    bool operator[](const Key& key) const {
122.1453 +      return position(key) < _sep;
122.1454 +    }
122.1455 +
122.1456 +    /// \brief Subscript operator of the map.
122.1457 +    ///
122.1458 +    /// Subscript operator of the map.
122.1459 +    Reference operator[](const Key& key) {
122.1460 +      return Reference(*this, key);
122.1461 +    }
122.1462 +
122.1463 +    /// \brief Set operation of the map.
122.1464 +    ///
122.1465 +    /// Set operation of the map.
122.1466 +    void set(const Key& key, bool value) {
122.1467 +      int pos = position(key);
122.1468 +      if (value) {
122.1469 +        if (pos < _sep) return;
122.1470 +        Key tmp = _array[_sep];
122.1471 +        _array[_sep] = key;
122.1472 +        Parent::set(key, _sep);
122.1473 +        _array[pos] = tmp;
122.1474 +        Parent::set(tmp, pos);
122.1475 +        ++_sep;
122.1476 +      } else {
122.1477 +        if (pos >= _sep) return;
122.1478 +        --_sep;
122.1479 +        Key tmp = _array[_sep];
122.1480 +        _array[_sep] = key;
122.1481 +        Parent::set(key, _sep);
122.1482 +        _array[pos] = tmp;
122.1483 +        Parent::set(tmp, pos);
122.1484 +      }
122.1485 +    }
122.1486 +
122.1487 +    /// \brief Set all items.
122.1488 +    ///
122.1489 +    /// Set all items in the map.
122.1490 +    /// \note Constant time operation.
122.1491 +    void setAll(bool value) {
122.1492 +      _sep = (value ? _array.size() : 0);
122.1493 +    }
122.1494 +
122.1495 +    /// \brief Returns the number of the keys mapped to \c true.
122.1496 +    ///
122.1497 +    /// Returns the number of the keys mapped to \c true.
122.1498 +    int trueNum() const {
122.1499 +      return _sep;
122.1500 +    }
122.1501 +
122.1502 +    /// \brief Returns the number of the keys mapped to \c false.
122.1503 +    ///
122.1504 +    /// Returns the number of the keys mapped to \c false.
122.1505 +    int falseNum() const {
122.1506 +      return _array.size() - _sep;
122.1507 +    }
122.1508 +
122.1509 +    /// \brief Iterator for the keys mapped to \c true.
122.1510 +    ///
122.1511 +    /// Iterator for the keys mapped to \c true. It works
122.1512 +    /// like a graph item iterator, it can be converted to
122.1513 +    /// the key type of the map, incremented with \c ++ operator, and
122.1514 +    /// if the iterator leaves the last valid key, it will be equal to
122.1515 +    /// \c INVALID.
122.1516 +    class TrueIt : public Key {
122.1517 +    public:
122.1518 +      typedef Key Parent;
122.1519 +
122.1520 +      /// \brief Creates an iterator.
122.1521 +      ///
122.1522 +      /// Creates an iterator. It iterates on the
122.1523 +      /// keys mapped to \c true.
122.1524 +      /// \param map The IterableBoolMap.
122.1525 +      explicit TrueIt(const IterableBoolMap& map)
122.1526 +        : Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID),
122.1527 +          _map(&map) {}
122.1528 +
122.1529 +      /// \brief Invalid constructor \& conversion.
122.1530 +      ///
122.1531 +      /// This constructor initializes the iterator to be invalid.
122.1532 +      /// \sa Invalid for more details.
122.1533 +      TrueIt(Invalid) : Parent(INVALID), _map(0) {}
122.1534 +
122.1535 +      /// \brief Increment operator.
122.1536 +      ///
122.1537 +      /// Increment operator.
122.1538 +      TrueIt& operator++() {
122.1539 +        int pos = _map->position(*this);
122.1540 +        Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID);
122.1541 +        return *this;
122.1542 +      }
122.1543 +
122.1544 +    private:
122.1545 +      const IterableBoolMap* _map;
122.1546 +    };
122.1547 +
122.1548 +    /// \brief Iterator for the keys mapped to \c false.
122.1549 +    ///
122.1550 +    /// Iterator for the keys mapped to \c false. It works
122.1551 +    /// like a graph item iterator, it can be converted to
122.1552 +    /// the key type of the map, incremented with \c ++ operator, and
122.1553 +    /// if the iterator leaves the last valid key, it will be equal to
122.1554 +    /// \c INVALID.
122.1555 +    class FalseIt : public Key {
122.1556 +    public:
122.1557 +      typedef Key Parent;
122.1558 +
122.1559 +      /// \brief Creates an iterator.
122.1560 +      ///
122.1561 +      /// Creates an iterator. It iterates on the
122.1562 +      /// keys mapped to \c false.
122.1563 +      /// \param map The IterableBoolMap.
122.1564 +      explicit FalseIt(const IterableBoolMap& map)
122.1565 +        : Parent(map._sep < int(map._array.size()) ?
122.1566 +                 map._array.back() : INVALID), _map(&map) {}
122.1567 +
122.1568 +      /// \brief Invalid constructor \& conversion.
122.1569 +      ///
122.1570 +      /// This constructor initializes the iterator to be invalid.
122.1571 +      /// \sa Invalid for more details.
122.1572 +      FalseIt(Invalid) : Parent(INVALID), _map(0) {}
122.1573 +
122.1574 +      /// \brief Increment operator.
122.1575 +      ///
122.1576 +      /// Increment operator.
122.1577 +      FalseIt& operator++() {
122.1578 +        int pos = _map->position(*this);
122.1579 +        Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID);
122.1580 +        return *this;
122.1581 +      }
122.1582 +
122.1583 +    private:
122.1584 +      const IterableBoolMap* _map;
122.1585 +    };
122.1586 +
122.1587 +    /// \brief Iterator for the keys mapped to a given value.
122.1588 +    ///
122.1589 +    /// Iterator for the keys mapped to a given value. It works
122.1590 +    /// like a graph item iterator, it can be converted to
122.1591 +    /// the key type of the map, incremented with \c ++ operator, and
122.1592 +    /// if the iterator leaves the last valid key, it will be equal to
122.1593 +    /// \c INVALID.
122.1594 +    class ItemIt : public Key {
122.1595 +    public:
122.1596 +      typedef Key Parent;
122.1597 +
122.1598 +      /// \brief Creates an iterator with a value.
122.1599 +      ///
122.1600 +      /// Creates an iterator with a value. It iterates on the
122.1601 +      /// keys mapped to the given value.
122.1602 +      /// \param map The IterableBoolMap.
122.1603 +      /// \param value The value.
122.1604 +      ItemIt(const IterableBoolMap& map, bool value)
122.1605 +        : Parent(value ? 
122.1606 +                 (map._sep > 0 ?
122.1607 +                  map._array[map._sep - 1] : INVALID) :
122.1608 +                 (map._sep < int(map._array.size()) ?
122.1609 +                  map._array.back() : INVALID)), _map(&map) {}
122.1610 +
122.1611 +      /// \brief Invalid constructor \& conversion.
122.1612 +      ///
122.1613 +      /// This constructor initializes the iterator to be invalid.
122.1614 +      /// \sa Invalid for more details.
122.1615 +      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
122.1616 +
122.1617 +      /// \brief Increment operator.
122.1618 +      ///
122.1619 +      /// Increment operator.
122.1620 +      ItemIt& operator++() {
122.1621 +        int pos = _map->position(*this);
122.1622 +        int _sep = pos >= _map->_sep ? _map->_sep : 0;
122.1623 +        Parent::operator=(pos > _sep ? _map->_array[pos - 1] : INVALID);
122.1624 +        return *this;
122.1625 +      }
122.1626 +
122.1627 +    private:
122.1628 +      const IterableBoolMap* _map;
122.1629 +    };
122.1630 +
122.1631 +  protected:
122.1632 +
122.1633 +    virtual void add(const Key& key) {
122.1634 +      Parent::add(key);
122.1635 +      Parent::set(key, _array.size());
122.1636 +      _array.push_back(key);
122.1637 +    }
122.1638 +
122.1639 +    virtual void add(const std::vector<Key>& keys) {
122.1640 +      Parent::add(keys);
122.1641 +      for (int i = 0; i < int(keys.size()); ++i) {
122.1642 +        Parent::set(keys[i], _array.size());
122.1643 +        _array.push_back(keys[i]);
122.1644 +      }
122.1645 +    }
122.1646 +
122.1647 +    virtual void erase(const Key& key) {
122.1648 +      int pos = position(key);
122.1649 +      if (pos < _sep) {
122.1650 +        --_sep;
122.1651 +        Parent::set(_array[_sep], pos);
122.1652 +        _array[pos] = _array[_sep];
122.1653 +        Parent::set(_array.back(), _sep);
122.1654 +        _array[_sep] = _array.back();
122.1655 +        _array.pop_back();
122.1656 +      } else {
122.1657 +        Parent::set(_array.back(), pos);
122.1658 +        _array[pos] = _array.back();
122.1659 +        _array.pop_back();
122.1660 +      }
122.1661 +      Parent::erase(key);
122.1662 +    }
122.1663 +
122.1664 +    virtual void erase(const std::vector<Key>& keys) {
122.1665 +      for (int i = 0; i < int(keys.size()); ++i) {
122.1666 +        int pos = position(keys[i]);
122.1667 +        if (pos < _sep) {
122.1668 +          --_sep;
122.1669 +          Parent::set(_array[_sep], pos);
122.1670 +          _array[pos] = _array[_sep];
122.1671 +          Parent::set(_array.back(), _sep);
122.1672 +          _array[_sep] = _array.back();
122.1673 +          _array.pop_back();
122.1674 +        } else {
122.1675 +          Parent::set(_array.back(), pos);
122.1676 +          _array[pos] = _array.back();
122.1677 +          _array.pop_back();
122.1678 +        }
122.1679 +      }
122.1680 +      Parent::erase(keys);
122.1681 +    }
122.1682 +
122.1683 +    virtual void build() {
122.1684 +      Parent::build();
122.1685 +      typename Parent::Notifier* nf = Parent::notifier();
122.1686 +      Key it;
122.1687 +      for (nf->first(it); it != INVALID; nf->next(it)) {
122.1688 +        Parent::set(it, _array.size());
122.1689 +        _array.push_back(it);
122.1690 +      }
122.1691 +      _sep = 0;
122.1692 +    }
122.1693 +
122.1694 +    virtual void clear() {
122.1695 +      _array.clear();
122.1696 +      _sep = 0;
122.1697 +      Parent::clear();
122.1698 +    }
122.1699 +
122.1700 +  };
122.1701 +
122.1702 +
122.1703 +  namespace _maps_bits {
122.1704 +    template <typename Item>
122.1705 +    struct IterableIntMapNode {
122.1706 +      IterableIntMapNode() : value(-1) {}
122.1707 +      IterableIntMapNode(int _value) : value(_value) {}
122.1708 +      Item prev, next;
122.1709 +      int value;
122.1710 +    };
122.1711 +  }
122.1712 +
122.1713 +  /// \brief Dynamic iterable integer map.
122.1714 +  ///
122.1715 +  /// This class provides a special graph map type which can store an
122.1716 +  /// integer value for graph items (\c Node, \c Arc or \c Edge).
122.1717 +  /// For each non-negative value it is possible to iterate on the keys
122.1718 +  /// mapped to the value.
122.1719 +  ///
122.1720 +  /// This map is intended to be used with small integer values, for which
122.1721 +  /// it is efficient, and supports iteration only for non-negative values.
122.1722 +  /// If you need large values and/or iteration for negative integers,
122.1723 +  /// consider to use \ref IterableValueMap instead.
122.1724 +  ///
122.1725 +  /// This type is a reference map, so it can be modified with the
122.1726 +  /// subscript operator.
122.1727 +  ///
122.1728 +  /// \note The size of the data structure depends on the largest
122.1729 +  /// value in the map.
122.1730 +  ///
122.1731 +  /// \tparam GR The graph type.
122.1732 +  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
122.1733 +  /// \c GR::Edge).
122.1734 +  ///
122.1735 +  /// \see IterableBoolMap, IterableValueMap
122.1736 +  /// \see CrossRefMap
122.1737 +  template <typename GR, typename K>
122.1738 +  class IterableIntMap
122.1739 +    : protected ItemSetTraits<GR, K>::
122.1740 +        template Map<_maps_bits::IterableIntMapNode<K> >::Type {
122.1741 +  public:
122.1742 +    typedef typename ItemSetTraits<GR, K>::
122.1743 +      template Map<_maps_bits::IterableIntMapNode<K> >::Type Parent;
122.1744 +
122.1745 +    /// The key type
122.1746 +    typedef K Key;
122.1747 +    /// The value type
122.1748 +    typedef int Value;
122.1749 +    /// The graph type
122.1750 +    typedef GR Graph;
122.1751 +
122.1752 +    /// \brief Constructor of the map.
122.1753 +    ///
122.1754 +    /// Constructor of the map. It sets all values to -1.
122.1755 +    explicit IterableIntMap(const Graph& graph)
122.1756 +      : Parent(graph) {}
122.1757 +
122.1758 +    /// \brief Constructor of the map with a given value.
122.1759 +    ///
122.1760 +    /// Constructor of the map with a given value.
122.1761 +    explicit IterableIntMap(const Graph& graph, int value)
122.1762 +      : Parent(graph, _maps_bits::IterableIntMapNode<K>(value)) {
122.1763 +      if (value >= 0) {
122.1764 +        for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
122.1765 +          lace(it);
122.1766 +        }
122.1767 +      }
122.1768 +    }
122.1769 +
122.1770 +  private:
122.1771 +
122.1772 +    void unlace(const Key& key) {
122.1773 +      typename Parent::Value& node = Parent::operator[](key);
122.1774 +      if (node.value < 0) return;
122.1775 +      if (node.prev != INVALID) {
122.1776 +        Parent::operator[](node.prev).next = node.next;
122.1777 +      } else {
122.1778 +        _first[node.value] = node.next;
122.1779 +      }
122.1780 +      if (node.next != INVALID) {
122.1781 +        Parent::operator[](node.next).prev = node.prev;
122.1782 +      }
122.1783 +      while (!_first.empty() && _first.back() == INVALID) {
122.1784 +        _first.pop_back();
122.1785 +      }
122.1786 +    }
122.1787 +
122.1788 +    void lace(const Key& key) {
122.1789 +      typename Parent::Value& node = Parent::operator[](key);
122.1790 +      if (node.value < 0) return;
122.1791 +      if (node.value >= int(_first.size())) {
122.1792 +        _first.resize(node.value + 1, INVALID);
122.1793 +      }
122.1794 +      node.prev = INVALID;
122.1795 +      node.next = _first[node.value];
122.1796 +      if (node.next != INVALID) {
122.1797 +        Parent::operator[](node.next).prev = key;
122.1798 +      }
122.1799 +      _first[node.value] = key;
122.1800 +    }
122.1801 +
122.1802 +  public:
122.1803 +
122.1804 +    /// Indicates that the map is reference map.
122.1805 +    typedef True ReferenceMapTag;
122.1806 +
122.1807 +    /// \brief Reference to the value of the map.
122.1808 +    ///
122.1809 +    /// This class is similar to the \c int type. It can
122.1810 +    /// be converted to \c int and it has the same operators.
122.1811 +    class Reference {
122.1812 +      friend class IterableIntMap;
122.1813 +    private:
122.1814 +      Reference(IterableIntMap& map, const Key& key)
122.1815 +        : _key(key), _map(map) {}
122.1816 +    public:
122.1817 +
122.1818 +      Reference& operator=(const Reference& value) {
122.1819 +        _map.set(_key, static_cast<const int&>(value));
122.1820 +         return *this;
122.1821 +      }
122.1822 +
122.1823 +      operator const int&() const {
122.1824 +        return static_cast<const IterableIntMap&>(_map)[_key];
122.1825 +      }
122.1826 +
122.1827 +      Reference& operator=(int value) {
122.1828 +        _map.set(_key, value);
122.1829 +        return *this;
122.1830 +      }
122.1831 +      Reference& operator++() {
122.1832 +        _map.set(_key, _map[_key] + 1);
122.1833 +        return *this;
122.1834 +      }
122.1835 +      int operator++(int) {
122.1836 +        int value = _map[_key];
122.1837 +        _map.set(_key, value + 1);
122.1838 +        return value;
122.1839 +      }
122.1840 +      Reference& operator--() {
122.1841 +        _map.set(_key, _map[_key] - 1);
122.1842 +        return *this;
122.1843 +      }
122.1844 +      int operator--(int) {
122.1845 +        int value = _map[_key];
122.1846 +        _map.set(_key, value - 1);
122.1847 +        return value;
122.1848 +      }
122.1849 +      Reference& operator+=(int value) {
122.1850 +        _map.set(_key, _map[_key] + value);
122.1851 +        return *this;
122.1852 +      }
122.1853 +      Reference& operator-=(int value) {
122.1854 +        _map.set(_key, _map[_key] - value);
122.1855 +        return *this;
122.1856 +      }
122.1857 +      Reference& operator*=(int value) {
122.1858 +        _map.set(_key, _map[_key] * value);
122.1859 +        return *this;
122.1860 +      }
122.1861 +      Reference& operator/=(int value) {
122.1862 +        _map.set(_key, _map[_key] / value);
122.1863 +        return *this;
122.1864 +      }
122.1865 +      Reference& operator%=(int value) {
122.1866 +        _map.set(_key, _map[_key] % value);
122.1867 +        return *this;
122.1868 +      }
122.1869 +      Reference& operator&=(int value) {
122.1870 +        _map.set(_key, _map[_key] & value);
122.1871 +        return *this;
122.1872 +      }
122.1873 +      Reference& operator|=(int value) {
122.1874 +        _map.set(_key, _map[_key] | value);
122.1875 +        return *this;
122.1876 +      }
122.1877 +      Reference& operator^=(int value) {
122.1878 +        _map.set(_key, _map[_key] ^ value);
122.1879 +        return *this;
122.1880 +      }
122.1881 +      Reference& operator<<=(int value) {
122.1882 +        _map.set(_key, _map[_key] << value);
122.1883 +        return *this;
122.1884 +      }
122.1885 +      Reference& operator>>=(int value) {
122.1886 +        _map.set(_key, _map[_key] >> value);
122.1887 +        return *this;
122.1888 +      }
122.1889 +
122.1890 +    private:
122.1891 +      Key _key;
122.1892 +      IterableIntMap& _map;
122.1893 +    };
122.1894 +
122.1895 +    /// The const reference type.
122.1896 +    typedef const Value& ConstReference;
122.1897 +
122.1898 +    /// \brief Gives back the maximal value plus one.
122.1899 +    ///
122.1900 +    /// Gives back the maximal value plus one.
122.1901 +    int size() const {
122.1902 +      return _first.size();
122.1903 +    }
122.1904 +
122.1905 +    /// \brief Set operation of the map.
122.1906 +    ///
122.1907 +    /// Set operation of the map.
122.1908 +    void set(const Key& key, const Value& value) {
122.1909 +      unlace(key);
122.1910 +      Parent::operator[](key).value = value;
122.1911 +      lace(key);
122.1912 +    }
122.1913 +
122.1914 +    /// \brief Const subscript operator of the map.
122.1915 +    ///
122.1916 +    /// Const subscript operator of the map.
122.1917 +    const Value& operator[](const Key& key) const {
122.1918 +      return Parent::operator[](key).value;
122.1919 +    }
122.1920 +
122.1921 +    /// \brief Subscript operator of the map.
122.1922 +    ///
122.1923 +    /// Subscript operator of the map.
122.1924 +    Reference operator[](const Key& key) {
122.1925 +      return Reference(*this, key);
122.1926 +    }
122.1927 +
122.1928 +    /// \brief Iterator for the keys with the same value.
122.1929 +    ///
122.1930 +    /// Iterator for the keys with the same value. It works
122.1931 +    /// like a graph item iterator, it can be converted to
122.1932 +    /// the item type of the map, incremented with \c ++ operator, and
122.1933 +    /// if the iterator leaves the last valid item, it will be equal to
122.1934 +    /// \c INVALID.
122.1935 +    class ItemIt : public Key {
122.1936 +    public:
122.1937 +      typedef Key Parent;
122.1938 +
122.1939 +      /// \brief Invalid constructor \& conversion.
122.1940 +      ///
122.1941 +      /// This constructor initializes the iterator to be invalid.
122.1942 +      /// \sa Invalid for more details.
122.1943 +      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
122.1944 +
122.1945 +      /// \brief Creates an iterator with a value.
122.1946 +      ///
122.1947 +      /// Creates an iterator with a value. It iterates on the
122.1948 +      /// keys mapped to the given value.
122.1949 +      /// \param map The IterableIntMap.
122.1950 +      /// \param value The value.
122.1951 +      ItemIt(const IterableIntMap& map, int value) : _map(&map) {
122.1952 +        if (value < 0 || value >= int(_map->_first.size())) {
122.1953 +          Parent::operator=(INVALID);
122.1954 +        } else {
122.1955 +          Parent::operator=(_map->_first[value]);
122.1956 +        }
122.1957 +      }
122.1958 +
122.1959 +      /// \brief Increment operator.
122.1960 +      ///
122.1961 +      /// Increment operator.
122.1962 +      ItemIt& operator++() {
122.1963 +        Parent::operator=(_map->IterableIntMap::Parent::
122.1964 +                          operator[](static_cast<Parent&>(*this)).next);
122.1965 +        return *this;
122.1966 +      }
122.1967 +
122.1968 +    private:
122.1969 +      const IterableIntMap* _map;
122.1970 +    };
122.1971 +
122.1972 +  protected:
122.1973 +
122.1974 +    virtual void erase(const Key& key) {
122.1975 +      unlace(key);
122.1976 +      Parent::erase(key);
122.1977 +    }
122.1978 +
122.1979 +    virtual void erase(const std::vector<Key>& keys) {
122.1980 +      for (int i = 0; i < int(keys.size()); ++i) {
122.1981 +        unlace(keys[i]);
122.1982 +      }
122.1983 +      Parent::erase(keys);
122.1984 +    }
122.1985 +
122.1986 +    virtual void clear() {
122.1987 +      _first.clear();
122.1988 +      Parent::clear();
122.1989 +    }
122.1990 +
122.1991 +  private:
122.1992 +    std::vector<Key> _first;
122.1993 +  };
122.1994 +
122.1995 +  namespace _maps_bits {
122.1996 +    template <typename Item, typename Value>
122.1997 +    struct IterableValueMapNode {
122.1998 +      IterableValueMapNode(Value _value = Value()) : value(_value) {}
122.1999 +      Item prev, next;
122.2000 +      Value value;
122.2001 +    };
122.2002 +  }
122.2003 +
122.2004 +  /// \brief Dynamic iterable map for comparable values.
122.2005 +  ///
122.2006 +  /// This class provides a special graph map type which can store a
122.2007 +  /// comparable value for graph items (\c Node, \c Arc or \c Edge).
122.2008 +  /// For each value it is possible to iterate on the keys mapped to
122.2009 +  /// the value (\c ItemIt), and the values of the map can be accessed
122.2010 +  /// with an STL compatible forward iterator (\c ValueIt).
122.2011 +  /// The map stores a linked list for each value, which contains
122.2012 +  /// the items mapped to the value, and the used values are stored
122.2013 +  /// in balanced binary tree (\c std::map).
122.2014 +  ///
122.2015 +  /// \ref IterableBoolMap and \ref IterableIntMap are similar classes
122.2016 +  /// specialized for \c bool and \c int values, respectively.
122.2017 +  ///
122.2018 +  /// This type is not reference map, so it cannot be modified with
122.2019 +  /// the subscript operator.
122.2020 +  ///
122.2021 +  /// \tparam GR The graph type.
122.2022 +  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
122.2023 +  /// \c GR::Edge).
122.2024 +  /// \tparam V The value type of the map. It can be any comparable
122.2025 +  /// value type.
122.2026 +  ///
122.2027 +  /// \see IterableBoolMap, IterableIntMap
122.2028 +  /// \see CrossRefMap
122.2029 +  template <typename GR, typename K, typename V>
122.2030 +  class IterableValueMap
122.2031 +    : protected ItemSetTraits<GR, K>::
122.2032 +        template Map<_maps_bits::IterableValueMapNode<K, V> >::Type {
122.2033 +  public:
122.2034 +    typedef typename ItemSetTraits<GR, K>::
122.2035 +      template Map<_maps_bits::IterableValueMapNode<K, V> >::Type Parent;
122.2036 +
122.2037 +    /// The key type
122.2038 +    typedef K Key;
122.2039 +    /// The value type
122.2040 +    typedef V Value;
122.2041 +    /// The graph type
122.2042 +    typedef GR Graph;
122.2043 +
122.2044 +  public:
122.2045 +
122.2046 +    /// \brief Constructor of the map with a given value.
122.2047 +    ///
122.2048 +    /// Constructor of the map with a given value.
122.2049 +    explicit IterableValueMap(const Graph& graph,
122.2050 +                              const Value& value = Value())
122.2051 +      : Parent(graph, _maps_bits::IterableValueMapNode<K, V>(value)) {
122.2052 +      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
122.2053 +        lace(it);
122.2054 +      }
122.2055 +    }
122.2056 +
122.2057 +  protected:
122.2058 +
122.2059 +    void unlace(const Key& key) {
122.2060 +      typename Parent::Value& node = Parent::operator[](key);
122.2061 +      if (node.prev != INVALID) {
122.2062 +        Parent::operator[](node.prev).next = node.next;
122.2063 +      } else {
122.2064 +        if (node.next != INVALID) {
122.2065 +          _first[node.value] = node.next;
122.2066 +        } else {
122.2067 +          _first.erase(node.value);
122.2068 +        }
122.2069 +      }
122.2070 +      if (node.next != INVALID) {
122.2071 +        Parent::operator[](node.next).prev = node.prev;
122.2072 +      }
122.2073 +    }
122.2074 +
122.2075 +    void lace(const Key& key) {
122.2076 +      typename Parent::Value& node = Parent::operator[](key);
122.2077 +      typename std::map<Value, Key>::iterator it = _first.find(node.value);
122.2078 +      if (it == _first.end()) {
122.2079 +        node.prev = node.next = INVALID;
122.2080 +        _first.insert(std::make_pair(node.value, key));
122.2081 +      } else {
122.2082 +        node.prev = INVALID;
122.2083 +        node.next = it->second;
122.2084 +        if (node.next != INVALID) {
122.2085 +          Parent::operator[](node.next).prev = key;
122.2086 +        }
122.2087 +        it->second = key;
122.2088 +      }
122.2089 +    }
122.2090 +
122.2091 +  public:
122.2092 +
122.2093 +    /// \brief Forward iterator for values.
122.2094 +    ///
122.2095 +    /// This iterator is an STL compatible forward
122.2096 +    /// iterator on the values of the map. The values can
122.2097 +    /// be accessed in the <tt>[beginValue, endValue)</tt> range.
122.2098 +    class ValueIt
122.2099 +      : public std::iterator<std::forward_iterator_tag, Value> {
122.2100 +      friend class IterableValueMap;
122.2101 +    private:
122.2102 +      ValueIt(typename std::map<Value, Key>::const_iterator _it)
122.2103 +        : it(_it) {}
122.2104 +    public:
122.2105 +
122.2106 +      /// Constructor
122.2107 +      ValueIt() {}
122.2108 +
122.2109 +      /// \e
122.2110 +      ValueIt& operator++() { ++it; return *this; }
122.2111 +      /// \e
122.2112 +      ValueIt operator++(int) {
122.2113 +        ValueIt tmp(*this);
122.2114 +        operator++();
122.2115 +        return tmp;
122.2116 +      }
122.2117 +
122.2118 +      /// \e
122.2119 +      const Value& operator*() const { return it->first; }
122.2120 +      /// \e
122.2121 +      const Value* operator->() const { return &(it->first); }
122.2122 +
122.2123 +      /// \e
122.2124 +      bool operator==(ValueIt jt) const { return it == jt.it; }
122.2125 +      /// \e
122.2126 +      bool operator!=(ValueIt jt) const { return it != jt.it; }
122.2127 +
122.2128 +    private:
122.2129 +      typename std::map<Value, Key>::const_iterator it;
122.2130 +    };
122.2131 +
122.2132 +    /// \brief Returns an iterator to the first value.
122.2133 +    ///
122.2134 +    /// Returns an STL compatible iterator to the
122.2135 +    /// first value of the map. The values of the
122.2136 +    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
122.2137 +    /// range.
122.2138 +    ValueIt beginValue() const {
122.2139 +      return ValueIt(_first.begin());
122.2140 +    }
122.2141 +
122.2142 +    /// \brief Returns an iterator after the last value.
122.2143 +    ///
122.2144 +    /// Returns an STL compatible iterator after the
122.2145 +    /// last value of the map. The values of the
122.2146 +    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
122.2147 +    /// range.
122.2148 +    ValueIt endValue() const {
122.2149 +      return ValueIt(_first.end());
122.2150 +    }
122.2151 +
122.2152 +    /// \brief Set operation of the map.
122.2153 +    ///
122.2154 +    /// Set operation of the map.
122.2155 +    void set(const Key& key, const Value& value) {
122.2156 +      unlace(key);
122.2157 +      Parent::operator[](key).value = value;
122.2158 +      lace(key);
122.2159 +    }
122.2160 +
122.2161 +    /// \brief Const subscript operator of the map.
122.2162 +    ///
122.2163 +    /// Const subscript operator of the map.
122.2164 +    const Value& operator[](const Key& key) const {
122.2165 +      return Parent::operator[](key).value;
122.2166 +    }
122.2167 +
122.2168 +    /// \brief Iterator for the keys with the same value.
122.2169 +    ///
122.2170 +    /// Iterator for the keys with the same value. It works
122.2171 +    /// like a graph item iterator, it can be converted to
122.2172 +    /// the item type of the map, incremented with \c ++ operator, and
122.2173 +    /// if the iterator leaves the last valid item, it will be equal to
122.2174 +    /// \c INVALID.
122.2175 +    class ItemIt : public Key {
122.2176 +    public:
122.2177 +      typedef Key Parent;
122.2178 +
122.2179 +      /// \brief Invalid constructor \& conversion.
122.2180 +      ///
122.2181 +      /// This constructor initializes the iterator to be invalid.
122.2182 +      /// \sa Invalid for more details.
122.2183 +      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
122.2184 +
122.2185 +      /// \brief Creates an iterator with a value.
122.2186 +      ///
122.2187 +      /// Creates an iterator with a value. It iterates on the
122.2188 +      /// keys which have the given value.
122.2189 +      /// \param map The IterableValueMap
122.2190 +      /// \param value The value
122.2191 +      ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) {
122.2192 +        typename std::map<Value, Key>::const_iterator it =
122.2193 +          map._first.find(value);
122.2194 +        if (it == map._first.end()) {
122.2195 +          Parent::operator=(INVALID);
122.2196 +        } else {
122.2197 +          Parent::operator=(it->second);
122.2198 +        }
122.2199 +      }
122.2200 +
122.2201 +      /// \brief Increment operator.
122.2202 +      ///
122.2203 +      /// Increment Operator.
122.2204 +      ItemIt& operator++() {
122.2205 +        Parent::operator=(_map->IterableValueMap::Parent::
122.2206 +                          operator[](static_cast<Parent&>(*this)).next);
122.2207 +        return *this;
122.2208 +      }
122.2209 +
122.2210 +
122.2211 +    private:
122.2212 +      const IterableValueMap* _map;
122.2213 +    };
122.2214 +
122.2215 +  protected:
122.2216 +
122.2217 +    virtual void add(const Key& key) {
122.2218 +      Parent::add(key);
122.2219 +      unlace(key);
122.2220 +    }
122.2221 +
122.2222 +    virtual void add(const std::vector<Key>& keys) {
122.2223 +      Parent::add(keys);
122.2224 +      for (int i = 0; i < int(keys.size()); ++i) {
122.2225 +        lace(keys[i]);
122.2226 +      }
122.2227 +    }
122.2228 +
122.2229 +    virtual void erase(const Key& key) {
122.2230 +      unlace(key);
122.2231 +      Parent::erase(key);
122.2232 +    }
122.2233 +
122.2234 +    virtual void erase(const std::vector<Key>& keys) {
122.2235 +      for (int i = 0; i < int(keys.size()); ++i) {
122.2236 +        unlace(keys[i]);
122.2237 +      }
122.2238 +      Parent::erase(keys);
122.2239 +    }
122.2240 +
122.2241 +    virtual void build() {
122.2242 +      Parent::build();
122.2243 +      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
122.2244 +        lace(it);
122.2245 +      }
122.2246 +    }
122.2247 +
122.2248 +    virtual void clear() {
122.2249 +      _first.clear();
122.2250 +      Parent::clear();
122.2251 +    }
122.2252 +
122.2253 +  private:
122.2254 +    std::map<Value, Key> _first;
122.2255 +  };
122.2256 +
122.2257 +  /// \brief Map of the source nodes of arcs in a digraph.
122.2258 +  ///
122.2259 +  /// SourceMap provides access for the source node of each arc in a digraph,
122.2260 +  /// which is returned by the \c source() function of the digraph.
122.2261 +  /// \tparam GR The digraph type.
122.2262    /// \see TargetMap
122.2263 -  template <typename Digraph>
122.2264 +  template <typename GR>
122.2265    class SourceMap {
122.2266    public:
122.2267  
122.2268 -    typedef typename Digraph::Node Value;
122.2269 -    typedef typename Digraph::Arc Key;
122.2270 +    /// The key type (the \c Arc type of the digraph).
122.2271 +    typedef typename GR::Arc Key;
122.2272 +    /// The value type (the \c Node type of the digraph).
122.2273 +    typedef typename GR::Node Value;
122.2274  
122.2275      /// \brief Constructor
122.2276      ///
122.2277 -    /// Constructor
122.2278 +    /// Constructor.
122.2279      /// \param digraph The digraph that the map belongs to.
122.2280 -    explicit SourceMap(const Digraph& digraph) : _digraph(digraph) {}
122.2281 -
122.2282 -    /// \brief The subscript operator.
122.2283 +    explicit SourceMap(const GR& digraph) : _graph(digraph) {}
122.2284 +
122.2285 +    /// \brief Returns the source node of the given arc.
122.2286      ///
122.2287 -    /// The subscript operator.
122.2288 -    /// \param arc The arc
122.2289 -    /// \return The source of the arc
122.2290 +    /// Returns the source node of the given arc.
122.2291      Value operator[](const Key& arc) const {
122.2292 -      return _digraph.source(arc);
122.2293 +      return _graph.source(arc);
122.2294      }
122.2295  
122.2296    private:
122.2297 -    const Digraph& _digraph;
122.2298 +    const GR& _graph;
122.2299    };
122.2300  
122.2301    /// \brief Returns a \c SourceMap class.
122.2302    ///
122.2303    /// This function just returns an \c SourceMap class.
122.2304    /// \relates SourceMap
122.2305 -  template <typename Digraph>
122.2306 -  inline SourceMap<Digraph> sourceMap(const Digraph& digraph) {
122.2307 -    return SourceMap<Digraph>(digraph);
122.2308 +  template <typename GR>
122.2309 +  inline SourceMap<GR> sourceMap(const GR& graph) {
122.2310 +    return SourceMap<GR>(graph);
122.2311    }
122.2312  
122.2313 -  /// \brief Returns the target of the given arc.
122.2314 +  /// \brief Map of the target nodes of arcs in a digraph.
122.2315    ///
122.2316 -  /// The TargetMap gives back the target Node of the given arc.
122.2317 +  /// TargetMap provides access for the target node of each arc in a digraph,
122.2318 +  /// which is returned by the \c target() function of the digraph.
122.2319 +  /// \tparam GR The digraph type.
122.2320    /// \see SourceMap
122.2321 -  template <typename Digraph>
122.2322 +  template <typename GR>
122.2323    class TargetMap {
122.2324    public:
122.2325  
122.2326 -    typedef typename Digraph::Node Value;
122.2327 -    typedef typename Digraph::Arc Key;
122.2328 +    /// The key type (the \c Arc type of the digraph).
122.2329 +    typedef typename GR::Arc Key;
122.2330 +    /// The value type (the \c Node type of the digraph).
122.2331 +    typedef typename GR::Node Value;
122.2332  
122.2333      /// \brief Constructor
122.2334      ///
122.2335 -    /// Constructor
122.2336 +    /// Constructor.
122.2337      /// \param digraph The digraph that the map belongs to.
122.2338 -    explicit TargetMap(const Digraph& digraph) : _digraph(digraph) {}
122.2339 -
122.2340 -    /// \brief The subscript operator.
122.2341 +    explicit TargetMap(const GR& digraph) : _graph(digraph) {}
122.2342 +
122.2343 +    /// \brief Returns the target node of the given arc.
122.2344      ///
122.2345 -    /// The subscript operator.
122.2346 -    /// \param e The arc
122.2347 -    /// \return The target of the arc
122.2348 +    /// Returns the target node of the given arc.
122.2349      Value operator[](const Key& e) const {
122.2350 -      return _digraph.target(e);
122.2351 +      return _graph.target(e);
122.2352      }
122.2353  
122.2354    private:
122.2355 -    const Digraph& _digraph;
122.2356 +    const GR& _graph;
122.2357    };
122.2358  
122.2359    /// \brief Returns a \c TargetMap class.
122.2360    ///
122.2361    /// This function just returns a \c TargetMap class.
122.2362    /// \relates TargetMap
122.2363 -  template <typename Digraph>
122.2364 -  inline TargetMap<Digraph> targetMap(const Digraph& digraph) {
122.2365 -    return TargetMap<Digraph>(digraph);
122.2366 +  template <typename GR>
122.2367 +  inline TargetMap<GR> targetMap(const GR& graph) {
122.2368 +    return TargetMap<GR>(graph);
122.2369    }
122.2370  
122.2371 -  /// \brief Returns the "forward" directed arc view of an edge.
122.2372 +  /// \brief Map of the "forward" directed arc view of edges in a graph.
122.2373    ///
122.2374 -  /// Returns the "forward" directed arc view of an edge.
122.2375 +  /// ForwardMap provides access for the "forward" directed arc view of
122.2376 +  /// each edge in a graph, which is returned by the \c direct() function
122.2377 +  /// of the graph with \c true parameter.
122.2378 +  /// \tparam GR The graph type.
122.2379    /// \see BackwardMap
122.2380 -  template <typename Graph>
122.2381 +  template <typename GR>
122.2382    class ForwardMap {
122.2383    public:
122.2384  
122.2385 -    typedef typename Graph::Arc Value;
122.2386 -    typedef typename Graph::Edge Key;
122.2387 +    /// The key type (the \c Edge type of the digraph).
122.2388 +    typedef typename GR::Edge Key;
122.2389 +    /// The value type (the \c Arc type of the digraph).
122.2390 +    typedef typename GR::Arc Value;
122.2391  
122.2392      /// \brief Constructor
122.2393      ///
122.2394 -    /// Constructor
122.2395 +    /// Constructor.
122.2396      /// \param graph The graph that the map belongs to.
122.2397 -    explicit ForwardMap(const Graph& graph) : _graph(graph) {}
122.2398 -
122.2399 -    /// \brief The subscript operator.
122.2400 +    explicit ForwardMap(const GR& graph) : _graph(graph) {}
122.2401 +
122.2402 +    /// \brief Returns the "forward" directed arc view of the given edge.
122.2403      ///
122.2404 -    /// The subscript operator.
122.2405 -    /// \param key An edge
122.2406 -    /// \return The "forward" directed arc view of edge
122.2407 +    /// Returns the "forward" directed arc view of the given edge.
122.2408      Value operator[](const Key& key) const {
122.2409        return _graph.direct(key, true);
122.2410      }
122.2411  
122.2412    private:
122.2413 -    const Graph& _graph;
122.2414 +    const GR& _graph;
122.2415    };
122.2416  
122.2417    /// \brief Returns a \c ForwardMap class.
122.2418    ///
122.2419    /// This function just returns an \c ForwardMap class.
122.2420    /// \relates ForwardMap
122.2421 -  template <typename Graph>
122.2422 -  inline ForwardMap<Graph> forwardMap(const Graph& graph) {
122.2423 -    return ForwardMap<Graph>(graph);
122.2424 +  template <typename GR>
122.2425 +  inline ForwardMap<GR> forwardMap(const GR& graph) {
122.2426 +    return ForwardMap<GR>(graph);
122.2427    }
122.2428  
122.2429 -  /// \brief Returns the "backward" directed arc view of an edge.
122.2430 +  /// \brief Map of the "backward" directed arc view of edges in a graph.
122.2431    ///
122.2432 -  /// Returns the "backward" directed arc view of an edge.
122.2433 +  /// BackwardMap provides access for the "backward" directed arc view of
122.2434 +  /// each edge in a graph, which is returned by the \c direct() function
122.2435 +  /// of the graph with \c false parameter.
122.2436 +  /// \tparam GR The graph type.
122.2437    /// \see ForwardMap
122.2438 -  template <typename Graph>
122.2439 +  template <typename GR>
122.2440    class BackwardMap {
122.2441    public:
122.2442  
122.2443 -    typedef typename Graph::Arc Value;
122.2444 -    typedef typename Graph::Edge Key;
122.2445 +    /// The key type (the \c Edge type of the digraph).
122.2446 +    typedef typename GR::Edge Key;
122.2447 +    /// The value type (the \c Arc type of the digraph).
122.2448 +    typedef typename GR::Arc Value;
122.2449  
122.2450      /// \brief Constructor
122.2451      ///
122.2452 -    /// Constructor
122.2453 +    /// Constructor.
122.2454      /// \param graph The graph that the map belongs to.
122.2455 -    explicit BackwardMap(const Graph& graph) : _graph(graph) {}
122.2456 -
122.2457 -    /// \brief The subscript operator.
122.2458 +    explicit BackwardMap(const GR& graph) : _graph(graph) {}
122.2459 +
122.2460 +    /// \brief Returns the "backward" directed arc view of the given edge.
122.2461      ///
122.2462 -    /// The subscript operator.
122.2463 -    /// \param key An edge
122.2464 -    /// \return The "backward" directed arc view of edge
122.2465 +    /// Returns the "backward" directed arc view of the given edge.
122.2466      Value operator[](const Key& key) const {
122.2467        return _graph.direct(key, false);
122.2468      }
122.2469  
122.2470    private:
122.2471 -    const Graph& _graph;
122.2472 +    const GR& _graph;
122.2473    };
122.2474  
122.2475    /// \brief Returns a \c BackwardMap class
122.2476  
122.2477    /// This function just returns a \c BackwardMap class.
122.2478    /// \relates BackwardMap
122.2479 -  template <typename Graph>
122.2480 -  inline BackwardMap<Graph> backwardMap(const Graph& graph) {
122.2481 -    return BackwardMap<Graph>(graph);
122.2482 +  template <typename GR>
122.2483 +  inline BackwardMap<GR> backwardMap(const GR& graph) {
122.2484 +    return BackwardMap<GR>(graph);
122.2485    }
122.2486  
122.2487 -  /// \brief Potential difference map
122.2488 -  ///
122.2489 -  /// If there is an potential map on the nodes then we
122.2490 -  /// can get an arc map as we get the substraction of the
122.2491 -  /// values of the target and source.
122.2492 -  template <typename Digraph, typename NodeMap>
122.2493 -  class PotentialDifferenceMap {
122.2494 -  public:
122.2495 -    typedef typename Digraph::Arc Key;
122.2496 -    typedef typename NodeMap::Value Value;
122.2497 -
122.2498 -    /// \brief Constructor
122.2499 -    ///
122.2500 -    /// Contructor of the map
122.2501 -    explicit PotentialDifferenceMap(const Digraph& digraph,
122.2502 -                                    const NodeMap& potential)
122.2503 -      : _digraph(digraph), _potential(potential) {}
122.2504 -
122.2505 -    /// \brief Const subscription operator
122.2506 -    ///
122.2507 -    /// Const subscription operator
122.2508 -    Value operator[](const Key& arc) const {
122.2509 -      return _potential[_digraph.target(arc)] -
122.2510 -        _potential[_digraph.source(arc)];
122.2511 -    }
122.2512 -
122.2513 -  private:
122.2514 -    const Digraph& _digraph;
122.2515 -    const NodeMap& _potential;
122.2516 -  };
122.2517 -
122.2518 -  /// \brief Returns a PotentialDifferenceMap.
122.2519 -  ///
122.2520 -  /// This function just returns a PotentialDifferenceMap.
122.2521 -  /// \relates PotentialDifferenceMap
122.2522 -  template <typename Digraph, typename NodeMap>
122.2523 -  PotentialDifferenceMap<Digraph, NodeMap>
122.2524 -  potentialDifferenceMap(const Digraph& digraph, const NodeMap& potential) {
122.2525 -    return PotentialDifferenceMap<Digraph, NodeMap>(digraph, potential);
122.2526 -  }
122.2527 -
122.2528 -  /// \brief Map of the node in-degrees.
122.2529 +  /// \brief Map of the in-degrees of nodes in a digraph.
122.2530    ///
122.2531    /// This map returns the in-degree of a node. Once it is constructed,
122.2532 -  /// the degrees are stored in a standard NodeMap, so each query is done
122.2533 +  /// the degrees are stored in a standard \c NodeMap, so each query is done
122.2534    /// in constant time. On the other hand, the values are updated automatically
122.2535    /// whenever the digraph changes.
122.2536    ///
122.2537 -  /// \warning Besides addNode() and addArc(), a digraph structure may provide
122.2538 -  /// alternative ways to modify the digraph. The correct behavior of InDegMap
122.2539 -  /// is not guarantied if these additional features are used. For example
122.2540 -  /// the functions \ref ListDigraph::changeSource() "changeSource()",
122.2541 +  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
122.2542 +  /// may provide alternative ways to modify the digraph.
122.2543 +  /// The correct behavior of InDegMap is not guarantied if these additional
122.2544 +  /// features are used. For example the functions
122.2545 +  /// \ref ListDigraph::changeSource() "changeSource()",
122.2546    /// \ref ListDigraph::changeTarget() "changeTarget()" and
122.2547    /// \ref ListDigraph::reverseArc() "reverseArc()"
122.2548    /// of \ref ListDigraph will \e not update the degree values correctly.
122.2549    ///
122.2550    /// \sa OutDegMap
122.2551 -
122.2552 -  template <typename _Digraph>
122.2553 +  template <typename GR>
122.2554    class InDegMap
122.2555 -    : protected ItemSetTraits<_Digraph, typename _Digraph::Arc>
122.2556 +    : protected ItemSetTraits<GR, typename GR::Arc>
122.2557        ::ItemNotifier::ObserverBase {
122.2558  
122.2559    public:
122.2560  
122.2561 -    typedef _Digraph Digraph;
122.2562 +    /// The graph type of InDegMap
122.2563 +    typedef GR Graph;
122.2564 +    typedef GR Digraph;
122.2565 +    /// The key type
122.2566 +    typedef typename Digraph::Node Key;
122.2567 +    /// The value type
122.2568      typedef int Value;
122.2569 -    typedef typename Digraph::Node Key;
122.2570  
122.2571      typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
122.2572      ::ItemNotifier::ObserverBase Parent;
122.2573 @@ -2523,9 +3528,9 @@
122.2574  
122.2575      /// \brief Constructor.
122.2576      ///
122.2577 -    /// Constructor for creating in-degree map.
122.2578 -    explicit InDegMap(const Digraph& digraph)
122.2579 -      : _digraph(digraph), _deg(digraph) {
122.2580 +    /// Constructor for creating an in-degree map.
122.2581 +    explicit InDegMap(const Digraph& graph)
122.2582 +      : _digraph(graph), _deg(graph) {
122.2583        Parent::attach(_digraph.notifier(typename Digraph::Arc()));
122.2584  
122.2585        for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
122.2586 @@ -2533,6 +3538,8 @@
122.2587        }
122.2588      }
122.2589  
122.2590 +    /// \brief Gives back the in-degree of a Node.
122.2591 +    ///
122.2592      /// Gives back the in-degree of a Node.
122.2593      int operator[](const Key& key) const {
122.2594        return _deg[key];
122.2595 @@ -2579,33 +3586,37 @@
122.2596      AutoNodeMap _deg;
122.2597    };
122.2598  
122.2599 -  /// \brief Map of the node out-degrees.
122.2600 +  /// \brief Map of the out-degrees of nodes in a digraph.
122.2601    ///
122.2602    /// This map returns the out-degree of a node. Once it is constructed,
122.2603 -  /// the degrees are stored in a standard NodeMap, so each query is done
122.2604 +  /// the degrees are stored in a standard \c NodeMap, so each query is done
122.2605    /// in constant time. On the other hand, the values are updated automatically
122.2606    /// whenever the digraph changes.
122.2607    ///
122.2608 -  /// \warning Besides addNode() and addArc(), a digraph structure may provide
122.2609 -  /// alternative ways to modify the digraph. The correct behavior of OutDegMap
122.2610 -  /// is not guarantied if these additional features are used. For example
122.2611 -  /// the functions \ref ListDigraph::changeSource() "changeSource()",
122.2612 +  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
122.2613 +  /// may provide alternative ways to modify the digraph.
122.2614 +  /// The correct behavior of OutDegMap is not guarantied if these additional
122.2615 +  /// features are used. For example the functions
122.2616 +  /// \ref ListDigraph::changeSource() "changeSource()",
122.2617    /// \ref ListDigraph::changeTarget() "changeTarget()" and
122.2618    /// \ref ListDigraph::reverseArc() "reverseArc()"
122.2619    /// of \ref ListDigraph will \e not update the degree values correctly.
122.2620    ///
122.2621    /// \sa InDegMap
122.2622 -
122.2623 -  template <typename _Digraph>
122.2624 +  template <typename GR>
122.2625    class OutDegMap
122.2626 -    : protected ItemSetTraits<_Digraph, typename _Digraph::Arc>
122.2627 +    : protected ItemSetTraits<GR, typename GR::Arc>
122.2628        ::ItemNotifier::ObserverBase {
122.2629  
122.2630    public:
122.2631  
122.2632 -    typedef _Digraph Digraph;
122.2633 +    /// The graph type of OutDegMap
122.2634 +    typedef GR Graph;
122.2635 +    typedef GR Digraph;
122.2636 +    /// The key type
122.2637 +    typedef typename Digraph::Node Key;
122.2638 +    /// The value type
122.2639      typedef int Value;
122.2640 -    typedef typename Digraph::Node Key;
122.2641  
122.2642      typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
122.2643      ::ItemNotifier::ObserverBase Parent;
122.2644 @@ -2645,9 +3656,9 @@
122.2645  
122.2646      /// \brief Constructor.
122.2647      ///
122.2648 -    /// Constructor for creating out-degree map.
122.2649 -    explicit OutDegMap(const Digraph& digraph)
122.2650 -      : _digraph(digraph), _deg(digraph) {
122.2651 +    /// Constructor for creating an out-degree map.
122.2652 +    explicit OutDegMap(const Digraph& graph)
122.2653 +      : _digraph(graph), _deg(graph) {
122.2654        Parent::attach(_digraph.notifier(typename Digraph::Arc()));
122.2655  
122.2656        for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
122.2657 @@ -2655,6 +3666,8 @@
122.2658        }
122.2659      }
122.2660  
122.2661 +    /// \brief Gives back the out-degree of a Node.
122.2662 +    ///
122.2663      /// Gives back the out-degree of a Node.
122.2664      int operator[](const Key& key) const {
122.2665        return _deg[key];
122.2666 @@ -2701,6 +3714,56 @@
122.2667      AutoNodeMap _deg;
122.2668    };
122.2669  
122.2670 +  /// \brief Potential difference map
122.2671 +  ///
122.2672 +  /// PotentialDifferenceMap returns the difference between the potentials of
122.2673 +  /// the source and target nodes of each arc in a digraph, i.e. it returns
122.2674 +  /// \code
122.2675 +  ///   potential[gr.target(arc)] - potential[gr.source(arc)].
122.2676 +  /// \endcode
122.2677 +  /// \tparam GR The digraph type.
122.2678 +  /// \tparam POT A node map storing the potentials.
122.2679 +  template <typename GR, typename POT>
122.2680 +  class PotentialDifferenceMap {
122.2681 +  public:
122.2682 +    /// Key type
122.2683 +    typedef typename GR::Arc Key;
122.2684 +    /// Value type
122.2685 +    typedef typename POT::Value Value;
122.2686 +
122.2687 +    /// \brief Constructor
122.2688 +    ///
122.2689 +    /// Contructor of the map.
122.2690 +    explicit PotentialDifferenceMap(const GR& gr,
122.2691 +                                    const POT& potential)
122.2692 +      : _digraph(gr), _potential(potential) {}
122.2693 +
122.2694 +    /// \brief Returns the potential difference for the given arc.
122.2695 +    ///
122.2696 +    /// Returns the potential difference for the given arc, i.e.
122.2697 +    /// \code
122.2698 +    ///   potential[gr.target(arc)] - potential[gr.source(arc)].
122.2699 +    /// \endcode
122.2700 +    Value operator[](const Key& arc) const {
122.2701 +      return _potential[_digraph.target(arc)] -
122.2702 +        _potential[_digraph.source(arc)];
122.2703 +    }
122.2704 +
122.2705 +  private:
122.2706 +    const GR& _digraph;
122.2707 +    const POT& _potential;
122.2708 +  };
122.2709 +
122.2710 +  /// \brief Returns a PotentialDifferenceMap.
122.2711 +  ///
122.2712 +  /// This function just returns a PotentialDifferenceMap.
122.2713 +  /// \relates PotentialDifferenceMap
122.2714 +  template <typename GR, typename POT>
122.2715 +  PotentialDifferenceMap<GR, POT>
122.2716 +  potentialDifferenceMap(const GR& gr, const POT& potential) {
122.2717 +    return PotentialDifferenceMap<GR, POT>(gr, potential);
122.2718 +  }
122.2719 +
122.2720    /// @}
122.2721  }
122.2722  
   123.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   123.2 +++ b/lemon/matching.h	Thu Nov 05 15:50:01 2009 +0100
   123.3 @@ -0,0 +1,3244 @@
   123.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   123.5 + *
   123.6 + * This file is a part of LEMON, a generic C++ optimization library.
   123.7 + *
   123.8 + * Copyright (C) 2003-2009
   123.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  123.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  123.11 + *
  123.12 + * Permission to use, modify and distribute this software is granted
  123.13 + * provided that this copyright notice appears in all copies. For
  123.14 + * precise terms see the accompanying LICENSE file.
  123.15 + *
  123.16 + * This software is provided "AS IS" with no warranty of any kind,
  123.17 + * express or implied, and with no claim as to its suitability for any
  123.18 + * purpose.
  123.19 + *
  123.20 + */
  123.21 +
  123.22 +#ifndef LEMON_MAX_MATCHING_H
  123.23 +#define LEMON_MAX_MATCHING_H
  123.24 +
  123.25 +#include <vector>
  123.26 +#include <queue>
  123.27 +#include <set>
  123.28 +#include <limits>
  123.29 +
  123.30 +#include <lemon/core.h>
  123.31 +#include <lemon/unionfind.h>
  123.32 +#include <lemon/bin_heap.h>
  123.33 +#include <lemon/maps.h>
  123.34 +
  123.35 +///\ingroup matching
  123.36 +///\file
  123.37 +///\brief Maximum matching algorithms in general graphs.
  123.38 +
  123.39 +namespace lemon {
  123.40 +
  123.41 +  /// \ingroup matching
  123.42 +  ///
  123.43 +  /// \brief Maximum cardinality matching in general graphs
  123.44 +  ///
  123.45 +  /// This class implements Edmonds' alternating forest matching algorithm
  123.46 +  /// for finding a maximum cardinality matching in a general undirected graph.
  123.47 +  /// It can be started from an arbitrary initial matching 
  123.48 +  /// (the default is the empty one).
  123.49 +  ///
  123.50 +  /// The dual solution of the problem is a map of the nodes to
  123.51 +  /// \ref MaxMatching::Status "Status", having values \c EVEN (or \c D),
  123.52 +  /// \c ODD (or \c A) and \c MATCHED (or \c C) defining the Gallai-Edmonds
  123.53 +  /// decomposition of the graph. The nodes in \c EVEN/D induce a subgraph
  123.54 +  /// with factor-critical components, the nodes in \c ODD/A form the
  123.55 +  /// canonical barrier, and the nodes in \c MATCHED/C induce a graph having
  123.56 +  /// a perfect matching. The number of the factor-critical components
  123.57 +  /// minus the number of barrier nodes is a lower bound on the
  123.58 +  /// unmatched nodes, and the matching is optimal if and only if this bound is
  123.59 +  /// tight. This decomposition can be obtained using \ref status() or
  123.60 +  /// \ref statusMap() after running the algorithm.
  123.61 +  ///
  123.62 +  /// \tparam GR The undirected graph type the algorithm runs on.
  123.63 +  template <typename GR>
  123.64 +  class MaxMatching {
  123.65 +  public:
  123.66 +
  123.67 +    /// The graph type of the algorithm
  123.68 +    typedef GR Graph;
  123.69 +    /// The type of the matching map
  123.70 +    typedef typename Graph::template NodeMap<typename Graph::Arc>
  123.71 +    MatchingMap;
  123.72 +
  123.73 +    ///\brief Status constants for Gallai-Edmonds decomposition.
  123.74 +    ///
  123.75 +    ///These constants are used for indicating the Gallai-Edmonds 
  123.76 +    ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
  123.77 +    ///induce a subgraph with factor-critical components, the nodes with
  123.78 +    ///status \c ODD (or \c A) form the canonical barrier, and the nodes
  123.79 +    ///with status \c MATCHED (or \c C) induce a subgraph having a 
  123.80 +    ///perfect matching.
  123.81 +    enum Status {
  123.82 +      EVEN = 1,       ///< = 1. (\c D is an alias for \c EVEN.)
  123.83 +      D = 1,
  123.84 +      MATCHED = 0,    ///< = 0. (\c C is an alias for \c MATCHED.)
  123.85 +      C = 0,
  123.86 +      ODD = -1,       ///< = -1. (\c A is an alias for \c ODD.)
  123.87 +      A = -1,
  123.88 +      UNMATCHED = -2  ///< = -2.
  123.89 +    };
  123.90 +
  123.91 +    /// The type of the status map
  123.92 +    typedef typename Graph::template NodeMap<Status> StatusMap;
  123.93 +
  123.94 +  private:
  123.95 +
  123.96 +    TEMPLATE_GRAPH_TYPEDEFS(Graph);
  123.97 +
  123.98 +    typedef UnionFindEnum<IntNodeMap> BlossomSet;
  123.99 +    typedef ExtendFindEnum<IntNodeMap> TreeSet;
 123.100 +    typedef RangeMap<Node> NodeIntMap;
 123.101 +    typedef MatchingMap EarMap;
 123.102 +    typedef std::vector<Node> NodeQueue;
 123.103 +
 123.104 +    const Graph& _graph;
 123.105 +    MatchingMap* _matching;
 123.106 +    StatusMap* _status;
 123.107 +
 123.108 +    EarMap* _ear;
 123.109 +
 123.110 +    IntNodeMap* _blossom_set_index;
 123.111 +    BlossomSet* _blossom_set;
 123.112 +    NodeIntMap* _blossom_rep;
 123.113 +
 123.114 +    IntNodeMap* _tree_set_index;
 123.115 +    TreeSet* _tree_set;
 123.116 +
 123.117 +    NodeQueue _node_queue;
 123.118 +    int _process, _postpone, _last;
 123.119 +
 123.120 +    int _node_num;
 123.121 +
 123.122 +  private:
 123.123 +
 123.124 +    void createStructures() {
 123.125 +      _node_num = countNodes(_graph);
 123.126 +      if (!_matching) {
 123.127 +        _matching = new MatchingMap(_graph);
 123.128 +      }
 123.129 +      if (!_status) {
 123.130 +        _status = new StatusMap(_graph);
 123.131 +      }
 123.132 +      if (!_ear) {
 123.133 +        _ear = new EarMap(_graph);
 123.134 +      }
 123.135 +      if (!_blossom_set) {
 123.136 +        _blossom_set_index = new IntNodeMap(_graph);
 123.137 +        _blossom_set = new BlossomSet(*_blossom_set_index);
 123.138 +      }
 123.139 +      if (!_blossom_rep) {
 123.140 +        _blossom_rep = new NodeIntMap(_node_num);
 123.141 +      }
 123.142 +      if (!_tree_set) {
 123.143 +        _tree_set_index = new IntNodeMap(_graph);
 123.144 +        _tree_set = new TreeSet(*_tree_set_index);
 123.145 +      }
 123.146 +      _node_queue.resize(_node_num);
 123.147 +    }
 123.148 +
 123.149 +    void destroyStructures() {
 123.150 +      if (_matching) {
 123.151 +        delete _matching;
 123.152 +      }
 123.153 +      if (_status) {
 123.154 +        delete _status;
 123.155 +      }
 123.156 +      if (_ear) {
 123.157 +        delete _ear;
 123.158 +      }
 123.159 +      if (_blossom_set) {
 123.160 +        delete _blossom_set;
 123.161 +        delete _blossom_set_index;
 123.162 +      }
 123.163 +      if (_blossom_rep) {
 123.164 +        delete _blossom_rep;
 123.165 +      }
 123.166 +      if (_tree_set) {
 123.167 +        delete _tree_set_index;
 123.168 +        delete _tree_set;
 123.169 +      }
 123.170 +    }
 123.171 +
 123.172 +    void processDense(const Node& n) {
 123.173 +      _process = _postpone = _last = 0;
 123.174 +      _node_queue[_last++] = n;
 123.175 +
 123.176 +      while (_process != _last) {
 123.177 +        Node u = _node_queue[_process++];
 123.178 +        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
 123.179 +          Node v = _graph.target(a);
 123.180 +          if ((*_status)[v] == MATCHED) {
 123.181 +            extendOnArc(a);
 123.182 +          } else if ((*_status)[v] == UNMATCHED) {
 123.183 +            augmentOnArc(a);
 123.184 +            return;
 123.185 +          }
 123.186 +        }
 123.187 +      }
 123.188 +
 123.189 +      while (_postpone != _last) {
 123.190 +        Node u = _node_queue[_postpone++];
 123.191 +
 123.192 +        for (OutArcIt a(_graph, u); a != INVALID ; ++a) {
 123.193 +          Node v = _graph.target(a);
 123.194 +
 123.195 +          if ((*_status)[v] == EVEN) {
 123.196 +            if (_blossom_set->find(u) != _blossom_set->find(v)) {
 123.197 +              shrinkOnEdge(a);
 123.198 +            }
 123.199 +          }
 123.200 +
 123.201 +          while (_process != _last) {
 123.202 +            Node w = _node_queue[_process++];
 123.203 +            for (OutArcIt b(_graph, w); b != INVALID; ++b) {
 123.204 +              Node x = _graph.target(b);
 123.205 +              if ((*_status)[x] == MATCHED) {
 123.206 +                extendOnArc(b);
 123.207 +              } else if ((*_status)[x] == UNMATCHED) {
 123.208 +                augmentOnArc(b);
 123.209 +                return;
 123.210 +              }
 123.211 +            }
 123.212 +          }
 123.213 +        }
 123.214 +      }
 123.215 +    }
 123.216 +
 123.217 +    void processSparse(const Node& n) {
 123.218 +      _process = _last = 0;
 123.219 +      _node_queue[_last++] = n;
 123.220 +      while (_process != _last) {
 123.221 +        Node u = _node_queue[_process++];
 123.222 +        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
 123.223 +          Node v = _graph.target(a);
 123.224 +
 123.225 +          if ((*_status)[v] == EVEN) {
 123.226 +            if (_blossom_set->find(u) != _blossom_set->find(v)) {
 123.227 +              shrinkOnEdge(a);
 123.228 +            }
 123.229 +          } else if ((*_status)[v] == MATCHED) {
 123.230 +            extendOnArc(a);
 123.231 +          } else if ((*_status)[v] == UNMATCHED) {
 123.232 +            augmentOnArc(a);
 123.233 +            return;
 123.234 +          }
 123.235 +        }
 123.236 +      }
 123.237 +    }
 123.238 +
 123.239 +    void shrinkOnEdge(const Edge& e) {
 123.240 +      Node nca = INVALID;
 123.241 +
 123.242 +      {
 123.243 +        std::set<Node> left_set, right_set;
 123.244 +
 123.245 +        Node left = (*_blossom_rep)[_blossom_set->find(_graph.u(e))];
 123.246 +        left_set.insert(left);
 123.247 +
 123.248 +        Node right = (*_blossom_rep)[_blossom_set->find(_graph.v(e))];
 123.249 +        right_set.insert(right);
 123.250 +
 123.251 +        while (true) {
 123.252 +          if ((*_matching)[left] == INVALID) break;
 123.253 +          left = _graph.target((*_matching)[left]);
 123.254 +          left = (*_blossom_rep)[_blossom_set->
 123.255 +                                 find(_graph.target((*_ear)[left]))];
 123.256 +          if (right_set.find(left) != right_set.end()) {
 123.257 +            nca = left;
 123.258 +            break;
 123.259 +          }
 123.260 +          left_set.insert(left);
 123.261 +
 123.262 +          if ((*_matching)[right] == INVALID) break;
 123.263 +          right = _graph.target((*_matching)[right]);
 123.264 +          right = (*_blossom_rep)[_blossom_set->
 123.265 +                                  find(_graph.target((*_ear)[right]))];
 123.266 +          if (left_set.find(right) != left_set.end()) {
 123.267 +            nca = right;
 123.268 +            break;
 123.269 +          }
 123.270 +          right_set.insert(right);
 123.271 +        }
 123.272 +
 123.273 +        if (nca == INVALID) {
 123.274 +          if ((*_matching)[left] == INVALID) {
 123.275 +            nca = right;
 123.276 +            while (left_set.find(nca) == left_set.end()) {
 123.277 +              nca = _graph.target((*_matching)[nca]);
 123.278 +              nca =(*_blossom_rep)[_blossom_set->
 123.279 +                                   find(_graph.target((*_ear)[nca]))];
 123.280 +            }
 123.281 +          } else {
 123.282 +            nca = left;
 123.283 +            while (right_set.find(nca) == right_set.end()) {
 123.284 +              nca = _graph.target((*_matching)[nca]);
 123.285 +              nca = (*_blossom_rep)[_blossom_set->
 123.286 +                                   find(_graph.target((*_ear)[nca]))];
 123.287 +            }
 123.288 +          }
 123.289 +        }
 123.290 +      }
 123.291 +
 123.292 +      {
 123.293 +
 123.294 +        Node node = _graph.u(e);
 123.295 +        Arc arc = _graph.direct(e, true);
 123.296 +        Node base = (*_blossom_rep)[_blossom_set->find(node)];
 123.297 +
 123.298 +        while (base != nca) {
 123.299 +          (*_ear)[node] = arc;
 123.300 +
 123.301 +          Node n = node;
 123.302 +          while (n != base) {
 123.303 +            n = _graph.target((*_matching)[n]);
 123.304 +            Arc a = (*_ear)[n];
 123.305 +            n = _graph.target(a);
 123.306 +            (*_ear)[n] = _graph.oppositeArc(a);
 123.307 +          }
 123.308 +          node = _graph.target((*_matching)[base]);
 123.309 +          _tree_set->erase(base);
 123.310 +          _tree_set->erase(node);
 123.311 +          _blossom_set->insert(node, _blossom_set->find(base));
 123.312 +          (*_status)[node] = EVEN;
 123.313 +          _node_queue[_last++] = node;
 123.314 +          arc = _graph.oppositeArc((*_ear)[node]);
 123.315 +          node = _graph.target((*_ear)[node]);
 123.316 +          base = (*_blossom_rep)[_blossom_set->find(node)];
 123.317 +          _blossom_set->join(_graph.target(arc), base);
 123.318 +        }
 123.319 +      }
 123.320 +
 123.321 +      (*_blossom_rep)[_blossom_set->find(nca)] = nca;
 123.322 +
 123.323 +      {
 123.324 +
 123.325 +        Node node = _graph.v(e);
 123.326 +        Arc arc = _graph.direct(e, false);
 123.327 +        Node base = (*_blossom_rep)[_blossom_set->find(node)];
 123.328 +
 123.329 +        while (base != nca) {
 123.330 +          (*_ear)[node] = arc;
 123.331 +
 123.332 +          Node n = node;
 123.333 +          while (n != base) {
 123.334 +            n = _graph.target((*_matching)[n]);
 123.335 +            Arc a = (*_ear)[n];
 123.336 +            n = _graph.target(a);
 123.337 +            (*_ear)[n] = _graph.oppositeArc(a);
 123.338 +          }
 123.339 +          node = _graph.target((*_matching)[base]);
 123.340 +          _tree_set->erase(base);
 123.341 +          _tree_set->erase(node);
 123.342 +          _blossom_set->insert(node, _blossom_set->find(base));
 123.343 +          (*_status)[node] = EVEN;
 123.344 +          _node_queue[_last++] = node;
 123.345 +          arc = _graph.oppositeArc((*_ear)[node]);
 123.346 +          node = _graph.target((*_ear)[node]);
 123.347 +          base = (*_blossom_rep)[_blossom_set->find(node)];
 123.348 +          _blossom_set->join(_graph.target(arc), base);
 123.349 +        }
 123.350 +      }
 123.351 +
 123.352 +      (*_blossom_rep)[_blossom_set->find(nca)] = nca;
 123.353 +    }
 123.354 +
 123.355 +    void extendOnArc(const Arc& a) {
 123.356 +      Node base = _graph.source(a);
 123.357 +      Node odd = _graph.target(a);
 123.358 +
 123.359 +      (*_ear)[odd] = _graph.oppositeArc(a);
 123.360 +      Node even = _graph.target((*_matching)[odd]);
 123.361 +      (*_blossom_rep)[_blossom_set->insert(even)] = even;
 123.362 +      (*_status)[odd] = ODD;
 123.363 +      (*_status)[even] = EVEN;
 123.364 +      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(base)]);
 123.365 +      _tree_set->insert(odd, tree);
 123.366 +      _tree_set->insert(even, tree);
 123.367 +      _node_queue[_last++] = even;
 123.368 +
 123.369 +    }
 123.370 +
 123.371 +    void augmentOnArc(const Arc& a) {
 123.372 +      Node even = _graph.source(a);
 123.373 +      Node odd = _graph.target(a);
 123.374 +
 123.375 +      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(even)]);
 123.376 +
 123.377 +      (*_matching)[odd] = _graph.oppositeArc(a);
 123.378 +      (*_status)[odd] = MATCHED;
 123.379 +
 123.380 +      Arc arc = (*_matching)[even];
 123.381 +      (*_matching)[even] = a;
 123.382 +
 123.383 +      while (arc != INVALID) {
 123.384 +        odd = _graph.target(arc);
 123.385 +        arc = (*_ear)[odd];
 123.386 +        even = _graph.target(arc);
 123.387 +        (*_matching)[odd] = arc;
 123.388 +        arc = (*_matching)[even];
 123.389 +        (*_matching)[even] = _graph.oppositeArc((*_matching)[odd]);
 123.390 +      }
 123.391 +
 123.392 +      for (typename TreeSet::ItemIt it(*_tree_set, tree);
 123.393 +           it != INVALID; ++it) {
 123.394 +        if ((*_status)[it] == ODD) {
 123.395 +          (*_status)[it] = MATCHED;
 123.396 +        } else {
 123.397 +          int blossom = _blossom_set->find(it);
 123.398 +          for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom);
 123.399 +               jt != INVALID; ++jt) {
 123.400 +            (*_status)[jt] = MATCHED;
 123.401 +          }
 123.402 +          _blossom_set->eraseClass(blossom);
 123.403 +        }
 123.404 +      }
 123.405 +      _tree_set->eraseClass(tree);
 123.406 +
 123.407 +    }
 123.408 +
 123.409 +  public:
 123.410 +
 123.411 +    /// \brief Constructor
 123.412 +    ///
 123.413 +    /// Constructor.
 123.414 +    MaxMatching(const Graph& graph)
 123.415 +      : _graph(graph), _matching(0), _status(0), _ear(0),
 123.416 +        _blossom_set_index(0), _blossom_set(0), _blossom_rep(0),
 123.417 +        _tree_set_index(0), _tree_set(0) {}
 123.418 +
 123.419 +    ~MaxMatching() {
 123.420 +      destroyStructures();
 123.421 +    }
 123.422 +
 123.423 +    /// \name Execution Control
 123.424 +    /// The simplest way to execute the algorithm is to use the
 123.425 +    /// \c run() member function.\n
 123.426 +    /// If you need better control on the execution, you have to call
 123.427 +    /// one of the functions \ref init(), \ref greedyInit() or
 123.428 +    /// \ref matchingInit() first, then you can start the algorithm with
 123.429 +    /// \ref startSparse() or \ref startDense().
 123.430 +
 123.431 +    ///@{
 123.432 +
 123.433 +    /// \brief Set the initial matching to the empty matching.
 123.434 +    ///
 123.435 +    /// This function sets the initial matching to the empty matching.
 123.436 +    void init() {
 123.437 +      createStructures();
 123.438 +      for(NodeIt n(_graph); n != INVALID; ++n) {
 123.439 +        (*_matching)[n] = INVALID;
 123.440 +        (*_status)[n] = UNMATCHED;
 123.441 +      }
 123.442 +    }
 123.443 +
 123.444 +    /// \brief Find an initial matching in a greedy way.
 123.445 +    ///
 123.446 +    /// This function finds an initial matching in a greedy way.
 123.447 +    void greedyInit() {
 123.448 +      createStructures();
 123.449 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 123.450 +        (*_matching)[n] = INVALID;
 123.451 +        (*_status)[n] = UNMATCHED;
 123.452 +      }
 123.453 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 123.454 +        if ((*_matching)[n] == INVALID) {
 123.455 +          for (OutArcIt a(_graph, n); a != INVALID ; ++a) {
 123.456 +            Node v = _graph.target(a);
 123.457 +            if ((*_matching)[v] == INVALID && v != n) {
 123.458 +              (*_matching)[n] = a;
 123.459 +              (*_status)[n] = MATCHED;
 123.460 +              (*_matching)[v] = _graph.oppositeArc(a);
 123.461 +              (*_status)[v] = MATCHED;
 123.462 +              break;
 123.463 +            }
 123.464 +          }
 123.465 +        }
 123.466 +      }
 123.467 +    }
 123.468 +
 123.469 +
 123.470 +    /// \brief Initialize the matching from a map.
 123.471 +    ///
 123.472 +    /// This function initializes the matching from a \c bool valued edge
 123.473 +    /// map. This map should have the property that there are no two incident
 123.474 +    /// edges with \c true value, i.e. it really contains a matching.
 123.475 +    /// \return \c true if the map contains a matching.
 123.476 +    template <typename MatchingMap>
 123.477 +    bool matchingInit(const MatchingMap& matching) {
 123.478 +      createStructures();
 123.479 +
 123.480 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 123.481 +        (*_matching)[n] = INVALID;
 123.482 +        (*_status)[n] = UNMATCHED;
 123.483 +      }
 123.484 +      for(EdgeIt e(_graph); e!=INVALID; ++e) {
 123.485 +        if (matching[e]) {
 123.486 +
 123.487 +          Node u = _graph.u(e);
 123.488 +          if ((*_matching)[u] != INVALID) return false;
 123.489 +          (*_matching)[u] = _graph.direct(e, true);
 123.490 +          (*_status)[u] = MATCHED;
 123.491 +
 123.492 +          Node v = _graph.v(e);
 123.493 +          if ((*_matching)[v] != INVALID) return false;
 123.494 +          (*_matching)[v] = _graph.direct(e, false);
 123.495 +          (*_status)[v] = MATCHED;
 123.496 +        }
 123.497 +      }
 123.498 +      return true;
 123.499 +    }
 123.500 +
 123.501 +    /// \brief Start Edmonds' algorithm
 123.502 +    ///
 123.503 +    /// This function runs the original Edmonds' algorithm.
 123.504 +    ///
 123.505 +    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
 123.506 +    /// called before using this function.
 123.507 +    void startSparse() {
 123.508 +      for(NodeIt n(_graph); n != INVALID; ++n) {
 123.509 +        if ((*_status)[n] == UNMATCHED) {
 123.510 +          (*_blossom_rep)[_blossom_set->insert(n)] = n;
 123.511 +          _tree_set->insert(n);
 123.512 +          (*_status)[n] = EVEN;
 123.513 +          processSparse(n);
 123.514 +        }
 123.515 +      }
 123.516 +    }
 123.517 +
 123.518 +    /// \brief Start Edmonds' algorithm with a heuristic improvement 
 123.519 +    /// for dense graphs
 123.520 +    ///
 123.521 +    /// This function runs Edmonds' algorithm with a heuristic of postponing
 123.522 +    /// shrinks, therefore resulting in a faster algorithm for dense graphs.
 123.523 +    ///
 123.524 +    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
 123.525 +    /// called before using this function.
 123.526 +    void startDense() {
 123.527 +      for(NodeIt n(_graph); n != INVALID; ++n) {
 123.528 +        if ((*_status)[n] == UNMATCHED) {
 123.529 +          (*_blossom_rep)[_blossom_set->insert(n)] = n;
 123.530 +          _tree_set->insert(n);
 123.531 +          (*_status)[n] = EVEN;
 123.532 +          processDense(n);
 123.533 +        }
 123.534 +      }
 123.535 +    }
 123.536 +
 123.537 +
 123.538 +    /// \brief Run Edmonds' algorithm
 123.539 +    ///
 123.540 +    /// This function runs Edmonds' algorithm. An additional heuristic of 
 123.541 +    /// postponing shrinks is used for relatively dense graphs 
 123.542 +    /// (for which <tt>m>=2*n</tt> holds).
 123.543 +    void run() {
 123.544 +      if (countEdges(_graph) < 2 * countNodes(_graph)) {
 123.545 +        greedyInit();
 123.546 +        startSparse();
 123.547 +      } else {
 123.548 +        init();
 123.549 +        startDense();
 123.550 +      }
 123.551 +    }
 123.552 +
 123.553 +    /// @}
 123.554 +
 123.555 +    /// \name Primal Solution
 123.556 +    /// Functions to get the primal solution, i.e. the maximum matching.
 123.557 +
 123.558 +    /// @{
 123.559 +
 123.560 +    /// \brief Return the size (cardinality) of the matching.
 123.561 +    ///
 123.562 +    /// This function returns the size (cardinality) of the current matching. 
 123.563 +    /// After run() it returns the size of the maximum matching in the graph.
 123.564 +    int matchingSize() const {
 123.565 +      int size = 0;
 123.566 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 123.567 +        if ((*_matching)[n] != INVALID) {
 123.568 +          ++size;
 123.569 +        }
 123.570 +      }
 123.571 +      return size / 2;
 123.572 +    }
 123.573 +
 123.574 +    /// \brief Return \c true if the given edge is in the matching.
 123.575 +    ///
 123.576 +    /// This function returns \c true if the given edge is in the current 
 123.577 +    /// matching.
 123.578 +    bool matching(const Edge& edge) const {
 123.579 +      return edge == (*_matching)[_graph.u(edge)];
 123.580 +    }
 123.581 +
 123.582 +    /// \brief Return the matching arc (or edge) incident to the given node.
 123.583 +    ///
 123.584 +    /// This function returns the matching arc (or edge) incident to the
 123.585 +    /// given node in the current matching or \c INVALID if the node is 
 123.586 +    /// not covered by the matching.
 123.587 +    Arc matching(const Node& n) const {
 123.588 +      return (*_matching)[n];
 123.589 +    }
 123.590 +
 123.591 +    /// \brief Return a const reference to the matching map.
 123.592 +    ///
 123.593 +    /// This function returns a const reference to a node map that stores
 123.594 +    /// the matching arc (or edge) incident to each node.
 123.595 +    const MatchingMap& matchingMap() const {
 123.596 +      return *_matching;
 123.597 +    }
 123.598 +
 123.599 +    /// \brief Return the mate of the given node.
 123.600 +    ///
 123.601 +    /// This function returns the mate of the given node in the current 
 123.602 +    /// matching or \c INVALID if the node is not covered by the matching.
 123.603 +    Node mate(const Node& n) const {
 123.604 +      return (*_matching)[n] != INVALID ?
 123.605 +        _graph.target((*_matching)[n]) : INVALID;
 123.606 +    }
 123.607 +
 123.608 +    /// @}
 123.609 +
 123.610 +    /// \name Dual Solution
 123.611 +    /// Functions to get the dual solution, i.e. the Gallai-Edmonds 
 123.612 +    /// decomposition.
 123.613 +
 123.614 +    /// @{
 123.615 +
 123.616 +    /// \brief Return the status of the given node in the Edmonds-Gallai
 123.617 +    /// decomposition.
 123.618 +    ///
 123.619 +    /// This function returns the \ref Status "status" of the given node
 123.620 +    /// in the Edmonds-Gallai decomposition.
 123.621 +    Status status(const Node& n) const {
 123.622 +      return (*_status)[n];
 123.623 +    }
 123.624 +
 123.625 +    /// \brief Return a const reference to the status map, which stores
 123.626 +    /// the Edmonds-Gallai decomposition.
 123.627 +    ///
 123.628 +    /// This function returns a const reference to a node map that stores the
 123.629 +    /// \ref Status "status" of each node in the Edmonds-Gallai decomposition.
 123.630 +    const StatusMap& statusMap() const {
 123.631 +      return *_status;
 123.632 +    }
 123.633 +
 123.634 +    /// \brief Return \c true if the given node is in the barrier.
 123.635 +    ///
 123.636 +    /// This function returns \c true if the given node is in the barrier.
 123.637 +    bool barrier(const Node& n) const {
 123.638 +      return (*_status)[n] == ODD;
 123.639 +    }
 123.640 +
 123.641 +    /// @}
 123.642 +
 123.643 +  };
 123.644 +
 123.645 +  /// \ingroup matching
 123.646 +  ///
 123.647 +  /// \brief Weighted matching in general graphs
 123.648 +  ///
 123.649 +  /// This class provides an efficient implementation of Edmond's
 123.650 +  /// maximum weighted matching algorithm. The implementation is based
 123.651 +  /// on extensive use of priority queues and provides
 123.652 +  /// \f$O(nm\log n)\f$ time complexity.
 123.653 +  ///
 123.654 +  /// The maximum weighted matching problem is to find a subset of the 
 123.655 +  /// edges in an undirected graph with maximum overall weight for which 
 123.656 +  /// each node has at most one incident edge.
 123.657 +  /// It can be formulated with the following linear program.
 123.658 +  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
 123.659 +  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
 123.660 +      \quad \forall B\in\mathcal{O}\f] */
 123.661 +  /// \f[x_e \ge 0\quad \forall e\in E\f]
 123.662 +  /// \f[\max \sum_{e\in E}x_ew_e\f]
 123.663 +  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
 123.664 +  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
 123.665 +  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
 123.666 +  /// subsets of the nodes.
 123.667 +  ///
 123.668 +  /// The algorithm calculates an optimal matching and a proof of the
 123.669 +  /// optimality. The solution of the dual problem can be used to check
 123.670 +  /// the result of the algorithm. The dual linear problem is the
 123.671 +  /// following.
 123.672 +  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
 123.673 +      z_B \ge w_{uv} \quad \forall uv\in E\f] */
 123.674 +  /// \f[y_u \ge 0 \quad \forall u \in V\f]
 123.675 +  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
 123.676 +  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
 123.677 +      \frac{\vert B \vert - 1}{2}z_B\f] */
 123.678 +  ///
 123.679 +  /// The algorithm can be executed with the run() function. 
 123.680 +  /// After it the matching (the primal solution) and the dual solution
 123.681 +  /// can be obtained using the query functions and the 
 123.682 +  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, 
 123.683 +  /// which is able to iterate on the nodes of a blossom. 
 123.684 +  /// If the value type is integer, then the dual solution is multiplied
 123.685 +  /// by \ref MaxWeightedMatching::dualScale "4".
 123.686 +  ///
 123.687 +  /// \tparam GR The undirected graph type the algorithm runs on.
 123.688 +  /// \tparam WM The type edge weight map. The default type is 
 123.689 +  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
 123.690 +#ifdef DOXYGEN
 123.691 +  template <typename GR, typename WM>
 123.692 +#else
 123.693 +  template <typename GR,
 123.694 +            typename WM = typename GR::template EdgeMap<int> >
 123.695 +#endif
 123.696 +  class MaxWeightedMatching {
 123.697 +  public:
 123.698 +
 123.699 +    /// The graph type of the algorithm
 123.700 +    typedef GR Graph;
 123.701 +    /// The type of the edge weight map
 123.702 +    typedef WM WeightMap;
 123.703 +    /// The value type of the edge weights
 123.704 +    typedef typename WeightMap::Value Value;
 123.705 +
 123.706 +    /// The type of the matching map
 123.707 +    typedef typename Graph::template NodeMap<typename Graph::Arc>
 123.708 +    MatchingMap;
 123.709 +
 123.710 +    /// \brief Scaling factor for dual solution
 123.711 +    ///
 123.712 +    /// Scaling factor for dual solution. It is equal to 4 or 1
 123.713 +    /// according to the value type.
 123.714 +    static const int dualScale =
 123.715 +      std::numeric_limits<Value>::is_integer ? 4 : 1;
 123.716 +
 123.717 +  private:
 123.718 +
 123.719 +    TEMPLATE_GRAPH_TYPEDEFS(Graph);
 123.720 +
 123.721 +    typedef typename Graph::template NodeMap<Value> NodePotential;
 123.722 +    typedef std::vector<Node> BlossomNodeList;
 123.723 +
 123.724 +    struct BlossomVariable {
 123.725 +      int begin, end;
 123.726 +      Value value;
 123.727 +
 123.728 +      BlossomVariable(int _begin, int _end, Value _value)
 123.729 +        : begin(_begin), end(_end), value(_value) {}
 123.730 +
 123.731 +    };
 123.732 +
 123.733 +    typedef std::vector<BlossomVariable> BlossomPotential;
 123.734 +
 123.735 +    const Graph& _graph;
 123.736 +    const WeightMap& _weight;
 123.737 +
 123.738 +    MatchingMap* _matching;
 123.739 +
 123.740 +    NodePotential* _node_potential;
 123.741 +
 123.742 +    BlossomPotential _blossom_potential;
 123.743 +    BlossomNodeList _blossom_node_list;
 123.744 +
 123.745 +    int _node_num;
 123.746 +    int _blossom_num;
 123.747 +
 123.748 +    typedef RangeMap<int> IntIntMap;
 123.749 +
 123.750 +    enum Status {
 123.751 +      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
 123.752 +    };
 123.753 +
 123.754 +    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
 123.755 +    struct BlossomData {
 123.756 +      int tree;
 123.757 +      Status status;
 123.758 +      Arc pred, next;
 123.759 +      Value pot, offset;
 123.760 +      Node base;
 123.761 +    };
 123.762 +
 123.763 +    IntNodeMap *_blossom_index;
 123.764 +    BlossomSet *_blossom_set;
 123.765 +    RangeMap<BlossomData>* _blossom_data;
 123.766 +
 123.767 +    IntNodeMap *_node_index;
 123.768 +    IntArcMap *_node_heap_index;
 123.769 +
 123.770 +    struct NodeData {
 123.771 +
 123.772 +      NodeData(IntArcMap& node_heap_index)
 123.773 +        : heap(node_heap_index) {}
 123.774 +
 123.775 +      int blossom;
 123.776 +      Value pot;
 123.777 +      BinHeap<Value, IntArcMap> heap;
 123.778 +      std::map<int, Arc> heap_index;
 123.779 +
 123.780 +      int tree;
 123.781 +    };
 123.782 +
 123.783 +    RangeMap<NodeData>* _node_data;
 123.784 +
 123.785 +    typedef ExtendFindEnum<IntIntMap> TreeSet;
 123.786 +
 123.787 +    IntIntMap *_tree_set_index;
 123.788 +    TreeSet *_tree_set;
 123.789 +
 123.790 +    IntNodeMap *_delta1_index;
 123.791 +    BinHeap<Value, IntNodeMap> *_delta1;
 123.792 +
 123.793 +    IntIntMap *_delta2_index;
 123.794 +    BinHeap<Value, IntIntMap> *_delta2;
 123.795 +
 123.796 +    IntEdgeMap *_delta3_index;
 123.797 +    BinHeap<Value, IntEdgeMap> *_delta3;
 123.798 +
 123.799 +    IntIntMap *_delta4_index;
 123.800 +    BinHeap<Value, IntIntMap> *_delta4;
 123.801 +
 123.802 +    Value _delta_sum;
 123.803 +
 123.804 +    void createStructures() {
 123.805 +      _node_num = countNodes(_graph);
 123.806 +      _blossom_num = _node_num * 3 / 2;
 123.807 +
 123.808 +      if (!_matching) {
 123.809 +        _matching = new MatchingMap(_graph);
 123.810 +      }
 123.811 +      if (!_node_potential) {
 123.812 +        _node_potential = new NodePotential(_graph);
 123.813 +      }
 123.814 +      if (!_blossom_set) {
 123.815 +        _blossom_index = new IntNodeMap(_graph);
 123.816 +        _blossom_set = new BlossomSet(*_blossom_index);
 123.817 +        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
 123.818 +      }
 123.819 +
 123.820 +      if (!_node_index) {
 123.821 +        _node_index = new IntNodeMap(_graph);
 123.822 +        _node_heap_index = new IntArcMap(_graph);
 123.823 +        _node_data = new RangeMap<NodeData>(_node_num,
 123.824 +                                              NodeData(*_node_heap_index));
 123.825 +      }
 123.826 +
 123.827 +      if (!_tree_set) {
 123.828 +        _tree_set_index = new IntIntMap(_blossom_num);
 123.829 +        _tree_set = new TreeSet(*_tree_set_index);
 123.830 +      }
 123.831 +      if (!_delta1) {
 123.832 +        _delta1_index = new IntNodeMap(_graph);
 123.833 +        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
 123.834 +      }
 123.835 +      if (!_delta2) {
 123.836 +        _delta2_index = new IntIntMap(_blossom_num);
 123.837 +        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
 123.838 +      }
 123.839 +      if (!_delta3) {
 123.840 +        _delta3_index = new IntEdgeMap(_graph);
 123.841 +        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
 123.842 +      }
 123.843 +      if (!_delta4) {
 123.844 +        _delta4_index = new IntIntMap(_blossom_num);
 123.845 +        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
 123.846 +      }
 123.847 +    }
 123.848 +
 123.849 +    void destroyStructures() {
 123.850 +      _node_num = countNodes(_graph);
 123.851 +      _blossom_num = _node_num * 3 / 2;
 123.852 +
 123.853 +      if (_matching) {
 123.854 +        delete _matching;
 123.855 +      }
 123.856 +      if (_node_potential) {
 123.857 +        delete _node_potential;
 123.858 +      }
 123.859 +      if (_blossom_set) {
 123.860 +        delete _blossom_index;
 123.861 +        delete _blossom_set;
 123.862 +        delete _blossom_data;
 123.863 +      }
 123.864 +
 123.865 +      if (_node_index) {
 123.866 +        delete _node_index;
 123.867 +        delete _node_heap_index;
 123.868 +        delete _node_data;
 123.869 +      }
 123.870 +
 123.871 +      if (_tree_set) {
 123.872 +        delete _tree_set_index;
 123.873 +        delete _tree_set;
 123.874 +      }
 123.875 +      if (_delta1) {
 123.876 +        delete _delta1_index;
 123.877 +        delete _delta1;
 123.878 +      }
 123.879 +      if (_delta2) {
 123.880 +        delete _delta2_index;
 123.881 +        delete _delta2;
 123.882 +      }
 123.883 +      if (_delta3) {
 123.884 +        delete _delta3_index;
 123.885 +        delete _delta3;
 123.886 +      }
 123.887 +      if (_delta4) {
 123.888 +        delete _delta4_index;
 123.889 +        delete _delta4;
 123.890 +      }
 123.891 +    }
 123.892 +
 123.893 +    void matchedToEven(int blossom, int tree) {
 123.894 +      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
 123.895 +        _delta2->erase(blossom);
 123.896 +      }
 123.897 +
 123.898 +      if (!_blossom_set->trivial(blossom)) {
 123.899 +        (*_blossom_data)[blossom].pot -=
 123.900 +          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
 123.901 +      }
 123.902 +
 123.903 +      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
 123.904 +           n != INVALID; ++n) {
 123.905 +
 123.906 +        _blossom_set->increase(n, std::numeric_limits<Value>::max());
 123.907 +        int ni = (*_node_index)[n];
 123.908 +
 123.909 +        (*_node_data)[ni].heap.clear();
 123.910 +        (*_node_data)[ni].heap_index.clear();
 123.911 +
 123.912 +        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
 123.913 +
 123.914 +        _delta1->push(n, (*_node_data)[ni].pot);
 123.915 +
 123.916 +        for (InArcIt e(_graph, n); e != INVALID; ++e) {
 123.917 +          Node v = _graph.source(e);
 123.918 +          int vb = _blossom_set->find(v);
 123.919 +          int vi = (*_node_index)[v];
 123.920 +
 123.921 +          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
 123.922 +            dualScale * _weight[e];
 123.923 +
 123.924 +          if ((*_blossom_data)[vb].status == EVEN) {
 123.925 +            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
 123.926 +              _delta3->push(e, rw / 2);
 123.927 +            }
 123.928 +          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
 123.929 +            if (_delta3->state(e) != _delta3->IN_HEAP) {
 123.930 +              _delta3->push(e, rw);
 123.931 +            }
 123.932 +          } else {
 123.933 +            typename std::map<int, Arc>::iterator it =
 123.934 +              (*_node_data)[vi].heap_index.find(tree);
 123.935 +
 123.936 +            if (it != (*_node_data)[vi].heap_index.end()) {
 123.937 +              if ((*_node_data)[vi].heap[it->second] > rw) {
 123.938 +                (*_node_data)[vi].heap.replace(it->second, e);
 123.939 +                (*_node_data)[vi].heap.decrease(e, rw);
 123.940 +                it->second = e;
 123.941 +              }
 123.942 +            } else {
 123.943 +              (*_node_data)[vi].heap.push(e, rw);
 123.944 +              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
 123.945 +            }
 123.946 +
 123.947 +            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
 123.948 +              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
 123.949 +
 123.950 +              if ((*_blossom_data)[vb].status == MATCHED) {
 123.951 +                if (_delta2->state(vb) != _delta2->IN_HEAP) {
 123.952 +                  _delta2->push(vb, _blossom_set->classPrio(vb) -
 123.953 +                               (*_blossom_data)[vb].offset);
 123.954 +                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
 123.955 +                           (*_blossom_data)[vb].offset){
 123.956 +                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
 123.957 +                                   (*_blossom_data)[vb].offset);
 123.958 +                }
 123.959 +              }
 123.960 +            }
 123.961 +          }
 123.962 +        }
 123.963 +      }
 123.964 +      (*_blossom_data)[blossom].offset = 0;
 123.965 +    }
 123.966 +
 123.967 +    void matchedToOdd(int blossom) {
 123.968 +      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
 123.969 +        _delta2->erase(blossom);
 123.970 +      }
 123.971 +      (*_blossom_data)[blossom].offset += _delta_sum;
 123.972 +      if (!_blossom_set->trivial(blossom)) {
 123.973 +        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
 123.974 +                     (*_blossom_data)[blossom].offset);
 123.975 +      }
 123.976 +    }
 123.977 +
 123.978 +    void evenToMatched(int blossom, int tree) {
 123.979 +      if (!_blossom_set->trivial(blossom)) {
 123.980 +        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
 123.981 +      }
 123.982 +
 123.983 +      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
 123.984 +           n != INVALID; ++n) {
 123.985 +        int ni = (*_node_index)[n];
 123.986 +        (*_node_data)[ni].pot -= _delta_sum;
 123.987 +
 123.988 +        _delta1->erase(n);
 123.989 +
 123.990 +        for (InArcIt e(_graph, n); e != INVALID; ++e) {
 123.991 +          Node v = _graph.source(e);
 123.992 +          int vb = _blossom_set->find(v);
 123.993 +          int vi = (*_node_index)[v];
 123.994 +
 123.995 +          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
 123.996 +            dualScale * _weight[e];
 123.997 +
 123.998 +          if (vb == blossom) {
 123.999 +            if (_delta3->state(e) == _delta3->IN_HEAP) {
123.1000 +              _delta3->erase(e);
123.1001 +            }
123.1002 +          } else if ((*_blossom_data)[vb].status == EVEN) {
123.1003 +
123.1004 +            if (_delta3->state(e) == _delta3->IN_HEAP) {
123.1005 +              _delta3->erase(e);
123.1006 +            }
123.1007 +
123.1008 +            int vt = _tree_set->find(vb);
123.1009 +
123.1010 +            if (vt != tree) {
123.1011 +
123.1012 +              Arc r = _graph.oppositeArc(e);
123.1013 +
123.1014 +              typename std::map<int, Arc>::iterator it =
123.1015 +                (*_node_data)[ni].heap_index.find(vt);
123.1016 +
123.1017 +              if (it != (*_node_data)[ni].heap_index.end()) {
123.1018 +                if ((*_node_data)[ni].heap[it->second] > rw) {
123.1019 +                  (*_node_data)[ni].heap.replace(it->second, r);
123.1020 +                  (*_node_data)[ni].heap.decrease(r, rw);
123.1021 +                  it->second = r;
123.1022 +                }
123.1023 +              } else {
123.1024 +                (*_node_data)[ni].heap.push(r, rw);
123.1025 +                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
123.1026 +              }
123.1027 +
123.1028 +              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
123.1029 +                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
123.1030 +
123.1031 +                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
123.1032 +                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
123.1033 +                               (*_blossom_data)[blossom].offset);
123.1034 +                } else if ((*_delta2)[blossom] >
123.1035 +                           _blossom_set->classPrio(blossom) -
123.1036 +                           (*_blossom_data)[blossom].offset){
123.1037 +                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
123.1038 +                                   (*_blossom_data)[blossom].offset);
123.1039 +                }
123.1040 +              }
123.1041 +            }
123.1042 +
123.1043 +          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
123.1044 +            if (_delta3->state(e) == _delta3->IN_HEAP) {
123.1045 +              _delta3->erase(e);
123.1046 +            }
123.1047 +          } else {
123.1048 +
123.1049 +            typename std::map<int, Arc>::iterator it =
123.1050 +              (*_node_data)[vi].heap_index.find(tree);
123.1051 +
123.1052 +            if (it != (*_node_data)[vi].heap_index.end()) {
123.1053 +              (*_node_data)[vi].heap.erase(it->second);
123.1054 +              (*_node_data)[vi].heap_index.erase(it);
123.1055 +              if ((*_node_data)[vi].heap.empty()) {
123.1056 +                _blossom_set->increase(v, std::numeric_limits<Value>::max());
123.1057 +              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
123.1058 +                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
123.1059 +              }
123.1060 +
123.1061 +              if ((*_blossom_data)[vb].status == MATCHED) {
123.1062 +                if (_blossom_set->classPrio(vb) ==
123.1063 +                    std::numeric_limits<Value>::max()) {
123.1064 +                  _delta2->erase(vb);
123.1065 +                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
123.1066 +                           (*_blossom_data)[vb].offset) {
123.1067 +                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
123.1068 +                                   (*_blossom_data)[vb].offset);
123.1069 +                }
123.1070 +              }
123.1071 +            }
123.1072 +          }
123.1073 +        }
123.1074 +      }
123.1075 +    }
123.1076 +
123.1077 +    void oddToMatched(int blossom) {
123.1078 +      (*_blossom_data)[blossom].offset -= _delta_sum;
123.1079 +
123.1080 +      if (_blossom_set->classPrio(blossom) !=
123.1081 +          std::numeric_limits<Value>::max()) {
123.1082 +        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
123.1083 +                       (*_blossom_data)[blossom].offset);
123.1084 +      }
123.1085 +
123.1086 +      if (!_blossom_set->trivial(blossom)) {
123.1087 +        _delta4->erase(blossom);
123.1088 +      }
123.1089 +    }
123.1090 +
123.1091 +    void oddToEven(int blossom, int tree) {
123.1092 +      if (!_blossom_set->trivial(blossom)) {
123.1093 +        _delta4->erase(blossom);
123.1094 +        (*_blossom_data)[blossom].pot -=
123.1095 +          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
123.1096 +      }
123.1097 +
123.1098 +      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
123.1099 +           n != INVALID; ++n) {
123.1100 +        int ni = (*_node_index)[n];
123.1101 +
123.1102 +        _blossom_set->increase(n, std::numeric_limits<Value>::max());
123.1103 +
123.1104 +        (*_node_data)[ni].heap.clear();
123.1105 +        (*_node_data)[ni].heap_index.clear();
123.1106 +        (*_node_data)[ni].pot +=
123.1107 +          2 * _delta_sum - (*_blossom_data)[blossom].offset;
123.1108 +
123.1109 +        _delta1->push(n, (*_node_data)[ni].pot);
123.1110 +
123.1111 +        for (InArcIt e(_graph, n); e != INVALID; ++e) {
123.1112 +          Node v = _graph.source(e);
123.1113 +          int vb = _blossom_set->find(v);
123.1114 +          int vi = (*_node_index)[v];
123.1115 +
123.1116 +          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
123.1117 +            dualScale * _weight[e];
123.1118 +
123.1119 +          if ((*_blossom_data)[vb].status == EVEN) {
123.1120 +            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
123.1121 +              _delta3->push(e, rw / 2);
123.1122 +            }
123.1123 +          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
123.1124 +            if (_delta3->state(e) != _delta3->IN_HEAP) {
123.1125 +              _delta3->push(e, rw);
123.1126 +            }
123.1127 +          } else {
123.1128 +
123.1129 +            typename std::map<int, Arc>::iterator it =
123.1130 +              (*_node_data)[vi].heap_index.find(tree);
123.1131 +
123.1132 +            if (it != (*_node_data)[vi].heap_index.end()) {
123.1133 +              if ((*_node_data)[vi].heap[it->second] > rw) {
123.1134 +                (*_node_data)[vi].heap.replace(it->second, e);
123.1135 +                (*_node_data)[vi].heap.decrease(e, rw);
123.1136 +                it->second = e;
123.1137 +              }
123.1138 +            } else {
123.1139 +              (*_node_data)[vi].heap.push(e, rw);
123.1140 +              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
123.1141 +            }
123.1142 +
123.1143 +            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
123.1144 +              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
123.1145 +
123.1146 +              if ((*_blossom_data)[vb].status == MATCHED) {
123.1147 +                if (_delta2->state(vb) != _delta2->IN_HEAP) {
123.1148 +                  _delta2->push(vb, _blossom_set->classPrio(vb) -
123.1149 +                               (*_blossom_data)[vb].offset);
123.1150 +                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
123.1151 +                           (*_blossom_data)[vb].offset) {
123.1152 +                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
123.1153 +                                   (*_blossom_data)[vb].offset);
123.1154 +                }
123.1155 +              }
123.1156 +            }
123.1157 +          }
123.1158 +        }
123.1159 +      }
123.1160 +      (*_blossom_data)[blossom].offset = 0;
123.1161 +    }
123.1162 +
123.1163 +
123.1164 +    void matchedToUnmatched(int blossom) {
123.1165 +      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
123.1166 +        _delta2->erase(blossom);
123.1167 +      }
123.1168 +
123.1169 +      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
123.1170 +           n != INVALID; ++n) {
123.1171 +        int ni = (*_node_index)[n];
123.1172 +
123.1173 +        _blossom_set->increase(n, std::numeric_limits<Value>::max());
123.1174 +
123.1175 +        (*_node_data)[ni].heap.clear();
123.1176 +        (*_node_data)[ni].heap_index.clear();
123.1177 +
123.1178 +        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
123.1179 +          Node v = _graph.target(e);
123.1180 +          int vb = _blossom_set->find(v);
123.1181 +          int vi = (*_node_index)[v];
123.1182 +
123.1183 +          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
123.1184 +            dualScale * _weight[e];
123.1185 +
123.1186 +          if ((*_blossom_data)[vb].status == EVEN) {
123.1187 +            if (_delta3->state(e) != _delta3->IN_HEAP) {
123.1188 +              _delta3->push(e, rw);
123.1189 +            }
123.1190 +          }
123.1191 +        }
123.1192 +      }
123.1193 +    }
123.1194 +
123.1195 +    void unmatchedToMatched(int blossom) {
123.1196 +      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
123.1197 +           n != INVALID; ++n) {
123.1198 +        int ni = (*_node_index)[n];
123.1199 +
123.1200 +        for (InArcIt e(_graph, n); e != INVALID; ++e) {
123.1201 +          Node v = _graph.source(e);
123.1202 +          int vb = _blossom_set->find(v);
123.1203 +          int vi = (*_node_index)[v];
123.1204 +
123.1205 +          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
123.1206 +            dualScale * _weight[e];
123.1207 +
123.1208 +          if (vb == blossom) {
123.1209 +            if (_delta3->state(e) == _delta3->IN_HEAP) {
123.1210 +              _delta3->erase(e);
123.1211 +            }
123.1212 +          } else if ((*_blossom_data)[vb].status == EVEN) {
123.1213 +
123.1214 +            if (_delta3->state(e) == _delta3->IN_HEAP) {
123.1215 +              _delta3->erase(e);
123.1216 +            }
123.1217 +
123.1218 +            int vt = _tree_set->find(vb);
123.1219 +
123.1220 +            Arc r = _graph.oppositeArc(e);
123.1221 +
123.1222 +            typename std::map<int, Arc>::iterator it =
123.1223 +              (*_node_data)[ni].heap_index.find(vt);
123.1224 +
123.1225 +            if (it != (*_node_data)[ni].heap_index.end()) {
123.1226 +              if ((*_node_data)[ni].heap[it->second] > rw) {
123.1227 +                (*_node_data)[ni].heap.replace(it->second, r);
123.1228 +                (*_node_data)[ni].heap.decrease(r, rw);
123.1229 +                it->second = r;
123.1230 +              }
123.1231 +            } else {
123.1232 +              (*_node_data)[ni].heap.push(r, rw);
123.1233 +              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
123.1234 +            }
123.1235 +
123.1236 +            if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
123.1237 +              _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
123.1238 +
123.1239 +              if (_delta2->state(blossom) != _delta2->IN_HEAP) {
123.1240 +                _delta2->push(blossom, _blossom_set->classPrio(blossom) -
123.1241 +                             (*_blossom_data)[blossom].offset);
123.1242 +              } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
123.1243 +                         (*_blossom_data)[blossom].offset){
123.1244 +                _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
123.1245 +                                 (*_blossom_data)[blossom].offset);
123.1246 +              }
123.1247 +            }
123.1248 +
123.1249 +          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
123.1250 +            if (_delta3->state(e) == _delta3->IN_HEAP) {
123.1251 +              _delta3->erase(e);
123.1252 +            }
123.1253 +          }
123.1254 +        }
123.1255 +      }
123.1256 +    }
123.1257 +
123.1258 +    void alternatePath(int even, int tree) {
123.1259 +      int odd;
123.1260 +
123.1261 +      evenToMatched(even, tree);
123.1262 +      (*_blossom_data)[even].status = MATCHED;
123.1263 +
123.1264 +      while ((*_blossom_data)[even].pred != INVALID) {
123.1265 +        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
123.1266 +        (*_blossom_data)[odd].status = MATCHED;
123.1267 +        oddToMatched(odd);
123.1268 +        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
123.1269 +
123.1270 +        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
123.1271 +        (*_blossom_data)[even].status = MATCHED;
123.1272 +        evenToMatched(even, tree);
123.1273 +        (*_blossom_data)[even].next =
123.1274 +          _graph.oppositeArc((*_blossom_data)[odd].pred);
123.1275 +      }
123.1276 +
123.1277 +    }
123.1278 +
123.1279 +    void destroyTree(int tree) {
123.1280 +      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
123.1281 +        if ((*_blossom_data)[b].status == EVEN) {
123.1282 +          (*_blossom_data)[b].status = MATCHED;
123.1283 +          evenToMatched(b, tree);
123.1284 +        } else if ((*_blossom_data)[b].status == ODD) {
123.1285 +          (*_blossom_data)[b].status = MATCHED;
123.1286 +          oddToMatched(b);
123.1287 +        }
123.1288 +      }
123.1289 +      _tree_set->eraseClass(tree);
123.1290 +    }
123.1291 +
123.1292 +
123.1293 +    void unmatchNode(const Node& node) {
123.1294 +      int blossom = _blossom_set->find(node);
123.1295 +      int tree = _tree_set->find(blossom);
123.1296 +
123.1297 +      alternatePath(blossom, tree);
123.1298 +      destroyTree(tree);
123.1299 +
123.1300 +      (*_blossom_data)[blossom].status = UNMATCHED;
123.1301 +      (*_blossom_data)[blossom].base = node;
123.1302 +      matchedToUnmatched(blossom);
123.1303 +    }
123.1304 +
123.1305 +
123.1306 +    void augmentOnEdge(const Edge& edge) {
123.1307 +
123.1308 +      int left = _blossom_set->find(_graph.u(edge));
123.1309 +      int right = _blossom_set->find(_graph.v(edge));
123.1310 +
123.1311 +      if ((*_blossom_data)[left].status == EVEN) {
123.1312 +        int left_tree = _tree_set->find(left);
123.1313 +        alternatePath(left, left_tree);
123.1314 +        destroyTree(left_tree);
123.1315 +      } else {
123.1316 +        (*_blossom_data)[left].status = MATCHED;
123.1317 +        unmatchedToMatched(left);
123.1318 +      }
123.1319 +
123.1320 +      if ((*_blossom_data)[right].status == EVEN) {
123.1321 +        int right_tree = _tree_set->find(right);
123.1322 +        alternatePath(right, right_tree);
123.1323 +        destroyTree(right_tree);
123.1324 +      } else {
123.1325 +        (*_blossom_data)[right].status = MATCHED;
123.1326 +        unmatchedToMatched(right);
123.1327 +      }
123.1328 +
123.1329 +      (*_blossom_data)[left].next = _graph.direct(edge, true);
123.1330 +      (*_blossom_data)[right].next = _graph.direct(edge, false);
123.1331 +    }
123.1332 +
123.1333 +    void extendOnArc(const Arc& arc) {
123.1334 +      int base = _blossom_set->find(_graph.target(arc));
123.1335 +      int tree = _tree_set->find(base);
123.1336 +
123.1337 +      int odd = _blossom_set->find(_graph.source(arc));
123.1338 +      _tree_set->insert(odd, tree);
123.1339 +      (*_blossom_data)[odd].status = ODD;
123.1340 +      matchedToOdd(odd);
123.1341 +      (*_blossom_data)[odd].pred = arc;
123.1342 +
123.1343 +      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
123.1344 +      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
123.1345 +      _tree_set->insert(even, tree);
123.1346 +      (*_blossom_data)[even].status = EVEN;
123.1347 +      matchedToEven(even, tree);
123.1348 +    }
123.1349 +
123.1350 +    void shrinkOnEdge(const Edge& edge, int tree) {
123.1351 +      int nca = -1;
123.1352 +      std::vector<int> left_path, right_path;
123.1353 +
123.1354 +      {
123.1355 +        std::set<int> left_set, right_set;
123.1356 +        int left = _blossom_set->find(_graph.u(edge));
123.1357 +        left_path.push_back(left);
123.1358 +        left_set.insert(left);
123.1359 +
123.1360 +        int right = _blossom_set->find(_graph.v(edge));
123.1361 +        right_path.push_back(right);
123.1362 +        right_set.insert(right);
123.1363 +
123.1364 +        while (true) {
123.1365 +
123.1366 +          if ((*_blossom_data)[left].pred == INVALID) break;
123.1367 +
123.1368 +          left =
123.1369 +            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
123.1370 +          left_path.push_back(left);
123.1371 +          left =
123.1372 +            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
123.1373 +          left_path.push_back(left);
123.1374 +
123.1375 +          left_set.insert(left);
123.1376 +
123.1377 +          if (right_set.find(left) != right_set.end()) {
123.1378 +            nca = left;
123.1379 +            break;
123.1380 +          }
123.1381 +
123.1382 +          if ((*_blossom_data)[right].pred == INVALID) break;
123.1383 +
123.1384 +          right =
123.1385 +            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
123.1386 +          right_path.push_back(right);
123.1387 +          right =
123.1388 +            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
123.1389 +          right_path.push_back(right);
123.1390 +
123.1391 +          right_set.insert(right);
123.1392 +
123.1393 +          if (left_set.find(right) != left_set.end()) {
123.1394 +            nca = right;
123.1395 +            break;
123.1396 +          }
123.1397 +
123.1398 +        }
123.1399 +
123.1400 +        if (nca == -1) {
123.1401 +          if ((*_blossom_data)[left].pred == INVALID) {
123.1402 +            nca = right;
123.1403 +            while (left_set.find(nca) == left_set.end()) {
123.1404 +              nca =
123.1405 +                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
123.1406 +              right_path.push_back(nca);
123.1407 +              nca =
123.1408 +                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
123.1409 +              right_path.push_back(nca);
123.1410 +            }
123.1411 +          } else {
123.1412 +            nca = left;
123.1413 +            while (right_set.find(nca) == right_set.end()) {
123.1414 +              nca =
123.1415 +                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
123.1416 +              left_path.push_back(nca);
123.1417 +              nca =
123.1418 +                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
123.1419 +              left_path.push_back(nca);
123.1420 +            }
123.1421 +          }
123.1422 +        }
123.1423 +      }
123.1424 +
123.1425 +      std::vector<int> subblossoms;
123.1426 +      Arc prev;
123.1427 +
123.1428 +      prev = _graph.direct(edge, true);
123.1429 +      for (int i = 0; left_path[i] != nca; i += 2) {
123.1430 +        subblossoms.push_back(left_path[i]);
123.1431 +        (*_blossom_data)[left_path[i]].next = prev;
123.1432 +        _tree_set->erase(left_path[i]);
123.1433 +
123.1434 +        subblossoms.push_back(left_path[i + 1]);
123.1435 +        (*_blossom_data)[left_path[i + 1]].status = EVEN;
123.1436 +        oddToEven(left_path[i + 1], tree);
123.1437 +        _tree_set->erase(left_path[i + 1]);
123.1438 +        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
123.1439 +      }
123.1440 +
123.1441 +      int k = 0;
123.1442 +      while (right_path[k] != nca) ++k;
123.1443 +
123.1444 +      subblossoms.push_back(nca);
123.1445 +      (*_blossom_data)[nca].next = prev;
123.1446 +
123.1447 +      for (int i = k - 2; i >= 0; i -= 2) {
123.1448 +        subblossoms.push_back(right_path[i + 1]);
123.1449 +        (*_blossom_data)[right_path[i + 1]].status = EVEN;
123.1450 +        oddToEven(right_path[i + 1], tree);
123.1451 +        _tree_set->erase(right_path[i + 1]);
123.1452 +
123.1453 +        (*_blossom_data)[right_path[i + 1]].next =
123.1454 +          (*_blossom_data)[right_path[i + 1]].pred;
123.1455 +
123.1456 +        subblossoms.push_back(right_path[i]);
123.1457 +        _tree_set->erase(right_path[i]);
123.1458 +      }
123.1459 +
123.1460 +      int surface =
123.1461 +        _blossom_set->join(subblossoms.begin(), subblossoms.end());
123.1462 +
123.1463 +      for (int i = 0; i < int(subblossoms.size()); ++i) {
123.1464 +        if (!_blossom_set->trivial(subblossoms[i])) {
123.1465 +          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
123.1466 +        }
123.1467 +        (*_blossom_data)[subblossoms[i]].status = MATCHED;
123.1468 +      }
123.1469 +
123.1470 +      (*_blossom_data)[surface].pot = -2 * _delta_sum;
123.1471 +      (*_blossom_data)[surface].offset = 0;
123.1472 +      (*_blossom_data)[surface].status = EVEN;
123.1473 +      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
123.1474 +      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
123.1475 +
123.1476 +      _tree_set->insert(surface, tree);
123.1477 +      _tree_set->erase(nca);
123.1478 +    }
123.1479 +
123.1480 +    void splitBlossom(int blossom) {
123.1481 +      Arc next = (*_blossom_data)[blossom].next;
123.1482 +      Arc pred = (*_blossom_data)[blossom].pred;
123.1483 +
123.1484 +      int tree = _tree_set->find(blossom);
123.1485 +
123.1486 +      (*_blossom_data)[blossom].status = MATCHED;
123.1487 +      oddToMatched(blossom);
123.1488 +      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
123.1489 +        _delta2->erase(blossom);
123.1490 +      }
123.1491 +
123.1492 +      std::vector<int> subblossoms;
123.1493 +      _blossom_set->split(blossom, std::back_inserter(subblossoms));
123.1494 +
123.1495 +      Value offset = (*_blossom_data)[blossom].offset;
123.1496 +      int b = _blossom_set->find(_graph.source(pred));
123.1497 +      int d = _blossom_set->find(_graph.source(next));
123.1498 +
123.1499 +      int ib = -1, id = -1;
123.1500 +      for (int i = 0; i < int(subblossoms.size()); ++i) {
123.1501 +        if (subblossoms[i] == b) ib = i;
123.1502 +        if (subblossoms[i] == d) id = i;
123.1503 +
123.1504 +        (*_blossom_data)[subblossoms[i]].offset = offset;
123.1505 +        if (!_blossom_set->trivial(subblossoms[i])) {
123.1506 +          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
123.1507 +        }
123.1508 +        if (_blossom_set->classPrio(subblossoms[i]) !=
123.1509 +            std::numeric_limits<Value>::max()) {
123.1510 +          _delta2->push(subblossoms[i],
123.1511 +                        _blossom_set->classPrio(subblossoms[i]) -
123.1512 +                        (*_blossom_data)[subblossoms[i]].offset);
123.1513 +        }
123.1514 +      }
123.1515 +
123.1516 +      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
123.1517 +        for (int i = (id + 1) % subblossoms.size();
123.1518 +             i != ib; i = (i + 2) % subblossoms.size()) {
123.1519 +          int sb = subblossoms[i];
123.1520 +          int tb = subblossoms[(i + 1) % subblossoms.size()];
123.1521 +          (*_blossom_data)[sb].next =
123.1522 +            _graph.oppositeArc((*_blossom_data)[tb].next);
123.1523 +        }
123.1524 +
123.1525 +        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
123.1526 +          int sb = subblossoms[i];
123.1527 +          int tb = subblossoms[(i + 1) % subblossoms.size()];
123.1528 +          int ub = subblossoms[(i + 2) % subblossoms.size()];
123.1529 +
123.1530 +          (*_blossom_data)[sb].status = ODD;
123.1531 +          matchedToOdd(sb);
123.1532 +          _tree_set->insert(sb, tree);
123.1533 +          (*_blossom_data)[sb].pred = pred;
123.1534 +          (*_blossom_data)[sb].next =
123.1535 +                           _graph.oppositeArc((*_blossom_data)[tb].next);
123.1536 +
123.1537 +          pred = (*_blossom_data)[ub].next;
123.1538 +
123.1539 +          (*_blossom_data)[tb].status = EVEN;
123.1540 +          matchedToEven(tb, tree);
123.1541 +          _tree_set->insert(tb, tree);
123.1542 +          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
123.1543 +        }
123.1544 +
123.1545 +        (*_blossom_data)[subblossoms[id]].status = ODD;
123.1546 +        matchedToOdd(subblossoms[id]);
123.1547 +        _tree_set->insert(subblossoms[id], tree);
123.1548 +        (*_blossom_data)[subblossoms[id]].next = next;
123.1549 +        (*_blossom_data)[subblossoms[id]].pred = pred;
123.1550 +
123.1551 +      } else {
123.1552 +
123.1553 +        for (int i = (ib + 1) % subblossoms.size();
123.1554 +             i != id; i = (i + 2) % subblossoms.size()) {
123.1555 +          int sb = subblossoms[i];
123.1556 +          int tb = subblossoms[(i + 1) % subblossoms.size()];
123.1557 +          (*_blossom_data)[sb].next =
123.1558 +            _graph.oppositeArc((*_blossom_data)[tb].next);
123.1559 +        }
123.1560 +
123.1561 +        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
123.1562 +          int sb = subblossoms[i];
123.1563 +          int tb = subblossoms[(i + 1) % subblossoms.size()];
123.1564 +          int ub = subblossoms[(i + 2) % subblossoms.size()];
123.1565 +
123.1566 +          (*_blossom_data)[sb].status = ODD;
123.1567 +          matchedToOdd(sb);
123.1568 +          _tree_set->insert(sb, tree);
123.1569 +          (*_blossom_data)[sb].next = next;
123.1570 +          (*_blossom_data)[sb].pred =
123.1571 +            _graph.oppositeArc((*_blossom_data)[tb].next);
123.1572 +
123.1573 +          (*_blossom_data)[tb].status = EVEN;
123.1574 +          matchedToEven(tb, tree);
123.1575 +          _tree_set->insert(tb, tree);
123.1576 +          (*_blossom_data)[tb].pred =
123.1577 +            (*_blossom_data)[tb].next =
123.1578 +            _graph.oppositeArc((*_blossom_data)[ub].next);
123.1579 +          next = (*_blossom_data)[ub].next;
123.1580 +        }
123.1581 +
123.1582 +        (*_blossom_data)[subblossoms[ib]].status = ODD;
123.1583 +        matchedToOdd(subblossoms[ib]);
123.1584 +        _tree_set->insert(subblossoms[ib], tree);
123.1585 +        (*_blossom_data)[subblossoms[ib]].next = next;
123.1586 +        (*_blossom_data)[subblossoms[ib]].pred = pred;
123.1587 +      }
123.1588 +      _tree_set->erase(blossom);
123.1589 +    }
123.1590 +
123.1591 +    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
123.1592 +      if (_blossom_set->trivial(blossom)) {
123.1593 +        int bi = (*_node_index)[base];
123.1594 +        Value pot = (*_node_data)[bi].pot;
123.1595 +
123.1596 +        (*_matching)[base] = matching;
123.1597 +        _blossom_node_list.push_back(base);
123.1598 +        (*_node_potential)[base] = pot;
123.1599 +      } else {
123.1600 +
123.1601 +        Value pot = (*_blossom_data)[blossom].pot;
123.1602 +        int bn = _blossom_node_list.size();
123.1603 +
123.1604 +        std::vector<int> subblossoms;
123.1605 +        _blossom_set->split(blossom, std::back_inserter(subblossoms));
123.1606 +        int b = _blossom_set->find(base);
123.1607 +        int ib = -1;
123.1608 +        for (int i = 0; i < int(subblossoms.size()); ++i) {
123.1609 +          if (subblossoms[i] == b) { ib = i; break; }
123.1610 +        }
123.1611 +
123.1612 +        for (int i = 1; i < int(subblossoms.size()); i += 2) {
123.1613 +          int sb = subblossoms[(ib + i) % subblossoms.size()];
123.1614 +          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
123.1615 +
123.1616 +          Arc m = (*_blossom_data)[tb].next;
123.1617 +          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
123.1618 +          extractBlossom(tb, _graph.source(m), m);
123.1619 +        }
123.1620 +        extractBlossom(subblossoms[ib], base, matching);
123.1621 +
123.1622 +        int en = _blossom_node_list.size();
123.1623 +
123.1624 +        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
123.1625 +      }
123.1626 +    }
123.1627 +
123.1628 +    void extractMatching() {
123.1629 +      std::vector<int> blossoms;
123.1630 +      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
123.1631 +        blossoms.push_back(c);
123.1632 +      }
123.1633 +
123.1634 +      for (int i = 0; i < int(blossoms.size()); ++i) {
123.1635 +        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
123.1636 +
123.1637 +          Value offset = (*_blossom_data)[blossoms[i]].offset;
123.1638 +          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
123.1639 +          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
123.1640 +               n != INVALID; ++n) {
123.1641 +            (*_node_data)[(*_node_index)[n]].pot -= offset;
123.1642 +          }
123.1643 +
123.1644 +          Arc matching = (*_blossom_data)[blossoms[i]].next;
123.1645 +          Node base = _graph.source(matching);
123.1646 +          extractBlossom(blossoms[i], base, matching);
123.1647 +        } else {
123.1648 +          Node base = (*_blossom_data)[blossoms[i]].base;
123.1649 +          extractBlossom(blossoms[i], base, INVALID);
123.1650 +        }
123.1651 +      }
123.1652 +    }
123.1653 +
123.1654 +  public:
123.1655 +
123.1656 +    /// \brief Constructor
123.1657 +    ///
123.1658 +    /// Constructor.
123.1659 +    MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
123.1660 +      : _graph(graph), _weight(weight), _matching(0),
123.1661 +        _node_potential(0), _blossom_potential(), _blossom_node_list(),
123.1662 +        _node_num(0), _blossom_num(0),
123.1663 +
123.1664 +        _blossom_index(0), _blossom_set(0), _blossom_data(0),
123.1665 +        _node_index(0), _node_heap_index(0), _node_data(0),
123.1666 +        _tree_set_index(0), _tree_set(0),
123.1667 +
123.1668 +        _delta1_index(0), _delta1(0),
123.1669 +        _delta2_index(0), _delta2(0),
123.1670 +        _delta3_index(0), _delta3(0),
123.1671 +        _delta4_index(0), _delta4(0),
123.1672 +
123.1673 +        _delta_sum() {}
123.1674 +
123.1675 +    ~MaxWeightedMatching() {
123.1676 +      destroyStructures();
123.1677 +    }
123.1678 +
123.1679 +    /// \name Execution Control
123.1680 +    /// The simplest way to execute the algorithm is to use the
123.1681 +    /// \ref run() member function.
123.1682 +
123.1683 +    ///@{
123.1684 +
123.1685 +    /// \brief Initialize the algorithm
123.1686 +    ///
123.1687 +    /// This function initializes the algorithm.
123.1688 +    void init() {
123.1689 +      createStructures();
123.1690 +
123.1691 +      for (ArcIt e(_graph); e != INVALID; ++e) {
123.1692 +        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
123.1693 +      }
123.1694 +      for (NodeIt n(_graph); n != INVALID; ++n) {
123.1695 +        (*_delta1_index)[n] = _delta1->PRE_HEAP;
123.1696 +      }
123.1697 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
123.1698 +        (*_delta3_index)[e] = _delta3->PRE_HEAP;
123.1699 +      }
123.1700 +      for (int i = 0; i < _blossom_num; ++i) {
123.1701 +        (*_delta2_index)[i] = _delta2->PRE_HEAP;
123.1702 +        (*_delta4_index)[i] = _delta4->PRE_HEAP;
123.1703 +      }
123.1704 +
123.1705 +      int index = 0;
123.1706 +      for (NodeIt n(_graph); n != INVALID; ++n) {
123.1707 +        Value max = 0;
123.1708 +        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
123.1709 +          if (_graph.target(e) == n) continue;
123.1710 +          if ((dualScale * _weight[e]) / 2 > max) {
123.1711 +            max = (dualScale * _weight[e]) / 2;
123.1712 +          }
123.1713 +        }
123.1714 +        (*_node_index)[n] = index;
123.1715 +        (*_node_data)[index].pot = max;
123.1716 +        _delta1->push(n, max);
123.1717 +        int blossom =
123.1718 +          _blossom_set->insert(n, std::numeric_limits<Value>::max());
123.1719 +
123.1720 +        _tree_set->insert(blossom);
123.1721 +
123.1722 +        (*_blossom_data)[blossom].status = EVEN;
123.1723 +        (*_blossom_data)[blossom].pred = INVALID;
123.1724 +        (*_blossom_data)[blossom].next = INVALID;
123.1725 +        (*_blossom_data)[blossom].pot = 0;
123.1726 +        (*_blossom_data)[blossom].offset = 0;
123.1727 +        ++index;
123.1728 +      }
123.1729 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
123.1730 +        int si = (*_node_index)[_graph.u(e)];
123.1731 +        int ti = (*_node_index)[_graph.v(e)];
123.1732 +        if (_graph.u(e) != _graph.v(e)) {
123.1733 +          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
123.1734 +                            dualScale * _weight[e]) / 2);
123.1735 +        }
123.1736 +      }
123.1737 +    }
123.1738 +
123.1739 +    /// \brief Start the algorithm
123.1740 +    ///
123.1741 +    /// This function starts the algorithm.
123.1742 +    ///
123.1743 +    /// \pre \ref init() must be called before using this function.
123.1744 +    void start() {
123.1745 +      enum OpType {
123.1746 +        D1, D2, D3, D4
123.1747 +      };
123.1748 +
123.1749 +      int unmatched = _node_num;
123.1750 +      while (unmatched > 0) {
123.1751 +        Value d1 = !_delta1->empty() ?
123.1752 +          _delta1->prio() : std::numeric_limits<Value>::max();
123.1753 +
123.1754 +        Value d2 = !_delta2->empty() ?
123.1755 +          _delta2->prio() : std::numeric_limits<Value>::max();
123.1756 +
123.1757 +        Value d3 = !_delta3->empty() ?
123.1758 +          _delta3->prio() : std::numeric_limits<Value>::max();
123.1759 +
123.1760 +        Value d4 = !_delta4->empty() ?
123.1761 +          _delta4->prio() : std::numeric_limits<Value>::max();
123.1762 +
123.1763 +        _delta_sum = d1; OpType ot = D1;
123.1764 +        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
123.1765 +        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
123.1766 +        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
123.1767 +
123.1768 +
123.1769 +        switch (ot) {
123.1770 +        case D1:
123.1771 +          {
123.1772 +            Node n = _delta1->top();
123.1773 +            unmatchNode(n);
123.1774 +            --unmatched;
123.1775 +          }
123.1776 +          break;
123.1777 +        case D2:
123.1778 +          {
123.1779 +            int blossom = _delta2->top();
123.1780 +            Node n = _blossom_set->classTop(blossom);
123.1781 +            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
123.1782 +            extendOnArc(e);
123.1783 +          }
123.1784 +          break;
123.1785 +        case D3:
123.1786 +          {
123.1787 +            Edge e = _delta3->top();
123.1788 +
123.1789 +            int left_blossom = _blossom_set->find(_graph.u(e));
123.1790 +            int right_blossom = _blossom_set->find(_graph.v(e));
123.1791 +
123.1792 +            if (left_blossom == right_blossom) {
123.1793 +              _delta3->pop();
123.1794 +            } else {
123.1795 +              int left_tree;
123.1796 +              if ((*_blossom_data)[left_blossom].status == EVEN) {
123.1797 +                left_tree = _tree_set->find(left_blossom);
123.1798 +              } else {
123.1799 +                left_tree = -1;
123.1800 +                ++unmatched;
123.1801 +              }
123.1802 +              int right_tree;
123.1803 +              if ((*_blossom_data)[right_blossom].status == EVEN) {
123.1804 +                right_tree = _tree_set->find(right_blossom);
123.1805 +              } else {
123.1806 +                right_tree = -1;
123.1807 +                ++unmatched;
123.1808 +              }
123.1809 +
123.1810 +              if (left_tree == right_tree) {
123.1811 +                shrinkOnEdge(e, left_tree);
123.1812 +              } else {
123.1813 +                augmentOnEdge(e);
123.1814 +                unmatched -= 2;
123.1815 +              }
123.1816 +            }
123.1817 +          } break;
123.1818 +        case D4:
123.1819 +          splitBlossom(_delta4->top());
123.1820 +          break;
123.1821 +        }
123.1822 +      }
123.1823 +      extractMatching();
123.1824 +    }
123.1825 +
123.1826 +    /// \brief Run the algorithm.
123.1827 +    ///
123.1828 +    /// This method runs the \c %MaxWeightedMatching algorithm.
123.1829 +    ///
123.1830 +    /// \note mwm.run() is just a shortcut of the following code.
123.1831 +    /// \code
123.1832 +    ///   mwm.init();
123.1833 +    ///   mwm.start();
123.1834 +    /// \endcode
123.1835 +    void run() {
123.1836 +      init();
123.1837 +      start();
123.1838 +    }
123.1839 +
123.1840 +    /// @}
123.1841 +
123.1842 +    /// \name Primal Solution
123.1843 +    /// Functions to get the primal solution, i.e. the maximum weighted 
123.1844 +    /// matching.\n
123.1845 +    /// Either \ref run() or \ref start() function should be called before
123.1846 +    /// using them.
123.1847 +
123.1848 +    /// @{
123.1849 +
123.1850 +    /// \brief Return the weight of the matching.
123.1851 +    ///
123.1852 +    /// This function returns the weight of the found matching.
123.1853 +    ///
123.1854 +    /// \pre Either run() or start() must be called before using this function.
123.1855 +    Value matchingWeight() const {
123.1856 +      Value sum = 0;
123.1857 +      for (NodeIt n(_graph); n != INVALID; ++n) {
123.1858 +        if ((*_matching)[n] != INVALID) {
123.1859 +          sum += _weight[(*_matching)[n]];
123.1860 +        }
123.1861 +      }
123.1862 +      return sum /= 2;
123.1863 +    }
123.1864 +
123.1865 +    /// \brief Return the size (cardinality) of the matching.
123.1866 +    ///
123.1867 +    /// This function returns the size (cardinality) of the found matching.
123.1868 +    ///
123.1869 +    /// \pre Either run() or start() must be called before using this function.
123.1870 +    int matchingSize() const {
123.1871 +      int num = 0;
123.1872 +      for (NodeIt n(_graph); n != INVALID; ++n) {
123.1873 +        if ((*_matching)[n] != INVALID) {
123.1874 +          ++num;
123.1875 +        }
123.1876 +      }
123.1877 +      return num /= 2;
123.1878 +    }
123.1879 +
123.1880 +    /// \brief Return \c true if the given edge is in the matching.
123.1881 +    ///
123.1882 +    /// This function returns \c true if the given edge is in the found 
123.1883 +    /// matching.
123.1884 +    ///
123.1885 +    /// \pre Either run() or start() must be called before using this function.
123.1886 +    bool matching(const Edge& edge) const {
123.1887 +      return edge == (*_matching)[_graph.u(edge)];
123.1888 +    }
123.1889 +
123.1890 +    /// \brief Return the matching arc (or edge) incident to the given node.
123.1891 +    ///
123.1892 +    /// This function returns the matching arc (or edge) incident to the
123.1893 +    /// given node in the found matching or \c INVALID if the node is 
123.1894 +    /// not covered by the matching.
123.1895 +    ///
123.1896 +    /// \pre Either run() or start() must be called before using this function.
123.1897 +    Arc matching(const Node& node) const {
123.1898 +      return (*_matching)[node];
123.1899 +    }
123.1900 +
123.1901 +    /// \brief Return a const reference to the matching map.
123.1902 +    ///
123.1903 +    /// This function returns a const reference to a node map that stores
123.1904 +    /// the matching arc (or edge) incident to each node.
123.1905 +    const MatchingMap& matchingMap() const {
123.1906 +      return *_matching;
123.1907 +    }
123.1908 +
123.1909 +    /// \brief Return the mate of the given node.
123.1910 +    ///
123.1911 +    /// This function returns the mate of the given node in the found 
123.1912 +    /// matching or \c INVALID if the node is not covered by the matching.
123.1913 +    ///
123.1914 +    /// \pre Either run() or start() must be called before using this function.
123.1915 +    Node mate(const Node& node) const {
123.1916 +      return (*_matching)[node] != INVALID ?
123.1917 +        _graph.target((*_matching)[node]) : INVALID;
123.1918 +    }
123.1919 +
123.1920 +    /// @}
123.1921 +
123.1922 +    /// \name Dual Solution
123.1923 +    /// Functions to get the dual solution.\n
123.1924 +    /// Either \ref run() or \ref start() function should be called before
123.1925 +    /// using them.
123.1926 +
123.1927 +    /// @{
123.1928 +
123.1929 +    /// \brief Return the value of the dual solution.
123.1930 +    ///
123.1931 +    /// This function returns the value of the dual solution. 
123.1932 +    /// It should be equal to the primal value scaled by \ref dualScale 
123.1933 +    /// "dual scale".
123.1934 +    ///
123.1935 +    /// \pre Either run() or start() must be called before using this function.
123.1936 +    Value dualValue() const {
123.1937 +      Value sum = 0;
123.1938 +      for (NodeIt n(_graph); n != INVALID; ++n) {
123.1939 +        sum += nodeValue(n);
123.1940 +      }
123.1941 +      for (int i = 0; i < blossomNum(); ++i) {
123.1942 +        sum += blossomValue(i) * (blossomSize(i) / 2);
123.1943 +      }
123.1944 +      return sum;
123.1945 +    }
123.1946 +
123.1947 +    /// \brief Return the dual value (potential) of the given node.
123.1948 +    ///
123.1949 +    /// This function returns the dual value (potential) of the given node.
123.1950 +    ///
123.1951 +    /// \pre Either run() or start() must be called before using this function.
123.1952 +    Value nodeValue(const Node& n) const {
123.1953 +      return (*_node_potential)[n];
123.1954 +    }
123.1955 +
123.1956 +    /// \brief Return the number of the blossoms in the basis.
123.1957 +    ///
123.1958 +    /// This function returns the number of the blossoms in the basis.
123.1959 +    ///
123.1960 +    /// \pre Either run() or start() must be called before using this function.
123.1961 +    /// \see BlossomIt
123.1962 +    int blossomNum() const {
123.1963 +      return _blossom_potential.size();
123.1964 +    }
123.1965 +
123.1966 +    /// \brief Return the number of the nodes in the given blossom.
123.1967 +    ///
123.1968 +    /// This function returns the number of the nodes in the given blossom.
123.1969 +    ///
123.1970 +    /// \pre Either run() or start() must be called before using this function.
123.1971 +    /// \see BlossomIt
123.1972 +    int blossomSize(int k) const {
123.1973 +      return _blossom_potential[k].end - _blossom_potential[k].begin;
123.1974 +    }
123.1975 +
123.1976 +    /// \brief Return the dual value (ptential) of the given blossom.
123.1977 +    ///
123.1978 +    /// This function returns the dual value (ptential) of the given blossom.
123.1979 +    ///
123.1980 +    /// \pre Either run() or start() must be called before using this function.
123.1981 +    Value blossomValue(int k) const {
123.1982 +      return _blossom_potential[k].value;
123.1983 +    }
123.1984 +
123.1985 +    /// \brief Iterator for obtaining the nodes of a blossom.
123.1986 +    ///
123.1987 +    /// This class provides an iterator for obtaining the nodes of the 
123.1988 +    /// given blossom. It lists a subset of the nodes.
123.1989 +    /// Before using this iterator, you must allocate a 
123.1990 +    /// MaxWeightedMatching class and execute it.
123.1991 +    class BlossomIt {
123.1992 +    public:
123.1993 +
123.1994 +      /// \brief Constructor.
123.1995 +      ///
123.1996 +      /// Constructor to get the nodes of the given variable.
123.1997 +      ///
123.1998 +      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 
123.1999 +      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 
123.2000 +      /// called before initializing this iterator.
123.2001 +      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
123.2002 +        : _algorithm(&algorithm)
123.2003 +      {
123.2004 +        _index = _algorithm->_blossom_potential[variable].begin;
123.2005 +        _last = _algorithm->_blossom_potential[variable].end;
123.2006 +      }
123.2007 +
123.2008 +      /// \brief Conversion to \c Node.
123.2009 +      ///
123.2010 +      /// Conversion to \c Node.
123.2011 +      operator Node() const {
123.2012 +        return _algorithm->_blossom_node_list[_index];
123.2013 +      }
123.2014 +
123.2015 +      /// \brief Increment operator.
123.2016 +      ///
123.2017 +      /// Increment operator.
123.2018 +      BlossomIt& operator++() {
123.2019 +        ++_index;
123.2020 +        return *this;
123.2021 +      }
123.2022 +
123.2023 +      /// \brief Validity checking
123.2024 +      ///
123.2025 +      /// Checks whether the iterator is invalid.
123.2026 +      bool operator==(Invalid) const { return _index == _last; }
123.2027 +
123.2028 +      /// \brief Validity checking
123.2029 +      ///
123.2030 +      /// Checks whether the iterator is valid.
123.2031 +      bool operator!=(Invalid) const { return _index != _last; }
123.2032 +
123.2033 +    private:
123.2034 +      const MaxWeightedMatching* _algorithm;
123.2035 +      int _last;
123.2036 +      int _index;
123.2037 +    };
123.2038 +
123.2039 +    /// @}
123.2040 +
123.2041 +  };
123.2042 +
123.2043 +  /// \ingroup matching
123.2044 +  ///
123.2045 +  /// \brief Weighted perfect matching in general graphs
123.2046 +  ///
123.2047 +  /// This class provides an efficient implementation of Edmond's
123.2048 +  /// maximum weighted perfect matching algorithm. The implementation
123.2049 +  /// is based on extensive use of priority queues and provides
123.2050 +  /// \f$O(nm\log n)\f$ time complexity.
123.2051 +  ///
123.2052 +  /// The maximum weighted perfect matching problem is to find a subset of 
123.2053 +  /// the edges in an undirected graph with maximum overall weight for which 
123.2054 +  /// each node has exactly one incident edge.
123.2055 +  /// It can be formulated with the following linear program.
123.2056 +  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
123.2057 +  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
123.2058 +      \quad \forall B\in\mathcal{O}\f] */
123.2059 +  /// \f[x_e \ge 0\quad \forall e\in E\f]
123.2060 +  /// \f[\max \sum_{e\in E}x_ew_e\f]
123.2061 +  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
123.2062 +  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
123.2063 +  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
123.2064 +  /// subsets of the nodes.
123.2065 +  ///
123.2066 +  /// The algorithm calculates an optimal matching and a proof of the
123.2067 +  /// optimality. The solution of the dual problem can be used to check
123.2068 +  /// the result of the algorithm. The dual linear problem is the
123.2069 +  /// following.
123.2070 +  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
123.2071 +      w_{uv} \quad \forall uv\in E\f] */
123.2072 +  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
123.2073 +  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
123.2074 +      \frac{\vert B \vert - 1}{2}z_B\f] */
123.2075 +  ///
123.2076 +  /// The algorithm can be executed with the run() function. 
123.2077 +  /// After it the matching (the primal solution) and the dual solution
123.2078 +  /// can be obtained using the query functions and the 
123.2079 +  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
123.2080 +  /// which is able to iterate on the nodes of a blossom. 
123.2081 +  /// If the value type is integer, then the dual solution is multiplied
123.2082 +  /// by \ref MaxWeightedMatching::dualScale "4".
123.2083 +  ///
123.2084 +  /// \tparam GR The undirected graph type the algorithm runs on.
123.2085 +  /// \tparam WM The type edge weight map. The default type is 
123.2086 +  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
123.2087 +#ifdef DOXYGEN
123.2088 +  template <typename GR, typename WM>
123.2089 +#else
123.2090 +  template <typename GR,
123.2091 +            typename WM = typename GR::template EdgeMap<int> >
123.2092 +#endif
123.2093 +  class MaxWeightedPerfectMatching {
123.2094 +  public:
123.2095 +
123.2096 +    /// The graph type of the algorithm
123.2097 +    typedef GR Graph;
123.2098 +    /// The type of the edge weight map
123.2099 +    typedef WM WeightMap;
123.2100 +    /// The value type of the edge weights
123.2101 +    typedef typename WeightMap::Value Value;
123.2102 +
123.2103 +    /// \brief Scaling factor for dual solution
123.2104 +    ///
123.2105 +    /// Scaling factor for dual solution, it is equal to 4 or 1
123.2106 +    /// according to the value type.
123.2107 +    static const int dualScale =
123.2108 +      std::numeric_limits<Value>::is_integer ? 4 : 1;
123.2109 +
123.2110 +    /// The type of the matching map
123.2111 +    typedef typename Graph::template NodeMap<typename Graph::Arc>
123.2112 +    MatchingMap;
123.2113 +
123.2114 +  private:
123.2115 +
123.2116 +    TEMPLATE_GRAPH_TYPEDEFS(Graph);
123.2117 +
123.2118 +    typedef typename Graph::template NodeMap<Value> NodePotential;
123.2119 +    typedef std::vector<Node> BlossomNodeList;
123.2120 +
123.2121 +    struct BlossomVariable {
123.2122 +      int begin, end;
123.2123 +      Value value;
123.2124 +
123.2125 +      BlossomVariable(int _begin, int _end, Value _value)
123.2126 +        : begin(_begin), end(_end), value(_value) {}
123.2127 +
123.2128 +    };
123.2129 +
123.2130 +    typedef std::vector<BlossomVariable> BlossomPotential;
123.2131 +
123.2132 +    const Graph& _graph;
123.2133 +    const WeightMap& _weight;
123.2134 +
123.2135 +    MatchingMap* _matching;
123.2136 +
123.2137 +    NodePotential* _node_potential;
123.2138 +
123.2139 +    BlossomPotential _blossom_potential;
123.2140 +    BlossomNodeList _blossom_node_list;
123.2141 +
123.2142 +    int _node_num;
123.2143 +    int _blossom_num;
123.2144 +
123.2145 +    typedef RangeMap<int> IntIntMap;
123.2146 +
123.2147 +    enum Status {
123.2148 +      EVEN = -1, MATCHED = 0, ODD = 1
123.2149 +    };
123.2150 +
123.2151 +    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
123.2152 +    struct BlossomData {
123.2153 +      int tree;
123.2154 +      Status status;
123.2155 +      Arc pred, next;
123.2156 +      Value pot, offset;
123.2157 +    };
123.2158 +
123.2159 +    IntNodeMap *_blossom_index;
123.2160 +    BlossomSet *_blossom_set;
123.2161 +    RangeMap<BlossomData>* _blossom_data;
123.2162 +
123.2163 +    IntNodeMap *_node_index;
123.2164 +    IntArcMap *_node_heap_index;
123.2165 +
123.2166 +    struct NodeData {
123.2167 +
123.2168 +      NodeData(IntArcMap& node_heap_index)
123.2169 +        : heap(node_heap_index) {}
123.2170 +
123.2171 +      int blossom;
123.2172 +      Value pot;
123.2173 +      BinHeap<Value, IntArcMap> heap;
123.2174 +      std::map<int, Arc> heap_index;
123.2175 +
123.2176 +      int tree;
123.2177 +    };
123.2178 +
123.2179 +    RangeMap<NodeData>* _node_data;
123.2180 +
123.2181 +    typedef ExtendFindEnum<IntIntMap> TreeSet;
123.2182 +
123.2183 +    IntIntMap *_tree_set_index;
123.2184 +    TreeSet *_tree_set;
123.2185 +
123.2186 +    IntIntMap *_delta2_index;
123.2187 +    BinHeap<Value, IntIntMap> *_delta2;
123.2188 +
123.2189 +    IntEdgeMap *_delta3_index;
123.2190 +    BinHeap<Value, IntEdgeMap> *_delta3;
123.2191 +
123.2192 +    IntIntMap *_delta4_index;
123.2193 +    BinHeap<Value, IntIntMap> *_delta4;
123.2194 +
123.2195 +    Value _delta_sum;
123.2196 +
123.2197 +    void createStructures() {
123.2198 +      _node_num = countNodes(_graph);
123.2199 +      _blossom_num = _node_num * 3 / 2;
123.2200 +
123.2201 +      if (!_matching) {
123.2202 +        _matching = new MatchingMap(_graph);
123.2203 +      }
123.2204 +      if (!_node_potential) {
123.2205 +        _node_potential = new NodePotential(_graph);
123.2206 +      }
123.2207 +      if (!_blossom_set) {
123.2208 +        _blossom_index = new IntNodeMap(_graph);
123.2209 +        _blossom_set = new BlossomSet(*_blossom_index);
123.2210 +        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
123.2211 +      }
123.2212 +
123.2213 +      if (!_node_index) {
123.2214 +        _node_index = new IntNodeMap(_graph);
123.2215 +        _node_heap_index = new IntArcMap(_graph);
123.2216 +        _node_data = new RangeMap<NodeData>(_node_num,
123.2217 +                                            NodeData(*_node_heap_index));
123.2218 +      }
123.2219 +
123.2220 +      if (!_tree_set) {
123.2221 +        _tree_set_index = new IntIntMap(_blossom_num);
123.2222 +        _tree_set = new TreeSet(*_tree_set_index);
123.2223 +      }
123.2224 +      if (!_delta2) {
123.2225 +        _delta2_index = new IntIntMap(_blossom_num);
123.2226 +        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
123.2227 +      }
123.2228 +      if (!_delta3) {
123.2229 +        _delta3_index = new IntEdgeMap(_graph);
123.2230 +        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
123.2231 +      }
123.2232 +      if (!_delta4) {
123.2233 +        _delta4_index = new IntIntMap(_blossom_num);
123.2234 +        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
123.2235 +      }
123.2236 +    }
123.2237 +
123.2238 +    void destroyStructures() {
123.2239 +      _node_num = countNodes(_graph);
123.2240 +      _blossom_num = _node_num * 3 / 2;
123.2241 +
123.2242 +      if (_matching) {
123.2243 +        delete _matching;
123.2244 +      }
123.2245 +      if (_node_potential) {
123.2246 +        delete _node_potential;
123.2247 +      }
123.2248 +      if (_blossom_set) {
123.2249 +        delete _blossom_index;
123.2250 +        delete _blossom_set;
123.2251 +        delete _blossom_data;
123.2252 +      }
123.2253 +
123.2254 +      if (_node_index) {
123.2255 +        delete _node_index;
123.2256 +        delete _node_heap_index;
123.2257 +        delete _node_data;
123.2258 +      }
123.2259 +
123.2260 +      if (_tree_set) {
123.2261 +        delete _tree_set_index;
123.2262 +        delete _tree_set;
123.2263 +      }
123.2264 +      if (_delta2) {
123.2265 +        delete _delta2_index;
123.2266 +        delete _delta2;
123.2267 +      }
123.2268 +      if (_delta3) {
123.2269 +        delete _delta3_index;
123.2270 +        delete _delta3;
123.2271 +      }
123.2272 +      if (_delta4) {
123.2273 +        delete _delta4_index;
123.2274 +        delete _delta4;
123.2275 +      }
123.2276 +    }
123.2277 +
123.2278 +    void matchedToEven(int blossom, int tree) {
123.2279 +      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
123.2280 +        _delta2->erase(blossom);
123.2281 +      }
123.2282 +
123.2283 +      if (!_blossom_set->trivial(blossom)) {
123.2284 +        (*_blossom_data)[blossom].pot -=
123.2285 +          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
123.2286 +      }
123.2287 +
123.2288 +      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
123.2289 +           n != INVALID; ++n) {
123.2290 +
123.2291 +        _blossom_set->increase(n, std::numeric_limits<Value>::max());
123.2292 +        int ni = (*_node_index)[n];
123.2293 +
123.2294 +        (*_node_data)[ni].heap.clear();
123.2295 +        (*_node_data)[ni].heap_index.clear();
123.2296 +
123.2297 +        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
123.2298 +
123.2299 +        for (InArcIt e(_graph, n); e != INVALID; ++e) {
123.2300 +          Node v = _graph.source(e);
123.2301 +          int vb = _blossom_set->find(v);
123.2302 +          int vi = (*_node_index)[v];
123.2303 +
123.2304 +          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
123.2305 +            dualScale * _weight[e];
123.2306 +
123.2307 +          if ((*_blossom_data)[vb].status == EVEN) {
123.2308 +            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
123.2309 +              _delta3->push(e, rw / 2);
123.2310 +            }
123.2311 +          } else {
123.2312 +            typename std::map<int, Arc>::iterator it =
123.2313 +              (*_node_data)[vi].heap_index.find(tree);
123.2314 +
123.2315 +            if (it != (*_node_data)[vi].heap_index.end()) {
123.2316 +              if ((*_node_data)[vi].heap[it->second] > rw) {
123.2317 +                (*_node_data)[vi].heap.replace(it->second, e);
123.2318 +                (*_node_data)[vi].heap.decrease(e, rw);
123.2319 +                it->second = e;
123.2320 +              }
123.2321 +            } else {
123.2322 +              (*_node_data)[vi].heap.push(e, rw);
123.2323 +              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
123.2324 +            }
123.2325 +
123.2326 +            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
123.2327 +              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
123.2328 +
123.2329 +              if ((*_blossom_data)[vb].status == MATCHED) {
123.2330 +                if (_delta2->state(vb) != _delta2->IN_HEAP) {
123.2331 +                  _delta2->push(vb, _blossom_set->classPrio(vb) -
123.2332 +                               (*_blossom_data)[vb].offset);
123.2333 +                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
123.2334 +                           (*_blossom_data)[vb].offset){
123.2335 +                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
123.2336 +                                   (*_blossom_data)[vb].offset);
123.2337 +                }
123.2338 +              }
123.2339 +            }
123.2340 +          }
123.2341 +        }
123.2342 +      }
123.2343 +      (*_blossom_data)[blossom].offset = 0;
123.2344 +    }
123.2345 +
123.2346 +    void matchedToOdd(int blossom) {
123.2347 +      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
123.2348 +        _delta2->erase(blossom);
123.2349 +      }
123.2350 +      (*_blossom_data)[blossom].offset += _delta_sum;
123.2351 +      if (!_blossom_set->trivial(blossom)) {
123.2352 +        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
123.2353 +                     (*_blossom_data)[blossom].offset);
123.2354 +      }
123.2355 +    }
123.2356 +
123.2357 +    void evenToMatched(int blossom, int tree) {
123.2358 +      if (!_blossom_set->trivial(blossom)) {
123.2359 +        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
123.2360 +      }
123.2361 +
123.2362 +      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
123.2363 +           n != INVALID; ++n) {
123.2364 +        int ni = (*_node_index)[n];
123.2365 +        (*_node_data)[ni].pot -= _delta_sum;
123.2366 +
123.2367 +        for (InArcIt e(_graph, n); e != INVALID; ++e) {
123.2368 +          Node v = _graph.source(e);
123.2369 +          int vb = _blossom_set->find(v);
123.2370 +          int vi = (*_node_index)[v];
123.2371 +
123.2372 +          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
123.2373 +            dualScale * _weight[e];
123.2374 +
123.2375 +          if (vb == blossom) {
123.2376 +            if (_delta3->state(e) == _delta3->IN_HEAP) {
123.2377 +              _delta3->erase(e);
123.2378 +            }
123.2379 +          } else if ((*_blossom_data)[vb].status == EVEN) {
123.2380 +
123.2381 +            if (_delta3->state(e) == _delta3->IN_HEAP) {
123.2382 +              _delta3->erase(e);
123.2383 +            }
123.2384 +
123.2385 +            int vt = _tree_set->find(vb);
123.2386 +
123.2387 +            if (vt != tree) {
123.2388 +
123.2389 +              Arc r = _graph.oppositeArc(e);
123.2390 +
123.2391 +              typename std::map<int, Arc>::iterator it =
123.2392 +                (*_node_data)[ni].heap_index.find(vt);
123.2393 +
123.2394 +              if (it != (*_node_data)[ni].heap_index.end()) {
123.2395 +                if ((*_node_data)[ni].heap[it->second] > rw) {
123.2396 +                  (*_node_data)[ni].heap.replace(it->second, r);
123.2397 +                  (*_node_data)[ni].heap.decrease(r, rw);
123.2398 +                  it->second = r;
123.2399 +                }
123.2400 +              } else {
123.2401 +                (*_node_data)[ni].heap.push(r, rw);
123.2402 +                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
123.2403 +              }
123.2404 +
123.2405 +              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
123.2406 +                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
123.2407 +
123.2408 +                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
123.2409 +                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
123.2410 +                               (*_blossom_data)[blossom].offset);
123.2411 +                } else if ((*_delta2)[blossom] >
123.2412 +                           _blossom_set->classPrio(blossom) -
123.2413 +                           (*_blossom_data)[blossom].offset){
123.2414 +                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
123.2415 +                                   (*_blossom_data)[blossom].offset);
123.2416 +                }
123.2417 +              }
123.2418 +            }
123.2419 +          } else {
123.2420 +
123.2421 +            typename std::map<int, Arc>::iterator it =
123.2422 +              (*_node_data)[vi].heap_index.find(tree);
123.2423 +
123.2424 +            if (it != (*_node_data)[vi].heap_index.end()) {
123.2425 +              (*_node_data)[vi].heap.erase(it->second);
123.2426 +              (*_node_data)[vi].heap_index.erase(it);
123.2427 +              if ((*_node_data)[vi].heap.empty()) {
123.2428 +                _blossom_set->increase(v, std::numeric_limits<Value>::max());
123.2429 +              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
123.2430 +                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
123.2431 +              }
123.2432 +
123.2433 +              if ((*_blossom_data)[vb].status == MATCHED) {
123.2434 +                if (_blossom_set->classPrio(vb) ==
123.2435 +                    std::numeric_limits<Value>::max()) {
123.2436 +                  _delta2->erase(vb);
123.2437 +                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
123.2438 +                           (*_blossom_data)[vb].offset) {
123.2439 +                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
123.2440 +                                   (*_blossom_data)[vb].offset);
123.2441 +                }
123.2442 +              }
123.2443 +            }
123.2444 +          }
123.2445 +        }
123.2446 +      }
123.2447 +    }
123.2448 +
123.2449 +    void oddToMatched(int blossom) {
123.2450 +      (*_blossom_data)[blossom].offset -= _delta_sum;
123.2451 +
123.2452 +      if (_blossom_set->classPrio(blossom) !=
123.2453 +          std::numeric_limits<Value>::max()) {
123.2454 +        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
123.2455 +                       (*_blossom_data)[blossom].offset);
123.2456 +      }
123.2457 +
123.2458 +      if (!_blossom_set->trivial(blossom)) {
123.2459 +        _delta4->erase(blossom);
123.2460 +      }
123.2461 +    }
123.2462 +
123.2463 +    void oddToEven(int blossom, int tree) {
123.2464 +      if (!_blossom_set->trivial(blossom)) {
123.2465 +        _delta4->erase(blossom);
123.2466 +        (*_blossom_data)[blossom].pot -=
123.2467 +          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
123.2468 +      }
123.2469 +
123.2470 +      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
123.2471 +           n != INVALID; ++n) {
123.2472 +        int ni = (*_node_index)[n];
123.2473 +
123.2474 +        _blossom_set->increase(n, std::numeric_limits<Value>::max());
123.2475 +
123.2476 +        (*_node_data)[ni].heap.clear();
123.2477 +        (*_node_data)[ni].heap_index.clear();
123.2478 +        (*_node_data)[ni].pot +=
123.2479 +          2 * _delta_sum - (*_blossom_data)[blossom].offset;
123.2480 +
123.2481 +        for (InArcIt e(_graph, n); e != INVALID; ++e) {
123.2482 +          Node v = _graph.source(e);
123.2483 +          int vb = _blossom_set->find(v);
123.2484 +          int vi = (*_node_index)[v];
123.2485 +
123.2486 +          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
123.2487 +            dualScale * _weight[e];
123.2488 +
123.2489 +          if ((*_blossom_data)[vb].status == EVEN) {
123.2490 +            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
123.2491 +              _delta3->push(e, rw / 2);
123.2492 +            }
123.2493 +          } else {
123.2494 +
123.2495 +            typename std::map<int, Arc>::iterator it =
123.2496 +              (*_node_data)[vi].heap_index.find(tree);
123.2497 +
123.2498 +            if (it != (*_node_data)[vi].heap_index.end()) {
123.2499 +              if ((*_node_data)[vi].heap[it->second] > rw) {
123.2500 +                (*_node_data)[vi].heap.replace(it->second, e);
123.2501 +                (*_node_data)[vi].heap.decrease(e, rw);
123.2502 +                it->second = e;
123.2503 +              }
123.2504 +            } else {
123.2505 +              (*_node_data)[vi].heap.push(e, rw);
123.2506 +              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
123.2507 +            }
123.2508 +
123.2509 +            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
123.2510 +              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
123.2511 +
123.2512 +              if ((*_blossom_data)[vb].status == MATCHED) {
123.2513 +                if (_delta2->state(vb) != _delta2->IN_HEAP) {
123.2514 +                  _delta2->push(vb, _blossom_set->classPrio(vb) -
123.2515 +                               (*_blossom_data)[vb].offset);
123.2516 +                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
123.2517 +                           (*_blossom_data)[vb].offset) {
123.2518 +                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
123.2519 +                                   (*_blossom_data)[vb].offset);
123.2520 +                }
123.2521 +              }
123.2522 +            }
123.2523 +          }
123.2524 +        }
123.2525 +      }
123.2526 +      (*_blossom_data)[blossom].offset = 0;
123.2527 +    }
123.2528 +
123.2529 +    void alternatePath(int even, int tree) {
123.2530 +      int odd;
123.2531 +
123.2532 +      evenToMatched(even, tree);
123.2533 +      (*_blossom_data)[even].status = MATCHED;
123.2534 +
123.2535 +      while ((*_blossom_data)[even].pred != INVALID) {
123.2536 +        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
123.2537 +        (*_blossom_data)[odd].status = MATCHED;
123.2538 +        oddToMatched(odd);
123.2539 +        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
123.2540 +
123.2541 +        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
123.2542 +        (*_blossom_data)[even].status = MATCHED;
123.2543 +        evenToMatched(even, tree);
123.2544 +        (*_blossom_data)[even].next =
123.2545 +          _graph.oppositeArc((*_blossom_data)[odd].pred);
123.2546 +      }
123.2547 +
123.2548 +    }
123.2549 +
123.2550 +    void destroyTree(int tree) {
123.2551 +      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
123.2552 +        if ((*_blossom_data)[b].status == EVEN) {
123.2553 +          (*_blossom_data)[b].status = MATCHED;
123.2554 +          evenToMatched(b, tree);
123.2555 +        } else if ((*_blossom_data)[b].status == ODD) {
123.2556 +          (*_blossom_data)[b].status = MATCHED;
123.2557 +          oddToMatched(b);
123.2558 +        }
123.2559 +      }
123.2560 +      _tree_set->eraseClass(tree);
123.2561 +    }
123.2562 +
123.2563 +    void augmentOnEdge(const Edge& edge) {
123.2564 +
123.2565 +      int left = _blossom_set->find(_graph.u(edge));
123.2566 +      int right = _blossom_set->find(_graph.v(edge));
123.2567 +
123.2568 +      int left_tree = _tree_set->find(left);
123.2569 +      alternatePath(left, left_tree);
123.2570 +      destroyTree(left_tree);
123.2571 +
123.2572 +      int right_tree = _tree_set->find(right);
123.2573 +      alternatePath(right, right_tree);
123.2574 +      destroyTree(right_tree);
123.2575 +
123.2576 +      (*_blossom_data)[left].next = _graph.direct(edge, true);
123.2577 +      (*_blossom_data)[right].next = _graph.direct(edge, false);
123.2578 +    }
123.2579 +
123.2580 +    void extendOnArc(const Arc& arc) {
123.2581 +      int base = _blossom_set->find(_graph.target(arc));
123.2582 +      int tree = _tree_set->find(base);
123.2583 +
123.2584 +      int odd = _blossom_set->find(_graph.source(arc));
123.2585 +      _tree_set->insert(odd, tree);
123.2586 +      (*_blossom_data)[odd].status = ODD;
123.2587 +      matchedToOdd(odd);
123.2588 +      (*_blossom_data)[odd].pred = arc;
123.2589 +
123.2590 +      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
123.2591 +      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
123.2592 +      _tree_set->insert(even, tree);
123.2593 +      (*_blossom_data)[even].status = EVEN;
123.2594 +      matchedToEven(even, tree);
123.2595 +    }
123.2596 +
123.2597 +    void shrinkOnEdge(const Edge& edge, int tree) {
123.2598 +      int nca = -1;
123.2599 +      std::vector<int> left_path, right_path;
123.2600 +
123.2601 +      {
123.2602 +        std::set<int> left_set, right_set;
123.2603 +        int left = _blossom_set->find(_graph.u(edge));
123.2604 +        left_path.push_back(left);
123.2605 +        left_set.insert(left);
123.2606 +
123.2607 +        int right = _blossom_set->find(_graph.v(edge));
123.2608 +        right_path.push_back(right);
123.2609 +        right_set.insert(right);
123.2610 +
123.2611 +        while (true) {
123.2612 +
123.2613 +          if ((*_blossom_data)[left].pred == INVALID) break;
123.2614 +
123.2615 +          left =
123.2616 +            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
123.2617 +          left_path.push_back(left);
123.2618 +          left =
123.2619 +            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
123.2620 +          left_path.push_back(left);
123.2621 +
123.2622 +          left_set.insert(left);
123.2623 +
123.2624 +          if (right_set.find(left) != right_set.end()) {
123.2625 +            nca = left;
123.2626 +            break;
123.2627 +          }
123.2628 +
123.2629 +          if ((*_blossom_data)[right].pred == INVALID) break;
123.2630 +
123.2631 +          right =
123.2632 +            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
123.2633 +          right_path.push_back(right);
123.2634 +          right =
123.2635 +            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
123.2636 +          right_path.push_back(right);
123.2637 +
123.2638 +          right_set.insert(right);
123.2639 +
123.2640 +          if (left_set.find(right) != left_set.end()) {
123.2641 +            nca = right;
123.2642 +            break;
123.2643 +          }
123.2644 +
123.2645 +        }
123.2646 +
123.2647 +        if (nca == -1) {
123.2648 +          if ((*_blossom_data)[left].pred == INVALID) {
123.2649 +            nca = right;
123.2650 +            while (left_set.find(nca) == left_set.end()) {
123.2651 +              nca =
123.2652 +                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
123.2653 +              right_path.push_back(nca);
123.2654 +              nca =
123.2655 +                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
123.2656 +              right_path.push_back(nca);
123.2657 +            }
123.2658 +          } else {
123.2659 +            nca = left;
123.2660 +            while (right_set.find(nca) == right_set.end()) {
123.2661 +              nca =
123.2662 +                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
123.2663 +              left_path.push_back(nca);
123.2664 +              nca =
123.2665 +                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
123.2666 +              left_path.push_back(nca);
123.2667 +            }
123.2668 +          }
123.2669 +        }
123.2670 +      }
123.2671 +
123.2672 +      std::vector<int> subblossoms;
123.2673 +      Arc prev;
123.2674 +
123.2675 +      prev = _graph.direct(edge, true);
123.2676 +      for (int i = 0; left_path[i] != nca; i += 2) {
123.2677 +        subblossoms.push_back(left_path[i]);
123.2678 +        (*_blossom_data)[left_path[i]].next = prev;
123.2679 +        _tree_set->erase(left_path[i]);
123.2680 +
123.2681 +        subblossoms.push_back(left_path[i + 1]);
123.2682 +        (*_blossom_data)[left_path[i + 1]].status = EVEN;
123.2683 +        oddToEven(left_path[i + 1], tree);
123.2684 +        _tree_set->erase(left_path[i + 1]);
123.2685 +        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
123.2686 +      }
123.2687 +
123.2688 +      int k = 0;
123.2689 +      while (right_path[k] != nca) ++k;
123.2690 +
123.2691 +      subblossoms.push_back(nca);
123.2692 +      (*_blossom_data)[nca].next = prev;
123.2693 +
123.2694 +      for (int i = k - 2; i >= 0; i -= 2) {
123.2695 +        subblossoms.push_back(right_path[i + 1]);
123.2696 +        (*_blossom_data)[right_path[i + 1]].status = EVEN;
123.2697 +        oddToEven(right_path[i + 1], tree);
123.2698 +        _tree_set->erase(right_path[i + 1]);
123.2699 +
123.2700 +        (*_blossom_data)[right_path[i + 1]].next =
123.2701 +          (*_blossom_data)[right_path[i + 1]].pred;
123.2702 +
123.2703 +        subblossoms.push_back(right_path[i]);
123.2704 +        _tree_set->erase(right_path[i]);
123.2705 +      }
123.2706 +
123.2707 +      int surface =
123.2708 +        _blossom_set->join(subblossoms.begin(), subblossoms.end());
123.2709 +
123.2710 +      for (int i = 0; i < int(subblossoms.size()); ++i) {
123.2711 +        if (!_blossom_set->trivial(subblossoms[i])) {
123.2712 +          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
123.2713 +        }
123.2714 +        (*_blossom_data)[subblossoms[i]].status = MATCHED;
123.2715 +      }
123.2716 +
123.2717 +      (*_blossom_data)[surface].pot = -2 * _delta_sum;
123.2718 +      (*_blossom_data)[surface].offset = 0;
123.2719 +      (*_blossom_data)[surface].status = EVEN;
123.2720 +      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
123.2721 +      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
123.2722 +
123.2723 +      _tree_set->insert(surface, tree);
123.2724 +      _tree_set->erase(nca);
123.2725 +    }
123.2726 +
123.2727 +    void splitBlossom(int blossom) {
123.2728 +      Arc next = (*_blossom_data)[blossom].next;
123.2729 +      Arc pred = (*_blossom_data)[blossom].pred;
123.2730 +
123.2731 +      int tree = _tree_set->find(blossom);
123.2732 +
123.2733 +      (*_blossom_data)[blossom].status = MATCHED;
123.2734 +      oddToMatched(blossom);
123.2735 +      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
123.2736 +        _delta2->erase(blossom);
123.2737 +      }
123.2738 +
123.2739 +      std::vector<int> subblossoms;
123.2740 +      _blossom_set->split(blossom, std::back_inserter(subblossoms));
123.2741 +
123.2742 +      Value offset = (*_blossom_data)[blossom].offset;
123.2743 +      int b = _blossom_set->find(_graph.source(pred));
123.2744 +      int d = _blossom_set->find(_graph.source(next));
123.2745 +
123.2746 +      int ib = -1, id = -1;
123.2747 +      for (int i = 0; i < int(subblossoms.size()); ++i) {
123.2748 +        if (subblossoms[i] == b) ib = i;
123.2749 +        if (subblossoms[i] == d) id = i;
123.2750 +
123.2751 +        (*_blossom_data)[subblossoms[i]].offset = offset;
123.2752 +        if (!_blossom_set->trivial(subblossoms[i])) {
123.2753 +          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
123.2754 +        }
123.2755 +        if (_blossom_set->classPrio(subblossoms[i]) !=
123.2756 +            std::numeric_limits<Value>::max()) {
123.2757 +          _delta2->push(subblossoms[i],
123.2758 +                        _blossom_set->classPrio(subblossoms[i]) -
123.2759 +                        (*_blossom_data)[subblossoms[i]].offset);
123.2760 +        }
123.2761 +      }
123.2762 +
123.2763 +      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
123.2764 +        for (int i = (id + 1) % subblossoms.size();
123.2765 +             i != ib; i = (i + 2) % subblossoms.size()) {
123.2766 +          int sb = subblossoms[i];
123.2767 +          int tb = subblossoms[(i + 1) % subblossoms.size()];
123.2768 +          (*_blossom_data)[sb].next =
123.2769 +            _graph.oppositeArc((*_blossom_data)[tb].next);
123.2770 +        }
123.2771 +
123.2772 +        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
123.2773 +          int sb = subblossoms[i];
123.2774 +          int tb = subblossoms[(i + 1) % subblossoms.size()];
123.2775 +          int ub = subblossoms[(i + 2) % subblossoms.size()];
123.2776 +
123.2777 +          (*_blossom_data)[sb].status = ODD;
123.2778 +          matchedToOdd(sb);
123.2779 +          _tree_set->insert(sb, tree);
123.2780 +          (*_blossom_data)[sb].pred = pred;
123.2781 +          (*_blossom_data)[sb].next =
123.2782 +                           _graph.oppositeArc((*_blossom_data)[tb].next);
123.2783 +
123.2784 +          pred = (*_blossom_data)[ub].next;
123.2785 +
123.2786 +          (*_blossom_data)[tb].status = EVEN;
123.2787 +          matchedToEven(tb, tree);
123.2788 +          _tree_set->insert(tb, tree);
123.2789 +          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
123.2790 +        }
123.2791 +
123.2792 +        (*_blossom_data)[subblossoms[id]].status = ODD;
123.2793 +        matchedToOdd(subblossoms[id]);
123.2794 +        _tree_set->insert(subblossoms[id], tree);
123.2795 +        (*_blossom_data)[subblossoms[id]].next = next;
123.2796 +        (*_blossom_data)[subblossoms[id]].pred = pred;
123.2797 +
123.2798 +      } else {
123.2799 +
123.2800 +        for (int i = (ib + 1) % subblossoms.size();
123.2801 +             i != id; i = (i + 2) % subblossoms.size()) {
123.2802 +          int sb = subblossoms[i];
123.2803 +          int tb = subblossoms[(i + 1) % subblossoms.size()];
123.2804 +          (*_blossom_data)[sb].next =
123.2805 +            _graph.oppositeArc((*_blossom_data)[tb].next);
123.2806 +        }
123.2807 +
123.2808 +        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
123.2809 +          int sb = subblossoms[i];
123.2810 +          int tb = subblossoms[(i + 1) % subblossoms.size()];
123.2811 +          int ub = subblossoms[(i + 2) % subblossoms.size()];
123.2812 +
123.2813 +          (*_blossom_data)[sb].status = ODD;
123.2814 +          matchedToOdd(sb);
123.2815 +          _tree_set->insert(sb, tree);
123.2816 +          (*_blossom_data)[sb].next = next;
123.2817 +          (*_blossom_data)[sb].pred =
123.2818 +            _graph.oppositeArc((*_blossom_data)[tb].next);
123.2819 +
123.2820 +          (*_blossom_data)[tb].status = EVEN;
123.2821 +          matchedToEven(tb, tree);
123.2822 +          _tree_set->insert(tb, tree);
123.2823 +          (*_blossom_data)[tb].pred =
123.2824 +            (*_blossom_data)[tb].next =
123.2825 +            _graph.oppositeArc((*_blossom_data)[ub].next);
123.2826 +          next = (*_blossom_data)[ub].next;
123.2827 +        }
123.2828 +
123.2829 +        (*_blossom_data)[subblossoms[ib]].status = ODD;
123.2830 +        matchedToOdd(subblossoms[ib]);
123.2831 +        _tree_set->insert(subblossoms[ib], tree);
123.2832 +        (*_blossom_data)[subblossoms[ib]].next = next;
123.2833 +        (*_blossom_data)[subblossoms[ib]].pred = pred;
123.2834 +      }
123.2835 +      _tree_set->erase(blossom);
123.2836 +    }
123.2837 +
123.2838 +    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
123.2839 +      if (_blossom_set->trivial(blossom)) {
123.2840 +        int bi = (*_node_index)[base];
123.2841 +        Value pot = (*_node_data)[bi].pot;
123.2842 +
123.2843 +        (*_matching)[base] = matching;
123.2844 +        _blossom_node_list.push_back(base);
123.2845 +        (*_node_potential)[base] = pot;
123.2846 +      } else {
123.2847 +
123.2848 +        Value pot = (*_blossom_data)[blossom].pot;
123.2849 +        int bn = _blossom_node_list.size();
123.2850 +
123.2851 +        std::vector<int> subblossoms;
123.2852 +        _blossom_set->split(blossom, std::back_inserter(subblossoms));
123.2853 +        int b = _blossom_set->find(base);
123.2854 +        int ib = -1;
123.2855 +        for (int i = 0; i < int(subblossoms.size()); ++i) {
123.2856 +          if (subblossoms[i] == b) { ib = i; break; }
123.2857 +        }
123.2858 +
123.2859 +        for (int i = 1; i < int(subblossoms.size()); i += 2) {
123.2860 +          int sb = subblossoms[(ib + i) % subblossoms.size()];
123.2861 +          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
123.2862 +
123.2863 +          Arc m = (*_blossom_data)[tb].next;
123.2864 +          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
123.2865 +          extractBlossom(tb, _graph.source(m), m);
123.2866 +        }
123.2867 +        extractBlossom(subblossoms[ib], base, matching);
123.2868 +
123.2869 +        int en = _blossom_node_list.size();
123.2870 +
123.2871 +        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
123.2872 +      }
123.2873 +    }
123.2874 +
123.2875 +    void extractMatching() {
123.2876 +      std::vector<int> blossoms;
123.2877 +      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
123.2878 +        blossoms.push_back(c);
123.2879 +      }
123.2880 +
123.2881 +      for (int i = 0; i < int(blossoms.size()); ++i) {
123.2882 +
123.2883 +        Value offset = (*_blossom_data)[blossoms[i]].offset;
123.2884 +        (*_blossom_data)[blossoms[i]].pot += 2 * offset;
123.2885 +        for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
123.2886 +             n != INVALID; ++n) {
123.2887 +          (*_node_data)[(*_node_index)[n]].pot -= offset;
123.2888 +        }
123.2889 +
123.2890 +        Arc matching = (*_blossom_data)[blossoms[i]].next;
123.2891 +        Node base = _graph.source(matching);
123.2892 +        extractBlossom(blossoms[i], base, matching);
123.2893 +      }
123.2894 +    }
123.2895 +
123.2896 +  public:
123.2897 +
123.2898 +    /// \brief Constructor
123.2899 +    ///
123.2900 +    /// Constructor.
123.2901 +    MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
123.2902 +      : _graph(graph), _weight(weight), _matching(0),
123.2903 +        _node_potential(0), _blossom_potential(), _blossom_node_list(),
123.2904 +        _node_num(0), _blossom_num(0),
123.2905 +
123.2906 +        _blossom_index(0), _blossom_set(0), _blossom_data(0),
123.2907 +        _node_index(0), _node_heap_index(0), _node_data(0),
123.2908 +        _tree_set_index(0), _tree_set(0),
123.2909 +
123.2910 +        _delta2_index(0), _delta2(0),
123.2911 +        _delta3_index(0), _delta3(0),
123.2912 +        _delta4_index(0), _delta4(0),
123.2913 +
123.2914 +        _delta_sum() {}
123.2915 +
123.2916 +    ~MaxWeightedPerfectMatching() {
123.2917 +      destroyStructures();
123.2918 +    }
123.2919 +
123.2920 +    /// \name Execution Control
123.2921 +    /// The simplest way to execute the algorithm is to use the
123.2922 +    /// \ref run() member function.
123.2923 +
123.2924 +    ///@{
123.2925 +
123.2926 +    /// \brief Initialize the algorithm
123.2927 +    ///
123.2928 +    /// This function initializes the algorithm.
123.2929 +    void init() {
123.2930 +      createStructures();
123.2931 +
123.2932 +      for (ArcIt e(_graph); e != INVALID; ++e) {
123.2933 +        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
123.2934 +      }
123.2935 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
123.2936 +        (*_delta3_index)[e] = _delta3->PRE_HEAP;
123.2937 +      }
123.2938 +      for (int i = 0; i < _blossom_num; ++i) {
123.2939 +        (*_delta2_index)[i] = _delta2->PRE_HEAP;
123.2940 +        (*_delta4_index)[i] = _delta4->PRE_HEAP;
123.2941 +      }
123.2942 +
123.2943 +      int index = 0;
123.2944 +      for (NodeIt n(_graph); n != INVALID; ++n) {
123.2945 +        Value max = - std::numeric_limits<Value>::max();
123.2946 +        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
123.2947 +          if (_graph.target(e) == n) continue;
123.2948 +          if ((dualScale * _weight[e]) / 2 > max) {
123.2949 +            max = (dualScale * _weight[e]) / 2;
123.2950 +          }
123.2951 +        }
123.2952 +        (*_node_index)[n] = index;
123.2953 +        (*_node_data)[index].pot = max;
123.2954 +        int blossom =
123.2955 +          _blossom_set->insert(n, std::numeric_limits<Value>::max());
123.2956 +
123.2957 +        _tree_set->insert(blossom);
123.2958 +
123.2959 +        (*_blossom_data)[blossom].status = EVEN;
123.2960 +        (*_blossom_data)[blossom].pred = INVALID;
123.2961 +        (*_blossom_data)[blossom].next = INVALID;
123.2962 +        (*_blossom_data)[blossom].pot = 0;
123.2963 +        (*_blossom_data)[blossom].offset = 0;
123.2964 +        ++index;
123.2965 +      }
123.2966 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
123.2967 +        int si = (*_node_index)[_graph.u(e)];
123.2968 +        int ti = (*_node_index)[_graph.v(e)];
123.2969 +        if (_graph.u(e) != _graph.v(e)) {
123.2970 +          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
123.2971 +                            dualScale * _weight[e]) / 2);
123.2972 +        }
123.2973 +      }
123.2974 +    }
123.2975 +
123.2976 +    /// \brief Start the algorithm
123.2977 +    ///
123.2978 +    /// This function starts the algorithm.
123.2979 +    ///
123.2980 +    /// \pre \ref init() must be called before using this function.
123.2981 +    bool start() {
123.2982 +      enum OpType {
123.2983 +        D2, D3, D4
123.2984 +      };
123.2985 +
123.2986 +      int unmatched = _node_num;
123.2987 +      while (unmatched > 0) {
123.2988 +        Value d2 = !_delta2->empty() ?
123.2989 +          _delta2->prio() : std::numeric_limits<Value>::max();
123.2990 +
123.2991 +        Value d3 = !_delta3->empty() ?
123.2992 +          _delta3->prio() : std::numeric_limits<Value>::max();
123.2993 +
123.2994 +        Value d4 = !_delta4->empty() ?
123.2995 +          _delta4->prio() : std::numeric_limits<Value>::max();
123.2996 +
123.2997 +        _delta_sum = d2; OpType ot = D2;
123.2998 +        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
123.2999 +        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
123.3000 +
123.3001 +        if (_delta_sum == std::numeric_limits<Value>::max()) {
123.3002 +          return false;
123.3003 +        }
123.3004 +
123.3005 +        switch (ot) {
123.3006 +        case D2:
123.3007 +          {
123.3008 +            int blossom = _delta2->top();
123.3009 +            Node n = _blossom_set->classTop(blossom);
123.3010 +            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
123.3011 +            extendOnArc(e);
123.3012 +          }
123.3013 +          break;
123.3014 +        case D3:
123.3015 +          {
123.3016 +            Edge e = _delta3->top();
123.3017 +
123.3018 +            int left_blossom = _blossom_set->find(_graph.u(e));
123.3019 +            int right_blossom = _blossom_set->find(_graph.v(e));
123.3020 +
123.3021 +            if (left_blossom == right_blossom) {
123.3022 +              _delta3->pop();
123.3023 +            } else {
123.3024 +              int left_tree = _tree_set->find(left_blossom);
123.3025 +              int right_tree = _tree_set->find(right_blossom);
123.3026 +
123.3027 +              if (left_tree == right_tree) {
123.3028 +                shrinkOnEdge(e, left_tree);
123.3029 +              } else {
123.3030 +                augmentOnEdge(e);
123.3031 +                unmatched -= 2;
123.3032 +              }
123.3033 +            }
123.3034 +          } break;
123.3035 +        case D4:
123.3036 +          splitBlossom(_delta4->top());
123.3037 +          break;
123.3038 +        }
123.3039 +      }
123.3040 +      extractMatching();
123.3041 +      return true;
123.3042 +    }
123.3043 +
123.3044 +    /// \brief Run the algorithm.
123.3045 +    ///
123.3046 +    /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
123.3047 +    ///
123.3048 +    /// \note mwpm.run() is just a shortcut of the following code.
123.3049 +    /// \code
123.3050 +    ///   mwpm.init();
123.3051 +    ///   mwpm.start();
123.3052 +    /// \endcode
123.3053 +    bool run() {
123.3054 +      init();
123.3055 +      return start();
123.3056 +    }
123.3057 +
123.3058 +    /// @}
123.3059 +
123.3060 +    /// \name Primal Solution
123.3061 +    /// Functions to get the primal solution, i.e. the maximum weighted 
123.3062 +    /// perfect matching.\n
123.3063 +    /// Either \ref run() or \ref start() function should be called before
123.3064 +    /// using them.
123.3065 +
123.3066 +    /// @{
123.3067 +
123.3068 +    /// \brief Return the weight of the matching.
123.3069 +    ///
123.3070 +    /// This function returns the weight of the found matching.
123.3071 +    ///
123.3072 +    /// \pre Either run() or start() must be called before using this function.
123.3073 +    Value matchingWeight() const {
123.3074 +      Value sum = 0;
123.3075 +      for (NodeIt n(_graph); n != INVALID; ++n) {
123.3076 +        if ((*_matching)[n] != INVALID) {
123.3077 +          sum += _weight[(*_matching)[n]];
123.3078 +        }
123.3079 +      }
123.3080 +      return sum /= 2;
123.3081 +    }
123.3082 +
123.3083 +    /// \brief Return \c true if the given edge is in the matching.
123.3084 +    ///
123.3085 +    /// This function returns \c true if the given edge is in the found 
123.3086 +    /// matching.
123.3087 +    ///
123.3088 +    /// \pre Either run() or start() must be called before using this function.
123.3089 +    bool matching(const Edge& edge) const {
123.3090 +      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
123.3091 +    }
123.3092 +
123.3093 +    /// \brief Return the matching arc (or edge) incident to the given node.
123.3094 +    ///
123.3095 +    /// This function returns the matching arc (or edge) incident to the
123.3096 +    /// given node in the found matching or \c INVALID if the node is 
123.3097 +    /// not covered by the matching.
123.3098 +    ///
123.3099 +    /// \pre Either run() or start() must be called before using this function.
123.3100 +    Arc matching(const Node& node) const {
123.3101 +      return (*_matching)[node];
123.3102 +    }
123.3103 +
123.3104 +    /// \brief Return a const reference to the matching map.
123.3105 +    ///
123.3106 +    /// This function returns a const reference to a node map that stores
123.3107 +    /// the matching arc (or edge) incident to each node.
123.3108 +    const MatchingMap& matchingMap() const {
123.3109 +      return *_matching;
123.3110 +    }
123.3111 +
123.3112 +    /// \brief Return the mate of the given node.
123.3113 +    ///
123.3114 +    /// This function returns the mate of the given node in the found 
123.3115 +    /// matching or \c INVALID if the node is not covered by the matching.
123.3116 +    ///
123.3117 +    /// \pre Either run() or start() must be called before using this function.
123.3118 +    Node mate(const Node& node) const {
123.3119 +      return _graph.target((*_matching)[node]);
123.3120 +    }
123.3121 +
123.3122 +    /// @}
123.3123 +
123.3124 +    /// \name Dual Solution
123.3125 +    /// Functions to get the dual solution.\n
123.3126 +    /// Either \ref run() or \ref start() function should be called before
123.3127 +    /// using them.
123.3128 +
123.3129 +    /// @{
123.3130 +
123.3131 +    /// \brief Return the value of the dual solution.
123.3132 +    ///
123.3133 +    /// This function returns the value of the dual solution. 
123.3134 +    /// It should be equal to the primal value scaled by \ref dualScale 
123.3135 +    /// "dual scale".
123.3136 +    ///
123.3137 +    /// \pre Either run() or start() must be called before using this function.
123.3138 +    Value dualValue() const {
123.3139 +      Value sum = 0;
123.3140 +      for (NodeIt n(_graph); n != INVALID; ++n) {
123.3141 +        sum += nodeValue(n);
123.3142 +      }
123.3143 +      for (int i = 0; i < blossomNum(); ++i) {
123.3144 +        sum += blossomValue(i) * (blossomSize(i) / 2);
123.3145 +      }
123.3146 +      return sum;
123.3147 +    }
123.3148 +
123.3149 +    /// \brief Return the dual value (potential) of the given node.
123.3150 +    ///
123.3151 +    /// This function returns the dual value (potential) of the given node.
123.3152 +    ///
123.3153 +    /// \pre Either run() or start() must be called before using this function.
123.3154 +    Value nodeValue(const Node& n) const {
123.3155 +      return (*_node_potential)[n];
123.3156 +    }
123.3157 +
123.3158 +    /// \brief Return the number of the blossoms in the basis.
123.3159 +    ///
123.3160 +    /// This function returns the number of the blossoms in the basis.
123.3161 +    ///
123.3162 +    /// \pre Either run() or start() must be called before using this function.
123.3163 +    /// \see BlossomIt
123.3164 +    int blossomNum() const {
123.3165 +      return _blossom_potential.size();
123.3166 +    }
123.3167 +
123.3168 +    /// \brief Return the number of the nodes in the given blossom.
123.3169 +    ///
123.3170 +    /// This function returns the number of the nodes in the given blossom.
123.3171 +    ///
123.3172 +    /// \pre Either run() or start() must be called before using this function.
123.3173 +    /// \see BlossomIt
123.3174 +    int blossomSize(int k) const {
123.3175 +      return _blossom_potential[k].end - _blossom_potential[k].begin;
123.3176 +    }
123.3177 +
123.3178 +    /// \brief Return the dual value (ptential) of the given blossom.
123.3179 +    ///
123.3180 +    /// This function returns the dual value (ptential) of the given blossom.
123.3181 +    ///
123.3182 +    /// \pre Either run() or start() must be called before using this function.
123.3183 +    Value blossomValue(int k) const {
123.3184 +      return _blossom_potential[k].value;
123.3185 +    }
123.3186 +
123.3187 +    /// \brief Iterator for obtaining the nodes of a blossom.
123.3188 +    ///
123.3189 +    /// This class provides an iterator for obtaining the nodes of the 
123.3190 +    /// given blossom. It lists a subset of the nodes.
123.3191 +    /// Before using this iterator, you must allocate a 
123.3192 +    /// MaxWeightedPerfectMatching class and execute it.
123.3193 +    class BlossomIt {
123.3194 +    public:
123.3195 +
123.3196 +      /// \brief Constructor.
123.3197 +      ///
123.3198 +      /// Constructor to get the nodes of the given variable.
123.3199 +      ///
123.3200 +      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 
123.3201 +      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 
123.3202 +      /// must be called before initializing this iterator.
123.3203 +      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
123.3204 +        : _algorithm(&algorithm)
123.3205 +      {
123.3206 +        _index = _algorithm->_blossom_potential[variable].begin;
123.3207 +        _last = _algorithm->_blossom_potential[variable].end;
123.3208 +      }
123.3209 +
123.3210 +      /// \brief Conversion to \c Node.
123.3211 +      ///
123.3212 +      /// Conversion to \c Node.
123.3213 +      operator Node() const {
123.3214 +        return _algorithm->_blossom_node_list[_index];
123.3215 +      }
123.3216 +
123.3217 +      /// \brief Increment operator.
123.3218 +      ///
123.3219 +      /// Increment operator.
123.3220 +      BlossomIt& operator++() {
123.3221 +        ++_index;
123.3222 +        return *this;
123.3223 +      }
123.3224 +
123.3225 +      /// \brief Validity checking
123.3226 +      ///
123.3227 +      /// This function checks whether the iterator is invalid.
123.3228 +      bool operator==(Invalid) const { return _index == _last; }
123.3229 +
123.3230 +      /// \brief Validity checking
123.3231 +      ///
123.3232 +      /// This function checks whether the iterator is valid.
123.3233 +      bool operator!=(Invalid) const { return _index != _last; }
123.3234 +
123.3235 +    private:
123.3236 +      const MaxWeightedPerfectMatching* _algorithm;
123.3237 +      int _last;
123.3238 +      int _index;
123.3239 +    };
123.3240 +
123.3241 +    /// @}
123.3242 +
123.3243 +  };
123.3244 +
123.3245 +} //END OF NAMESPACE LEMON
123.3246 +
123.3247 +#endif //LEMON_MAX_MATCHING_H
   124.1 --- a/lemon/math.h	Fri Oct 16 10:21:37 2009 +0200
   124.2 +++ b/lemon/math.h	Thu Nov 05 15:50:01 2009 +0100
   124.3 @@ -2,7 +2,7 @@
   124.4   *
   124.5   * This file is a part of LEMON, a generic C++ optimization library.
   124.6   *
   124.7 - * Copyright (C) 2003-2008
   124.8 + * Copyright (C) 2003-2009
   124.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  124.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  124.11   *
  124.12 @@ -55,6 +55,15 @@
  124.13    /// 1/sqrt(2)
  124.14    const long double SQRT1_2 = 0.7071067811865475244008443621048490L;
  124.15  
  124.16 +  ///Check whether the parameter is NaN or not
  124.17 +  
  124.18 +  ///This function checks whether the parameter is NaN or not.
  124.19 +  ///Is should be equivalent with std::isnan(), but it is not
  124.20 +  ///provided by all compilers.
  124.21 +  inline bool isNaN(double v)
  124.22 +    {
  124.23 +      return v!=v;
  124.24 +    }
  124.25  
  124.26    /// @}
  124.27  
   125.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   125.2 +++ b/lemon/min_cost_arborescence.h	Thu Nov 05 15:50:01 2009 +0100
   125.3 @@ -0,0 +1,807 @@
   125.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   125.5 + *
   125.6 + * This file is a part of LEMON, a generic C++ optimization library.
   125.7 + *
   125.8 + * Copyright (C) 2003-2008
   125.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  125.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  125.11 + *
  125.12 + * Permission to use, modify and distribute this software is granted
  125.13 + * provided that this copyright notice appears in all copies. For
  125.14 + * precise terms see the accompanying LICENSE file.
  125.15 + *
  125.16 + * This software is provided "AS IS" with no warranty of any kind,
  125.17 + * express or implied, and with no claim as to its suitability for any
  125.18 + * purpose.
  125.19 + *
  125.20 + */
  125.21 +
  125.22 +#ifndef LEMON_MIN_COST_ARBORESCENCE_H
  125.23 +#define LEMON_MIN_COST_ARBORESCENCE_H
  125.24 +
  125.25 +///\ingroup spantree
  125.26 +///\file
  125.27 +///\brief Minimum Cost Arborescence algorithm.
  125.28 +
  125.29 +#include <vector>
  125.30 +
  125.31 +#include <lemon/list_graph.h>
  125.32 +#include <lemon/bin_heap.h>
  125.33 +#include <lemon/assert.h>
  125.34 +
  125.35 +namespace lemon {
  125.36 +
  125.37 +
  125.38 +  /// \brief Default traits class for MinCostArborescence class.
  125.39 +  ///
  125.40 +  /// Default traits class for MinCostArborescence class.
  125.41 +  /// \param GR Digraph type.
  125.42 +  /// \param CM Type of the cost map.
  125.43 +  template <class GR, class CM>
  125.44 +  struct MinCostArborescenceDefaultTraits{
  125.45 +
  125.46 +    /// \brief The digraph type the algorithm runs on.
  125.47 +    typedef GR Digraph;
  125.48 +
  125.49 +    /// \brief The type of the map that stores the arc costs.
  125.50 +    ///
  125.51 +    /// The type of the map that stores the arc costs.
  125.52 +    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
  125.53 +    typedef CM CostMap;
  125.54 +
  125.55 +    /// \brief The value type of the costs.
  125.56 +    ///
  125.57 +    /// The value type of the costs.
  125.58 +    typedef typename CostMap::Value Value;
  125.59 +
  125.60 +    /// \brief The type of the map that stores which arcs are in the
  125.61 +    /// arborescence.
  125.62 +    ///
  125.63 +    /// The type of the map that stores which arcs are in the
  125.64 +    /// arborescence.  It must conform to the \ref concepts::WriteMap
  125.65 +    /// "WriteMap" concept, and its value type must be \c bool
  125.66 +    /// (or convertible). Initially it will be set to \c false on each
  125.67 +    /// arc, then it will be set on each arborescence arc once.
  125.68 +    typedef typename Digraph::template ArcMap<bool> ArborescenceMap;
  125.69 +
  125.70 +    /// \brief Instantiates a \c ArborescenceMap.
  125.71 +    ///
  125.72 +    /// This function instantiates a \c ArborescenceMap.
  125.73 +    /// \param digraph The digraph to which we would like to calculate
  125.74 +    /// the \c ArborescenceMap.
  125.75 +    static ArborescenceMap *createArborescenceMap(const Digraph &digraph){
  125.76 +      return new ArborescenceMap(digraph);
  125.77 +    }
  125.78 +
  125.79 +    /// \brief The type of the \c PredMap
  125.80 +    ///
  125.81 +    /// The type of the \c PredMap. It must confrom to the
  125.82 +    /// \ref concepts::WriteMap "WriteMap" concept, and its value type
  125.83 +    /// must be the \c Arc type of the digraph.
  125.84 +    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
  125.85 +
  125.86 +    /// \brief Instantiates a \c PredMap.
  125.87 +    ///
  125.88 +    /// This function instantiates a \c PredMap.
  125.89 +    /// \param digraph The digraph to which we would like to define the
  125.90 +    /// \c PredMap.
  125.91 +    static PredMap *createPredMap(const Digraph &digraph){
  125.92 +      return new PredMap(digraph);
  125.93 +    }
  125.94 +
  125.95 +  };
  125.96 +
  125.97 +  /// \ingroup spantree
  125.98 +  ///
  125.99 +  /// \brief Minimum Cost Arborescence algorithm class.
 125.100 +  ///
 125.101 +  /// This class provides an efficient implementation of the
 125.102 +  /// Minimum Cost Arborescence algorithm. The arborescence is a tree
 125.103 +  /// which is directed from a given source node of the digraph. One or
 125.104 +  /// more sources should be given to the algorithm and it will calculate
 125.105 +  /// the minimum cost subgraph that is the union of arborescences with the
 125.106 +  /// given sources and spans all the nodes which are reachable from the
 125.107 +  /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+e).
 125.108 +  ///
 125.109 +  /// The algorithm also provides an optimal dual solution, therefore
 125.110 +  /// the optimality of the solution can be checked.
 125.111 +  ///
 125.112 +  /// \param GR The digraph type the algorithm runs on.
 125.113 +  /// \param CM A read-only arc map storing the costs of the
 125.114 +  /// arcs. It is read once for each arc, so the map may involve in
 125.115 +  /// relatively time consuming process to compute the arc costs if
 125.116 +  /// it is necessary. The default map type is \ref
 125.117 +  /// concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
 125.118 +  /// \param TR Traits class to set various data types used
 125.119 +  /// by the algorithm. The default traits class is
 125.120 +  /// \ref MinCostArborescenceDefaultTraits
 125.121 +  /// "MinCostArborescenceDefaultTraits<GR, CM>".
 125.122 +#ifndef DOXYGEN
 125.123 +  template <typename GR,
 125.124 +            typename CM = typename GR::template ArcMap<int>,
 125.125 +            typename TR =
 125.126 +              MinCostArborescenceDefaultTraits<GR, CM> >
 125.127 +#else
 125.128 +  template <typename GR, typename CM, typedef TR>
 125.129 +#endif
 125.130 +  class MinCostArborescence {
 125.131 +  public:
 125.132 +
 125.133 +    /// \brief The \ref MinCostArborescenceDefaultTraits "traits class" 
 125.134 +    /// of the algorithm. 
 125.135 +    typedef TR Traits;
 125.136 +    /// The type of the underlying digraph.
 125.137 +    typedef typename Traits::Digraph Digraph;
 125.138 +    /// The type of the map that stores the arc costs.
 125.139 +    typedef typename Traits::CostMap CostMap;
 125.140 +    ///The type of the costs of the arcs.
 125.141 +    typedef typename Traits::Value Value;
 125.142 +    ///The type of the predecessor map.
 125.143 +    typedef typename Traits::PredMap PredMap;
 125.144 +    ///The type of the map that stores which arcs are in the arborescence.
 125.145 +    typedef typename Traits::ArborescenceMap ArborescenceMap;
 125.146 +
 125.147 +    typedef MinCostArborescence Create;
 125.148 +
 125.149 +  private:
 125.150 +
 125.151 +    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 125.152 +
 125.153 +    struct CostArc {
 125.154 +
 125.155 +      Arc arc;
 125.156 +      Value value;
 125.157 +
 125.158 +      CostArc() {}
 125.159 +      CostArc(Arc _arc, Value _value) : arc(_arc), value(_value) {}
 125.160 +
 125.161 +    };
 125.162 +
 125.163 +    const Digraph *_digraph;
 125.164 +    const CostMap *_cost;
 125.165 +
 125.166 +    PredMap *_pred;
 125.167 +    bool local_pred;
 125.168 +
 125.169 +    ArborescenceMap *_arborescence;
 125.170 +    bool local_arborescence;
 125.171 +
 125.172 +    typedef typename Digraph::template ArcMap<int> ArcOrder;
 125.173 +    ArcOrder *_arc_order;
 125.174 +
 125.175 +    typedef typename Digraph::template NodeMap<int> NodeOrder;
 125.176 +    NodeOrder *_node_order;
 125.177 +
 125.178 +    typedef typename Digraph::template NodeMap<CostArc> CostArcMap;
 125.179 +    CostArcMap *_cost_arcs;
 125.180 +
 125.181 +    struct StackLevel {
 125.182 +
 125.183 +      std::vector<CostArc> arcs;
 125.184 +      int node_level;
 125.185 +
 125.186 +    };
 125.187 +
 125.188 +    std::vector<StackLevel> level_stack;
 125.189 +    std::vector<Node> queue;
 125.190 +
 125.191 +    typedef std::vector<typename Digraph::Node> DualNodeList;
 125.192 +
 125.193 +    DualNodeList _dual_node_list;
 125.194 +
 125.195 +    struct DualVariable {
 125.196 +      int begin, end;
 125.197 +      Value value;
 125.198 +
 125.199 +      DualVariable(int _begin, int _end, Value _value)
 125.200 +        : begin(_begin), end(_end), value(_value) {}
 125.201 +
 125.202 +    };
 125.203 +
 125.204 +    typedef std::vector<DualVariable> DualVariables;
 125.205 +
 125.206 +    DualVariables _dual_variables;
 125.207 +
 125.208 +    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
 125.209 +
 125.210 +    HeapCrossRef *_heap_cross_ref;
 125.211 +
 125.212 +    typedef BinHeap<int, HeapCrossRef> Heap;
 125.213 +
 125.214 +    Heap *_heap;
 125.215 +
 125.216 +  protected:
 125.217 +
 125.218 +    MinCostArborescence() {}
 125.219 +
 125.220 +  private:
 125.221 +
 125.222 +    void createStructures() {
 125.223 +      if (!_pred) {
 125.224 +        local_pred = true;
 125.225 +        _pred = Traits::createPredMap(*_digraph);
 125.226 +      }
 125.227 +      if (!_arborescence) {
 125.228 +        local_arborescence = true;
 125.229 +        _arborescence = Traits::createArborescenceMap(*_digraph);
 125.230 +      }
 125.231 +      if (!_arc_order) {
 125.232 +        _arc_order = new ArcOrder(*_digraph);
 125.233 +      }
 125.234 +      if (!_node_order) {
 125.235 +        _node_order = new NodeOrder(*_digraph);
 125.236 +      }
 125.237 +      if (!_cost_arcs) {
 125.238 +        _cost_arcs = new CostArcMap(*_digraph);
 125.239 +      }
 125.240 +      if (!_heap_cross_ref) {
 125.241 +        _heap_cross_ref = new HeapCrossRef(*_digraph, -1);
 125.242 +      }
 125.243 +      if (!_heap) {
 125.244 +        _heap = new Heap(*_heap_cross_ref);
 125.245 +      }
 125.246 +    }
 125.247 +
 125.248 +    void destroyStructures() {
 125.249 +      if (local_arborescence) {
 125.250 +        delete _arborescence;
 125.251 +      }
 125.252 +      if (local_pred) {
 125.253 +        delete _pred;
 125.254 +      }
 125.255 +      if (_arc_order) {
 125.256 +        delete _arc_order;
 125.257 +      }
 125.258 +      if (_node_order) {
 125.259 +        delete _node_order;
 125.260 +      }
 125.261 +      if (_cost_arcs) {
 125.262 +        delete _cost_arcs;
 125.263 +      }
 125.264 +      if (_heap) {
 125.265 +        delete _heap;
 125.266 +      }
 125.267 +      if (_heap_cross_ref) {
 125.268 +        delete _heap_cross_ref;
 125.269 +      }
 125.270 +    }
 125.271 +
 125.272 +    Arc prepare(Node node) {
 125.273 +      std::vector<Node> nodes;
 125.274 +      (*_node_order)[node] = _dual_node_list.size();
 125.275 +      StackLevel level;
 125.276 +      level.node_level = _dual_node_list.size();
 125.277 +      _dual_node_list.push_back(node);
 125.278 +      for (InArcIt it(*_digraph, node); it != INVALID; ++it) {
 125.279 +        Arc arc = it;
 125.280 +        Node source = _digraph->source(arc);
 125.281 +        Value value = (*_cost)[it];
 125.282 +        if (source == node || (*_node_order)[source] == -3) continue;
 125.283 +        if ((*_cost_arcs)[source].arc == INVALID) {
 125.284 +          (*_cost_arcs)[source].arc = arc;
 125.285 +          (*_cost_arcs)[source].value = value;
 125.286 +          nodes.push_back(source);
 125.287 +        } else {
 125.288 +          if ((*_cost_arcs)[source].value > value) {
 125.289 +            (*_cost_arcs)[source].arc = arc;
 125.290 +            (*_cost_arcs)[source].value = value;
 125.291 +          }
 125.292 +        }
 125.293 +      }
 125.294 +      CostArc minimum = (*_cost_arcs)[nodes[0]];
 125.295 +      for (int i = 1; i < int(nodes.size()); ++i) {
 125.296 +        if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
 125.297 +          minimum = (*_cost_arcs)[nodes[i]];
 125.298 +        }
 125.299 +      }
 125.300 +      (*_arc_order)[minimum.arc] = _dual_variables.size();
 125.301 +      DualVariable var(_dual_node_list.size() - 1,
 125.302 +                       _dual_node_list.size(), minimum.value);
 125.303 +      _dual_variables.push_back(var);
 125.304 +      for (int i = 0; i < int(nodes.size()); ++i) {
 125.305 +        (*_cost_arcs)[nodes[i]].value -= minimum.value;
 125.306 +        level.arcs.push_back((*_cost_arcs)[nodes[i]]);
 125.307 +        (*_cost_arcs)[nodes[i]].arc = INVALID;
 125.308 +      }
 125.309 +      level_stack.push_back(level);
 125.310 +      return minimum.arc;
 125.311 +    }
 125.312 +
 125.313 +    Arc contract(Node node) {
 125.314 +      int node_bottom = bottom(node);
 125.315 +      std::vector<Node> nodes;
 125.316 +      while (!level_stack.empty() &&
 125.317 +             level_stack.back().node_level >= node_bottom) {
 125.318 +        for (int i = 0; i < int(level_stack.back().arcs.size()); ++i) {
 125.319 +          Arc arc = level_stack.back().arcs[i].arc;
 125.320 +          Node source = _digraph->source(arc);
 125.321 +          Value value = level_stack.back().arcs[i].value;
 125.322 +          if ((*_node_order)[source] >= node_bottom) continue;
 125.323 +          if ((*_cost_arcs)[source].arc == INVALID) {
 125.324 +            (*_cost_arcs)[source].arc = arc;
 125.325 +            (*_cost_arcs)[source].value = value;
 125.326 +            nodes.push_back(source);
 125.327 +          } else {
 125.328 +            if ((*_cost_arcs)[source].value > value) {
 125.329 +              (*_cost_arcs)[source].arc = arc;
 125.330 +              (*_cost_arcs)[source].value = value;
 125.331 +            }
 125.332 +          }
 125.333 +        }
 125.334 +        level_stack.pop_back();
 125.335 +      }
 125.336 +      CostArc minimum = (*_cost_arcs)[nodes[0]];
 125.337 +      for (int i = 1; i < int(nodes.size()); ++i) {
 125.338 +        if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
 125.339 +          minimum = (*_cost_arcs)[nodes[i]];
 125.340 +        }
 125.341 +      }
 125.342 +      (*_arc_order)[minimum.arc] = _dual_variables.size();
 125.343 +      DualVariable var(node_bottom, _dual_node_list.size(), minimum.value);
 125.344 +      _dual_variables.push_back(var);
 125.345 +      StackLevel level;
 125.346 +      level.node_level = node_bottom;
 125.347 +      for (int i = 0; i < int(nodes.size()); ++i) {
 125.348 +        (*_cost_arcs)[nodes[i]].value -= minimum.value;
 125.349 +        level.arcs.push_back((*_cost_arcs)[nodes[i]]);
 125.350 +        (*_cost_arcs)[nodes[i]].arc = INVALID;
 125.351 +      }
 125.352 +      level_stack.push_back(level);
 125.353 +      return minimum.arc;
 125.354 +    }
 125.355 +
 125.356 +    int bottom(Node node) {
 125.357 +      int k = level_stack.size() - 1;
 125.358 +      while (level_stack[k].node_level > (*_node_order)[node]) {
 125.359 +        --k;
 125.360 +      }
 125.361 +      return level_stack[k].node_level;
 125.362 +    }
 125.363 +
 125.364 +    void finalize(Arc arc) {
 125.365 +      Node node = _digraph->target(arc);
 125.366 +      _heap->push(node, (*_arc_order)[arc]);
 125.367 +      _pred->set(node, arc);
 125.368 +      while (!_heap->empty()) {
 125.369 +        Node source = _heap->top();
 125.370 +        _heap->pop();
 125.371 +        (*_node_order)[source] = -1;
 125.372 +        for (OutArcIt it(*_digraph, source); it != INVALID; ++it) {
 125.373 +          if ((*_arc_order)[it] < 0) continue;
 125.374 +          Node target = _digraph->target(it);
 125.375 +          switch(_heap->state(target)) {
 125.376 +          case Heap::PRE_HEAP:
 125.377 +            _heap->push(target, (*_arc_order)[it]);
 125.378 +            _pred->set(target, it);
 125.379 +            break;
 125.380 +          case Heap::IN_HEAP:
 125.381 +            if ((*_arc_order)[it] < (*_heap)[target]) {
 125.382 +              _heap->decrease(target, (*_arc_order)[it]);
 125.383 +              _pred->set(target, it);
 125.384 +            }
 125.385 +            break;
 125.386 +          case Heap::POST_HEAP:
 125.387 +            break;
 125.388 +          }
 125.389 +        }
 125.390 +        _arborescence->set((*_pred)[source], true);
 125.391 +      }
 125.392 +    }
 125.393 +
 125.394 +
 125.395 +  public:
 125.396 +
 125.397 +    /// \name Named Template Parameters
 125.398 +
 125.399 +    /// @{
 125.400 +
 125.401 +    template <class T>
 125.402 +    struct SetArborescenceMapTraits : public Traits {
 125.403 +      typedef T ArborescenceMap;
 125.404 +      static ArborescenceMap *createArborescenceMap(const Digraph &)
 125.405 +      {
 125.406 +        LEMON_ASSERT(false, "ArborescenceMap is not initialized");
 125.407 +        return 0; // ignore warnings
 125.408 +      }
 125.409 +    };
 125.410 +
 125.411 +    /// \brief \ref named-templ-param "Named parameter" for
 125.412 +    /// setting \c ArborescenceMap type
 125.413 +    ///
 125.414 +    /// \ref named-templ-param "Named parameter" for setting
 125.415 +    /// \c ArborescenceMap type.
 125.416 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept,
 125.417 +    /// and its value type must be \c bool (or convertible).
 125.418 +    /// Initially it will be set to \c false on each arc,
 125.419 +    /// then it will be set on each arborescence arc once.
 125.420 +    template <class T>
 125.421 +    struct SetArborescenceMap
 125.422 +      : public MinCostArborescence<Digraph, CostMap,
 125.423 +                                   SetArborescenceMapTraits<T> > {
 125.424 +    };
 125.425 +
 125.426 +    template <class T>
 125.427 +    struct SetPredMapTraits : public Traits {
 125.428 +      typedef T PredMap;
 125.429 +      static PredMap *createPredMap(const Digraph &)
 125.430 +      {
 125.431 +        LEMON_ASSERT(false, "PredMap is not initialized");
 125.432 +        return 0; // ignore warnings
 125.433 +      }
 125.434 +    };
 125.435 +
 125.436 +    /// \brief \ref named-templ-param "Named parameter" for
 125.437 +    /// setting \c PredMap type
 125.438 +    ///
 125.439 +    /// \ref named-templ-param "Named parameter" for setting
 125.440 +    /// \c PredMap type.
 125.441 +    /// It must meet the \ref concepts::WriteMap "WriteMap" concept, 
 125.442 +    /// and its value type must be the \c Arc type of the digraph.
 125.443 +    template <class T>
 125.444 +    struct SetPredMap
 125.445 +      : public MinCostArborescence<Digraph, CostMap, SetPredMapTraits<T> > {
 125.446 +    };
 125.447 +
 125.448 +    /// @}
 125.449 +
 125.450 +    /// \brief Constructor.
 125.451 +    ///
 125.452 +    /// \param digraph The digraph the algorithm will run on.
 125.453 +    /// \param cost The cost map used by the algorithm.
 125.454 +    MinCostArborescence(const Digraph& digraph, const CostMap& cost)
 125.455 +      : _digraph(&digraph), _cost(&cost), _pred(0), local_pred(false),
 125.456 +        _arborescence(0), local_arborescence(false),
 125.457 +        _arc_order(0), _node_order(0), _cost_arcs(0),
 125.458 +        _heap_cross_ref(0), _heap(0) {}
 125.459 +
 125.460 +    /// \brief Destructor.
 125.461 +    ~MinCostArborescence() {
 125.462 +      destroyStructures();
 125.463 +    }
 125.464 +
 125.465 +    /// \brief Sets the arborescence map.
 125.466 +    ///
 125.467 +    /// Sets the arborescence map.
 125.468 +    /// \return <tt>(*this)</tt>
 125.469 +    MinCostArborescence& arborescenceMap(ArborescenceMap& m) {
 125.470 +      if (local_arborescence) {
 125.471 +        delete _arborescence;
 125.472 +      }
 125.473 +      local_arborescence = false;
 125.474 +      _arborescence = &m;
 125.475 +      return *this;
 125.476 +    }
 125.477 +
 125.478 +    /// \brief Sets the predecessor map.
 125.479 +    ///
 125.480 +    /// Sets the predecessor map.
 125.481 +    /// \return <tt>(*this)</tt>
 125.482 +    MinCostArborescence& predMap(PredMap& m) {
 125.483 +      if (local_pred) {
 125.484 +        delete _pred;
 125.485 +      }
 125.486 +      local_pred = false;
 125.487 +      _pred = &m;
 125.488 +      return *this;
 125.489 +    }
 125.490 +
 125.491 +    /// \name Execution Control
 125.492 +    /// The simplest way to execute the algorithm is to use
 125.493 +    /// one of the member functions called \c run(...). \n
 125.494 +    /// If you need better control on the execution,
 125.495 +    /// you have to call \ref init() first, then you can add several
 125.496 +    /// source nodes with \ref addSource().
 125.497 +    /// Finally \ref start() will perform the arborescence
 125.498 +    /// computation.
 125.499 +
 125.500 +    ///@{
 125.501 +
 125.502 +    /// \brief Initializes the internal data structures.
 125.503 +    ///
 125.504 +    /// Initializes the internal data structures.
 125.505 +    ///
 125.506 +    void init() {
 125.507 +      createStructures();
 125.508 +      _heap->clear();
 125.509 +      for (NodeIt it(*_digraph); it != INVALID; ++it) {
 125.510 +        (*_cost_arcs)[it].arc = INVALID;
 125.511 +        (*_node_order)[it] = -3;
 125.512 +        (*_heap_cross_ref)[it] = Heap::PRE_HEAP;
 125.513 +        _pred->set(it, INVALID);
 125.514 +      }
 125.515 +      for (ArcIt it(*_digraph); it != INVALID; ++it) {
 125.516 +        _arborescence->set(it, false);
 125.517 +        (*_arc_order)[it] = -1;
 125.518 +      }
 125.519 +      _dual_node_list.clear();
 125.520 +      _dual_variables.clear();
 125.521 +    }
 125.522 +
 125.523 +    /// \brief Adds a new source node.
 125.524 +    ///
 125.525 +    /// Adds a new source node to the algorithm.
 125.526 +    void addSource(Node source) {
 125.527 +      std::vector<Node> nodes;
 125.528 +      nodes.push_back(source);
 125.529 +      while (!nodes.empty()) {
 125.530 +        Node node = nodes.back();
 125.531 +        nodes.pop_back();
 125.532 +        for (OutArcIt it(*_digraph, node); it != INVALID; ++it) {
 125.533 +          Node target = _digraph->target(it);
 125.534 +          if ((*_node_order)[target] == -3) {
 125.535 +            (*_node_order)[target] = -2;
 125.536 +            nodes.push_back(target);
 125.537 +            queue.push_back(target);
 125.538 +          }
 125.539 +        }
 125.540 +      }
 125.541 +      (*_node_order)[source] = -1;
 125.542 +    }
 125.543 +
 125.544 +    /// \brief Processes the next node in the priority queue.
 125.545 +    ///
 125.546 +    /// Processes the next node in the priority queue.
 125.547 +    ///
 125.548 +    /// \return The processed node.
 125.549 +    ///
 125.550 +    /// \warning The queue must not be empty.
 125.551 +    Node processNextNode() {
 125.552 +      Node node = queue.back();
 125.553 +      queue.pop_back();
 125.554 +      if ((*_node_order)[node] == -2) {
 125.555 +        Arc arc = prepare(node);
 125.556 +        Node source = _digraph->source(arc);
 125.557 +        while ((*_node_order)[source] != -1) {
 125.558 +          if ((*_node_order)[source] >= 0) {
 125.559 +            arc = contract(source);
 125.560 +          } else {
 125.561 +            arc = prepare(source);
 125.562 +          }
 125.563 +          source = _digraph->source(arc);
 125.564 +        }
 125.565 +        finalize(arc);
 125.566 +        level_stack.clear();
 125.567 +      }
 125.568 +      return node;
 125.569 +    }
 125.570 +
 125.571 +    /// \brief Returns the number of the nodes to be processed.
 125.572 +    ///
 125.573 +    /// Returns the number of the nodes to be processed in the priority
 125.574 +    /// queue.
 125.575 +    int queueSize() const {
 125.576 +      return queue.size();
 125.577 +    }
 125.578 +
 125.579 +    /// \brief Returns \c false if there are nodes to be processed.
 125.580 +    ///
 125.581 +    /// Returns \c false if there are nodes to be processed.
 125.582 +    bool emptyQueue() const {
 125.583 +      return queue.empty();
 125.584 +    }
 125.585 +
 125.586 +    /// \brief Executes the algorithm.
 125.587 +    ///
 125.588 +    /// Executes the algorithm.
 125.589 +    ///
 125.590 +    /// \pre init() must be called and at least one node should be added
 125.591 +    /// with addSource() before using this function.
 125.592 +    ///
 125.593 +    ///\note mca.start() is just a shortcut of the following code.
 125.594 +    ///\code
 125.595 +    ///while (!mca.emptyQueue()) {
 125.596 +    ///  mca.processNextNode();
 125.597 +    ///}
 125.598 +    ///\endcode
 125.599 +    void start() {
 125.600 +      while (!emptyQueue()) {
 125.601 +        processNextNode();
 125.602 +      }
 125.603 +    }
 125.604 +
 125.605 +    /// \brief Runs %MinCostArborescence algorithm from node \c s.
 125.606 +    ///
 125.607 +    /// This method runs the %MinCostArborescence algorithm from
 125.608 +    /// a root node \c s.
 125.609 +    ///
 125.610 +    /// \note mca.run(s) is just a shortcut of the following code.
 125.611 +    /// \code
 125.612 +    /// mca.init();
 125.613 +    /// mca.addSource(s);
 125.614 +    /// mca.start();
 125.615 +    /// \endcode
 125.616 +    void run(Node s) {
 125.617 +      init();
 125.618 +      addSource(s);
 125.619 +      start();
 125.620 +    }
 125.621 +
 125.622 +    ///@}
 125.623 +
 125.624 +    /// \name Query Functions
 125.625 +    /// The result of the %MinCostArborescence algorithm can be obtained
 125.626 +    /// using these functions.\n
 125.627 +    /// Either run() or start() must be called before using them.
 125.628 +
 125.629 +    /// @{
 125.630 +
 125.631 +    /// \brief Returns the cost of the arborescence.
 125.632 +    ///
 125.633 +    /// Returns the cost of the arborescence.
 125.634 +    Value arborescenceCost() const {
 125.635 +      Value sum = 0;
 125.636 +      for (ArcIt it(*_digraph); it != INVALID; ++it) {
 125.637 +        if (arborescence(it)) {
 125.638 +          sum += (*_cost)[it];
 125.639 +        }
 125.640 +      }
 125.641 +      return sum;
 125.642 +    }
 125.643 +
 125.644 +    /// \brief Returns \c true if the arc is in the arborescence.
 125.645 +    ///
 125.646 +    /// Returns \c true if the given arc is in the arborescence.
 125.647 +    /// \param arc An arc of the digraph.
 125.648 +    /// \pre \ref run() must be called before using this function.
 125.649 +    bool arborescence(Arc arc) const {
 125.650 +      return (*_pred)[_digraph->target(arc)] == arc;
 125.651 +    }
 125.652 +
 125.653 +    /// \brief Returns a const reference to the arborescence map.
 125.654 +    ///
 125.655 +    /// Returns a const reference to the arborescence map.
 125.656 +    /// \pre \ref run() must be called before using this function.
 125.657 +    const ArborescenceMap& arborescenceMap() const {
 125.658 +      return *_arborescence;
 125.659 +    }
 125.660 +
 125.661 +    /// \brief Returns the predecessor arc of the given node.
 125.662 +    ///
 125.663 +    /// Returns the predecessor arc of the given node.
 125.664 +    /// \pre \ref run() must be called before using this function.
 125.665 +    Arc pred(Node node) const {
 125.666 +      return (*_pred)[node];
 125.667 +    }
 125.668 +
 125.669 +    /// \brief Returns a const reference to the pred map.
 125.670 +    ///
 125.671 +    /// Returns a const reference to the pred map.
 125.672 +    /// \pre \ref run() must be called before using this function.
 125.673 +    const PredMap& predMap() const {
 125.674 +      return *_pred;
 125.675 +    }
 125.676 +
 125.677 +    /// \brief Indicates that a node is reachable from the sources.
 125.678 +    ///
 125.679 +    /// Indicates that a node is reachable from the sources.
 125.680 +    bool reached(Node node) const {
 125.681 +      return (*_node_order)[node] != -3;
 125.682 +    }
 125.683 +
 125.684 +    /// \brief Indicates that a node is processed.
 125.685 +    ///
 125.686 +    /// Indicates that a node is processed. The arborescence path exists
 125.687 +    /// from the source to the given node.
 125.688 +    bool processed(Node node) const {
 125.689 +      return (*_node_order)[node] == -1;
 125.690 +    }
 125.691 +
 125.692 +    /// \brief Returns the number of the dual variables in basis.
 125.693 +    ///
 125.694 +    /// Returns the number of the dual variables in basis.
 125.695 +    int dualNum() const {
 125.696 +      return _dual_variables.size();
 125.697 +    }
 125.698 +
 125.699 +    /// \brief Returns the value of the dual solution.
 125.700 +    ///
 125.701 +    /// Returns the value of the dual solution. It should be
 125.702 +    /// equal to the arborescence value.
 125.703 +    Value dualValue() const {
 125.704 +      Value sum = 0;
 125.705 +      for (int i = 0; i < int(_dual_variables.size()); ++i) {
 125.706 +        sum += _dual_variables[i].value;
 125.707 +      }
 125.708 +      return sum;
 125.709 +    }
 125.710 +
 125.711 +    /// \brief Returns the number of the nodes in the dual variable.
 125.712 +    ///
 125.713 +    /// Returns the number of the nodes in the dual variable.
 125.714 +    int dualSize(int k) const {
 125.715 +      return _dual_variables[k].end - _dual_variables[k].begin;
 125.716 +    }
 125.717 +
 125.718 +    /// \brief Returns the value of the dual variable.
 125.719 +    ///
 125.720 +    /// Returns the the value of the dual variable.
 125.721 +    Value dualValue(int k) const {
 125.722 +      return _dual_variables[k].value;
 125.723 +    }
 125.724 +
 125.725 +    /// \brief LEMON iterator for getting a dual variable.
 125.726 +    ///
 125.727 +    /// This class provides a common style LEMON iterator for getting a
 125.728 +    /// dual variable of \ref MinCostArborescence algorithm.
 125.729 +    /// It iterates over a subset of the nodes.
 125.730 +    class DualIt {
 125.731 +    public:
 125.732 +
 125.733 +      /// \brief Constructor.
 125.734 +      ///
 125.735 +      /// Constructor for getting the nodeset of the dual variable
 125.736 +      /// of \ref MinCostArborescence algorithm.
 125.737 +      DualIt(const MinCostArborescence& algorithm, int variable)
 125.738 +        : _algorithm(&algorithm)
 125.739 +      {
 125.740 +        _index = _algorithm->_dual_variables[variable].begin;
 125.741 +        _last = _algorithm->_dual_variables[variable].end;
 125.742 +      }
 125.743 +
 125.744 +      /// \brief Conversion to \c Node.
 125.745 +      ///
 125.746 +      /// Conversion to \c Node.
 125.747 +      operator Node() const {
 125.748 +        return _algorithm->_dual_node_list[_index];
 125.749 +      }
 125.750 +
 125.751 +      /// \brief Increment operator.
 125.752 +      ///
 125.753 +      /// Increment operator.
 125.754 +      DualIt& operator++() {
 125.755 +        ++_index;
 125.756 +        return *this;
 125.757 +      }
 125.758 +
 125.759 +      /// \brief Validity checking
 125.760 +      ///
 125.761 +      /// Checks whether the iterator is invalid.
 125.762 +      bool operator==(Invalid) const {
 125.763 +        return _index == _last;
 125.764 +      }
 125.765 +
 125.766 +      /// \brief Validity checking
 125.767 +      ///
 125.768 +      /// Checks whether the iterator is valid.
 125.769 +      bool operator!=(Invalid) const {
 125.770 +        return _index != _last;
 125.771 +      }
 125.772 +
 125.773 +    private:
 125.774 +      const MinCostArborescence* _algorithm;
 125.775 +      int _index, _last;
 125.776 +    };
 125.777 +
 125.778 +    /// @}
 125.779 +
 125.780 +  };
 125.781 +
 125.782 +  /// \ingroup spantree
 125.783 +  ///
 125.784 +  /// \brief Function type interface for MinCostArborescence algorithm.
 125.785 +  ///
 125.786 +  /// Function type interface for MinCostArborescence algorithm.
 125.787 +  /// \param digraph The digraph the algorithm runs on.
 125.788 +  /// \param cost An arc map storing the costs.
 125.789 +  /// \param source The source node of the arborescence.
 125.790 +  /// \retval arborescence An arc map with \c bool (or convertible) value
 125.791 +  /// type that stores the arborescence.
 125.792 +  /// \return The total cost of the arborescence.
 125.793 +  ///
 125.794 +  /// \sa MinCostArborescence
 125.795 +  template <typename Digraph, typename CostMap, typename ArborescenceMap>
 125.796 +  typename CostMap::Value minCostArborescence(const Digraph& digraph,
 125.797 +                                              const CostMap& cost,
 125.798 +                                              typename Digraph::Node source,
 125.799 +                                              ArborescenceMap& arborescence) {
 125.800 +    typename MinCostArborescence<Digraph, CostMap>
 125.801 +      ::template SetArborescenceMap<ArborescenceMap>
 125.802 +      ::Create mca(digraph, cost);
 125.803 +    mca.arborescenceMap(arborescence);
 125.804 +    mca.run(source);
 125.805 +    return mca.arborescenceCost();
 125.806 +  }
 125.807 +
 125.808 +}
 125.809 +
 125.810 +#endif
   126.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   126.2 +++ b/lemon/nauty_reader.h	Thu Nov 05 15:50:01 2009 +0100
   126.3 @@ -0,0 +1,113 @@
   126.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   126.5 + *
   126.6 + * This file is a part of LEMON, a generic C++ optimization library.
   126.7 + *
   126.8 + * Copyright (C) 2003-2009
   126.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  126.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  126.11 + *
  126.12 + * Permission to use, modify and distribute this software is granted
  126.13 + * provided that this copyright notice appears in all copies. For
  126.14 + * precise terms see the accompanying LICENSE file.
  126.15 + *
  126.16 + * This software is provided "AS IS" with no warranty of any kind,
  126.17 + * express or implied, and with no claim as to its suitability for any
  126.18 + * purpose.
  126.19 + *
  126.20 + */
  126.21 +
  126.22 +#ifndef LEMON_NAUTY_READER_H
  126.23 +#define LEMON_NAUTY_READER_H
  126.24 +
  126.25 +#include <vector>
  126.26 +#include <iostream>
  126.27 +#include <string>
  126.28 +
  126.29 +/// \ingroup nauty_group
  126.30 +/// \file
  126.31 +/// \brief Nauty file reader.
  126.32 +
  126.33 +namespace lemon {
  126.34 +
  126.35 +  /// \ingroup nauty_group
  126.36 +  ///
  126.37 +  /// \brief Nauty file reader
  126.38 +  ///
  126.39 +  /// The \e geng program is in the \e gtools suite of the nauty
  126.40 +  /// package. This tool can generate all non-isomorphic undirected
  126.41 +  /// graphs of several classes with given node number (e.g.
  126.42 +  /// general, connected, biconnected, triangle-free, 4-cycle-free,
  126.43 +  /// bipartite and graphs with given edge number and degree
  126.44 +  /// constraints). This function reads a \e nauty \e graph6 \e format
  126.45 +  /// line from the given stream and builds it in the given graph.
  126.46 +  ///
  126.47 +  /// The site of nauty package: http://cs.anu.edu.au/~bdm/nauty/
  126.48 +  ///
  126.49 +  /// For example, the number of all non-isomorphic planar graphs
  126.50 +  /// can be computed with the following code.
  126.51 +  ///\code
  126.52 +  /// int num = 0;
  126.53 +  /// SmartGraph graph;
  126.54 +  /// while (readNautyGraph(graph, std::cin)) {
  126.55 +  ///   PlanarityChecking<SmartGraph> pc(graph);
  126.56 +  ///   if (pc.run()) ++num;
  126.57 +  /// }
  126.58 +  /// std::cout << "Number of planar graphs: " << num << std::endl;
  126.59 +  ///\endcode
  126.60 +  ///
  126.61 +  /// The nauty files are quite huge, therefore instead of the direct
  126.62 +  /// file generation pipelining is recommended. For example,
  126.63 +  ///\code
  126.64 +  /// ./geng -c 10 | ./num_of_planar_graphs
  126.65 +  ///\endcode
  126.66 +  template <typename Graph>
  126.67 +  std::istream& readNautyGraph(Graph& graph, std::istream& is = std::cin) {
  126.68 +    graph.clear();
  126.69 +
  126.70 +    std::string line;
  126.71 +    if (getline(is, line)) {
  126.72 +      int index = 0;
  126.73 +
  126.74 +      int n;
  126.75 +
  126.76 +      if (line[index] == '>') {
  126.77 +        index += 10;
  126.78 +      }
  126.79 +
  126.80 +      char c = line[index++]; c -= 63;
  126.81 +      if (c != 63) {
  126.82 +        n = int(c);
  126.83 +      } else {
  126.84 +        c = line[index++]; c -= 63;
  126.85 +        n = (int(c) << 12);
  126.86 +        c = line[index++]; c -= 63;
  126.87 +        n |= (int(c) << 6);
  126.88 +        c = line[index++]; c -= 63;
  126.89 +        n |= int(c);
  126.90 +      }
  126.91 +
  126.92 +      std::vector<typename Graph::Node> nodes;
  126.93 +      for (int i = 0; i < n; ++i) {
  126.94 +        nodes.push_back(graph.addNode());
  126.95 +      }
  126.96 +
  126.97 +      int bit = -1;
  126.98 +      for (int j = 0; j < n; ++j) {
  126.99 +        for (int i = 0; i < j; ++i) {
 126.100 +          if (bit == -1) {
 126.101 +            c = line[index++]; c -= 63;
 126.102 +            bit = 5;
 126.103 +          }
 126.104 +          bool b = (c & (1 << (bit--))) != 0;
 126.105 +
 126.106 +          if (b) {
 126.107 +            graph.addEdge(nodes[i], nodes[j]);
 126.108 +          }
 126.109 +        }
 126.110 +      }
 126.111 +    }
 126.112 +    return is;
 126.113 +  }
 126.114 +}
 126.115 +
 126.116 +#endif
   127.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   127.2 +++ b/lemon/network_simplex.h	Thu Nov 05 15:50:01 2009 +0100
   127.3 @@ -0,0 +1,1485 @@
   127.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   127.5 + *
   127.6 + * This file is a part of LEMON, a generic C++ optimization library.
   127.7 + *
   127.8 + * Copyright (C) 2003-2009
   127.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  127.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  127.11 + *
  127.12 + * Permission to use, modify and distribute this software is granted
  127.13 + * provided that this copyright notice appears in all copies. For
  127.14 + * precise terms see the accompanying LICENSE file.
  127.15 + *
  127.16 + * This software is provided "AS IS" with no warranty of any kind,
  127.17 + * express or implied, and with no claim as to its suitability for any
  127.18 + * purpose.
  127.19 + *
  127.20 + */
  127.21 +
  127.22 +#ifndef LEMON_NETWORK_SIMPLEX_H
  127.23 +#define LEMON_NETWORK_SIMPLEX_H
  127.24 +
  127.25 +/// \ingroup min_cost_flow_algs
  127.26 +///
  127.27 +/// \file
  127.28 +/// \brief Network Simplex algorithm for finding a minimum cost flow.
  127.29 +
  127.30 +#include <vector>
  127.31 +#include <limits>
  127.32 +#include <algorithm>
  127.33 +
  127.34 +#include <lemon/core.h>
  127.35 +#include <lemon/math.h>
  127.36 +
  127.37 +namespace lemon {
  127.38 +
  127.39 +  /// \addtogroup min_cost_flow_algs
  127.40 +  /// @{
  127.41 +
  127.42 +  /// \brief Implementation of the primal Network Simplex algorithm
  127.43 +  /// for finding a \ref min_cost_flow "minimum cost flow".
  127.44 +  ///
  127.45 +  /// \ref NetworkSimplex implements the primal Network Simplex algorithm
  127.46 +  /// for finding a \ref min_cost_flow "minimum cost flow"
  127.47 +  /// \ref amo93networkflows, \ref dantzig63linearprog,
  127.48 +  /// \ref kellyoneill91netsimplex.
  127.49 +  /// This algorithm is a specialized version of the linear programming
  127.50 +  /// simplex method directly for the minimum cost flow problem.
  127.51 +  /// It is one of the most efficient solution methods.
  127.52 +  ///
  127.53 +  /// In general this class is the fastest implementation available
  127.54 +  /// in LEMON for the minimum cost flow problem.
  127.55 +  /// Moreover it supports both directions of the supply/demand inequality
  127.56 +  /// constraints. For more information see \ref SupplyType.
  127.57 +  ///
  127.58 +  /// Most of the parameters of the problem (except for the digraph)
  127.59 +  /// can be given using separate functions, and the algorithm can be
  127.60 +  /// executed using the \ref run() function. If some parameters are not
  127.61 +  /// specified, then default values will be used.
  127.62 +  ///
  127.63 +  /// \tparam GR The digraph type the algorithm runs on.
  127.64 +  /// \tparam V The value type used for flow amounts, capacity bounds
  127.65 +  /// and supply values in the algorithm. By default it is \c int.
  127.66 +  /// \tparam C The value type used for costs and potentials in the
  127.67 +  /// algorithm. By default it is the same as \c V.
  127.68 +  ///
  127.69 +  /// \warning Both value types must be signed and all input data must
  127.70 +  /// be integer.
  127.71 +  ///
  127.72 +  /// \note %NetworkSimplex provides five different pivot rule
  127.73 +  /// implementations, from which the most efficient one is used
  127.74 +  /// by default. For more information see \ref PivotRule.
  127.75 +  template <typename GR, typename V = int, typename C = V>
  127.76 +  class NetworkSimplex
  127.77 +  {
  127.78 +  public:
  127.79 +
  127.80 +    /// The type of the flow amounts, capacity bounds and supply values
  127.81 +    typedef V Value;
  127.82 +    /// The type of the arc costs
  127.83 +    typedef C Cost;
  127.84 +
  127.85 +  public:
  127.86 +
  127.87 +    /// \brief Problem type constants for the \c run() function.
  127.88 +    ///
  127.89 +    /// Enum type containing the problem type constants that can be
  127.90 +    /// returned by the \ref run() function of the algorithm.
  127.91 +    enum ProblemType {
  127.92 +      /// The problem has no feasible solution (flow).
  127.93 +      INFEASIBLE,
  127.94 +      /// The problem has optimal solution (i.e. it is feasible and
  127.95 +      /// bounded), and the algorithm has found optimal flow and node
  127.96 +      /// potentials (primal and dual solutions).
  127.97 +      OPTIMAL,
  127.98 +      /// The objective function of the problem is unbounded, i.e.
  127.99 +      /// there is a directed cycle having negative total cost and
 127.100 +      /// infinite upper bound.
 127.101 +      UNBOUNDED
 127.102 +    };
 127.103 +    
 127.104 +    /// \brief Constants for selecting the type of the supply constraints.
 127.105 +    ///
 127.106 +    /// Enum type containing constants for selecting the supply type,
 127.107 +    /// i.e. the direction of the inequalities in the supply/demand
 127.108 +    /// constraints of the \ref min_cost_flow "minimum cost flow problem".
 127.109 +    ///
 127.110 +    /// The default supply type is \c GEQ, the \c LEQ type can be
 127.111 +    /// selected using \ref supplyType().
 127.112 +    /// The equality form is a special case of both supply types.
 127.113 +    enum SupplyType {
 127.114 +      /// This option means that there are <em>"greater or equal"</em>
 127.115 +      /// supply/demand constraints in the definition of the problem.
 127.116 +      GEQ,
 127.117 +      /// This option means that there are <em>"less or equal"</em>
 127.118 +      /// supply/demand constraints in the definition of the problem.
 127.119 +      LEQ
 127.120 +    };
 127.121 +    
 127.122 +    /// \brief Constants for selecting the pivot rule.
 127.123 +    ///
 127.124 +    /// Enum type containing constants for selecting the pivot rule for
 127.125 +    /// the \ref run() function.
 127.126 +    ///
 127.127 +    /// \ref NetworkSimplex provides five different pivot rule
 127.128 +    /// implementations that significantly affect the running time
 127.129 +    /// of the algorithm.
 127.130 +    /// By default \ref BLOCK_SEARCH "Block Search" is used, which
 127.131 +    /// proved to be the most efficient and the most robust on various
 127.132 +    /// test inputs according to our benchmark tests.
 127.133 +    /// However another pivot rule can be selected using the \ref run()
 127.134 +    /// function with the proper parameter.
 127.135 +    enum PivotRule {
 127.136 +
 127.137 +      /// The First Eligible pivot rule.
 127.138 +      /// The next eligible arc is selected in a wraparound fashion
 127.139 +      /// in every iteration.
 127.140 +      FIRST_ELIGIBLE,
 127.141 +
 127.142 +      /// The Best Eligible pivot rule.
 127.143 +      /// The best eligible arc is selected in every iteration.
 127.144 +      BEST_ELIGIBLE,
 127.145 +
 127.146 +      /// The Block Search pivot rule.
 127.147 +      /// A specified number of arcs are examined in every iteration
 127.148 +      /// in a wraparound fashion and the best eligible arc is selected
 127.149 +      /// from this block.
 127.150 +      BLOCK_SEARCH,
 127.151 +
 127.152 +      /// The Candidate List pivot rule.
 127.153 +      /// In a major iteration a candidate list is built from eligible arcs
 127.154 +      /// in a wraparound fashion and in the following minor iterations
 127.155 +      /// the best eligible arc is selected from this list.
 127.156 +      CANDIDATE_LIST,
 127.157 +
 127.158 +      /// The Altering Candidate List pivot rule.
 127.159 +      /// It is a modified version of the Candidate List method.
 127.160 +      /// It keeps only the several best eligible arcs from the former
 127.161 +      /// candidate list and extends this list in every iteration.
 127.162 +      ALTERING_LIST
 127.163 +    };
 127.164 +    
 127.165 +  private:
 127.166 +
 127.167 +    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
 127.168 +
 127.169 +    typedef std::vector<int> IntVector;
 127.170 +    typedef std::vector<bool> BoolVector;
 127.171 +    typedef std::vector<Value> ValueVector;
 127.172 +    typedef std::vector<Cost> CostVector;
 127.173 +
 127.174 +    // State constants for arcs
 127.175 +    enum ArcStateEnum {
 127.176 +      STATE_UPPER = -1,
 127.177 +      STATE_TREE  =  0,
 127.178 +      STATE_LOWER =  1
 127.179 +    };
 127.180 +
 127.181 +  private:
 127.182 +
 127.183 +    // Data related to the underlying digraph
 127.184 +    const GR &_graph;
 127.185 +    int _node_num;
 127.186 +    int _arc_num;
 127.187 +    int _all_arc_num;
 127.188 +    int _search_arc_num;
 127.189 +
 127.190 +    // Parameters of the problem
 127.191 +    bool _have_lower;
 127.192 +    SupplyType _stype;
 127.193 +    Value _sum_supply;
 127.194 +
 127.195 +    // Data structures for storing the digraph
 127.196 +    IntNodeMap _node_id;
 127.197 +    IntArcMap _arc_id;
 127.198 +    IntVector _source;
 127.199 +    IntVector _target;
 127.200 +
 127.201 +    // Node and arc data
 127.202 +    ValueVector _lower;
 127.203 +    ValueVector _upper;
 127.204 +    ValueVector _cap;
 127.205 +    CostVector _cost;
 127.206 +    ValueVector _supply;
 127.207 +    ValueVector _flow;
 127.208 +    CostVector _pi;
 127.209 +
 127.210 +    // Data for storing the spanning tree structure
 127.211 +    IntVector _parent;
 127.212 +    IntVector _pred;
 127.213 +    IntVector _thread;
 127.214 +    IntVector _rev_thread;
 127.215 +    IntVector _succ_num;
 127.216 +    IntVector _last_succ;
 127.217 +    IntVector _dirty_revs;
 127.218 +    BoolVector _forward;
 127.219 +    IntVector _state;
 127.220 +    int _root;
 127.221 +
 127.222 +    // Temporary data used in the current pivot iteration
 127.223 +    int in_arc, join, u_in, v_in, u_out, v_out;
 127.224 +    int first, second, right, last;
 127.225 +    int stem, par_stem, new_stem;
 127.226 +    Value delta;
 127.227 +
 127.228 +  public:
 127.229 +  
 127.230 +    /// \brief Constant for infinite upper bounds (capacities).
 127.231 +    ///
 127.232 +    /// Constant for infinite upper bounds (capacities).
 127.233 +    /// It is \c std::numeric_limits<Value>::infinity() if available,
 127.234 +    /// \c std::numeric_limits<Value>::max() otherwise.
 127.235 +    const Value INF;
 127.236 +
 127.237 +  private:
 127.238 +
 127.239 +    // Implementation of the First Eligible pivot rule
 127.240 +    class FirstEligiblePivotRule
 127.241 +    {
 127.242 +    private:
 127.243 +
 127.244 +      // References to the NetworkSimplex class
 127.245 +      const IntVector  &_source;
 127.246 +      const IntVector  &_target;
 127.247 +      const CostVector &_cost;
 127.248 +      const IntVector  &_state;
 127.249 +      const CostVector &_pi;
 127.250 +      int &_in_arc;
 127.251 +      int _search_arc_num;
 127.252 +
 127.253 +      // Pivot rule data
 127.254 +      int _next_arc;
 127.255 +
 127.256 +    public:
 127.257 +
 127.258 +      // Constructor
 127.259 +      FirstEligiblePivotRule(NetworkSimplex &ns) :
 127.260 +        _source(ns._source), _target(ns._target),
 127.261 +        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
 127.262 +        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
 127.263 +        _next_arc(0)
 127.264 +      {}
 127.265 +
 127.266 +      // Find next entering arc
 127.267 +      bool findEnteringArc() {
 127.268 +        Cost c;
 127.269 +        for (int e = _next_arc; e < _search_arc_num; ++e) {
 127.270 +          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 127.271 +          if (c < 0) {
 127.272 +            _in_arc = e;
 127.273 +            _next_arc = e + 1;
 127.274 +            return true;
 127.275 +          }
 127.276 +        }
 127.277 +        for (int e = 0; e < _next_arc; ++e) {
 127.278 +          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 127.279 +          if (c < 0) {
 127.280 +            _in_arc = e;
 127.281 +            _next_arc = e + 1;
 127.282 +            return true;
 127.283 +          }
 127.284 +        }
 127.285 +        return false;
 127.286 +      }
 127.287 +
 127.288 +    }; //class FirstEligiblePivotRule
 127.289 +
 127.290 +
 127.291 +    // Implementation of the Best Eligible pivot rule
 127.292 +    class BestEligiblePivotRule
 127.293 +    {
 127.294 +    private:
 127.295 +
 127.296 +      // References to the NetworkSimplex class
 127.297 +      const IntVector  &_source;
 127.298 +      const IntVector  &_target;
 127.299 +      const CostVector &_cost;
 127.300 +      const IntVector  &_state;
 127.301 +      const CostVector &_pi;
 127.302 +      int &_in_arc;
 127.303 +      int _search_arc_num;
 127.304 +
 127.305 +    public:
 127.306 +
 127.307 +      // Constructor
 127.308 +      BestEligiblePivotRule(NetworkSimplex &ns) :
 127.309 +        _source(ns._source), _target(ns._target),
 127.310 +        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
 127.311 +        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num)
 127.312 +      {}
 127.313 +
 127.314 +      // Find next entering arc
 127.315 +      bool findEnteringArc() {
 127.316 +        Cost c, min = 0;
 127.317 +        for (int e = 0; e < _search_arc_num; ++e) {
 127.318 +          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 127.319 +          if (c < min) {
 127.320 +            min = c;
 127.321 +            _in_arc = e;
 127.322 +          }
 127.323 +        }
 127.324 +        return min < 0;
 127.325 +      }
 127.326 +
 127.327 +    }; //class BestEligiblePivotRule
 127.328 +
 127.329 +
 127.330 +    // Implementation of the Block Search pivot rule
 127.331 +    class BlockSearchPivotRule
 127.332 +    {
 127.333 +    private:
 127.334 +
 127.335 +      // References to the NetworkSimplex class
 127.336 +      const IntVector  &_source;
 127.337 +      const IntVector  &_target;
 127.338 +      const CostVector &_cost;
 127.339 +      const IntVector  &_state;
 127.340 +      const CostVector &_pi;
 127.341 +      int &_in_arc;
 127.342 +      int _search_arc_num;
 127.343 +
 127.344 +      // Pivot rule data
 127.345 +      int _block_size;
 127.346 +      int _next_arc;
 127.347 +
 127.348 +    public:
 127.349 +
 127.350 +      // Constructor
 127.351 +      BlockSearchPivotRule(NetworkSimplex &ns) :
 127.352 +        _source(ns._source), _target(ns._target),
 127.353 +        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
 127.354 +        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
 127.355 +        _next_arc(0)
 127.356 +      {
 127.357 +        // The main parameters of the pivot rule
 127.358 +        const double BLOCK_SIZE_FACTOR = 0.5;
 127.359 +        const int MIN_BLOCK_SIZE = 10;
 127.360 +
 127.361 +        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
 127.362 +                                    std::sqrt(double(_search_arc_num))),
 127.363 +                                MIN_BLOCK_SIZE );
 127.364 +      }
 127.365 +
 127.366 +      // Find next entering arc
 127.367 +      bool findEnteringArc() {
 127.368 +        Cost c, min = 0;
 127.369 +        int cnt = _block_size;
 127.370 +        int e;
 127.371 +        for (e = _next_arc; e < _search_arc_num; ++e) {
 127.372 +          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 127.373 +          if (c < min) {
 127.374 +            min = c;
 127.375 +            _in_arc = e;
 127.376 +          }
 127.377 +          if (--cnt == 0) {
 127.378 +            if (min < 0) goto search_end;
 127.379 +            cnt = _block_size;
 127.380 +          }
 127.381 +        }
 127.382 +        for (e = 0; e < _next_arc; ++e) {
 127.383 +          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 127.384 +          if (c < min) {
 127.385 +            min = c;
 127.386 +            _in_arc = e;
 127.387 +          }
 127.388 +          if (--cnt == 0) {
 127.389 +            if (min < 0) goto search_end;
 127.390 +            cnt = _block_size;
 127.391 +          }
 127.392 +        }
 127.393 +        if (min >= 0) return false;
 127.394 +
 127.395 +      search_end:
 127.396 +        _next_arc = e;
 127.397 +        return true;
 127.398 +      }
 127.399 +
 127.400 +    }; //class BlockSearchPivotRule
 127.401 +
 127.402 +
 127.403 +    // Implementation of the Candidate List pivot rule
 127.404 +    class CandidateListPivotRule
 127.405 +    {
 127.406 +    private:
 127.407 +
 127.408 +      // References to the NetworkSimplex class
 127.409 +      const IntVector  &_source;
 127.410 +      const IntVector  &_target;
 127.411 +      const CostVector &_cost;
 127.412 +      const IntVector  &_state;
 127.413 +      const CostVector &_pi;
 127.414 +      int &_in_arc;
 127.415 +      int _search_arc_num;
 127.416 +
 127.417 +      // Pivot rule data
 127.418 +      IntVector _candidates;
 127.419 +      int _list_length, _minor_limit;
 127.420 +      int _curr_length, _minor_count;
 127.421 +      int _next_arc;
 127.422 +
 127.423 +    public:
 127.424 +
 127.425 +      /// Constructor
 127.426 +      CandidateListPivotRule(NetworkSimplex &ns) :
 127.427 +        _source(ns._source), _target(ns._target),
 127.428 +        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
 127.429 +        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
 127.430 +        _next_arc(0)
 127.431 +      {
 127.432 +        // The main parameters of the pivot rule
 127.433 +        const double LIST_LENGTH_FACTOR = 0.25;
 127.434 +        const int MIN_LIST_LENGTH = 10;
 127.435 +        const double MINOR_LIMIT_FACTOR = 0.1;
 127.436 +        const int MIN_MINOR_LIMIT = 3;
 127.437 +
 127.438 +        _list_length = std::max( int(LIST_LENGTH_FACTOR *
 127.439 +                                     std::sqrt(double(_search_arc_num))),
 127.440 +                                 MIN_LIST_LENGTH );
 127.441 +        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
 127.442 +                                 MIN_MINOR_LIMIT );
 127.443 +        _curr_length = _minor_count = 0;
 127.444 +        _candidates.resize(_list_length);
 127.445 +      }
 127.446 +
 127.447 +      /// Find next entering arc
 127.448 +      bool findEnteringArc() {
 127.449 +        Cost min, c;
 127.450 +        int e;
 127.451 +        if (_curr_length > 0 && _minor_count < _minor_limit) {
 127.452 +          // Minor iteration: select the best eligible arc from the
 127.453 +          // current candidate list
 127.454 +          ++_minor_count;
 127.455 +          min = 0;
 127.456 +          for (int i = 0; i < _curr_length; ++i) {
 127.457 +            e = _candidates[i];
 127.458 +            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 127.459 +            if (c < min) {
 127.460 +              min = c;
 127.461 +              _in_arc = e;
 127.462 +            }
 127.463 +            else if (c >= 0) {
 127.464 +              _candidates[i--] = _candidates[--_curr_length];
 127.465 +            }
 127.466 +          }
 127.467 +          if (min < 0) return true;
 127.468 +        }
 127.469 +
 127.470 +        // Major iteration: build a new candidate list
 127.471 +        min = 0;
 127.472 +        _curr_length = 0;
 127.473 +        for (e = _next_arc; e < _search_arc_num; ++e) {
 127.474 +          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 127.475 +          if (c < 0) {
 127.476 +            _candidates[_curr_length++] = e;
 127.477 +            if (c < min) {
 127.478 +              min = c;
 127.479 +              _in_arc = e;
 127.480 +            }
 127.481 +            if (_curr_length == _list_length) goto search_end;
 127.482 +          }
 127.483 +        }
 127.484 +        for (e = 0; e < _next_arc; ++e) {
 127.485 +          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 127.486 +          if (c < 0) {
 127.487 +            _candidates[_curr_length++] = e;
 127.488 +            if (c < min) {
 127.489 +              min = c;
 127.490 +              _in_arc = e;
 127.491 +            }
 127.492 +            if (_curr_length == _list_length) goto search_end;
 127.493 +          }
 127.494 +        }
 127.495 +        if (_curr_length == 0) return false;
 127.496 +      
 127.497 +      search_end:        
 127.498 +        _minor_count = 1;
 127.499 +        _next_arc = e;
 127.500 +        return true;
 127.501 +      }
 127.502 +
 127.503 +    }; //class CandidateListPivotRule
 127.504 +
 127.505 +
 127.506 +    // Implementation of the Altering Candidate List pivot rule
 127.507 +    class AlteringListPivotRule
 127.508 +    {
 127.509 +    private:
 127.510 +
 127.511 +      // References to the NetworkSimplex class
 127.512 +      const IntVector  &_source;
 127.513 +      const IntVector  &_target;
 127.514 +      const CostVector &_cost;
 127.515 +      const IntVector  &_state;
 127.516 +      const CostVector &_pi;
 127.517 +      int &_in_arc;
 127.518 +      int _search_arc_num;
 127.519 +
 127.520 +      // Pivot rule data
 127.521 +      int _block_size, _head_length, _curr_length;
 127.522 +      int _next_arc;
 127.523 +      IntVector _candidates;
 127.524 +      CostVector _cand_cost;
 127.525 +
 127.526 +      // Functor class to compare arcs during sort of the candidate list
 127.527 +      class SortFunc
 127.528 +      {
 127.529 +      private:
 127.530 +        const CostVector &_map;
 127.531 +      public:
 127.532 +        SortFunc(const CostVector &map) : _map(map) {}
 127.533 +        bool operator()(int left, int right) {
 127.534 +          return _map[left] > _map[right];
 127.535 +        }
 127.536 +      };
 127.537 +
 127.538 +      SortFunc _sort_func;
 127.539 +
 127.540 +    public:
 127.541 +
 127.542 +      // Constructor
 127.543 +      AlteringListPivotRule(NetworkSimplex &ns) :
 127.544 +        _source(ns._source), _target(ns._target),
 127.545 +        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
 127.546 +        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
 127.547 +        _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
 127.548 +      {
 127.549 +        // The main parameters of the pivot rule
 127.550 +        const double BLOCK_SIZE_FACTOR = 1.0;
 127.551 +        const int MIN_BLOCK_SIZE = 10;
 127.552 +        const double HEAD_LENGTH_FACTOR = 0.1;
 127.553 +        const int MIN_HEAD_LENGTH = 3;
 127.554 +
 127.555 +        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
 127.556 +                                    std::sqrt(double(_search_arc_num))),
 127.557 +                                MIN_BLOCK_SIZE );
 127.558 +        _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
 127.559 +                                 MIN_HEAD_LENGTH );
 127.560 +        _candidates.resize(_head_length + _block_size);
 127.561 +        _curr_length = 0;
 127.562 +      }
 127.563 +
 127.564 +      // Find next entering arc
 127.565 +      bool findEnteringArc() {
 127.566 +        // Check the current candidate list
 127.567 +        int e;
 127.568 +        for (int i = 0; i < _curr_length; ++i) {
 127.569 +          e = _candidates[i];
 127.570 +          _cand_cost[e] = _state[e] *
 127.571 +            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 127.572 +          if (_cand_cost[e] >= 0) {
 127.573 +            _candidates[i--] = _candidates[--_curr_length];
 127.574 +          }
 127.575 +        }
 127.576 +
 127.577 +        // Extend the list
 127.578 +        int cnt = _block_size;
 127.579 +        int limit = _head_length;
 127.580 +
 127.581 +        for (e = _next_arc; e < _search_arc_num; ++e) {
 127.582 +          _cand_cost[e] = _state[e] *
 127.583 +            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 127.584 +          if (_cand_cost[e] < 0) {
 127.585 +            _candidates[_curr_length++] = e;
 127.586 +          }
 127.587 +          if (--cnt == 0) {
 127.588 +            if (_curr_length > limit) goto search_end;
 127.589 +            limit = 0;
 127.590 +            cnt = _block_size;
 127.591 +          }
 127.592 +        }
 127.593 +        for (e = 0; e < _next_arc; ++e) {
 127.594 +          _cand_cost[e] = _state[e] *
 127.595 +            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 127.596 +          if (_cand_cost[e] < 0) {
 127.597 +            _candidates[_curr_length++] = e;
 127.598 +          }
 127.599 +          if (--cnt == 0) {
 127.600 +            if (_curr_length > limit) goto search_end;
 127.601 +            limit = 0;
 127.602 +            cnt = _block_size;
 127.603 +          }
 127.604 +        }
 127.605 +        if (_curr_length == 0) return false;
 127.606 +        
 127.607 +      search_end:
 127.608 +
 127.609 +        // Make heap of the candidate list (approximating a partial sort)
 127.610 +        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
 127.611 +                   _sort_func );
 127.612 +
 127.613 +        // Pop the first element of the heap
 127.614 +        _in_arc = _candidates[0];
 127.615 +        _next_arc = e;
 127.616 +        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
 127.617 +                  _sort_func );
 127.618 +        _curr_length = std::min(_head_length, _curr_length - 1);
 127.619 +        return true;
 127.620 +      }
 127.621 +
 127.622 +    }; //class AlteringListPivotRule
 127.623 +
 127.624 +  public:
 127.625 +
 127.626 +    /// \brief Constructor.
 127.627 +    ///
 127.628 +    /// The constructor of the class.
 127.629 +    ///
 127.630 +    /// \param graph The digraph the algorithm runs on.
 127.631 +    /// \param arc_mixing Indicate if the arcs have to be stored in a
 127.632 +    /// mixed order in the internal data structure. 
 127.633 +    /// In special cases, it could lead to better overall performance,
 127.634 +    /// but it is usually slower. Therefore it is disabled by default.
 127.635 +    NetworkSimplex(const GR& graph, bool arc_mixing = false) :
 127.636 +      _graph(graph), _node_id(graph), _arc_id(graph),
 127.637 +      INF(std::numeric_limits<Value>::has_infinity ?
 127.638 +          std::numeric_limits<Value>::infinity() :
 127.639 +          std::numeric_limits<Value>::max())
 127.640 +    {
 127.641 +      // Check the value types
 127.642 +      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
 127.643 +        "The flow type of NetworkSimplex must be signed");
 127.644 +      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
 127.645 +        "The cost type of NetworkSimplex must be signed");
 127.646 +        
 127.647 +      // Resize vectors
 127.648 +      _node_num = countNodes(_graph);
 127.649 +      _arc_num = countArcs(_graph);
 127.650 +      int all_node_num = _node_num + 1;
 127.651 +      int max_arc_num = _arc_num + 2 * _node_num;
 127.652 +
 127.653 +      _source.resize(max_arc_num);
 127.654 +      _target.resize(max_arc_num);
 127.655 +
 127.656 +      _lower.resize(_arc_num);
 127.657 +      _upper.resize(_arc_num);
 127.658 +      _cap.resize(max_arc_num);
 127.659 +      _cost.resize(max_arc_num);
 127.660 +      _supply.resize(all_node_num);
 127.661 +      _flow.resize(max_arc_num);
 127.662 +      _pi.resize(all_node_num);
 127.663 +
 127.664 +      _parent.resize(all_node_num);
 127.665 +      _pred.resize(all_node_num);
 127.666 +      _forward.resize(all_node_num);
 127.667 +      _thread.resize(all_node_num);
 127.668 +      _rev_thread.resize(all_node_num);
 127.669 +      _succ_num.resize(all_node_num);
 127.670 +      _last_succ.resize(all_node_num);
 127.671 +      _state.resize(max_arc_num);
 127.672 +
 127.673 +      // Copy the graph
 127.674 +      int i = 0;
 127.675 +      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
 127.676 +        _node_id[n] = i;
 127.677 +      }
 127.678 +      if (arc_mixing) {
 127.679 +        // Store the arcs in a mixed order
 127.680 +        int k = std::max(int(std::sqrt(double(_arc_num))), 10);
 127.681 +        int i = 0, j = 0;
 127.682 +        for (ArcIt a(_graph); a != INVALID; ++a) {
 127.683 +          _arc_id[a] = i;
 127.684 +          _source[i] = _node_id[_graph.source(a)];
 127.685 +          _target[i] = _node_id[_graph.target(a)];
 127.686 +          if ((i += k) >= _arc_num) i = ++j;
 127.687 +        }
 127.688 +      } else {
 127.689 +        // Store the arcs in the original order
 127.690 +        int i = 0;
 127.691 +        for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
 127.692 +          _arc_id[a] = i;
 127.693 +          _source[i] = _node_id[_graph.source(a)];
 127.694 +          _target[i] = _node_id[_graph.target(a)];
 127.695 +        }
 127.696 +      }
 127.697 +      
 127.698 +      // Reset parameters
 127.699 +      reset();
 127.700 +    }
 127.701 +
 127.702 +    /// \name Parameters
 127.703 +    /// The parameters of the algorithm can be specified using these
 127.704 +    /// functions.
 127.705 +
 127.706 +    /// @{
 127.707 +
 127.708 +    /// \brief Set the lower bounds on the arcs.
 127.709 +    ///
 127.710 +    /// This function sets the lower bounds on the arcs.
 127.711 +    /// If it is not used before calling \ref run(), the lower bounds
 127.712 +    /// will be set to zero on all arcs.
 127.713 +    ///
 127.714 +    /// \param map An arc map storing the lower bounds.
 127.715 +    /// Its \c Value type must be convertible to the \c Value type
 127.716 +    /// of the algorithm.
 127.717 +    ///
 127.718 +    /// \return <tt>(*this)</tt>
 127.719 +    template <typename LowerMap>
 127.720 +    NetworkSimplex& lowerMap(const LowerMap& map) {
 127.721 +      _have_lower = true;
 127.722 +      for (ArcIt a(_graph); a != INVALID; ++a) {
 127.723 +        _lower[_arc_id[a]] = map[a];
 127.724 +      }
 127.725 +      return *this;
 127.726 +    }
 127.727 +
 127.728 +    /// \brief Set the upper bounds (capacities) on the arcs.
 127.729 +    ///
 127.730 +    /// This function sets the upper bounds (capacities) on the arcs.
 127.731 +    /// If it is not used before calling \ref run(), the upper bounds
 127.732 +    /// will be set to \ref INF on all arcs (i.e. the flow value will be
 127.733 +    /// unbounded from above on each arc).
 127.734 +    ///
 127.735 +    /// \param map An arc map storing the upper bounds.
 127.736 +    /// Its \c Value type must be convertible to the \c Value type
 127.737 +    /// of the algorithm.
 127.738 +    ///
 127.739 +    /// \return <tt>(*this)</tt>
 127.740 +    template<typename UpperMap>
 127.741 +    NetworkSimplex& upperMap(const UpperMap& map) {
 127.742 +      for (ArcIt a(_graph); a != INVALID; ++a) {
 127.743 +        _upper[_arc_id[a]] = map[a];
 127.744 +      }
 127.745 +      return *this;
 127.746 +    }
 127.747 +
 127.748 +    /// \brief Set the costs of the arcs.
 127.749 +    ///
 127.750 +    /// This function sets the costs of the arcs.
 127.751 +    /// If it is not used before calling \ref run(), the costs
 127.752 +    /// will be set to \c 1 on all arcs.
 127.753 +    ///
 127.754 +    /// \param map An arc map storing the costs.
 127.755 +    /// Its \c Value type must be convertible to the \c Cost type
 127.756 +    /// of the algorithm.
 127.757 +    ///
 127.758 +    /// \return <tt>(*this)</tt>
 127.759 +    template<typename CostMap>
 127.760 +    NetworkSimplex& costMap(const CostMap& map) {
 127.761 +      for (ArcIt a(_graph); a != INVALID; ++a) {
 127.762 +        _cost[_arc_id[a]] = map[a];
 127.763 +      }
 127.764 +      return *this;
 127.765 +    }
 127.766 +
 127.767 +    /// \brief Set the supply values of the nodes.
 127.768 +    ///
 127.769 +    /// This function sets the supply values of the nodes.
 127.770 +    /// If neither this function nor \ref stSupply() is used before
 127.771 +    /// calling \ref run(), the supply of each node will be set to zero.
 127.772 +    ///
 127.773 +    /// \param map A node map storing the supply values.
 127.774 +    /// Its \c Value type must be convertible to the \c Value type
 127.775 +    /// of the algorithm.
 127.776 +    ///
 127.777 +    /// \return <tt>(*this)</tt>
 127.778 +    template<typename SupplyMap>
 127.779 +    NetworkSimplex& supplyMap(const SupplyMap& map) {
 127.780 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 127.781 +        _supply[_node_id[n]] = map[n];
 127.782 +      }
 127.783 +      return *this;
 127.784 +    }
 127.785 +
 127.786 +    /// \brief Set single source and target nodes and a supply value.
 127.787 +    ///
 127.788 +    /// This function sets a single source node and a single target node
 127.789 +    /// and the required flow value.
 127.790 +    /// If neither this function nor \ref supplyMap() is used before
 127.791 +    /// calling \ref run(), the supply of each node will be set to zero.
 127.792 +    ///
 127.793 +    /// Using this function has the same effect as using \ref supplyMap()
 127.794 +    /// with such a map in which \c k is assigned to \c s, \c -k is
 127.795 +    /// assigned to \c t and all other nodes have zero supply value.
 127.796 +    ///
 127.797 +    /// \param s The source node.
 127.798 +    /// \param t The target node.
 127.799 +    /// \param k The required amount of flow from node \c s to node \c t
 127.800 +    /// (i.e. the supply of \c s and the demand of \c t).
 127.801 +    ///
 127.802 +    /// \return <tt>(*this)</tt>
 127.803 +    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
 127.804 +      for (int i = 0; i != _node_num; ++i) {
 127.805 +        _supply[i] = 0;
 127.806 +      }
 127.807 +      _supply[_node_id[s]] =  k;
 127.808 +      _supply[_node_id[t]] = -k;
 127.809 +      return *this;
 127.810 +    }
 127.811 +    
 127.812 +    /// \brief Set the type of the supply constraints.
 127.813 +    ///
 127.814 +    /// This function sets the type of the supply/demand constraints.
 127.815 +    /// If it is not used before calling \ref run(), the \ref GEQ supply
 127.816 +    /// type will be used.
 127.817 +    ///
 127.818 +    /// For more information see \ref SupplyType.
 127.819 +    ///
 127.820 +    /// \return <tt>(*this)</tt>
 127.821 +    NetworkSimplex& supplyType(SupplyType supply_type) {
 127.822 +      _stype = supply_type;
 127.823 +      return *this;
 127.824 +    }
 127.825 +
 127.826 +    /// @}
 127.827 +
 127.828 +    /// \name Execution Control
 127.829 +    /// The algorithm can be executed using \ref run().
 127.830 +
 127.831 +    /// @{
 127.832 +
 127.833 +    /// \brief Run the algorithm.
 127.834 +    ///
 127.835 +    /// This function runs the algorithm.
 127.836 +    /// The paramters can be specified using functions \ref lowerMap(),
 127.837 +    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), 
 127.838 +    /// \ref supplyType().
 127.839 +    /// For example,
 127.840 +    /// \code
 127.841 +    ///   NetworkSimplex<ListDigraph> ns(graph);
 127.842 +    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
 127.843 +    ///     .supplyMap(sup).run();
 127.844 +    /// \endcode
 127.845 +    ///
 127.846 +    /// This function can be called more than once. All the parameters
 127.847 +    /// that have been given are kept for the next call, unless
 127.848 +    /// \ref reset() is called, thus only the modified parameters
 127.849 +    /// have to be set again. See \ref reset() for examples.
 127.850 +    /// However the underlying digraph must not be modified after this
 127.851 +    /// class have been constructed, since it copies and extends the graph.
 127.852 +    ///
 127.853 +    /// \param pivot_rule The pivot rule that will be used during the
 127.854 +    /// algorithm. For more information see \ref PivotRule.
 127.855 +    ///
 127.856 +    /// \return \c INFEASIBLE if no feasible flow exists,
 127.857 +    /// \n \c OPTIMAL if the problem has optimal solution
 127.858 +    /// (i.e. it is feasible and bounded), and the algorithm has found
 127.859 +    /// optimal flow and node potentials (primal and dual solutions),
 127.860 +    /// \n \c UNBOUNDED if the objective function of the problem is
 127.861 +    /// unbounded, i.e. there is a directed cycle having negative total
 127.862 +    /// cost and infinite upper bound.
 127.863 +    ///
 127.864 +    /// \see ProblemType, PivotRule
 127.865 +    ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
 127.866 +      if (!init()) return INFEASIBLE;
 127.867 +      return start(pivot_rule);
 127.868 +    }
 127.869 +
 127.870 +    /// \brief Reset all the parameters that have been given before.
 127.871 +    ///
 127.872 +    /// This function resets all the paramaters that have been given
 127.873 +    /// before using functions \ref lowerMap(), \ref upperMap(),
 127.874 +    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
 127.875 +    ///
 127.876 +    /// It is useful for multiple run() calls. If this function is not
 127.877 +    /// used, all the parameters given before are kept for the next
 127.878 +    /// \ref run() call.
 127.879 +    /// However the underlying digraph must not be modified after this
 127.880 +    /// class have been constructed, since it copies and extends the graph.
 127.881 +    ///
 127.882 +    /// For example,
 127.883 +    /// \code
 127.884 +    ///   NetworkSimplex<ListDigraph> ns(graph);
 127.885 +    ///
 127.886 +    ///   // First run
 127.887 +    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
 127.888 +    ///     .supplyMap(sup).run();
 127.889 +    ///
 127.890 +    ///   // Run again with modified cost map (reset() is not called,
 127.891 +    ///   // so only the cost map have to be set again)
 127.892 +    ///   cost[e] += 100;
 127.893 +    ///   ns.costMap(cost).run();
 127.894 +    ///
 127.895 +    ///   // Run again from scratch using reset()
 127.896 +    ///   // (the lower bounds will be set to zero on all arcs)
 127.897 +    ///   ns.reset();
 127.898 +    ///   ns.upperMap(capacity).costMap(cost)
 127.899 +    ///     .supplyMap(sup).run();
 127.900 +    /// \endcode
 127.901 +    ///
 127.902 +    /// \return <tt>(*this)</tt>
 127.903 +    NetworkSimplex& reset() {
 127.904 +      for (int i = 0; i != _node_num; ++i) {
 127.905 +        _supply[i] = 0;
 127.906 +      }
 127.907 +      for (int i = 0; i != _arc_num; ++i) {
 127.908 +        _lower[i] = 0;
 127.909 +        _upper[i] = INF;
 127.910 +        _cost[i] = 1;
 127.911 +      }
 127.912 +      _have_lower = false;
 127.913 +      _stype = GEQ;
 127.914 +      return *this;
 127.915 +    }
 127.916 +
 127.917 +    /// @}
 127.918 +
 127.919 +    /// \name Query Functions
 127.920 +    /// The results of the algorithm can be obtained using these
 127.921 +    /// functions.\n
 127.922 +    /// The \ref run() function must be called before using them.
 127.923 +
 127.924 +    /// @{
 127.925 +
 127.926 +    /// \brief Return the total cost of the found flow.
 127.927 +    ///
 127.928 +    /// This function returns the total cost of the found flow.
 127.929 +    /// Its complexity is O(e).
 127.930 +    ///
 127.931 +    /// \note The return type of the function can be specified as a
 127.932 +    /// template parameter. For example,
 127.933 +    /// \code
 127.934 +    ///   ns.totalCost<double>();
 127.935 +    /// \endcode
 127.936 +    /// It is useful if the total cost cannot be stored in the \c Cost
 127.937 +    /// type of the algorithm, which is the default return type of the
 127.938 +    /// function.
 127.939 +    ///
 127.940 +    /// \pre \ref run() must be called before using this function.
 127.941 +    template <typename Number>
 127.942 +    Number totalCost() const {
 127.943 +      Number c = 0;
 127.944 +      for (ArcIt a(_graph); a != INVALID; ++a) {
 127.945 +        int i = _arc_id[a];
 127.946 +        c += Number(_flow[i]) * Number(_cost[i]);
 127.947 +      }
 127.948 +      return c;
 127.949 +    }
 127.950 +
 127.951 +#ifndef DOXYGEN
 127.952 +    Cost totalCost() const {
 127.953 +      return totalCost<Cost>();
 127.954 +    }
 127.955 +#endif
 127.956 +
 127.957 +    /// \brief Return the flow on the given arc.
 127.958 +    ///
 127.959 +    /// This function returns the flow on the given arc.
 127.960 +    ///
 127.961 +    /// \pre \ref run() must be called before using this function.
 127.962 +    Value flow(const Arc& a) const {
 127.963 +      return _flow[_arc_id[a]];
 127.964 +    }
 127.965 +
 127.966 +    /// \brief Return the flow map (the primal solution).
 127.967 +    ///
 127.968 +    /// This function copies the flow value on each arc into the given
 127.969 +    /// map. The \c Value type of the algorithm must be convertible to
 127.970 +    /// the \c Value type of the map.
 127.971 +    ///
 127.972 +    /// \pre \ref run() must be called before using this function.
 127.973 +    template <typename FlowMap>
 127.974 +    void flowMap(FlowMap &map) const {
 127.975 +      for (ArcIt a(_graph); a != INVALID; ++a) {
 127.976 +        map.set(a, _flow[_arc_id[a]]);
 127.977 +      }
 127.978 +    }
 127.979 +
 127.980 +    /// \brief Return the potential (dual value) of the given node.
 127.981 +    ///
 127.982 +    /// This function returns the potential (dual value) of the
 127.983 +    /// given node.
 127.984 +    ///
 127.985 +    /// \pre \ref run() must be called before using this function.
 127.986 +    Cost potential(const Node& n) const {
 127.987 +      return _pi[_node_id[n]];
 127.988 +    }
 127.989 +
 127.990 +    /// \brief Return the potential map (the dual solution).
 127.991 +    ///
 127.992 +    /// This function copies the potential (dual value) of each node
 127.993 +    /// into the given map.
 127.994 +    /// The \c Cost type of the algorithm must be convertible to the
 127.995 +    /// \c Value type of the map.
 127.996 +    ///
 127.997 +    /// \pre \ref run() must be called before using this function.
 127.998 +    template <typename PotentialMap>
 127.999 +    void potentialMap(PotentialMap &map) const {
127.1000 +      for (NodeIt n(_graph); n != INVALID; ++n) {
127.1001 +        map.set(n, _pi[_node_id[n]]);
127.1002 +      }
127.1003 +    }
127.1004 +
127.1005 +    /// @}
127.1006 +
127.1007 +  private:
127.1008 +
127.1009 +    // Initialize internal data structures
127.1010 +    bool init() {
127.1011 +      if (_node_num == 0) return false;
127.1012 +
127.1013 +      // Check the sum of supply values
127.1014 +      _sum_supply = 0;
127.1015 +      for (int i = 0; i != _node_num; ++i) {
127.1016 +        _sum_supply += _supply[i];
127.1017 +      }
127.1018 +      if ( !((_stype == GEQ && _sum_supply <= 0) ||
127.1019 +             (_stype == LEQ && _sum_supply >= 0)) ) return false;
127.1020 +
127.1021 +      // Remove non-zero lower bounds
127.1022 +      if (_have_lower) {
127.1023 +        for (int i = 0; i != _arc_num; ++i) {
127.1024 +          Value c = _lower[i];
127.1025 +          if (c >= 0) {
127.1026 +            _cap[i] = _upper[i] < INF ? _upper[i] - c : INF;
127.1027 +          } else {
127.1028 +            _cap[i] = _upper[i] < INF + c ? _upper[i] - c : INF;
127.1029 +          }
127.1030 +          _supply[_source[i]] -= c;
127.1031 +          _supply[_target[i]] += c;
127.1032 +        }
127.1033 +      } else {
127.1034 +        for (int i = 0; i != _arc_num; ++i) {
127.1035 +          _cap[i] = _upper[i];
127.1036 +        }
127.1037 +      }
127.1038 +
127.1039 +      // Initialize artifical cost
127.1040 +      Cost ART_COST;
127.1041 +      if (std::numeric_limits<Cost>::is_exact) {
127.1042 +        ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
127.1043 +      } else {
127.1044 +        ART_COST = std::numeric_limits<Cost>::min();
127.1045 +        for (int i = 0; i != _arc_num; ++i) {
127.1046 +          if (_cost[i] > ART_COST) ART_COST = _cost[i];
127.1047 +        }
127.1048 +        ART_COST = (ART_COST + 1) * _node_num;
127.1049 +      }
127.1050 +
127.1051 +      // Initialize arc maps
127.1052 +      for (int i = 0; i != _arc_num; ++i) {
127.1053 +        _flow[i] = 0;
127.1054 +        _state[i] = STATE_LOWER;
127.1055 +      }
127.1056 +      
127.1057 +      // Set data for the artificial root node
127.1058 +      _root = _node_num;
127.1059 +      _parent[_root] = -1;
127.1060 +      _pred[_root] = -1;
127.1061 +      _thread[_root] = 0;
127.1062 +      _rev_thread[0] = _root;
127.1063 +      _succ_num[_root] = _node_num + 1;
127.1064 +      _last_succ[_root] = _root - 1;
127.1065 +      _supply[_root] = -_sum_supply;
127.1066 +      _pi[_root] = 0;
127.1067 +
127.1068 +      // Add artificial arcs and initialize the spanning tree data structure
127.1069 +      if (_sum_supply == 0) {
127.1070 +        // EQ supply constraints
127.1071 +        _search_arc_num = _arc_num;
127.1072 +        _all_arc_num = _arc_num + _node_num;
127.1073 +        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
127.1074 +          _parent[u] = _root;
127.1075 +          _pred[u] = e;
127.1076 +          _thread[u] = u + 1;
127.1077 +          _rev_thread[u + 1] = u;
127.1078 +          _succ_num[u] = 1;
127.1079 +          _last_succ[u] = u;
127.1080 +          _cap[e] = INF;
127.1081 +          _state[e] = STATE_TREE;
127.1082 +          if (_supply[u] >= 0) {
127.1083 +            _forward[u] = true;
127.1084 +            _pi[u] = 0;
127.1085 +            _source[e] = u;
127.1086 +            _target[e] = _root;
127.1087 +            _flow[e] = _supply[u];
127.1088 +            _cost[e] = 0;
127.1089 +          } else {
127.1090 +            _forward[u] = false;
127.1091 +            _pi[u] = ART_COST;
127.1092 +            _source[e] = _root;
127.1093 +            _target[e] = u;
127.1094 +            _flow[e] = -_supply[u];
127.1095 +            _cost[e] = ART_COST;
127.1096 +          }
127.1097 +        }
127.1098 +      }
127.1099 +      else if (_sum_supply > 0) {
127.1100 +        // LEQ supply constraints
127.1101 +        _search_arc_num = _arc_num + _node_num;
127.1102 +        int f = _arc_num + _node_num;
127.1103 +        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
127.1104 +          _parent[u] = _root;
127.1105 +          _thread[u] = u + 1;
127.1106 +          _rev_thread[u + 1] = u;
127.1107 +          _succ_num[u] = 1;
127.1108 +          _last_succ[u] = u;
127.1109 +          if (_supply[u] >= 0) {
127.1110 +            _forward[u] = true;
127.1111 +            _pi[u] = 0;
127.1112 +            _pred[u] = e;
127.1113 +            _source[e] = u;
127.1114 +            _target[e] = _root;
127.1115 +            _cap[e] = INF;
127.1116 +            _flow[e] = _supply[u];
127.1117 +            _cost[e] = 0;
127.1118 +            _state[e] = STATE_TREE;
127.1119 +          } else {
127.1120 +            _forward[u] = false;
127.1121 +            _pi[u] = ART_COST;
127.1122 +            _pred[u] = f;
127.1123 +            _source[f] = _root;
127.1124 +            _target[f] = u;
127.1125 +            _cap[f] = INF;
127.1126 +            _flow[f] = -_supply[u];
127.1127 +            _cost[f] = ART_COST;
127.1128 +            _state[f] = STATE_TREE;
127.1129 +            _source[e] = u;
127.1130 +            _target[e] = _root;
127.1131 +            _cap[e] = INF;
127.1132 +            _flow[e] = 0;
127.1133 +            _cost[e] = 0;
127.1134 +            _state[e] = STATE_LOWER;
127.1135 +            ++f;
127.1136 +          }
127.1137 +        }
127.1138 +        _all_arc_num = f;
127.1139 +      }
127.1140 +      else {
127.1141 +        // GEQ supply constraints
127.1142 +        _search_arc_num = _arc_num + _node_num;
127.1143 +        int f = _arc_num + _node_num;
127.1144 +        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
127.1145 +          _parent[u] = _root;
127.1146 +          _thread[u] = u + 1;
127.1147 +          _rev_thread[u + 1] = u;
127.1148 +          _succ_num[u] = 1;
127.1149 +          _last_succ[u] = u;
127.1150 +          if (_supply[u] <= 0) {
127.1151 +            _forward[u] = false;
127.1152 +            _pi[u] = 0;
127.1153 +            _pred[u] = e;
127.1154 +            _source[e] = _root;
127.1155 +            _target[e] = u;
127.1156 +            _cap[e] = INF;
127.1157 +            _flow[e] = -_supply[u];
127.1158 +            _cost[e] = 0;
127.1159 +            _state[e] = STATE_TREE;
127.1160 +          } else {
127.1161 +            _forward[u] = true;
127.1162 +            _pi[u] = -ART_COST;
127.1163 +            _pred[u] = f;
127.1164 +            _source[f] = u;
127.1165 +            _target[f] = _root;
127.1166 +            _cap[f] = INF;
127.1167 +            _flow[f] = _supply[u];
127.1168 +            _state[f] = STATE_TREE;
127.1169 +            _cost[f] = ART_COST;
127.1170 +            _source[e] = _root;
127.1171 +            _target[e] = u;
127.1172 +            _cap[e] = INF;
127.1173 +            _flow[e] = 0;
127.1174 +            _cost[e] = 0;
127.1175 +            _state[e] = STATE_LOWER;
127.1176 +            ++f;
127.1177 +          }
127.1178 +        }
127.1179 +        _all_arc_num = f;
127.1180 +      }
127.1181 +
127.1182 +      return true;
127.1183 +    }
127.1184 +
127.1185 +    // Find the join node
127.1186 +    void findJoinNode() {
127.1187 +      int u = _source[in_arc];
127.1188 +      int v = _target[in_arc];
127.1189 +      while (u != v) {
127.1190 +        if (_succ_num[u] < _succ_num[v]) {
127.1191 +          u = _parent[u];
127.1192 +        } else {
127.1193 +          v = _parent[v];
127.1194 +        }
127.1195 +      }
127.1196 +      join = u;
127.1197 +    }
127.1198 +
127.1199 +    // Find the leaving arc of the cycle and returns true if the
127.1200 +    // leaving arc is not the same as the entering arc
127.1201 +    bool findLeavingArc() {
127.1202 +      // Initialize first and second nodes according to the direction
127.1203 +      // of the cycle
127.1204 +      if (_state[in_arc] == STATE_LOWER) {
127.1205 +        first  = _source[in_arc];
127.1206 +        second = _target[in_arc];
127.1207 +      } else {
127.1208 +        first  = _target[in_arc];
127.1209 +        second = _source[in_arc];
127.1210 +      }
127.1211 +      delta = _cap[in_arc];
127.1212 +      int result = 0;
127.1213 +      Value d;
127.1214 +      int e;
127.1215 +
127.1216 +      // Search the cycle along the path form the first node to the root
127.1217 +      for (int u = first; u != join; u = _parent[u]) {
127.1218 +        e = _pred[u];
127.1219 +        d = _forward[u] ?
127.1220 +          _flow[e] : (_cap[e] == INF ? INF : _cap[e] - _flow[e]);
127.1221 +        if (d < delta) {
127.1222 +          delta = d;
127.1223 +          u_out = u;
127.1224 +          result = 1;
127.1225 +        }
127.1226 +      }
127.1227 +      // Search the cycle along the path form the second node to the root
127.1228 +      for (int u = second; u != join; u = _parent[u]) {
127.1229 +        e = _pred[u];
127.1230 +        d = _forward[u] ? 
127.1231 +          (_cap[e] == INF ? INF : _cap[e] - _flow[e]) : _flow[e];
127.1232 +        if (d <= delta) {
127.1233 +          delta = d;
127.1234 +          u_out = u;
127.1235 +          result = 2;
127.1236 +        }
127.1237 +      }
127.1238 +
127.1239 +      if (result == 1) {
127.1240 +        u_in = first;
127.1241 +        v_in = second;
127.1242 +      } else {
127.1243 +        u_in = second;
127.1244 +        v_in = first;
127.1245 +      }
127.1246 +      return result != 0;
127.1247 +    }
127.1248 +
127.1249 +    // Change _flow and _state vectors
127.1250 +    void changeFlow(bool change) {
127.1251 +      // Augment along the cycle
127.1252 +      if (delta > 0) {
127.1253 +        Value val = _state[in_arc] * delta;
127.1254 +        _flow[in_arc] += val;
127.1255 +        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
127.1256 +          _flow[_pred[u]] += _forward[u] ? -val : val;
127.1257 +        }
127.1258 +        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
127.1259 +          _flow[_pred[u]] += _forward[u] ? val : -val;
127.1260 +        }
127.1261 +      }
127.1262 +      // Update the state of the entering and leaving arcs
127.1263 +      if (change) {
127.1264 +        _state[in_arc] = STATE_TREE;
127.1265 +        _state[_pred[u_out]] =
127.1266 +          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
127.1267 +      } else {
127.1268 +        _state[in_arc] = -_state[in_arc];
127.1269 +      }
127.1270 +    }
127.1271 +
127.1272 +    // Update the tree structure
127.1273 +    void updateTreeStructure() {
127.1274 +      int u, w;
127.1275 +      int old_rev_thread = _rev_thread[u_out];
127.1276 +      int old_succ_num = _succ_num[u_out];
127.1277 +      int old_last_succ = _last_succ[u_out];
127.1278 +      v_out = _parent[u_out];
127.1279 +
127.1280 +      u = _last_succ[u_in];  // the last successor of u_in
127.1281 +      right = _thread[u];    // the node after it
127.1282 +
127.1283 +      // Handle the case when old_rev_thread equals to v_in
127.1284 +      // (it also means that join and v_out coincide)
127.1285 +      if (old_rev_thread == v_in) {
127.1286 +        last = _thread[_last_succ[u_out]];
127.1287 +      } else {
127.1288 +        last = _thread[v_in];
127.1289 +      }
127.1290 +
127.1291 +      // Update _thread and _parent along the stem nodes (i.e. the nodes
127.1292 +      // between u_in and u_out, whose parent have to be changed)
127.1293 +      _thread[v_in] = stem = u_in;
127.1294 +      _dirty_revs.clear();
127.1295 +      _dirty_revs.push_back(v_in);
127.1296 +      par_stem = v_in;
127.1297 +      while (stem != u_out) {
127.1298 +        // Insert the next stem node into the thread list
127.1299 +        new_stem = _parent[stem];
127.1300 +        _thread[u] = new_stem;
127.1301 +        _dirty_revs.push_back(u);
127.1302 +
127.1303 +        // Remove the subtree of stem from the thread list
127.1304 +        w = _rev_thread[stem];
127.1305 +        _thread[w] = right;
127.1306 +        _rev_thread[right] = w;
127.1307 +
127.1308 +        // Change the parent node and shift stem nodes
127.1309 +        _parent[stem] = par_stem;
127.1310 +        par_stem = stem;
127.1311 +        stem = new_stem;
127.1312 +
127.1313 +        // Update u and right
127.1314 +        u = _last_succ[stem] == _last_succ[par_stem] ?
127.1315 +          _rev_thread[par_stem] : _last_succ[stem];
127.1316 +        right = _thread[u];
127.1317 +      }
127.1318 +      _parent[u_out] = par_stem;
127.1319 +      _thread[u] = last;
127.1320 +      _rev_thread[last] = u;
127.1321 +      _last_succ[u_out] = u;
127.1322 +
127.1323 +      // Remove the subtree of u_out from the thread list except for
127.1324 +      // the case when old_rev_thread equals to v_in
127.1325 +      // (it also means that join and v_out coincide)
127.1326 +      if (old_rev_thread != v_in) {
127.1327 +        _thread[old_rev_thread] = right;
127.1328 +        _rev_thread[right] = old_rev_thread;
127.1329 +      }
127.1330 +
127.1331 +      // Update _rev_thread using the new _thread values
127.1332 +      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
127.1333 +        u = _dirty_revs[i];
127.1334 +        _rev_thread[_thread[u]] = u;
127.1335 +      }
127.1336 +
127.1337 +      // Update _pred, _forward, _last_succ and _succ_num for the
127.1338 +      // stem nodes from u_out to u_in
127.1339 +      int tmp_sc = 0, tmp_ls = _last_succ[u_out];
127.1340 +      u = u_out;
127.1341 +      while (u != u_in) {
127.1342 +        w = _parent[u];
127.1343 +        _pred[u] = _pred[w];
127.1344 +        _forward[u] = !_forward[w];
127.1345 +        tmp_sc += _succ_num[u] - _succ_num[w];
127.1346 +        _succ_num[u] = tmp_sc;
127.1347 +        _last_succ[w] = tmp_ls;
127.1348 +        u = w;
127.1349 +      }
127.1350 +      _pred[u_in] = in_arc;
127.1351 +      _forward[u_in] = (u_in == _source[in_arc]);
127.1352 +      _succ_num[u_in] = old_succ_num;
127.1353 +
127.1354 +      // Set limits for updating _last_succ form v_in and v_out
127.1355 +      // towards the root
127.1356 +      int up_limit_in = -1;
127.1357 +      int up_limit_out = -1;
127.1358 +      if (_last_succ[join] == v_in) {
127.1359 +        up_limit_out = join;
127.1360 +      } else {
127.1361 +        up_limit_in = join;
127.1362 +      }
127.1363 +
127.1364 +      // Update _last_succ from v_in towards the root
127.1365 +      for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
127.1366 +           u = _parent[u]) {
127.1367 +        _last_succ[u] = _last_succ[u_out];
127.1368 +      }
127.1369 +      // Update _last_succ from v_out towards the root
127.1370 +      if (join != old_rev_thread && v_in != old_rev_thread) {
127.1371 +        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
127.1372 +             u = _parent[u]) {
127.1373 +          _last_succ[u] = old_rev_thread;
127.1374 +        }
127.1375 +      } else {
127.1376 +        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
127.1377 +             u = _parent[u]) {
127.1378 +          _last_succ[u] = _last_succ[u_out];
127.1379 +        }
127.1380 +      }
127.1381 +
127.1382 +      // Update _succ_num from v_in to join
127.1383 +      for (u = v_in; u != join; u = _parent[u]) {
127.1384 +        _succ_num[u] += old_succ_num;
127.1385 +      }
127.1386 +      // Update _succ_num from v_out to join
127.1387 +      for (u = v_out; u != join; u = _parent[u]) {
127.1388 +        _succ_num[u] -= old_succ_num;
127.1389 +      }
127.1390 +    }
127.1391 +
127.1392 +    // Update potentials
127.1393 +    void updatePotential() {
127.1394 +      Cost sigma = _forward[u_in] ?
127.1395 +        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
127.1396 +        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
127.1397 +      // Update potentials in the subtree, which has been moved
127.1398 +      int end = _thread[_last_succ[u_in]];
127.1399 +      for (int u = u_in; u != end; u = _thread[u]) {
127.1400 +        _pi[u] += sigma;
127.1401 +      }
127.1402 +    }
127.1403 +
127.1404 +    // Execute the algorithm
127.1405 +    ProblemType start(PivotRule pivot_rule) {
127.1406 +      // Select the pivot rule implementation
127.1407 +      switch (pivot_rule) {
127.1408 +        case FIRST_ELIGIBLE:
127.1409 +          return start<FirstEligiblePivotRule>();
127.1410 +        case BEST_ELIGIBLE:
127.1411 +          return start<BestEligiblePivotRule>();
127.1412 +        case BLOCK_SEARCH:
127.1413 +          return start<BlockSearchPivotRule>();
127.1414 +        case CANDIDATE_LIST:
127.1415 +          return start<CandidateListPivotRule>();
127.1416 +        case ALTERING_LIST:
127.1417 +          return start<AlteringListPivotRule>();
127.1418 +      }
127.1419 +      return INFEASIBLE; // avoid warning
127.1420 +    }
127.1421 +
127.1422 +    template <typename PivotRuleImpl>
127.1423 +    ProblemType start() {
127.1424 +      PivotRuleImpl pivot(*this);
127.1425 +
127.1426 +      // Execute the Network Simplex algorithm
127.1427 +      while (pivot.findEnteringArc()) {
127.1428 +        findJoinNode();
127.1429 +        bool change = findLeavingArc();
127.1430 +        if (delta >= INF) return UNBOUNDED;
127.1431 +        changeFlow(change);
127.1432 +        if (change) {
127.1433 +          updateTreeStructure();
127.1434 +          updatePotential();
127.1435 +        }
127.1436 +      }
127.1437 +      
127.1438 +      // Check feasibility
127.1439 +      for (int e = _search_arc_num; e != _all_arc_num; ++e) {
127.1440 +        if (_flow[e] != 0) return INFEASIBLE;
127.1441 +      }
127.1442 +
127.1443 +      // Transform the solution and the supply map to the original form
127.1444 +      if (_have_lower) {
127.1445 +        for (int i = 0; i != _arc_num; ++i) {
127.1446 +          Value c = _lower[i];
127.1447 +          if (c != 0) {
127.1448 +            _flow[i] += c;
127.1449 +            _supply[_source[i]] += c;
127.1450 +            _supply[_target[i]] -= c;
127.1451 +          }
127.1452 +        }
127.1453 +      }
127.1454 +      
127.1455 +      // Shift potentials to meet the requirements of the GEQ/LEQ type
127.1456 +      // optimality conditions
127.1457 +      if (_sum_supply == 0) {
127.1458 +        if (_stype == GEQ) {
127.1459 +          Cost max_pot = std::numeric_limits<Cost>::min();
127.1460 +          for (int i = 0; i != _node_num; ++i) {
127.1461 +            if (_pi[i] > max_pot) max_pot = _pi[i];
127.1462 +          }
127.1463 +          if (max_pot > 0) {
127.1464 +            for (int i = 0; i != _node_num; ++i)
127.1465 +              _pi[i] -= max_pot;
127.1466 +          }
127.1467 +        } else {
127.1468 +          Cost min_pot = std::numeric_limits<Cost>::max();
127.1469 +          for (int i = 0; i != _node_num; ++i) {
127.1470 +            if (_pi[i] < min_pot) min_pot = _pi[i];
127.1471 +          }
127.1472 +          if (min_pot < 0) {
127.1473 +            for (int i = 0; i != _node_num; ++i)
127.1474 +              _pi[i] -= min_pot;
127.1475 +          }
127.1476 +        }
127.1477 +      }
127.1478 +
127.1479 +      return OPTIMAL;
127.1480 +    }
127.1481 +
127.1482 +  }; //class NetworkSimplex
127.1483 +
127.1484 +  ///@}
127.1485 +
127.1486 +} //namespace lemon
127.1487 +
127.1488 +#endif //LEMON_NETWORK_SIMPLEX_H
   128.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   128.2 +++ b/lemon/pairing_heap.h	Thu Nov 05 15:50:01 2009 +0100
   128.3 @@ -0,0 +1,474 @@
   128.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   128.5 + *
   128.6 + * This file is a part of LEMON, a generic C++ optimization library.
   128.7 + *
   128.8 + * Copyright (C) 2003-2009
   128.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  128.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  128.11 + *
  128.12 + * Permission to use, modify and distribute this software is granted
  128.13 + * provided that this copyright notice appears in all copies. For
  128.14 + * precise terms see the accompanying LICENSE file.
  128.15 + *
  128.16 + * This software is provided "AS IS" with no warranty of any kind,
  128.17 + * express or implied, and with no claim as to its suitability for any
  128.18 + * purpose.
  128.19 + *
  128.20 + */
  128.21 +
  128.22 +#ifndef LEMON_PAIRING_HEAP_H
  128.23 +#define LEMON_PAIRING_HEAP_H
  128.24 +
  128.25 +///\file
  128.26 +///\ingroup heaps
  128.27 +///\brief Pairing heap implementation.
  128.28 +
  128.29 +#include <vector>
  128.30 +#include <utility>
  128.31 +#include <functional>
  128.32 +#include <lemon/math.h>
  128.33 +
  128.34 +namespace lemon {
  128.35 +
  128.36 +  /// \ingroup heaps
  128.37 +  ///
  128.38 +  ///\brief Pairing Heap.
  128.39 +  ///
  128.40 +  /// This class implements the \e pairing \e heap data structure.
  128.41 +  /// It fully conforms to the \ref concepts::Heap "heap concept".
  128.42 +  ///
  128.43 +  /// The methods \ref increase() and \ref erase() are not efficient
  128.44 +  /// in a pairing heap. In case of many calls of these operations,
  128.45 +  /// it is better to use other heap structure, e.g. \ref BinHeap
  128.46 +  /// "binary heap".
  128.47 +  ///
  128.48 +  /// \tparam PR Type of the priorities of the items.
  128.49 +  /// \tparam IM A read-writable item map with \c int values, used
  128.50 +  /// internally to handle the cross references.
  128.51 +  /// \tparam CMP A functor class for comparing the priorities.
  128.52 +  /// The default is \c std::less<PR>.
  128.53 +#ifdef DOXYGEN
  128.54 +  template <typename PR, typename IM, typename CMP>
  128.55 +#else
  128.56 +  template <typename PR, typename IM, typename CMP = std::less<PR> >
  128.57 +#endif
  128.58 +  class PairingHeap {
  128.59 +  public:
  128.60 +    /// Type of the item-int map.
  128.61 +    typedef IM ItemIntMap;
  128.62 +    /// Type of the priorities.
  128.63 +    typedef PR Prio;
  128.64 +    /// Type of the items stored in the heap.
  128.65 +    typedef typename ItemIntMap::Key Item;
  128.66 +    /// Functor type for comparing the priorities.
  128.67 +    typedef CMP Compare;
  128.68 +
  128.69 +    /// \brief Type to represent the states of the items.
  128.70 +    ///
  128.71 +    /// Each item has a state associated to it. It can be "in heap",
  128.72 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
  128.73 +    /// heap's point of view, but may be useful to the user.
  128.74 +    ///
  128.75 +    /// The item-int map must be initialized in such way that it assigns
  128.76 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
  128.77 +    enum State {
  128.78 +      IN_HEAP = 0,    ///< = 0.
  128.79 +      PRE_HEAP = -1,  ///< = -1.
  128.80 +      POST_HEAP = -2  ///< = -2.
  128.81 +    };
  128.82 +
  128.83 +  private:
  128.84 +    class store;
  128.85 +
  128.86 +    std::vector<store> _data;
  128.87 +    int _min;
  128.88 +    ItemIntMap &_iim;
  128.89 +    Compare _comp;
  128.90 +    int _num_items;
  128.91 +
  128.92 +  public:
  128.93 +    /// \brief Constructor.
  128.94 +    ///
  128.95 +    /// Constructor.
  128.96 +    /// \param map A map that assigns \c int values to the items.
  128.97 +    /// It is used internally to handle the cross references.
  128.98 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  128.99 +    explicit PairingHeap(ItemIntMap &map)
 128.100 +      : _min(0), _iim(map), _num_items(0) {}
 128.101 +
 128.102 +    /// \brief Constructor.
 128.103 +    ///
 128.104 +    /// Constructor.
 128.105 +    /// \param map A map that assigns \c int values to the items.
 128.106 +    /// It is used internally to handle the cross references.
 128.107 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
 128.108 +    /// \param comp The function object used for comparing the priorities.
 128.109 +    PairingHeap(ItemIntMap &map, const Compare &comp)
 128.110 +      : _min(0), _iim(map), _comp(comp), _num_items(0) {}
 128.111 +
 128.112 +    /// \brief The number of items stored in the heap.
 128.113 +    ///
 128.114 +    /// This function returns the number of items stored in the heap.
 128.115 +    int size() const { return _num_items; }
 128.116 +
 128.117 +    /// \brief Check if the heap is empty.
 128.118 +    ///
 128.119 +    /// This function returns \c true if the heap is empty.
 128.120 +    bool empty() const { return _num_items==0; }
 128.121 +
 128.122 +    /// \brief Make the heap empty.
 128.123 +    ///
 128.124 +    /// This functon makes the heap empty.
 128.125 +    /// It does not change the cross reference map. If you want to reuse
 128.126 +    /// a heap that is not surely empty, you should first clear it and
 128.127 +    /// then you should set the cross reference map to \c PRE_HEAP
 128.128 +    /// for each item.
 128.129 +    void clear() {
 128.130 +      _data.clear();
 128.131 +      _min = 0;
 128.132 +      _num_items = 0;
 128.133 +    }
 128.134 +
 128.135 +    /// \brief Set the priority of an item or insert it, if it is
 128.136 +    /// not stored in the heap.
 128.137 +    ///
 128.138 +    /// This method sets the priority of the given item if it is
 128.139 +    /// already stored in the heap. Otherwise it inserts the given
 128.140 +    /// item into the heap with the given priority.
 128.141 +    /// \param item The item.
 128.142 +    /// \param value The priority.
 128.143 +    void set (const Item& item, const Prio& value) {
 128.144 +      int i=_iim[item];
 128.145 +      if ( i>=0 && _data[i].in ) {
 128.146 +        if ( _comp(value, _data[i].prio) ) decrease(item, value);
 128.147 +        if ( _comp(_data[i].prio, value) ) increase(item, value);
 128.148 +      } else push(item, value);
 128.149 +    }
 128.150 +
 128.151 +    /// \brief Insert an item into the heap with the given priority.
 128.152 +    ///
 128.153 +    /// This function inserts the given item into the heap with the
 128.154 +    /// given priority.
 128.155 +    /// \param item The item to insert.
 128.156 +    /// \param value The priority of the item.
 128.157 +    /// \pre \e item must not be stored in the heap.
 128.158 +    void push (const Item& item, const Prio& value) {
 128.159 +      int i=_iim[item];
 128.160 +      if( i<0 ) {
 128.161 +        int s=_data.size();
 128.162 +        _iim.set(item, s);
 128.163 +        store st;
 128.164 +        st.name=item;
 128.165 +        _data.push_back(st);
 128.166 +        i=s;
 128.167 +      } else {
 128.168 +        _data[i].parent=_data[i].child=-1;
 128.169 +        _data[i].left_child=false;
 128.170 +        _data[i].degree=0;
 128.171 +        _data[i].in=true;
 128.172 +      }
 128.173 +
 128.174 +      _data[i].prio=value;
 128.175 +
 128.176 +      if ( _num_items!=0 ) {
 128.177 +        if ( _comp( value, _data[_min].prio) ) {
 128.178 +          fuse(i,_min);
 128.179 +          _min=i;
 128.180 +        }
 128.181 +        else fuse(_min,i);
 128.182 +      }
 128.183 +      else _min=i;
 128.184 +
 128.185 +      ++_num_items;
 128.186 +    }
 128.187 +
 128.188 +    /// \brief Return the item having minimum priority.
 128.189 +    ///
 128.190 +    /// This function returns the item having minimum priority.
 128.191 +    /// \pre The heap must be non-empty.
 128.192 +    Item top() const { return _data[_min].name; }
 128.193 +
 128.194 +    /// \brief The minimum priority.
 128.195 +    ///
 128.196 +    /// This function returns the minimum priority.
 128.197 +    /// \pre The heap must be non-empty.
 128.198 +    const Prio& prio() const { return _data[_min].prio; }
 128.199 +
 128.200 +    /// \brief The priority of the given item.
 128.201 +    ///
 128.202 +    /// This function returns the priority of the given item.
 128.203 +    /// \param item The item.
 128.204 +    /// \pre \e item must be in the heap.
 128.205 +    const Prio& operator[](const Item& item) const {
 128.206 +      return _data[_iim[item]].prio;
 128.207 +    }
 128.208 +
 128.209 +    /// \brief Remove the item having minimum priority.
 128.210 +    ///
 128.211 +    /// This function removes the item having minimum priority.
 128.212 +    /// \pre The heap must be non-empty.
 128.213 +    void pop() {
 128.214 +      std::vector<int> trees;
 128.215 +      int i=0, child_right = 0;
 128.216 +      _data[_min].in=false;
 128.217 +
 128.218 +      if( -1!=_data[_min].child ) {
 128.219 +        i=_data[_min].child;
 128.220 +        trees.push_back(i);
 128.221 +        _data[i].parent = -1;
 128.222 +        _data[_min].child = -1;
 128.223 +
 128.224 +        int ch=-1;
 128.225 +        while( _data[i].child!=-1 ) {
 128.226 +          ch=_data[i].child;
 128.227 +          if( _data[ch].left_child && i==_data[ch].parent ) {
 128.228 +            break;
 128.229 +          } else {
 128.230 +            if( _data[ch].left_child ) {
 128.231 +              child_right=_data[ch].parent;
 128.232 +              _data[ch].parent = i;
 128.233 +              --_data[i].degree;
 128.234 +            }
 128.235 +            else {
 128.236 +              child_right=ch;
 128.237 +              _data[i].child=-1;
 128.238 +              _data[i].degree=0;
 128.239 +            }
 128.240 +            _data[child_right].parent = -1;
 128.241 +            trees.push_back(child_right);
 128.242 +            i = child_right;
 128.243 +          }
 128.244 +        }
 128.245 +
 128.246 +        int num_child = trees.size();
 128.247 +        int other;
 128.248 +        for( i=0; i<num_child-1; i+=2 ) {
 128.249 +          if ( !_comp(_data[trees[i]].prio, _data[trees[i+1]].prio) ) {
 128.250 +            other=trees[i];
 128.251 +            trees[i]=trees[i+1];
 128.252 +            trees[i+1]=other;
 128.253 +          }
 128.254 +          fuse( trees[i], trees[i+1] );
 128.255 +        }
 128.256 +
 128.257 +        i = (0==(num_child % 2)) ? num_child-2 : num_child-1;
 128.258 +        while(i>=2) {
 128.259 +          if ( _comp(_data[trees[i]].prio, _data[trees[i-2]].prio) ) {
 128.260 +            other=trees[i];
 128.261 +            trees[i]=trees[i-2];
 128.262 +            trees[i-2]=other;
 128.263 +          }
 128.264 +          fuse( trees[i-2], trees[i] );
 128.265 +          i-=2;
 128.266 +        }
 128.267 +        _min = trees[0];
 128.268 +      }
 128.269 +      else {
 128.270 +        _min = _data[_min].child;
 128.271 +      }
 128.272 +
 128.273 +      if (_min >= 0) _data[_min].left_child = false;
 128.274 +      --_num_items;
 128.275 +    }
 128.276 +
 128.277 +    /// \brief Remove the given item from the heap.
 128.278 +    ///
 128.279 +    /// This function removes the given item from the heap if it is
 128.280 +    /// already stored.
 128.281 +    /// \param item The item to delete.
 128.282 +    /// \pre \e item must be in the heap.
 128.283 +    void erase (const Item& item) {
 128.284 +      int i=_iim[item];
 128.285 +      if ( i>=0 && _data[i].in ) {
 128.286 +        decrease( item, _data[_min].prio-1 );
 128.287 +        pop();
 128.288 +      }
 128.289 +    }
 128.290 +
 128.291 +    /// \brief Decrease the priority of an item to the given value.
 128.292 +    ///
 128.293 +    /// This function decreases the priority of an item to the given value.
 128.294 +    /// \param item The item.
 128.295 +    /// \param value The priority.
 128.296 +    /// \pre \e item must be stored in the heap with priority at least \e value.
 128.297 +    void decrease (Item item, const Prio& value) {
 128.298 +      int i=_iim[item];
 128.299 +      _data[i].prio=value;
 128.300 +      int p=_data[i].parent;
 128.301 +
 128.302 +      if( _data[i].left_child && i!=_data[p].child ) {
 128.303 +        p=_data[p].parent;
 128.304 +      }
 128.305 +
 128.306 +      if ( p!=-1 && _comp(value,_data[p].prio) ) {
 128.307 +        cut(i,p);
 128.308 +        if ( _comp(_data[_min].prio,value) ) {
 128.309 +          fuse(_min,i);
 128.310 +        } else {
 128.311 +          fuse(i,_min);
 128.312 +          _min=i;
 128.313 +        }
 128.314 +      }
 128.315 +    }
 128.316 +
 128.317 +    /// \brief Increase the priority of an item to the given value.
 128.318 +    ///
 128.319 +    /// This function increases the priority of an item to the given value.
 128.320 +    /// \param item The item.
 128.321 +    /// \param value The priority.
 128.322 +    /// \pre \e item must be stored in the heap with priority at most \e value.
 128.323 +    void increase (Item item, const Prio& value) {
 128.324 +      erase(item);
 128.325 +      push(item,value);
 128.326 +    }
 128.327 +
 128.328 +    /// \brief Return the state of an item.
 128.329 +    ///
 128.330 +    /// This method returns \c PRE_HEAP if the given item has never
 128.331 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
 128.332 +    /// and \c POST_HEAP otherwise.
 128.333 +    /// In the latter case it is possible that the item will get back
 128.334 +    /// to the heap again.
 128.335 +    /// \param item The item.
 128.336 +    State state(const Item &item) const {
 128.337 +      int i=_iim[item];
 128.338 +      if( i>=0 ) {
 128.339 +        if( _data[i].in ) i=0;
 128.340 +        else i=-2;
 128.341 +      }
 128.342 +      return State(i);
 128.343 +    }
 128.344 +
 128.345 +    /// \brief Set the state of an item in the heap.
 128.346 +    ///
 128.347 +    /// This function sets the state of the given item in the heap.
 128.348 +    /// It can be used to manually clear the heap when it is important
 128.349 +    /// to achive better time complexity.
 128.350 +    /// \param i The item.
 128.351 +    /// \param st The state. It should not be \c IN_HEAP.
 128.352 +    void state(const Item& i, State st) {
 128.353 +      switch (st) {
 128.354 +      case POST_HEAP:
 128.355 +      case PRE_HEAP:
 128.356 +        if (state(i) == IN_HEAP) erase(i);
 128.357 +        _iim[i]=st;
 128.358 +        break;
 128.359 +      case IN_HEAP:
 128.360 +        break;
 128.361 +      }
 128.362 +    }
 128.363 +
 128.364 +  private:
 128.365 +
 128.366 +    void cut(int a, int b) {
 128.367 +      int child_a;
 128.368 +      switch (_data[a].degree) {
 128.369 +        case 2:
 128.370 +          child_a = _data[_data[a].child].parent;
 128.371 +          if( _data[a].left_child ) {
 128.372 +            _data[child_a].left_child=true;
 128.373 +            _data[b].child=child_a;
 128.374 +            _data[child_a].parent=_data[a].parent;
 128.375 +          }
 128.376 +          else {
 128.377 +            _data[child_a].left_child=false;
 128.378 +            _data[child_a].parent=b;
 128.379 +            if( a!=_data[b].child )
 128.380 +              _data[_data[b].child].parent=child_a;
 128.381 +            else
 128.382 +              _data[b].child=child_a;
 128.383 +          }
 128.384 +          --_data[a].degree;
 128.385 +          _data[_data[a].child].parent=a;
 128.386 +          break;
 128.387 +
 128.388 +        case 1:
 128.389 +          child_a = _data[a].child;
 128.390 +          if( !_data[child_a].left_child ) {
 128.391 +            --_data[a].degree;
 128.392 +            if( _data[a].left_child ) {
 128.393 +              _data[child_a].left_child=true;
 128.394 +              _data[child_a].parent=_data[a].parent;
 128.395 +              _data[b].child=child_a;
 128.396 +            }
 128.397 +            else {
 128.398 +              _data[child_a].left_child=false;
 128.399 +              _data[child_a].parent=b;
 128.400 +              if( a!=_data[b].child )
 128.401 +                _data[_data[b].child].parent=child_a;
 128.402 +              else
 128.403 +                _data[b].child=child_a;
 128.404 +            }
 128.405 +            _data[a].child=-1;
 128.406 +          }
 128.407 +          else {
 128.408 +            --_data[b].degree;
 128.409 +            if( _data[a].left_child ) {
 128.410 +              _data[b].child =
 128.411 +                (1==_data[b].degree) ? _data[a].parent : -1;
 128.412 +            } else {
 128.413 +              if (1==_data[b].degree)
 128.414 +                _data[_data[b].child].parent=b;
 128.415 +              else
 128.416 +                _data[b].child=-1;
 128.417 +            }
 128.418 +          }
 128.419 +          break;
 128.420 +
 128.421 +        case 0:
 128.422 +          --_data[b].degree;
 128.423 +          if( _data[a].left_child ) {
 128.424 +            _data[b].child =
 128.425 +              (0!=_data[b].degree) ? _data[a].parent : -1;
 128.426 +          } else {
 128.427 +            if( 0!=_data[b].degree )
 128.428 +              _data[_data[b].child].parent=b;
 128.429 +            else
 128.430 +              _data[b].child=-1;
 128.431 +          }
 128.432 +          break;
 128.433 +      }
 128.434 +      _data[a].parent=-1;
 128.435 +      _data[a].left_child=false;
 128.436 +    }
 128.437 +
 128.438 +    void fuse(int a, int b) {
 128.439 +      int child_a = _data[a].child;
 128.440 +      int child_b = _data[b].child;
 128.441 +      _data[a].child=b;
 128.442 +      _data[b].parent=a;
 128.443 +      _data[b].left_child=true;
 128.444 +
 128.445 +      if( -1!=child_a ) {
 128.446 +        _data[b].child=child_a;
 128.447 +        _data[child_a].parent=b;
 128.448 +        _data[child_a].left_child=false;
 128.449 +        ++_data[b].degree;
 128.450 +
 128.451 +        if( -1!=child_b ) {
 128.452 +           _data[b].child=child_b;
 128.453 +           _data[child_b].parent=child_a;
 128.454 +        }
 128.455 +      }
 128.456 +      else { ++_data[a].degree; }
 128.457 +    }
 128.458 +
 128.459 +    class store {
 128.460 +      friend class PairingHeap;
 128.461 +
 128.462 +      Item name;
 128.463 +      int parent;
 128.464 +      int child;
 128.465 +      bool left_child;
 128.466 +      int degree;
 128.467 +      bool in;
 128.468 +      Prio prio;
 128.469 +
 128.470 +      store() : parent(-1), child(-1), left_child(false), degree(0), in(true) {}
 128.471 +    };
 128.472 +  };
 128.473 +
 128.474 +} //namespace lemon
 128.475 +
 128.476 +#endif //LEMON_PAIRING_HEAP_H
 128.477 +
   129.1 --- a/lemon/path.h	Fri Oct 16 10:21:37 2009 +0200
   129.2 +++ b/lemon/path.h	Thu Nov 05 15:50:01 2009 +0100
   129.3 @@ -2,7 +2,7 @@
   129.4   *
   129.5   * This file is a part of LEMON, a generic C++ optimization library.
   129.6   *
   129.7 - * Copyright (C) 2003-2008
   129.8 + * Copyright (C) 2003-2009
   129.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  129.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  129.11   *
  129.12 @@ -40,7 +40,7 @@
  129.13    /// \brief A structure for representing directed paths in a digraph.
  129.14    ///
  129.15    /// A structure for representing directed path in a digraph.
  129.16 -  /// \tparam _Digraph The digraph type in which the path is.
  129.17 +  /// \tparam GR The digraph type in which the path is.
  129.18    ///
  129.19    /// In a sense, the path can be treated as a list of arcs. The
  129.20    /// lemon path type stores just this list. As a consequence, it
  129.21 @@ -52,11 +52,11 @@
  129.22    /// insertion and erase is done in O(1) (amortized) time. The
  129.23    /// implementation uses two vectors for storing the front and back
  129.24    /// insertions.
  129.25 -  template <typename _Digraph>
  129.26 +  template <typename GR>
  129.27    class Path {
  129.28    public:
  129.29  
  129.30 -    typedef _Digraph Digraph;
  129.31 +    typedef GR Digraph;
  129.32      typedef typename Digraph::Arc Arc;
  129.33  
  129.34      /// \brief Default constructor
  129.35 @@ -137,7 +137,7 @@
  129.36  
  129.37      /// \brief The nth arc.
  129.38      ///
  129.39 -    /// \pre n is in the [0..length() - 1] range
  129.40 +    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
  129.41      const Arc& nth(int n) const {
  129.42        return n < int(head.size()) ? *(head.rbegin() + n) :
  129.43          *(tail.begin() + (n - head.size()));
  129.44 @@ -145,7 +145,7 @@
  129.45  
  129.46      /// \brief Initialize arc iterator to point to the nth arc
  129.47      ///
  129.48 -    /// \pre n is in the [0..length() - 1] range
  129.49 +    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
  129.50      ArcIt nthIt(int n) const {
  129.51        return ArcIt(*this, n);
  129.52      }
  129.53 @@ -228,7 +228,7 @@
  129.54    /// \brief A structure for representing directed paths in a digraph.
  129.55    ///
  129.56    /// A structure for representing directed path in a digraph.
  129.57 -  /// \tparam _Digraph The digraph type in which the path is.
  129.58 +  /// \tparam GR The digraph type in which the path is.
  129.59    ///
  129.60    /// In a sense, the path can be treated as a list of arcs. The
  129.61    /// lemon path type stores just this list. As a consequence it
  129.62 @@ -240,11 +240,11 @@
  129.63    /// erasure is amortized O(1) time. This implementation is faster
  129.64    /// then the \c Path type because it use just one vector for the
  129.65    /// arcs.
  129.66 -  template <typename _Digraph>
  129.67 +  template <typename GR>
  129.68    class SimplePath {
  129.69    public:
  129.70  
  129.71 -    typedef _Digraph Digraph;
  129.72 +    typedef GR Digraph;
  129.73      typedef typename Digraph::Arc Arc;
  129.74  
  129.75      /// \brief Default constructor
  129.76 @@ -329,7 +329,7 @@
  129.77  
  129.78      /// \brief The nth arc.
  129.79      ///
  129.80 -    /// \pre n is in the [0..length() - 1] range
  129.81 +    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
  129.82      const Arc& nth(int n) const {
  129.83        return data[n];
  129.84      }
  129.85 @@ -392,7 +392,7 @@
  129.86    /// \brief A structure for representing directed paths in a digraph.
  129.87    ///
  129.88    /// A structure for representing directed path in a digraph.
  129.89 -  /// \tparam _Digraph The digraph type in which the path is.
  129.90 +  /// \tparam GR The digraph type in which the path is.
  129.91    ///
  129.92    /// In a sense, the path can be treated as a list of arcs. The
  129.93    /// lemon path type stores just this list. As a consequence it
  129.94 @@ -404,11 +404,11 @@
  129.95    /// of the arc in the path. The length can be computed in O(n)
  129.96    /// time. The front and back insertion and erasure is O(1) time
  129.97    /// and it can be splited and spliced in O(1) time.
  129.98 -  template <typename _Digraph>
  129.99 +  template <typename GR>
 129.100    class ListPath {
 129.101    public:
 129.102  
 129.103 -    typedef _Digraph Digraph;
 129.104 +    typedef GR Digraph;
 129.105      typedef typename Digraph::Arc Arc;
 129.106  
 129.107    protected:
 129.108 @@ -507,7 +507,7 @@
 129.109      /// \brief The nth arc.
 129.110      ///
 129.111      /// This function looks for the nth arc in O(n) time.
 129.112 -    /// \pre n is in the [0..length() - 1] range
 129.113 +    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
 129.114      const Arc& nth(int n) const {
 129.115        Node *node = first;
 129.116        for (int i = 0; i < n; ++i) {
 129.117 @@ -732,7 +732,7 @@
 129.118    /// \brief A structure for representing directed paths in a digraph.
 129.119    ///
 129.120    /// A structure for representing directed path in a digraph.
 129.121 -  /// \tparam _Digraph The digraph type in which the path is.
 129.122 +  /// \tparam GR The digraph type in which the path is.
 129.123    ///
 129.124    /// In a sense, the path can be treated as a list of arcs. The
 129.125    /// lemon path type stores just this list. As a consequence it
 129.126 @@ -746,11 +746,11 @@
 129.127    /// Being the the most memory efficient path type in LEMON,
 129.128    /// it is intented to be
 129.129    /// used when you want to store a large number of paths.
 129.130 -  template <typename _Digraph>
 129.131 +  template <typename GR>
 129.132    class StaticPath {
 129.133    public:
 129.134  
 129.135 -    typedef _Digraph Digraph;
 129.136 +    typedef GR Digraph;
 129.137      typedef typename Digraph::Arc Arc;
 129.138  
 129.139      /// \brief Default constructor
 129.140 @@ -833,7 +833,7 @@
 129.141  
 129.142      /// \brief The nth arc.
 129.143      ///
 129.144 -    /// \pre n is in the [0..length() - 1] range
 129.145 +    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
 129.146      const Arc& nth(int n) const {
 129.147        return arcs[n];
 129.148      }
   130.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   130.2 +++ b/lemon/preflow.h	Thu Nov 05 15:50:01 2009 +0100
   130.3 @@ -0,0 +1,975 @@
   130.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   130.5 + *
   130.6 + * This file is a part of LEMON, a generic C++ optimization library.
   130.7 + *
   130.8 + * Copyright (C) 2003-2009
   130.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  130.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  130.11 + *
  130.12 + * Permission to use, modify and distribute this software is granted
  130.13 + * provided that this copyright notice appears in all copies. For
  130.14 + * precise terms see the accompanying LICENSE file.
  130.15 + *
  130.16 + * This software is provided "AS IS" with no warranty of any kind,
  130.17 + * express or implied, and with no claim as to its suitability for any
  130.18 + * purpose.
  130.19 + *
  130.20 + */
  130.21 +
  130.22 +#ifndef LEMON_PREFLOW_H
  130.23 +#define LEMON_PREFLOW_H
  130.24 +
  130.25 +#include <lemon/tolerance.h>
  130.26 +#include <lemon/elevator.h>
  130.27 +
  130.28 +/// \file
  130.29 +/// \ingroup max_flow
  130.30 +/// \brief Implementation of the preflow algorithm.
  130.31 +
  130.32 +namespace lemon {
  130.33 +
  130.34 +  /// \brief Default traits class of Preflow class.
  130.35 +  ///
  130.36 +  /// Default traits class of Preflow class.
  130.37 +  /// \tparam GR Digraph type.
  130.38 +  /// \tparam CAP Capacity map type.
  130.39 +  template <typename GR, typename CAP>
  130.40 +  struct PreflowDefaultTraits {
  130.41 +
  130.42 +    /// \brief The type of the digraph the algorithm runs on.
  130.43 +    typedef GR Digraph;
  130.44 +
  130.45 +    /// \brief The type of the map that stores the arc capacities.
  130.46 +    ///
  130.47 +    /// The type of the map that stores the arc capacities.
  130.48 +    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
  130.49 +    typedef CAP CapacityMap;
  130.50 +
  130.51 +    /// \brief The type of the flow values.
  130.52 +    typedef typename CapacityMap::Value Value;
  130.53 +
  130.54 +    /// \brief The type of the map that stores the flow values.
  130.55 +    ///
  130.56 +    /// The type of the map that stores the flow values.
  130.57 +    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  130.58 +#ifdef DOXYGEN
  130.59 +    typedef GR::ArcMap<Value> FlowMap;
  130.60 +#else
  130.61 +    typedef typename Digraph::template ArcMap<Value> FlowMap;
  130.62 +#endif
  130.63 +
  130.64 +    /// \brief Instantiates a FlowMap.
  130.65 +    ///
  130.66 +    /// This function instantiates a \ref FlowMap.
  130.67 +    /// \param digraph The digraph for which we would like to define
  130.68 +    /// the flow map.
  130.69 +    static FlowMap* createFlowMap(const Digraph& digraph) {
  130.70 +      return new FlowMap(digraph);
  130.71 +    }
  130.72 +
  130.73 +    /// \brief The elevator type used by Preflow algorithm.
  130.74 +    ///
  130.75 +    /// The elevator type used by Preflow algorithm.
  130.76 +    ///
  130.77 +    /// \sa Elevator, LinkedElevator
  130.78 +#ifdef DOXYGEN
  130.79 +    typedef lemon::Elevator<GR, GR::Node> Elevator;
  130.80 +#else
  130.81 +    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
  130.82 +#endif
  130.83 +
  130.84 +    /// \brief Instantiates an Elevator.
  130.85 +    ///
  130.86 +    /// This function instantiates an \ref Elevator.
  130.87 +    /// \param digraph The digraph for which we would like to define
  130.88 +    /// the elevator.
  130.89 +    /// \param max_level The maximum level of the elevator.
  130.90 +    static Elevator* createElevator(const Digraph& digraph, int max_level) {
  130.91 +      return new Elevator(digraph, max_level);
  130.92 +    }
  130.93 +
  130.94 +    /// \brief The tolerance used by the algorithm
  130.95 +    ///
  130.96 +    /// The tolerance used by the algorithm to handle inexact computation.
  130.97 +    typedef lemon::Tolerance<Value> Tolerance;
  130.98 +
  130.99 +  };
 130.100 +
 130.101 +
 130.102 +  /// \ingroup max_flow
 130.103 +  ///
 130.104 +  /// \brief %Preflow algorithm class.
 130.105 +  ///
 130.106 +  /// This class provides an implementation of Goldberg-Tarjan's \e preflow
 130.107 +  /// \e push-relabel algorithm producing a \ref max_flow
 130.108 +  /// "flow of maximum value" in a digraph \ref clrs01algorithms,
 130.109 +  /// \ref amo93networkflows, \ref goldberg88newapproach.
 130.110 +  /// The preflow algorithms are the fastest known maximum
 130.111 +  /// flow algorithms. The current implementation uses a mixture of the
 130.112 +  /// \e "highest label" and the \e "bound decrease" heuristics.
 130.113 +  /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
 130.114 +  ///
 130.115 +  /// The algorithm consists of two phases. After the first phase
 130.116 +  /// the maximum flow value and the minimum cut is obtained. The
 130.117 +  /// second phase constructs a feasible maximum flow on each arc.
 130.118 +  ///
 130.119 +  /// \tparam GR The type of the digraph the algorithm runs on.
 130.120 +  /// \tparam CAP The type of the capacity map. The default map
 130.121 +  /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
 130.122 +#ifdef DOXYGEN
 130.123 +  template <typename GR, typename CAP, typename TR>
 130.124 +#else
 130.125 +  template <typename GR,
 130.126 +            typename CAP = typename GR::template ArcMap<int>,
 130.127 +            typename TR = PreflowDefaultTraits<GR, CAP> >
 130.128 +#endif
 130.129 +  class Preflow {
 130.130 +  public:
 130.131 +
 130.132 +    ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
 130.133 +    typedef TR Traits;
 130.134 +    ///The type of the digraph the algorithm runs on.
 130.135 +    typedef typename Traits::Digraph Digraph;
 130.136 +    ///The type of the capacity map.
 130.137 +    typedef typename Traits::CapacityMap CapacityMap;
 130.138 +    ///The type of the flow values.
 130.139 +    typedef typename Traits::Value Value;
 130.140 +
 130.141 +    ///The type of the flow map.
 130.142 +    typedef typename Traits::FlowMap FlowMap;
 130.143 +    ///The type of the elevator.
 130.144 +    typedef typename Traits::Elevator Elevator;
 130.145 +    ///The type of the tolerance.
 130.146 +    typedef typename Traits::Tolerance Tolerance;
 130.147 +
 130.148 +  private:
 130.149 +
 130.150 +    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 130.151 +
 130.152 +    const Digraph& _graph;
 130.153 +    const CapacityMap* _capacity;
 130.154 +
 130.155 +    int _node_num;
 130.156 +
 130.157 +    Node _source, _target;
 130.158 +
 130.159 +    FlowMap* _flow;
 130.160 +    bool _local_flow;
 130.161 +
 130.162 +    Elevator* _level;
 130.163 +    bool _local_level;
 130.164 +
 130.165 +    typedef typename Digraph::template NodeMap<Value> ExcessMap;
 130.166 +    ExcessMap* _excess;
 130.167 +
 130.168 +    Tolerance _tolerance;
 130.169 +
 130.170 +    bool _phase;
 130.171 +
 130.172 +
 130.173 +    void createStructures() {
 130.174 +      _node_num = countNodes(_graph);
 130.175 +
 130.176 +      if (!_flow) {
 130.177 +        _flow = Traits::createFlowMap(_graph);
 130.178 +        _local_flow = true;
 130.179 +      }
 130.180 +      if (!_level) {
 130.181 +        _level = Traits::createElevator(_graph, _node_num);
 130.182 +        _local_level = true;
 130.183 +      }
 130.184 +      if (!_excess) {
 130.185 +        _excess = new ExcessMap(_graph);
 130.186 +      }
 130.187 +    }
 130.188 +
 130.189 +    void destroyStructures() {
 130.190 +      if (_local_flow) {
 130.191 +        delete _flow;
 130.192 +      }
 130.193 +      if (_local_level) {
 130.194 +        delete _level;
 130.195 +      }
 130.196 +      if (_excess) {
 130.197 +        delete _excess;
 130.198 +      }
 130.199 +    }
 130.200 +
 130.201 +  public:
 130.202 +
 130.203 +    typedef Preflow Create;
 130.204 +
 130.205 +    ///\name Named Template Parameters
 130.206 +
 130.207 +    ///@{
 130.208 +
 130.209 +    template <typename T>
 130.210 +    struct SetFlowMapTraits : public Traits {
 130.211 +      typedef T FlowMap;
 130.212 +      static FlowMap *createFlowMap(const Digraph&) {
 130.213 +        LEMON_ASSERT(false, "FlowMap is not initialized");
 130.214 +        return 0; // ignore warnings
 130.215 +      }
 130.216 +    };
 130.217 +
 130.218 +    /// \brief \ref named-templ-param "Named parameter" for setting
 130.219 +    /// FlowMap type
 130.220 +    ///
 130.221 +    /// \ref named-templ-param "Named parameter" for setting FlowMap
 130.222 +    /// type.
 130.223 +    template <typename T>
 130.224 +    struct SetFlowMap
 130.225 +      : public Preflow<Digraph, CapacityMap, SetFlowMapTraits<T> > {
 130.226 +      typedef Preflow<Digraph, CapacityMap,
 130.227 +                      SetFlowMapTraits<T> > Create;
 130.228 +    };
 130.229 +
 130.230 +    template <typename T>
 130.231 +    struct SetElevatorTraits : public Traits {
 130.232 +      typedef T Elevator;
 130.233 +      static Elevator *createElevator(const Digraph&, int) {
 130.234 +        LEMON_ASSERT(false, "Elevator is not initialized");
 130.235 +        return 0; // ignore warnings
 130.236 +      }
 130.237 +    };
 130.238 +
 130.239 +    /// \brief \ref named-templ-param "Named parameter" for setting
 130.240 +    /// Elevator type
 130.241 +    ///
 130.242 +    /// \ref named-templ-param "Named parameter" for setting Elevator
 130.243 +    /// type. If this named parameter is used, then an external
 130.244 +    /// elevator object must be passed to the algorithm using the
 130.245 +    /// \ref elevator(Elevator&) "elevator()" function before calling
 130.246 +    /// \ref run() or \ref init().
 130.247 +    /// \sa SetStandardElevator
 130.248 +    template <typename T>
 130.249 +    struct SetElevator
 130.250 +      : public Preflow<Digraph, CapacityMap, SetElevatorTraits<T> > {
 130.251 +      typedef Preflow<Digraph, CapacityMap,
 130.252 +                      SetElevatorTraits<T> > Create;
 130.253 +    };
 130.254 +
 130.255 +    template <typename T>
 130.256 +    struct SetStandardElevatorTraits : public Traits {
 130.257 +      typedef T Elevator;
 130.258 +      static Elevator *createElevator(const Digraph& digraph, int max_level) {
 130.259 +        return new Elevator(digraph, max_level);
 130.260 +      }
 130.261 +    };
 130.262 +
 130.263 +    /// \brief \ref named-templ-param "Named parameter" for setting
 130.264 +    /// Elevator type with automatic allocation
 130.265 +    ///
 130.266 +    /// \ref named-templ-param "Named parameter" for setting Elevator
 130.267 +    /// type with automatic allocation.
 130.268 +    /// The Elevator should have standard constructor interface to be
 130.269 +    /// able to automatically created by the algorithm (i.e. the
 130.270 +    /// digraph and the maximum level should be passed to it).
 130.271 +    /// However an external elevator object could also be passed to the
 130.272 +    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
 130.273 +    /// before calling \ref run() or \ref init().
 130.274 +    /// \sa SetElevator
 130.275 +    template <typename T>
 130.276 +    struct SetStandardElevator
 130.277 +      : public Preflow<Digraph, CapacityMap,
 130.278 +                       SetStandardElevatorTraits<T> > {
 130.279 +      typedef Preflow<Digraph, CapacityMap,
 130.280 +                      SetStandardElevatorTraits<T> > Create;
 130.281 +    };
 130.282 +
 130.283 +    /// @}
 130.284 +
 130.285 +  protected:
 130.286 +
 130.287 +    Preflow() {}
 130.288 +
 130.289 +  public:
 130.290 +
 130.291 +
 130.292 +    /// \brief The constructor of the class.
 130.293 +    ///
 130.294 +    /// The constructor of the class.
 130.295 +    /// \param digraph The digraph the algorithm runs on.
 130.296 +    /// \param capacity The capacity of the arcs.
 130.297 +    /// \param source The source node.
 130.298 +    /// \param target The target node.
 130.299 +    Preflow(const Digraph& digraph, const CapacityMap& capacity,
 130.300 +            Node source, Node target)
 130.301 +      : _graph(digraph), _capacity(&capacity),
 130.302 +        _node_num(0), _source(source), _target(target),
 130.303 +        _flow(0), _local_flow(false),
 130.304 +        _level(0), _local_level(false),
 130.305 +        _excess(0), _tolerance(), _phase() {}
 130.306 +
 130.307 +    /// \brief Destructor.
 130.308 +    ///
 130.309 +    /// Destructor.
 130.310 +    ~Preflow() {
 130.311 +      destroyStructures();
 130.312 +    }
 130.313 +
 130.314 +    /// \brief Sets the capacity map.
 130.315 +    ///
 130.316 +    /// Sets the capacity map.
 130.317 +    /// \return <tt>(*this)</tt>
 130.318 +    Preflow& capacityMap(const CapacityMap& map) {
 130.319 +      _capacity = &map;
 130.320 +      return *this;
 130.321 +    }
 130.322 +
 130.323 +    /// \brief Sets the flow map.
 130.324 +    ///
 130.325 +    /// Sets the flow map.
 130.326 +    /// If you don't use this function before calling \ref run() or
 130.327 +    /// \ref init(), an instance will be allocated automatically.
 130.328 +    /// The destructor deallocates this automatically allocated map,
 130.329 +    /// of course.
 130.330 +    /// \return <tt>(*this)</tt>
 130.331 +    Preflow& flowMap(FlowMap& map) {
 130.332 +      if (_local_flow) {
 130.333 +        delete _flow;
 130.334 +        _local_flow = false;
 130.335 +      }
 130.336 +      _flow = &map;
 130.337 +      return *this;
 130.338 +    }
 130.339 +
 130.340 +    /// \brief Sets the source node.
 130.341 +    ///
 130.342 +    /// Sets the source node.
 130.343 +    /// \return <tt>(*this)</tt>
 130.344 +    Preflow& source(const Node& node) {
 130.345 +      _source = node;
 130.346 +      return *this;
 130.347 +    }
 130.348 +
 130.349 +    /// \brief Sets the target node.
 130.350 +    ///
 130.351 +    /// Sets the target node.
 130.352 +    /// \return <tt>(*this)</tt>
 130.353 +    Preflow& target(const Node& node) {
 130.354 +      _target = node;
 130.355 +      return *this;
 130.356 +    }
 130.357 +
 130.358 +    /// \brief Sets the elevator used by algorithm.
 130.359 +    ///
 130.360 +    /// Sets the elevator used by algorithm.
 130.361 +    /// If you don't use this function before calling \ref run() or
 130.362 +    /// \ref init(), an instance will be allocated automatically.
 130.363 +    /// The destructor deallocates this automatically allocated elevator,
 130.364 +    /// of course.
 130.365 +    /// \return <tt>(*this)</tt>
 130.366 +    Preflow& elevator(Elevator& elevator) {
 130.367 +      if (_local_level) {
 130.368 +        delete _level;
 130.369 +        _local_level = false;
 130.370 +      }
 130.371 +      _level = &elevator;
 130.372 +      return *this;
 130.373 +    }
 130.374 +
 130.375 +    /// \brief Returns a const reference to the elevator.
 130.376 +    ///
 130.377 +    /// Returns a const reference to the elevator.
 130.378 +    ///
 130.379 +    /// \pre Either \ref run() or \ref init() must be called before
 130.380 +    /// using this function.
 130.381 +    const Elevator& elevator() const {
 130.382 +      return *_level;
 130.383 +    }
 130.384 +
 130.385 +    /// \brief Sets the tolerance used by the algorithm.
 130.386 +    ///
 130.387 +    /// Sets the tolerance object used by the algorithm.
 130.388 +    /// \return <tt>(*this)</tt>
 130.389 +    Preflow& tolerance(const Tolerance& tolerance) {
 130.390 +      _tolerance = tolerance;
 130.391 +      return *this;
 130.392 +    }
 130.393 +
 130.394 +    /// \brief Returns a const reference to the tolerance.
 130.395 +    ///
 130.396 +    /// Returns a const reference to the tolerance object used by
 130.397 +    /// the algorithm.
 130.398 +    const Tolerance& tolerance() const {
 130.399 +      return _tolerance;
 130.400 +    }
 130.401 +
 130.402 +    /// \name Execution Control
 130.403 +    /// The simplest way to execute the preflow algorithm is to use
 130.404 +    /// \ref run() or \ref runMinCut().\n
 130.405 +    /// If you need better control on the initial solution or the execution,
 130.406 +    /// you have to call one of the \ref init() functions first, then
 130.407 +    /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
 130.408 +
 130.409 +    ///@{
 130.410 +
 130.411 +    /// \brief Initializes the internal data structures.
 130.412 +    ///
 130.413 +    /// Initializes the internal data structures and sets the initial
 130.414 +    /// flow to zero on each arc.
 130.415 +    void init() {
 130.416 +      createStructures();
 130.417 +
 130.418 +      _phase = true;
 130.419 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 130.420 +        (*_excess)[n] = 0;
 130.421 +      }
 130.422 +
 130.423 +      for (ArcIt e(_graph); e != INVALID; ++e) {
 130.424 +        _flow->set(e, 0);
 130.425 +      }
 130.426 +
 130.427 +      typename Digraph::template NodeMap<bool> reached(_graph, false);
 130.428 +
 130.429 +      _level->initStart();
 130.430 +      _level->initAddItem(_target);
 130.431 +
 130.432 +      std::vector<Node> queue;
 130.433 +      reached[_source] = true;
 130.434 +
 130.435 +      queue.push_back(_target);
 130.436 +      reached[_target] = true;
 130.437 +      while (!queue.empty()) {
 130.438 +        _level->initNewLevel();
 130.439 +        std::vector<Node> nqueue;
 130.440 +        for (int i = 0; i < int(queue.size()); ++i) {
 130.441 +          Node n = queue[i];
 130.442 +          for (InArcIt e(_graph, n); e != INVALID; ++e) {
 130.443 +            Node u = _graph.source(e);
 130.444 +            if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
 130.445 +              reached[u] = true;
 130.446 +              _level->initAddItem(u);
 130.447 +              nqueue.push_back(u);
 130.448 +            }
 130.449 +          }
 130.450 +        }
 130.451 +        queue.swap(nqueue);
 130.452 +      }
 130.453 +      _level->initFinish();
 130.454 +
 130.455 +      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
 130.456 +        if (_tolerance.positive((*_capacity)[e])) {
 130.457 +          Node u = _graph.target(e);
 130.458 +          if ((*_level)[u] == _level->maxLevel()) continue;
 130.459 +          _flow->set(e, (*_capacity)[e]);
 130.460 +          (*_excess)[u] += (*_capacity)[e];
 130.461 +          if (u != _target && !_level->active(u)) {
 130.462 +            _level->activate(u);
 130.463 +          }
 130.464 +        }
 130.465 +      }
 130.466 +    }
 130.467 +
 130.468 +    /// \brief Initializes the internal data structures using the
 130.469 +    /// given flow map.
 130.470 +    ///
 130.471 +    /// Initializes the internal data structures and sets the initial
 130.472 +    /// flow to the given \c flowMap. The \c flowMap should contain a
 130.473 +    /// flow or at least a preflow, i.e. at each node excluding the
 130.474 +    /// source node the incoming flow should greater or equal to the
 130.475 +    /// outgoing flow.
 130.476 +    /// \return \c false if the given \c flowMap is not a preflow.
 130.477 +    template <typename FlowMap>
 130.478 +    bool init(const FlowMap& flowMap) {
 130.479 +      createStructures();
 130.480 +
 130.481 +      for (ArcIt e(_graph); e != INVALID; ++e) {
 130.482 +        _flow->set(e, flowMap[e]);
 130.483 +      }
 130.484 +
 130.485 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 130.486 +        Value excess = 0;
 130.487 +        for (InArcIt e(_graph, n); e != INVALID; ++e) {
 130.488 +          excess += (*_flow)[e];
 130.489 +        }
 130.490 +        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
 130.491 +          excess -= (*_flow)[e];
 130.492 +        }
 130.493 +        if (excess < 0 && n != _source) return false;
 130.494 +        (*_excess)[n] = excess;
 130.495 +      }
 130.496 +
 130.497 +      typename Digraph::template NodeMap<bool> reached(_graph, false);
 130.498 +
 130.499 +      _level->initStart();
 130.500 +      _level->initAddItem(_target);
 130.501 +
 130.502 +      std::vector<Node> queue;
 130.503 +      reached[_source] = true;
 130.504 +
 130.505 +      queue.push_back(_target);
 130.506 +      reached[_target] = true;
 130.507 +      while (!queue.empty()) {
 130.508 +        _level->initNewLevel();
 130.509 +        std::vector<Node> nqueue;
 130.510 +        for (int i = 0; i < int(queue.size()); ++i) {
 130.511 +          Node n = queue[i];
 130.512 +          for (InArcIt e(_graph, n); e != INVALID; ++e) {
 130.513 +            Node u = _graph.source(e);
 130.514 +            if (!reached[u] &&
 130.515 +                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
 130.516 +              reached[u] = true;
 130.517 +              _level->initAddItem(u);
 130.518 +              nqueue.push_back(u);
 130.519 +            }
 130.520 +          }
 130.521 +          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
 130.522 +            Node v = _graph.target(e);
 130.523 +            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
 130.524 +              reached[v] = true;
 130.525 +              _level->initAddItem(v);
 130.526 +              nqueue.push_back(v);
 130.527 +            }
 130.528 +          }
 130.529 +        }
 130.530 +        queue.swap(nqueue);
 130.531 +      }
 130.532 +      _level->initFinish();
 130.533 +
 130.534 +      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
 130.535 +        Value rem = (*_capacity)[e] - (*_flow)[e];
 130.536 +        if (_tolerance.positive(rem)) {
 130.537 +          Node u = _graph.target(e);
 130.538 +          if ((*_level)[u] == _level->maxLevel()) continue;
 130.539 +          _flow->set(e, (*_capacity)[e]);
 130.540 +          (*_excess)[u] += rem;
 130.541 +          if (u != _target && !_level->active(u)) {
 130.542 +            _level->activate(u);
 130.543 +          }
 130.544 +        }
 130.545 +      }
 130.546 +      for (InArcIt e(_graph, _source); e != INVALID; ++e) {
 130.547 +        Value rem = (*_flow)[e];
 130.548 +        if (_tolerance.positive(rem)) {
 130.549 +          Node v = _graph.source(e);
 130.550 +          if ((*_level)[v] == _level->maxLevel()) continue;
 130.551 +          _flow->set(e, 0);
 130.552 +          (*_excess)[v] += rem;
 130.553 +          if (v != _target && !_level->active(v)) {
 130.554 +            _level->activate(v);
 130.555 +          }
 130.556 +        }
 130.557 +      }
 130.558 +      return true;
 130.559 +    }
 130.560 +
 130.561 +    /// \brief Starts the first phase of the preflow algorithm.
 130.562 +    ///
 130.563 +    /// The preflow algorithm consists of two phases, this method runs
 130.564 +    /// the first phase. After the first phase the maximum flow value
 130.565 +    /// and a minimum value cut can already be computed, although a
 130.566 +    /// maximum flow is not yet obtained. So after calling this method
 130.567 +    /// \ref flowValue() returns the value of a maximum flow and \ref
 130.568 +    /// minCut() returns a minimum cut.
 130.569 +    /// \pre One of the \ref init() functions must be called before
 130.570 +    /// using this function.
 130.571 +    void startFirstPhase() {
 130.572 +      _phase = true;
 130.573 +
 130.574 +      Node n = _level->highestActive();
 130.575 +      int level = _level->highestActiveLevel();
 130.576 +      while (n != INVALID) {
 130.577 +        int num = _node_num;
 130.578 +
 130.579 +        while (num > 0 && n != INVALID) {
 130.580 +          Value excess = (*_excess)[n];
 130.581 +          int new_level = _level->maxLevel();
 130.582 +
 130.583 +          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
 130.584 +            Value rem = (*_capacity)[e] - (*_flow)[e];
 130.585 +            if (!_tolerance.positive(rem)) continue;
 130.586 +            Node v = _graph.target(e);
 130.587 +            if ((*_level)[v] < level) {
 130.588 +              if (!_level->active(v) && v != _target) {
 130.589 +                _level->activate(v);
 130.590 +              }
 130.591 +              if (!_tolerance.less(rem, excess)) {
 130.592 +                _flow->set(e, (*_flow)[e] + excess);
 130.593 +                (*_excess)[v] += excess;
 130.594 +                excess = 0;
 130.595 +                goto no_more_push_1;
 130.596 +              } else {
 130.597 +                excess -= rem;
 130.598 +                (*_excess)[v] += rem;
 130.599 +                _flow->set(e, (*_capacity)[e]);
 130.600 +              }
 130.601 +            } else if (new_level > (*_level)[v]) {
 130.602 +              new_level = (*_level)[v];
 130.603 +            }
 130.604 +          }
 130.605 +
 130.606 +          for (InArcIt e(_graph, n); e != INVALID; ++e) {
 130.607 +            Value rem = (*_flow)[e];
 130.608 +            if (!_tolerance.positive(rem)) continue;
 130.609 +            Node v = _graph.source(e);
 130.610 +            if ((*_level)[v] < level) {
 130.611 +              if (!_level->active(v) && v != _target) {
 130.612 +                _level->activate(v);
 130.613 +              }
 130.614 +              if (!_tolerance.less(rem, excess)) {
 130.615 +                _flow->set(e, (*_flow)[e] - excess);
 130.616 +                (*_excess)[v] += excess;
 130.617 +                excess = 0;
 130.618 +                goto no_more_push_1;
 130.619 +              } else {
 130.620 +                excess -= rem;
 130.621 +                (*_excess)[v] += rem;
 130.622 +                _flow->set(e, 0);
 130.623 +              }
 130.624 +            } else if (new_level > (*_level)[v]) {
 130.625 +              new_level = (*_level)[v];
 130.626 +            }
 130.627 +          }
 130.628 +
 130.629 +        no_more_push_1:
 130.630 +
 130.631 +          (*_excess)[n] = excess;
 130.632 +
 130.633 +          if (excess != 0) {
 130.634 +            if (new_level + 1 < _level->maxLevel()) {
 130.635 +              _level->liftHighestActive(new_level + 1);
 130.636 +            } else {
 130.637 +              _level->liftHighestActiveToTop();
 130.638 +            }
 130.639 +            if (_level->emptyLevel(level)) {
 130.640 +              _level->liftToTop(level);
 130.641 +            }
 130.642 +          } else {
 130.643 +            _level->deactivate(n);
 130.644 +          }
 130.645 +
 130.646 +          n = _level->highestActive();
 130.647 +          level = _level->highestActiveLevel();
 130.648 +          --num;
 130.649 +        }
 130.650 +
 130.651 +        num = _node_num * 20;
 130.652 +        while (num > 0 && n != INVALID) {
 130.653 +          Value excess = (*_excess)[n];
 130.654 +          int new_level = _level->maxLevel();
 130.655 +
 130.656 +          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
 130.657 +            Value rem = (*_capacity)[e] - (*_flow)[e];
 130.658 +            if (!_tolerance.positive(rem)) continue;
 130.659 +            Node v = _graph.target(e);
 130.660 +            if ((*_level)[v] < level) {
 130.661 +              if (!_level->active(v) && v != _target) {
 130.662 +                _level->activate(v);
 130.663 +              }
 130.664 +              if (!_tolerance.less(rem, excess)) {
 130.665 +                _flow->set(e, (*_flow)[e] + excess);
 130.666 +                (*_excess)[v] += excess;
 130.667 +                excess = 0;
 130.668 +                goto no_more_push_2;
 130.669 +              } else {
 130.670 +                excess -= rem;
 130.671 +                (*_excess)[v] += rem;
 130.672 +                _flow->set(e, (*_capacity)[e]);
 130.673 +              }
 130.674 +            } else if (new_level > (*_level)[v]) {
 130.675 +              new_level = (*_level)[v];
 130.676 +            }
 130.677 +          }
 130.678 +
 130.679 +          for (InArcIt e(_graph, n); e != INVALID; ++e) {
 130.680 +            Value rem = (*_flow)[e];
 130.681 +            if (!_tolerance.positive(rem)) continue;
 130.682 +            Node v = _graph.source(e);
 130.683 +            if ((*_level)[v] < level) {
 130.684 +              if (!_level->active(v) && v != _target) {
 130.685 +                _level->activate(v);
 130.686 +              }
 130.687 +              if (!_tolerance.less(rem, excess)) {
 130.688 +                _flow->set(e, (*_flow)[e] - excess);
 130.689 +                (*_excess)[v] += excess;
 130.690 +                excess = 0;
 130.691 +                goto no_more_push_2;
 130.692 +              } else {
 130.693 +                excess -= rem;
 130.694 +                (*_excess)[v] += rem;
 130.695 +                _flow->set(e, 0);
 130.696 +              }
 130.697 +            } else if (new_level > (*_level)[v]) {
 130.698 +              new_level = (*_level)[v];
 130.699 +            }
 130.700 +          }
 130.701 +
 130.702 +        no_more_push_2:
 130.703 +
 130.704 +          (*_excess)[n] = excess;
 130.705 +
 130.706 +          if (excess != 0) {
 130.707 +            if (new_level + 1 < _level->maxLevel()) {
 130.708 +              _level->liftActiveOn(level, new_level + 1);
 130.709 +            } else {
 130.710 +              _level->liftActiveToTop(level);
 130.711 +            }
 130.712 +            if (_level->emptyLevel(level)) {
 130.713 +              _level->liftToTop(level);
 130.714 +            }
 130.715 +          } else {
 130.716 +            _level->deactivate(n);
 130.717 +          }
 130.718 +
 130.719 +          while (level >= 0 && _level->activeFree(level)) {
 130.720 +            --level;
 130.721 +          }
 130.722 +          if (level == -1) {
 130.723 +            n = _level->highestActive();
 130.724 +            level = _level->highestActiveLevel();
 130.725 +          } else {
 130.726 +            n = _level->activeOn(level);
 130.727 +          }
 130.728 +          --num;
 130.729 +        }
 130.730 +      }
 130.731 +    }
 130.732 +
 130.733 +    /// \brief Starts the second phase of the preflow algorithm.
 130.734 +    ///
 130.735 +    /// The preflow algorithm consists of two phases, this method runs
 130.736 +    /// the second phase. After calling one of the \ref init() functions
 130.737 +    /// and \ref startFirstPhase() and then \ref startSecondPhase(),
 130.738 +    /// \ref flowMap() returns a maximum flow, \ref flowValue() returns the
 130.739 +    /// value of a maximum flow, \ref minCut() returns a minimum cut
 130.740 +    /// \pre One of the \ref init() functions and \ref startFirstPhase()
 130.741 +    /// must be called before using this function.
 130.742 +    void startSecondPhase() {
 130.743 +      _phase = false;
 130.744 +
 130.745 +      typename Digraph::template NodeMap<bool> reached(_graph);
 130.746 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 130.747 +        reached[n] = (*_level)[n] < _level->maxLevel();
 130.748 +      }
 130.749 +
 130.750 +      _level->initStart();
 130.751 +      _level->initAddItem(_source);
 130.752 +
 130.753 +      std::vector<Node> queue;
 130.754 +      queue.push_back(_source);
 130.755 +      reached[_source] = true;
 130.756 +
 130.757 +      while (!queue.empty()) {
 130.758 +        _level->initNewLevel();
 130.759 +        std::vector<Node> nqueue;
 130.760 +        for (int i = 0; i < int(queue.size()); ++i) {
 130.761 +          Node n = queue[i];
 130.762 +          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
 130.763 +            Node v = _graph.target(e);
 130.764 +            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
 130.765 +              reached[v] = true;
 130.766 +              _level->initAddItem(v);
 130.767 +              nqueue.push_back(v);
 130.768 +            }
 130.769 +          }
 130.770 +          for (InArcIt e(_graph, n); e != INVALID; ++e) {
 130.771 +            Node u = _graph.source(e);
 130.772 +            if (!reached[u] &&
 130.773 +                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
 130.774 +              reached[u] = true;
 130.775 +              _level->initAddItem(u);
 130.776 +              nqueue.push_back(u);
 130.777 +            }
 130.778 +          }
 130.779 +        }
 130.780 +        queue.swap(nqueue);
 130.781 +      }
 130.782 +      _level->initFinish();
 130.783 +
 130.784 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 130.785 +        if (!reached[n]) {
 130.786 +          _level->dirtyTopButOne(n);
 130.787 +        } else if ((*_excess)[n] > 0 && _target != n) {
 130.788 +          _level->activate(n);
 130.789 +        }
 130.790 +      }
 130.791 +
 130.792 +      Node n;
 130.793 +      while ((n = _level->highestActive()) != INVALID) {
 130.794 +        Value excess = (*_excess)[n];
 130.795 +        int level = _level->highestActiveLevel();
 130.796 +        int new_level = _level->maxLevel();
 130.797 +
 130.798 +        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
 130.799 +          Value rem = (*_capacity)[e] - (*_flow)[e];
 130.800 +          if (!_tolerance.positive(rem)) continue;
 130.801 +          Node v = _graph.target(e);
 130.802 +          if ((*_level)[v] < level) {
 130.803 +            if (!_level->active(v) && v != _source) {
 130.804 +              _level->activate(v);
 130.805 +            }
 130.806 +            if (!_tolerance.less(rem, excess)) {
 130.807 +              _flow->set(e, (*_flow)[e] + excess);
 130.808 +              (*_excess)[v] += excess;
 130.809 +              excess = 0;
 130.810 +              goto no_more_push;
 130.811 +            } else {
 130.812 +              excess -= rem;
 130.813 +              (*_excess)[v] += rem;
 130.814 +              _flow->set(e, (*_capacity)[e]);
 130.815 +            }
 130.816 +          } else if (new_level > (*_level)[v]) {
 130.817 +            new_level = (*_level)[v];
 130.818 +          }
 130.819 +        }
 130.820 +
 130.821 +        for (InArcIt e(_graph, n); e != INVALID; ++e) {
 130.822 +          Value rem = (*_flow)[e];
 130.823 +          if (!_tolerance.positive(rem)) continue;
 130.824 +          Node v = _graph.source(e);
 130.825 +          if ((*_level)[v] < level) {
 130.826 +            if (!_level->active(v) && v != _source) {
 130.827 +              _level->activate(v);
 130.828 +            }
 130.829 +            if (!_tolerance.less(rem, excess)) {
 130.830 +              _flow->set(e, (*_flow)[e] - excess);
 130.831 +              (*_excess)[v] += excess;
 130.832 +              excess = 0;
 130.833 +              goto no_more_push;
 130.834 +            } else {
 130.835 +              excess -= rem;
 130.836 +              (*_excess)[v] += rem;
 130.837 +              _flow->set(e, 0);
 130.838 +            }
 130.839 +          } else if (new_level > (*_level)[v]) {
 130.840 +            new_level = (*_level)[v];
 130.841 +          }
 130.842 +        }
 130.843 +
 130.844 +      no_more_push:
 130.845 +
 130.846 +        (*_excess)[n] = excess;
 130.847 +
 130.848 +        if (excess != 0) {
 130.849 +          if (new_level + 1 < _level->maxLevel()) {
 130.850 +            _level->liftHighestActive(new_level + 1);
 130.851 +          } else {
 130.852 +            // Calculation error
 130.853 +            _level->liftHighestActiveToTop();
 130.854 +          }
 130.855 +          if (_level->emptyLevel(level)) {
 130.856 +            // Calculation error
 130.857 +            _level->liftToTop(level);
 130.858 +          }
 130.859 +        } else {
 130.860 +          _level->deactivate(n);
 130.861 +        }
 130.862 +
 130.863 +      }
 130.864 +    }
 130.865 +
 130.866 +    /// \brief Runs the preflow algorithm.
 130.867 +    ///
 130.868 +    /// Runs the preflow algorithm.
 130.869 +    /// \note pf.run() is just a shortcut of the following code.
 130.870 +    /// \code
 130.871 +    ///   pf.init();
 130.872 +    ///   pf.startFirstPhase();
 130.873 +    ///   pf.startSecondPhase();
 130.874 +    /// \endcode
 130.875 +    void run() {
 130.876 +      init();
 130.877 +      startFirstPhase();
 130.878 +      startSecondPhase();
 130.879 +    }
 130.880 +
 130.881 +    /// \brief Runs the preflow algorithm to compute the minimum cut.
 130.882 +    ///
 130.883 +    /// Runs the preflow algorithm to compute the minimum cut.
 130.884 +    /// \note pf.runMinCut() is just a shortcut of the following code.
 130.885 +    /// \code
 130.886 +    ///   pf.init();
 130.887 +    ///   pf.startFirstPhase();
 130.888 +    /// \endcode
 130.889 +    void runMinCut() {
 130.890 +      init();
 130.891 +      startFirstPhase();
 130.892 +    }
 130.893 +
 130.894 +    /// @}
 130.895 +
 130.896 +    /// \name Query Functions
 130.897 +    /// The results of the preflow algorithm can be obtained using these
 130.898 +    /// functions.\n
 130.899 +    /// Either one of the \ref run() "run*()" functions or one of the
 130.900 +    /// \ref startFirstPhase() "start*()" functions should be called
 130.901 +    /// before using them.
 130.902 +
 130.903 +    ///@{
 130.904 +
 130.905 +    /// \brief Returns the value of the maximum flow.
 130.906 +    ///
 130.907 +    /// Returns the value of the maximum flow by returning the excess
 130.908 +    /// of the target node. This value equals to the value of
 130.909 +    /// the maximum flow already after the first phase of the algorithm.
 130.910 +    ///
 130.911 +    /// \pre Either \ref run() or \ref init() must be called before
 130.912 +    /// using this function.
 130.913 +    Value flowValue() const {
 130.914 +      return (*_excess)[_target];
 130.915 +    }
 130.916 +
 130.917 +    /// \brief Returns the flow value on the given arc.
 130.918 +    ///
 130.919 +    /// Returns the flow value on the given arc. This method can
 130.920 +    /// be called after the second phase of the algorithm.
 130.921 +    ///
 130.922 +    /// \pre Either \ref run() or \ref init() must be called before
 130.923 +    /// using this function.
 130.924 +    Value flow(const Arc& arc) const {
 130.925 +      return (*_flow)[arc];
 130.926 +    }
 130.927 +
 130.928 +    /// \brief Returns a const reference to the flow map.
 130.929 +    ///
 130.930 +    /// Returns a const reference to the arc map storing the found flow.
 130.931 +    /// This method can be called after the second phase of the algorithm.
 130.932 +    ///
 130.933 +    /// \pre Either \ref run() or \ref init() must be called before
 130.934 +    /// using this function.
 130.935 +    const FlowMap& flowMap() const {
 130.936 +      return *_flow;
 130.937 +    }
 130.938 +
 130.939 +    /// \brief Returns \c true when the node is on the source side of the
 130.940 +    /// minimum cut.
 130.941 +    ///
 130.942 +    /// Returns true when the node is on the source side of the found
 130.943 +    /// minimum cut. This method can be called both after running \ref
 130.944 +    /// startFirstPhase() and \ref startSecondPhase().
 130.945 +    ///
 130.946 +    /// \pre Either \ref run() or \ref init() must be called before
 130.947 +    /// using this function.
 130.948 +    bool minCut(const Node& node) const {
 130.949 +      return ((*_level)[node] == _level->maxLevel()) == _phase;
 130.950 +    }
 130.951 +
 130.952 +    /// \brief Gives back a minimum value cut.
 130.953 +    ///
 130.954 +    /// Sets \c cutMap to the characteristic vector of a minimum value
 130.955 +    /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
 130.956 +    /// node map with \c bool (or convertible) value type.
 130.957 +    ///
 130.958 +    /// This method can be called both after running \ref startFirstPhase()
 130.959 +    /// and \ref startSecondPhase(). The result after the second phase
 130.960 +    /// could be slightly different if inexact computation is used.
 130.961 +    ///
 130.962 +    /// \note This function calls \ref minCut() for each node, so it runs in
 130.963 +    /// O(n) time.
 130.964 +    ///
 130.965 +    /// \pre Either \ref run() or \ref init() must be called before
 130.966 +    /// using this function.
 130.967 +    template <typename CutMap>
 130.968 +    void minCutMap(CutMap& cutMap) const {
 130.969 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 130.970 +        cutMap.set(n, minCut(n));
 130.971 +      }
 130.972 +    }
 130.973 +
 130.974 +    /// @}
 130.975 +  };
 130.976 +}
 130.977 +
 130.978 +#endif
   131.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   131.2 +++ b/lemon/radix_heap.h	Thu Nov 05 15:50:01 2009 +0100
   131.3 @@ -0,0 +1,438 @@
   131.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   131.5 + *
   131.6 + * This file is a part of LEMON, a generic C++ optimization library.
   131.7 + *
   131.8 + * Copyright (C) 2003-2009
   131.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  131.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  131.11 + *
  131.12 + * Permission to use, modify and distribute this software is granted
  131.13 + * provided that this copyright notice appears in all copies. For
  131.14 + * precise terms see the accompanying LICENSE file.
  131.15 + *
  131.16 + * This software is provided "AS IS" with no warranty of any kind,
  131.17 + * express or implied, and with no claim as to its suitability for any
  131.18 + * purpose.
  131.19 + *
  131.20 + */
  131.21 +
  131.22 +#ifndef LEMON_RADIX_HEAP_H
  131.23 +#define LEMON_RADIX_HEAP_H
  131.24 +
  131.25 +///\ingroup heaps
  131.26 +///\file
  131.27 +///\brief Radix heap implementation.
  131.28 +
  131.29 +#include <vector>
  131.30 +#include <lemon/error.h>
  131.31 +
  131.32 +namespace lemon {
  131.33 +
  131.34 +
  131.35 +  /// \ingroup heaps
  131.36 +  ///
  131.37 +  /// \brief Radix heap data structure.
  131.38 +  ///
  131.39 +  /// This class implements the \e radix \e heap data structure.
  131.40 +  /// It practically conforms to the \ref concepts::Heap "heap concept",
  131.41 +  /// but it has some limitations due its special implementation.
  131.42 +  /// The type of the priorities must be \c int and the priority of an
  131.43 +  /// item cannot be decreased under the priority of the last removed item.
  131.44 +  ///
  131.45 +  /// \tparam IM A read-writable item map with \c int values, used
  131.46 +  /// internally to handle the cross references.
  131.47 +  template <typename IM>
  131.48 +  class RadixHeap {
  131.49 +
  131.50 +  public:
  131.51 +
  131.52 +    /// Type of the item-int map.
  131.53 +    typedef IM ItemIntMap;
  131.54 +    /// Type of the priorities.
  131.55 +    typedef int Prio;
  131.56 +    /// Type of the items stored in the heap.
  131.57 +    typedef typename ItemIntMap::Key Item;
  131.58 +
  131.59 +    /// \brief Exception thrown by RadixHeap.
  131.60 +    ///
  131.61 +    /// This exception is thrown when an item is inserted into a
  131.62 +    /// RadixHeap with a priority smaller than the last erased one.
  131.63 +    /// \see RadixHeap
  131.64 +    class PriorityUnderflowError : public Exception {
  131.65 +    public:
  131.66 +      virtual const char* what() const throw() {
  131.67 +        return "lemon::RadixHeap::PriorityUnderflowError";
  131.68 +      }
  131.69 +    };
  131.70 +
  131.71 +    /// \brief Type to represent the states of the items.
  131.72 +    ///
  131.73 +    /// Each item has a state associated to it. It can be "in heap",
  131.74 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
  131.75 +    /// heap's point of view, but may be useful to the user.
  131.76 +    ///
  131.77 +    /// The item-int map must be initialized in such way that it assigns
  131.78 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
  131.79 +    enum State {
  131.80 +      IN_HEAP = 0,    ///< = 0.
  131.81 +      PRE_HEAP = -1,  ///< = -1.
  131.82 +      POST_HEAP = -2  ///< = -2.
  131.83 +    };
  131.84 +
  131.85 +  private:
  131.86 +
  131.87 +    struct RadixItem {
  131.88 +      int prev, next, box;
  131.89 +      Item item;
  131.90 +      int prio;
  131.91 +      RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
  131.92 +    };
  131.93 +
  131.94 +    struct RadixBox {
  131.95 +      int first;
  131.96 +      int min, size;
  131.97 +      RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
  131.98 +    };
  131.99 +
 131.100 +    std::vector<RadixItem> _data;
 131.101 +    std::vector<RadixBox> _boxes;
 131.102 +
 131.103 +    ItemIntMap &_iim;
 131.104 +
 131.105 +  public:
 131.106 +
 131.107 +    /// \brief Constructor.
 131.108 +    ///
 131.109 +    /// Constructor.
 131.110 +    /// \param map A map that assigns \c int values to the items.
 131.111 +    /// It is used internally to handle the cross references.
 131.112 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
 131.113 +    /// \param minimum The initial minimum value of the heap.
 131.114 +    /// \param capacity The initial capacity of the heap.
 131.115 +    RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0)
 131.116 +      : _iim(map)
 131.117 +    {
 131.118 +      _boxes.push_back(RadixBox(minimum, 1));
 131.119 +      _boxes.push_back(RadixBox(minimum + 1, 1));
 131.120 +      while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
 131.121 +        extend();
 131.122 +      }
 131.123 +    }
 131.124 +
 131.125 +    /// \brief The number of items stored in the heap.
 131.126 +    ///
 131.127 +    /// This function returns the number of items stored in the heap.
 131.128 +    int size() const { return _data.size(); }
 131.129 +
 131.130 +    /// \brief Check if the heap is empty.
 131.131 +    ///
 131.132 +    /// This function returns \c true if the heap is empty.
 131.133 +    bool empty() const { return _data.empty(); }
 131.134 +
 131.135 +    /// \brief Make the heap empty.
 131.136 +    ///
 131.137 +    /// This functon makes the heap empty.
 131.138 +    /// It does not change the cross reference map. If you want to reuse
 131.139 +    /// a heap that is not surely empty, you should first clear it and
 131.140 +    /// then you should set the cross reference map to \c PRE_HEAP
 131.141 +    /// for each item.
 131.142 +    /// \param minimum The minimum value of the heap.
 131.143 +    /// \param capacity The capacity of the heap.
 131.144 +    void clear(int minimum = 0, int capacity = 0) {
 131.145 +      _data.clear(); _boxes.clear();
 131.146 +      _boxes.push_back(RadixBox(minimum, 1));
 131.147 +      _boxes.push_back(RadixBox(minimum + 1, 1));
 131.148 +      while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
 131.149 +        extend();
 131.150 +      }
 131.151 +    }
 131.152 +
 131.153 +  private:
 131.154 +
 131.155 +    bool upper(int box, Prio pr) {
 131.156 +      return pr < _boxes[box].min;
 131.157 +    }
 131.158 +
 131.159 +    bool lower(int box, Prio pr) {
 131.160 +      return pr >= _boxes[box].min + _boxes[box].size;
 131.161 +    }
 131.162 +
 131.163 +    // Remove item from the box list
 131.164 +    void remove(int index) {
 131.165 +      if (_data[index].prev >= 0) {
 131.166 +        _data[_data[index].prev].next = _data[index].next;
 131.167 +      } else {
 131.168 +        _boxes[_data[index].box].first = _data[index].next;
 131.169 +      }
 131.170 +      if (_data[index].next >= 0) {
 131.171 +        _data[_data[index].next].prev = _data[index].prev;
 131.172 +      }
 131.173 +    }
 131.174 +
 131.175 +    // Insert item into the box list
 131.176 +    void insert(int box, int index) {
 131.177 +      if (_boxes[box].first == -1) {
 131.178 +        _boxes[box].first = index;
 131.179 +        _data[index].next = _data[index].prev = -1;
 131.180 +      } else {
 131.181 +        _data[index].next = _boxes[box].first;
 131.182 +        _data[_boxes[box].first].prev = index;
 131.183 +        _data[index].prev = -1;
 131.184 +        _boxes[box].first = index;
 131.185 +      }
 131.186 +      _data[index].box = box;
 131.187 +    }
 131.188 +
 131.189 +    // Add a new box to the box list
 131.190 +    void extend() {
 131.191 +      int min = _boxes.back().min + _boxes.back().size;
 131.192 +      int bs = 2 * _boxes.back().size;
 131.193 +      _boxes.push_back(RadixBox(min, bs));
 131.194 +    }
 131.195 +
 131.196 +    // Move an item up into the proper box.
 131.197 +    void bubbleUp(int index) {
 131.198 +      if (!lower(_data[index].box, _data[index].prio)) return;
 131.199 +      remove(index);
 131.200 +      int box = findUp(_data[index].box, _data[index].prio);
 131.201 +      insert(box, index);
 131.202 +    }
 131.203 +
 131.204 +    // Find up the proper box for the item with the given priority
 131.205 +    int findUp(int start, int pr) {
 131.206 +      while (lower(start, pr)) {
 131.207 +        if (++start == int(_boxes.size())) {
 131.208 +          extend();
 131.209 +        }
 131.210 +      }
 131.211 +      return start;
 131.212 +    }
 131.213 +
 131.214 +    // Move an item down into the proper box
 131.215 +    void bubbleDown(int index) {
 131.216 +      if (!upper(_data[index].box, _data[index].prio)) return;
 131.217 +      remove(index);
 131.218 +      int box = findDown(_data[index].box, _data[index].prio);
 131.219 +      insert(box, index);
 131.220 +    }
 131.221 +
 131.222 +    // Find down the proper box for the item with the given priority
 131.223 +    int findDown(int start, int pr) {
 131.224 +      while (upper(start, pr)) {
 131.225 +        if (--start < 0) throw PriorityUnderflowError();
 131.226 +      }
 131.227 +      return start;
 131.228 +    }
 131.229 +
 131.230 +    // Find the first non-empty box
 131.231 +    int findFirst() {
 131.232 +      int first = 0;
 131.233 +      while (_boxes[first].first == -1) ++first;
 131.234 +      return first;
 131.235 +    }
 131.236 +
 131.237 +    // Gives back the minimum priority of the given box
 131.238 +    int minValue(int box) {
 131.239 +      int min = _data[_boxes[box].first].prio;
 131.240 +      for (int k = _boxes[box].first; k != -1; k = _data[k].next) {
 131.241 +        if (_data[k].prio < min) min = _data[k].prio;
 131.242 +      }
 131.243 +      return min;
 131.244 +    }
 131.245 +
 131.246 +    // Rearrange the items of the heap and make the first box non-empty
 131.247 +    void moveDown() {
 131.248 +      int box = findFirst();
 131.249 +      if (box == 0) return;
 131.250 +      int min = minValue(box);
 131.251 +      for (int i = 0; i <= box; ++i) {
 131.252 +        _boxes[i].min = min;
 131.253 +        min += _boxes[i].size;
 131.254 +      }
 131.255 +      int curr = _boxes[box].first, next;
 131.256 +      while (curr != -1) {
 131.257 +        next = _data[curr].next;
 131.258 +        bubbleDown(curr);
 131.259 +        curr = next;
 131.260 +      }
 131.261 +    }
 131.262 +
 131.263 +    void relocateLast(int index) {
 131.264 +      if (index != int(_data.size()) - 1) {
 131.265 +        _data[index] = _data.back();
 131.266 +        if (_data[index].prev != -1) {
 131.267 +          _data[_data[index].prev].next = index;
 131.268 +        } else {
 131.269 +          _boxes[_data[index].box].first = index;
 131.270 +        }
 131.271 +        if (_data[index].next != -1) {
 131.272 +          _data[_data[index].next].prev = index;
 131.273 +        }
 131.274 +        _iim[_data[index].item] = index;
 131.275 +      }
 131.276 +      _data.pop_back();
 131.277 +    }
 131.278 +
 131.279 +  public:
 131.280 +
 131.281 +    /// \brief Insert an item into the heap with the given priority.
 131.282 +    ///
 131.283 +    /// This function inserts the given item into the heap with the
 131.284 +    /// given priority.
 131.285 +    /// \param i The item to insert.
 131.286 +    /// \param p The priority of the item.
 131.287 +    /// \pre \e i must not be stored in the heap.
 131.288 +    /// \warning This method may throw an \c UnderFlowPriorityException.
 131.289 +    void push(const Item &i, const Prio &p) {
 131.290 +      int n = _data.size();
 131.291 +      _iim.set(i, n);
 131.292 +      _data.push_back(RadixItem(i, p));
 131.293 +      while (lower(_boxes.size() - 1, p)) {
 131.294 +        extend();
 131.295 +      }
 131.296 +      int box = findDown(_boxes.size() - 1, p);
 131.297 +      insert(box, n);
 131.298 +    }
 131.299 +
 131.300 +    /// \brief Return the item having minimum priority.
 131.301 +    ///
 131.302 +    /// This function returns the item having minimum priority.
 131.303 +    /// \pre The heap must be non-empty.
 131.304 +    Item top() const {
 131.305 +      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
 131.306 +      return _data[_boxes[0].first].item;
 131.307 +    }
 131.308 +
 131.309 +    /// \brief The minimum priority.
 131.310 +    ///
 131.311 +    /// This function returns the minimum priority.
 131.312 +    /// \pre The heap must be non-empty.
 131.313 +    Prio prio() const {
 131.314 +      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
 131.315 +      return _data[_boxes[0].first].prio;
 131.316 +     }
 131.317 +
 131.318 +    /// \brief Remove the item having minimum priority.
 131.319 +    ///
 131.320 +    /// This function removes the item having minimum priority.
 131.321 +    /// \pre The heap must be non-empty.
 131.322 +    void pop() {
 131.323 +      moveDown();
 131.324 +      int index = _boxes[0].first;
 131.325 +      _iim[_data[index].item] = POST_HEAP;
 131.326 +      remove(index);
 131.327 +      relocateLast(index);
 131.328 +    }
 131.329 +
 131.330 +    /// \brief Remove the given item from the heap.
 131.331 +    ///
 131.332 +    /// This function removes the given item from the heap if it is
 131.333 +    /// already stored.
 131.334 +    /// \param i The item to delete.
 131.335 +    /// \pre \e i must be in the heap.
 131.336 +    void erase(const Item &i) {
 131.337 +      int index = _iim[i];
 131.338 +      _iim[i] = POST_HEAP;
 131.339 +      remove(index);
 131.340 +      relocateLast(index);
 131.341 +   }
 131.342 +
 131.343 +    /// \brief The priority of the given item.
 131.344 +    ///
 131.345 +    /// This function returns the priority of the given item.
 131.346 +    /// \param i The item.
 131.347 +    /// \pre \e i must be in the heap.
 131.348 +    Prio operator[](const Item &i) const {
 131.349 +      int idx = _iim[i];
 131.350 +      return _data[idx].prio;
 131.351 +    }
 131.352 +
 131.353 +    /// \brief Set the priority of an item or insert it, if it is
 131.354 +    /// not stored in the heap.
 131.355 +    ///
 131.356 +    /// This method sets the priority of the given item if it is
 131.357 +    /// already stored in the heap. Otherwise it inserts the given
 131.358 +    /// item into the heap with the given priority.
 131.359 +    /// \param i The item.
 131.360 +    /// \param p The priority.
 131.361 +    /// \pre \e i must be in the heap.
 131.362 +    /// \warning This method may throw an \c UnderFlowPriorityException.
 131.363 +    void set(const Item &i, const Prio &p) {
 131.364 +      int idx = _iim[i];
 131.365 +      if( idx < 0 ) {
 131.366 +        push(i, p);
 131.367 +      }
 131.368 +      else if( p >= _data[idx].prio ) {
 131.369 +        _data[idx].prio = p;
 131.370 +        bubbleUp(idx);
 131.371 +      } else {
 131.372 +        _data[idx].prio = p;
 131.373 +        bubbleDown(idx);
 131.374 +      }
 131.375 +    }
 131.376 +
 131.377 +    /// \brief Decrease the priority of an item to the given value.
 131.378 +    ///
 131.379 +    /// This function decreases the priority of an item to the given value.
 131.380 +    /// \param i The item.
 131.381 +    /// \param p The priority.
 131.382 +    /// \pre \e i must be stored in the heap with priority at least \e p.
 131.383 +    /// \warning This method may throw an \c UnderFlowPriorityException.
 131.384 +    void decrease(const Item &i, const Prio &p) {
 131.385 +      int idx = _iim[i];
 131.386 +      _data[idx].prio = p;
 131.387 +      bubbleDown(idx);
 131.388 +    }
 131.389 +
 131.390 +    /// \brief Increase the priority of an item to the given value.
 131.391 +    ///
 131.392 +    /// This function increases the priority of an item to the given value.
 131.393 +    /// \param i The item.
 131.394 +    /// \param p The priority.
 131.395 +    /// \pre \e i must be stored in the heap with priority at most \e p.
 131.396 +    void increase(const Item &i, const Prio &p) {
 131.397 +      int idx = _iim[i];
 131.398 +      _data[idx].prio = p;
 131.399 +      bubbleUp(idx);
 131.400 +    }
 131.401 +
 131.402 +    /// \brief Return the state of an item.
 131.403 +    ///
 131.404 +    /// This method returns \c PRE_HEAP if the given item has never
 131.405 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
 131.406 +    /// and \c POST_HEAP otherwise.
 131.407 +    /// In the latter case it is possible that the item will get back
 131.408 +    /// to the heap again.
 131.409 +    /// \param i The item.
 131.410 +    State state(const Item &i) const {
 131.411 +      int s = _iim[i];
 131.412 +      if( s >= 0 ) s = 0;
 131.413 +      return State(s);
 131.414 +    }
 131.415 +
 131.416 +    /// \brief Set the state of an item in the heap.
 131.417 +    ///
 131.418 +    /// This function sets the state of the given item in the heap.
 131.419 +    /// It can be used to manually clear the heap when it is important
 131.420 +    /// to achive better time complexity.
 131.421 +    /// \param i The item.
 131.422 +    /// \param st The state. It should not be \c IN_HEAP.
 131.423 +    void state(const Item& i, State st) {
 131.424 +      switch (st) {
 131.425 +      case POST_HEAP:
 131.426 +      case PRE_HEAP:
 131.427 +        if (state(i) == IN_HEAP) {
 131.428 +          erase(i);
 131.429 +        }
 131.430 +        _iim[i] = st;
 131.431 +        break;
 131.432 +      case IN_HEAP:
 131.433 +        break;
 131.434 +      }
 131.435 +    }
 131.436 +
 131.437 +  }; // class RadixHeap
 131.438 +
 131.439 +} // namespace lemon
 131.440 +
 131.441 +#endif // LEMON_RADIX_HEAP_H
   132.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   132.2 +++ b/lemon/radix_sort.h	Thu Nov 05 15:50:01 2009 +0100
   132.3 @@ -0,0 +1,487 @@
   132.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   132.5 + *
   132.6 + * This file is a part of LEMON, a generic C++ optimization library.
   132.7 + *
   132.8 + * Copyright (C) 2003-2009
   132.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  132.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  132.11 + *
  132.12 + * Permission to use, modify and distribute this software is granted
  132.13 + * provided that this copyright notice appears in all copies. For
  132.14 + * precise terms see the accompanying LICENSE file.
  132.15 + *
  132.16 + * This software is provided "AS IS" with no warranty of any kind,
  132.17 + * express or implied, and with no claim as to its suitability for any
  132.18 + * purpose.
  132.19 + *
  132.20 + */
  132.21 +
  132.22 +#ifndef RADIX_SORT_H
  132.23 +#define RADIX_SORT_H
  132.24 +
  132.25 +/// \ingroup auxalg
  132.26 +/// \file
  132.27 +/// \brief Radix sort
  132.28 +///
  132.29 +/// Linear time sorting algorithms
  132.30 +
  132.31 +#include <vector>
  132.32 +#include <limits>
  132.33 +#include <iterator>
  132.34 +#include <algorithm>
  132.35 +
  132.36 +namespace lemon {
  132.37 +
  132.38 +  namespace _radix_sort_bits {
  132.39 +
  132.40 +    template <typename Value>
  132.41 +    struct Identity {
  132.42 +      const Value& operator()(const Value& val) {
  132.43 +        return val;
  132.44 +      }
  132.45 +    };
  132.46 +
  132.47 +
  132.48 +    template <typename Value, typename Iterator, typename Functor>
  132.49 +    Iterator radixSortPartition(Iterator first, Iterator last,
  132.50 +                                Functor functor, Value mask) {
  132.51 +      while (first != last && !(functor(*first) & mask)) {
  132.52 +        ++first;
  132.53 +      }
  132.54 +      if (first == last) {
  132.55 +        return first;
  132.56 +      }
  132.57 +      --last;
  132.58 +      while (first != last && (functor(*last) & mask)) {
  132.59 +        --last;
  132.60 +      }
  132.61 +      if (first == last) {
  132.62 +        return first;
  132.63 +      }
  132.64 +      std::iter_swap(first, last);
  132.65 +      ++first;
  132.66 +      if (!(first < last)) {
  132.67 +        return first;
  132.68 +      }
  132.69 +      while (true) {
  132.70 +        while (!(functor(*first) & mask)) {
  132.71 +          ++first;
  132.72 +        }
  132.73 +        --last;
  132.74 +        while (functor(*last) & mask) {
  132.75 +          --last;
  132.76 +        }
  132.77 +        if (!(first < last)) {
  132.78 +          return first;
  132.79 +        }
  132.80 +        std::iter_swap(first, last);
  132.81 +        ++first;
  132.82 +      }
  132.83 +    }
  132.84 +
  132.85 +    template <typename Iterator, typename Functor>
  132.86 +    Iterator radixSortSignPartition(Iterator first, Iterator last,
  132.87 +                                    Functor functor) {
  132.88 +      while (first != last && functor(*first) < 0) {
  132.89 +        ++first;
  132.90 +      }
  132.91 +      if (first == last) {
  132.92 +        return first;
  132.93 +      }
  132.94 +      --last;
  132.95 +      while (first != last && functor(*last) >= 0) {
  132.96 +        --last;
  132.97 +      }
  132.98 +      if (first == last) {
  132.99 +        return first;
 132.100 +      }
 132.101 +      std::iter_swap(first, last);
 132.102 +      ++first;
 132.103 +      if (!(first < last)) {
 132.104 +        return first;
 132.105 +      }
 132.106 +      while (true) {
 132.107 +        while (functor(*first) < 0) {
 132.108 +          ++first;
 132.109 +        }
 132.110 +        --last;
 132.111 +        while (functor(*last) >= 0) {
 132.112 +          --last;
 132.113 +        }
 132.114 +        if (!(first < last)) {
 132.115 +          return first;
 132.116 +        }
 132.117 +        std::iter_swap(first, last);
 132.118 +        ++first;
 132.119 +      }
 132.120 +    }
 132.121 +
 132.122 +    template <typename Value, typename Iterator, typename Functor>
 132.123 +    void radixIntroSort(Iterator first, Iterator last,
 132.124 +                        Functor functor, Value mask) {
 132.125 +      while (mask != 0 && last - first > 1) {
 132.126 +        Iterator cut = radixSortPartition(first, last, functor, mask);
 132.127 +        mask >>= 1;
 132.128 +        radixIntroSort(first, cut, functor, mask);
 132.129 +        first = cut;
 132.130 +      }
 132.131 +    }
 132.132 +
 132.133 +    template <typename Value, typename Iterator, typename Functor>
 132.134 +    void radixSignedSort(Iterator first, Iterator last, Functor functor) {
 132.135 +
 132.136 +      Iterator cut = radixSortSignPartition(first, last, functor);
 132.137 +
 132.138 +      Value mask;
 132.139 +      int max_digit;
 132.140 +      Iterator it;
 132.141 +
 132.142 +      mask = ~0; max_digit = 0;
 132.143 +      for (it = first; it != cut; ++it) {
 132.144 +        while ((mask & functor(*it)) != mask) {
 132.145 +          ++max_digit;
 132.146 +          mask <<= 1;
 132.147 +        }
 132.148 +      }
 132.149 +      radixIntroSort(first, cut, functor, 1 << max_digit);
 132.150 +
 132.151 +      mask = 0; max_digit = 0;
 132.152 +      for (it = cut; it != last; ++it) {
 132.153 +        while ((mask | functor(*it)) != mask) {
 132.154 +          ++max_digit;
 132.155 +          mask <<= 1; mask |= 1;
 132.156 +        }
 132.157 +      }
 132.158 +      radixIntroSort(cut, last, functor, 1 << max_digit);
 132.159 +    }
 132.160 +
 132.161 +    template <typename Value, typename Iterator, typename Functor>
 132.162 +    void radixUnsignedSort(Iterator first, Iterator last, Functor functor) {
 132.163 +
 132.164 +      Value mask = 0;
 132.165 +      int max_digit = 0;
 132.166 +
 132.167 +      Iterator it;
 132.168 +      for (it = first; it != last; ++it) {
 132.169 +        while ((mask | functor(*it)) != mask) {
 132.170 +          ++max_digit;
 132.171 +          mask <<= 1; mask |= 1;
 132.172 +        }
 132.173 +      }
 132.174 +      radixIntroSort(first, last, functor, 1 << max_digit);
 132.175 +    }
 132.176 +
 132.177 +
 132.178 +    template <typename Value,
 132.179 +              bool sign = std::numeric_limits<Value>::is_signed >
 132.180 +    struct RadixSortSelector {
 132.181 +      template <typename Iterator, typename Functor>
 132.182 +      static void sort(Iterator first, Iterator last, Functor functor) {
 132.183 +        radixSignedSort<Value>(first, last, functor);
 132.184 +      }
 132.185 +    };
 132.186 +
 132.187 +    template <typename Value>
 132.188 +    struct RadixSortSelector<Value, false> {
 132.189 +      template <typename Iterator, typename Functor>
 132.190 +      static void sort(Iterator first, Iterator last, Functor functor) {
 132.191 +        radixUnsignedSort<Value>(first, last, functor);
 132.192 +      }
 132.193 +    };
 132.194 +
 132.195 +  }
 132.196 +
 132.197 +  /// \ingroup auxalg
 132.198 +  ///
 132.199 +  /// \brief Sorts the STL compatible range into ascending order.
 132.200 +  ///
 132.201 +  /// The \c radixSort sorts an STL compatible range into ascending
 132.202 +  /// order.  The radix sort algorithm can sort items which are mapped
 132.203 +  /// to integers with an adaptable unary function \c functor and the
 132.204 +  /// order will be ascending according to these mapped values.
 132.205 +  ///
 132.206 +  /// It is also possible to use a normal function instead
 132.207 +  /// of the functor object. If the functor is not given it will use
 132.208 +  /// the identity function instead.
 132.209 +  ///
 132.210 +  /// This is a special quick sort algorithm where the pivot
 132.211 +  /// values to split the items are choosen to be 2<sup>k</sup>
 132.212 +  /// for each \c k.
 132.213 +  /// Therefore, the time complexity of the algorithm is O(log(c)*n) and
 132.214 +  /// it uses O(log(c)) additional space, where \c c is the maximal value
 132.215 +  /// and \c n is the number of the items in the container.
 132.216 +  ///
 132.217 +  /// \param first The begin of the given range.
 132.218 +  /// \param last The end of the given range.
 132.219 +  /// \param functor An adaptible unary function or a normal function
 132.220 +  /// which maps the items to any integer type which can be either
 132.221 +  /// signed or unsigned.
 132.222 +  ///
 132.223 +  /// \sa stableRadixSort()
 132.224 +  template <typename Iterator, typename Functor>
 132.225 +  void radixSort(Iterator first, Iterator last, Functor functor) {
 132.226 +    using namespace _radix_sort_bits;
 132.227 +    typedef typename Functor::result_type Value;
 132.228 +    RadixSortSelector<Value>::sort(first, last, functor);
 132.229 +  }
 132.230 +
 132.231 +  template <typename Iterator, typename Value, typename Key>
 132.232 +  void radixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
 132.233 +    using namespace _radix_sort_bits;
 132.234 +    RadixSortSelector<Value>::sort(first, last, functor);
 132.235 +  }
 132.236 +
 132.237 +  template <typename Iterator, typename Value, typename Key>
 132.238 +  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
 132.239 +    using namespace _radix_sort_bits;
 132.240 +    RadixSortSelector<Value>::sort(first, last, functor);
 132.241 +  }
 132.242 +
 132.243 +  template <typename Iterator, typename Value, typename Key>
 132.244 +  void radixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
 132.245 +    using namespace _radix_sort_bits;
 132.246 +    RadixSortSelector<Value>::sort(first, last, functor);
 132.247 +  }
 132.248 +
 132.249 +  template <typename Iterator, typename Value, typename Key>
 132.250 +  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
 132.251 +    using namespace _radix_sort_bits;
 132.252 +    RadixSortSelector<Value>::sort(first, last, functor);
 132.253 +  }
 132.254 +
 132.255 +  template <typename Iterator>
 132.256 +  void radixSort(Iterator first, Iterator last) {
 132.257 +    using namespace _radix_sort_bits;
 132.258 +    typedef typename std::iterator_traits<Iterator>::value_type Value;
 132.259 +    RadixSortSelector<Value>::sort(first, last, Identity<Value>());
 132.260 +  }
 132.261 +
 132.262 +  namespace _radix_sort_bits {
 132.263 +
 132.264 +    template <typename Value>
 132.265 +    unsigned char valueByte(Value value, int byte) {
 132.266 +      return value >> (std::numeric_limits<unsigned char>::digits * byte);
 132.267 +    }
 132.268 +
 132.269 +    template <typename Functor, typename Key>
 132.270 +    void stableRadixIntroSort(Key *first, Key *last, Key *target,
 132.271 +                              int byte, Functor functor) {
 132.272 +      const int size =
 132.273 +        unsigned(std::numeric_limits<unsigned char>::max()) + 1;
 132.274 +      std::vector<int> counter(size);
 132.275 +      for (int i = 0; i < size; ++i) {
 132.276 +        counter[i] = 0;
 132.277 +      }
 132.278 +      Key *it = first;
 132.279 +      while (first != last) {
 132.280 +        ++counter[valueByte(functor(*first), byte)];
 132.281 +        ++first;
 132.282 +      }
 132.283 +      int prev, num = 0;
 132.284 +      for (int i = 0; i < size; ++i) {
 132.285 +        prev = num;
 132.286 +        num += counter[i];
 132.287 +        counter[i] = prev;
 132.288 +      }
 132.289 +      while (it != last) {
 132.290 +        target[counter[valueByte(functor(*it), byte)]++] = *it;
 132.291 +        ++it;
 132.292 +      }
 132.293 +    }
 132.294 +
 132.295 +    template <typename Functor, typename Key>
 132.296 +    void signedStableRadixIntroSort(Key *first, Key *last, Key *target,
 132.297 +                                    int byte, Functor functor) {
 132.298 +      const int size =
 132.299 +        unsigned(std::numeric_limits<unsigned char>::max()) + 1;
 132.300 +      std::vector<int> counter(size);
 132.301 +      for (int i = 0; i < size; ++i) {
 132.302 +        counter[i] = 0;
 132.303 +      }
 132.304 +      Key *it = first;
 132.305 +      while (first != last) {
 132.306 +        counter[valueByte(functor(*first), byte)]++;
 132.307 +        ++first;
 132.308 +      }
 132.309 +      int prev, num = 0;
 132.310 +      for (int i = size / 2; i < size; ++i) {
 132.311 +        prev = num;
 132.312 +        num += counter[i];
 132.313 +        counter[i] = prev;
 132.314 +      }
 132.315 +      for (int i = 0; i < size / 2; ++i) {
 132.316 +        prev = num;
 132.317 +        num += counter[i];
 132.318 +        counter[i] = prev;
 132.319 +      }
 132.320 +      while (it != last) {
 132.321 +        target[counter[valueByte(functor(*it), byte)]++] = *it;
 132.322 +        ++it;
 132.323 +      }
 132.324 +    }
 132.325 +
 132.326 +
 132.327 +    template <typename Value, typename Iterator, typename Functor>
 132.328 +    void stableRadixSignedSort(Iterator first, Iterator last, Functor functor) {
 132.329 +      if (first == last) return;
 132.330 +      typedef typename std::iterator_traits<Iterator>::value_type Key;
 132.331 +      typedef std::allocator<Key> Allocator;
 132.332 +      Allocator allocator;
 132.333 +
 132.334 +      int length = std::distance(first, last);
 132.335 +      Key* buffer = allocator.allocate(2 * length);
 132.336 +      try {
 132.337 +        bool dir = true;
 132.338 +        std::copy(first, last, buffer);
 132.339 +        for (int i = 0; i < int(sizeof(Value)) - 1; ++i) {
 132.340 +          if (dir) {
 132.341 +            stableRadixIntroSort(buffer, buffer + length, buffer + length,
 132.342 +                                 i, functor);
 132.343 +          } else {
 132.344 +            stableRadixIntroSort(buffer + length, buffer + 2 * length, buffer,
 132.345 +                                 i, functor);
 132.346 +          }
 132.347 +          dir = !dir;
 132.348 +        }
 132.349 +        if (dir) {
 132.350 +          signedStableRadixIntroSort(buffer, buffer + length, buffer + length,
 132.351 +                                     sizeof(Value) - 1, functor);
 132.352 +          std::copy(buffer + length, buffer + 2 * length, first);
 132.353 +        }        else {
 132.354 +          signedStableRadixIntroSort(buffer + length, buffer + 2 * length,
 132.355 +                                     buffer, sizeof(Value) - 1, functor);
 132.356 +          std::copy(buffer, buffer + length, first);
 132.357 +        }
 132.358 +      } catch (...) {
 132.359 +        allocator.deallocate(buffer, 2 * length);
 132.360 +        throw;
 132.361 +      }
 132.362 +      allocator.deallocate(buffer, 2 * length);
 132.363 +    }
 132.364 +
 132.365 +    template <typename Value, typename Iterator, typename Functor>
 132.366 +    void stableRadixUnsignedSort(Iterator first, Iterator last,
 132.367 +                                 Functor functor) {
 132.368 +      if (first == last) return;
 132.369 +      typedef typename std::iterator_traits<Iterator>::value_type Key;
 132.370 +      typedef std::allocator<Key> Allocator;
 132.371 +      Allocator allocator;
 132.372 +
 132.373 +      int length = std::distance(first, last);
 132.374 +      Key *buffer = allocator.allocate(2 * length);
 132.375 +      try {
 132.376 +        bool dir = true;
 132.377 +        std::copy(first, last, buffer);
 132.378 +        for (int i = 0; i < int(sizeof(Value)); ++i) {
 132.379 +          if (dir) {
 132.380 +            stableRadixIntroSort(buffer, buffer + length,
 132.381 +                                 buffer + length, i, functor);
 132.382 +          } else {
 132.383 +            stableRadixIntroSort(buffer + length, buffer + 2 * length,
 132.384 +                                 buffer, i, functor);
 132.385 +          }
 132.386 +          dir = !dir;
 132.387 +        }
 132.388 +        if (dir) {
 132.389 +          std::copy(buffer, buffer + length, first);
 132.390 +        }        else {
 132.391 +          std::copy(buffer + length, buffer + 2 * length, first);
 132.392 +        }
 132.393 +      } catch (...) {
 132.394 +        allocator.deallocate(buffer, 2 * length);
 132.395 +        throw;
 132.396 +      }
 132.397 +      allocator.deallocate(buffer, 2 * length);
 132.398 +    }
 132.399 +
 132.400 +
 132.401 +
 132.402 +    template <typename Value,
 132.403 +              bool sign = std::numeric_limits<Value>::is_signed >
 132.404 +    struct StableRadixSortSelector {
 132.405 +      template <typename Iterator, typename Functor>
 132.406 +      static void sort(Iterator first, Iterator last, Functor functor) {
 132.407 +        stableRadixSignedSort<Value>(first, last, functor);
 132.408 +      }
 132.409 +    };
 132.410 +
 132.411 +    template <typename Value>
 132.412 +    struct StableRadixSortSelector<Value, false> {
 132.413 +      template <typename Iterator, typename Functor>
 132.414 +      static void sort(Iterator first, Iterator last, Functor functor) {
 132.415 +        stableRadixUnsignedSort<Value>(first, last, functor);
 132.416 +      }
 132.417 +    };
 132.418 +
 132.419 +  }
 132.420 +
 132.421 +  /// \ingroup auxalg
 132.422 +  ///
 132.423 +  /// \brief Sorts the STL compatible range into ascending order in a stable
 132.424 +  /// way.
 132.425 +  ///
 132.426 +  /// This function sorts an STL compatible range into ascending
 132.427 +  /// order according to an integer mapping in the same as radixSort() does.
 132.428 +  ///
 132.429 +  /// This sorting algorithm is stable, i.e. the order of two equal
 132.430 +  /// elements remains the same after the sorting.
 132.431 +  ///
 132.432 +  /// This sort algorithm  use a radix forward sort on the
 132.433 +  /// bytes of the integer number. The algorithm sorts the items
 132.434 +  /// byte-by-byte. First, it counts how many times a byte value occurs
 132.435 +  /// in the container, then it copies the corresponding items to
 132.436 +  /// another container in asceding order in O(n) time.
 132.437 +  ///
 132.438 +  /// The time complexity of the algorithm is O(log(c)*n) and
 132.439 +  /// it uses O(n) additional space, where \c c is the
 132.440 +  /// maximal value and \c n is the number of the items in the
 132.441 +  /// container.
 132.442 +  ///
 132.443 +
 132.444 +  /// \param first The begin of the given range.
 132.445 +  /// \param last The end of the given range.
 132.446 +  /// \param functor An adaptible unary function or a normal function
 132.447 +  /// which maps the items to any integer type which can be either
 132.448 +  /// signed or unsigned.
 132.449 +  /// \sa radixSort()
 132.450 +  template <typename Iterator, typename Functor>
 132.451 +  void stableRadixSort(Iterator first, Iterator last, Functor functor) {
 132.452 +    using namespace _radix_sort_bits;
 132.453 +    typedef typename Functor::result_type Value;
 132.454 +    StableRadixSortSelector<Value>::sort(first, last, functor);
 132.455 +  }
 132.456 +
 132.457 +  template <typename Iterator, typename Value, typename Key>
 132.458 +  void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
 132.459 +    using namespace _radix_sort_bits;
 132.460 +    StableRadixSortSelector<Value>::sort(first, last, functor);
 132.461 +  }
 132.462 +
 132.463 +  template <typename Iterator, typename Value, typename Key>
 132.464 +  void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
 132.465 +    using namespace _radix_sort_bits;
 132.466 +    StableRadixSortSelector<Value>::sort(first, last, functor);
 132.467 +  }
 132.468 +
 132.469 +  template <typename Iterator, typename Value, typename Key>
 132.470 +  void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
 132.471 +    using namespace _radix_sort_bits;
 132.472 +    StableRadixSortSelector<Value>::sort(first, last, functor);
 132.473 +  }
 132.474 +
 132.475 +  template <typename Iterator, typename Value, typename Key>
 132.476 +  void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
 132.477 +    using namespace _radix_sort_bits;
 132.478 +    StableRadixSortSelector<Value>::sort(first, last, functor);
 132.479 +  }
 132.480 +
 132.481 +  template <typename Iterator>
 132.482 +  void stableRadixSort(Iterator first, Iterator last) {
 132.483 +    using namespace _radix_sort_bits;
 132.484 +    typedef typename std::iterator_traits<Iterator>::value_type Value;
 132.485 +    StableRadixSortSelector<Value>::sort(first, last, Identity<Value>());
 132.486 +  }
 132.487 +
 132.488 +}
 132.489 +
 132.490 +#endif
   133.1 --- a/lemon/random.cc	Fri Oct 16 10:21:37 2009 +0200
   133.2 +++ b/lemon/random.cc	Thu Nov 05 15:50:01 2009 +0100
   133.3 @@ -2,7 +2,7 @@
   133.4   *
   133.5   * This file is a part of LEMON, a generic C++ optimization library.
   133.6   *
   133.7 - * Copyright (C) 2003-2008
   133.8 + * Copyright (C) 2003-2009
   133.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  133.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  133.11   *
   134.1 --- a/lemon/random.h	Fri Oct 16 10:21:37 2009 +0200
   134.2 +++ b/lemon/random.h	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   134.8 + * Copyright (C) 2003-2009
   134.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  134.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  134.11   *
  134.12 @@ -530,10 +530,6 @@
  134.13      ///
  134.14      /// @{
  134.15  
  134.16 -    ///\name Initialization
  134.17 -    ///
  134.18 -    /// @{
  134.19 -
  134.20      /// \brief Default constructor
  134.21      ///
  134.22      /// Constructor with constant seeding.
  134.23 @@ -607,7 +603,7 @@
  134.24      /// By default, this function calls the \c seedFromFile() member
  134.25      /// function with the <tt>/dev/urandom</tt> file. If it does not success,
  134.26      /// it uses the \c seedFromTime().
  134.27 -    /// \return Currently always true.
  134.28 +    /// \return Currently always \c true.
  134.29      bool seed() {
  134.30  #ifndef WIN32
  134.31        if (seedFromFile("/dev/urandom", 0)) return true;
  134.32 @@ -628,7 +624,7 @@
  134.33      /// entropy).
  134.34      /// \param file The source file
  134.35      /// \param offset The offset, from the file read.
  134.36 -    /// \return True when the seeding successes.
  134.37 +    /// \return \c true when the seeding successes.
  134.38  #ifndef WIN32
  134.39      bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
  134.40  #else
  134.41 @@ -649,7 +645,7 @@
  134.42      /// Seding from process id and time. This function uses the
  134.43      /// current process id and the current time for initialize the
  134.44      /// random sequence.
  134.45 -    /// \return Currently always true.
  134.46 +    /// \return Currently always \c true.
  134.47      bool seedFromTime() {
  134.48  #ifndef WIN32
  134.49        timeval tv;
  134.50 @@ -663,7 +659,7 @@
  134.51  
  134.52      /// @}
  134.53  
  134.54 -    ///\name Uniform distributions
  134.55 +    ///\name Uniform Distributions
  134.56      ///
  134.57      /// @{
  134.58  
  134.59 @@ -680,12 +676,6 @@
  134.60        return real<double>();
  134.61      }
  134.62  
  134.63 -    /// @}
  134.64 -
  134.65 -    ///\name Uniform distributions
  134.66 -    ///
  134.67 -    /// @{
  134.68 -
  134.69      /// \brief Returns a random real number from the range [0, 1)
  134.70      ///
  134.71      /// It returns a random double from the range [0, 1).
  134.72 @@ -741,8 +731,6 @@
  134.73        return _random_bits::IntConversion<Number, Word>::convert(core);
  134.74      }
  134.75  
  134.76 -    /// @}
  134.77 -
  134.78      unsigned int uinteger() {
  134.79        return uinteger<unsigned int>();
  134.80      }
  134.81 @@ -774,21 +762,20 @@
  134.82  
  134.83      /// @}
  134.84  
  134.85 -    ///\name Non-uniform distributions
  134.86 +    ///\name Non-uniform Distributions
  134.87      ///
  134.88 -
  134.89      ///@{
  134.90  
  134.91 -    /// \brief Returns a random bool
  134.92 +    /// \brief Returns a random bool with given probability of true result.
  134.93      ///
  134.94      /// It returns a random bool with given probability of true result.
  134.95      bool boolean(double p) {
  134.96        return operator()() < p;
  134.97      }
  134.98  
  134.99 -    /// Standard Gauss distribution
 134.100 +    /// Standard normal (Gauss) distribution
 134.101  
 134.102 -    /// Standard Gauss distribution.
 134.103 +    /// Standard normal (Gauss) distribution.
 134.104      /// \note The Cartesian form of the Box-Muller
 134.105      /// transformation is used to generate a random normal distribution.
 134.106      double gauss()
 134.107 @@ -801,15 +788,55 @@
 134.108        } while(S>=1);
 134.109        return std::sqrt(-2*std::log(S)/S)*V1;
 134.110      }
 134.111 -    /// Gauss distribution with given mean and standard deviation
 134.112 +    /// Normal (Gauss) distribution with given mean and standard deviation
 134.113  
 134.114 -    /// Gauss distribution with given mean and standard deviation.
 134.115 +    /// Normal (Gauss) distribution with given mean and standard deviation.
 134.116      /// \sa gauss()
 134.117      double gauss(double mean,double std_dev)
 134.118      {
 134.119        return gauss()*std_dev+mean;
 134.120      }
 134.121  
 134.122 +    /// Lognormal distribution
 134.123 +
 134.124 +    /// Lognormal distribution. The parameters are the mean and the standard
 134.125 +    /// deviation of <tt>exp(X)</tt>.
 134.126 +    ///
 134.127 +    double lognormal(double n_mean,double n_std_dev)
 134.128 +    {
 134.129 +      return std::exp(gauss(n_mean,n_std_dev));
 134.130 +    }
 134.131 +    /// Lognormal distribution
 134.132 +
 134.133 +    /// Lognormal distribution. The parameter is an <tt>std::pair</tt> of
 134.134 +    /// the mean and the standard deviation of <tt>exp(X)</tt>.
 134.135 +    ///
 134.136 +    double lognormal(const std::pair<double,double> &params)
 134.137 +    {
 134.138 +      return std::exp(gauss(params.first,params.second));
 134.139 +    }
 134.140 +    /// Compute the lognormal parameters from mean and standard deviation
 134.141 +
 134.142 +    /// This function computes the lognormal parameters from mean and
 134.143 +    /// standard deviation. The return value can direcly be passed to
 134.144 +    /// lognormal().
 134.145 +    std::pair<double,double> lognormalParamsFromMD(double mean,
 134.146 +                                                   double std_dev)
 134.147 +    {
 134.148 +      double fr=std_dev/mean;
 134.149 +      fr*=fr;
 134.150 +      double lg=std::log(1+fr);
 134.151 +      return std::pair<double,double>(std::log(mean)-lg/2.0,std::sqrt(lg));
 134.152 +    }
 134.153 +    /// Lognormal distribution with given mean and standard deviation
 134.154 +
 134.155 +    /// Lognormal distribution with given mean and standard deviation.
 134.156 +    ///
 134.157 +    double lognormalMD(double mean,double std_dev)
 134.158 +    {
 134.159 +      return lognormal(lognormalParamsFromMD(mean,std_dev));
 134.160 +    }
 134.161 +
 134.162      /// Exponential distribution with given mean
 134.163  
 134.164      /// This function generates an exponential distribution random number
 134.165 @@ -911,9 +938,8 @@
 134.166  
 134.167      ///@}
 134.168  
 134.169 -    ///\name Two dimensional distributions
 134.170 +    ///\name Two Dimensional Distributions
 134.171      ///
 134.172 -
 134.173      ///@{
 134.174  
 134.175      /// Uniform distribution on the full unit circle
 134.176 @@ -930,7 +956,7 @@
 134.177        } while(V1*V1+V2*V2>=1);
 134.178        return dim2::Point<double>(V1,V2);
 134.179      }
 134.180 -    /// A kind of two dimensional Gauss distribution
 134.181 +    /// A kind of two dimensional normal (Gauss) distribution
 134.182  
 134.183      /// This function provides a turning symmetric two-dimensional distribution.
 134.184      /// Both coordinates are of standard normal distribution, but they are not
   135.1 --- a/lemon/smart_graph.h	Fri Oct 16 10:21:37 2009 +0200
   135.2 +++ b/lemon/smart_graph.h	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   135.8 + * Copyright (C) 2003-2009
   135.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  135.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  135.11   *
  135.12 @@ -32,10 +32,7 @@
  135.13  namespace lemon {
  135.14  
  135.15    class SmartDigraph;
  135.16 -  ///Base of SmartDigraph
  135.17  
  135.18 -  ///Base of SmartDigraph
  135.19 -  ///
  135.20    class SmartDigraphBase {
  135.21    protected:
  135.22  
  135.23 @@ -55,7 +52,7 @@
  135.24  
  135.25    public:
  135.26  
  135.27 -    typedef SmartDigraphBase Graph;
  135.28 +    typedef SmartDigraphBase Digraph;
  135.29  
  135.30      class Node;
  135.31      class Arc;
  135.32 @@ -67,7 +64,7 @@
  135.33        : nodes(_g.nodes), arcs(_g.arcs) { }
  135.34  
  135.35      typedef True NodeNumTag;
  135.36 -    typedef True EdgeNumTag;
  135.37 +    typedef True ArcNumTag;
  135.38  
  135.39      int nodeNum() const { return nodes.size(); }
  135.40      int arcNum() const { return arcs.size(); }
  135.41 @@ -187,32 +184,26 @@
  135.42    ///
  135.43    ///\brief A smart directed graph class.
  135.44    ///
  135.45 -  ///This is a simple and fast digraph implementation.
  135.46 -  ///It is also quite memory efficient, but at the price
  135.47 -  ///that <b> it does support only limited (only stack-like)
  135.48 -  ///node and arc deletions</b>.
  135.49 -  ///It conforms to the \ref concepts::Digraph "Digraph concept" with
  135.50 -  ///an important extra feature that its maps are real \ref
  135.51 -  ///concepts::ReferenceMap "reference map"s.
  135.52 +  ///\ref SmartDigraph is a simple and fast digraph implementation.
  135.53 +  ///It is also quite memory efficient but at the price
  135.54 +  ///that it does not support node and arc deletion 
  135.55 +  ///(except for the Snapshot feature).
  135.56    ///
  135.57 -  ///\sa concepts::Digraph.
  135.58 +  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
  135.59 +  ///and it also provides some additional functionalities.
  135.60 +  ///Most of its member functions and nested classes are documented
  135.61 +  ///only in the concept class.
  135.62 +  ///
  135.63 +  ///\sa concepts::Digraph
  135.64 +  ///\sa SmartGraph
  135.65    class SmartDigraph : public ExtendedSmartDigraphBase {
  135.66 -  public:
  135.67 -
  135.68      typedef ExtendedSmartDigraphBase Parent;
  135.69  
  135.70    private:
  135.71 -
  135.72 -    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
  135.73 -
  135.74 -    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
  135.75 -    ///
  135.76 +    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
  135.77      SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
  135.78 -    ///\brief Assignment of SmartDigraph to another one is \e not allowed.
  135.79 -    ///Use DigraphCopy() instead.
  135.80 -
  135.81 -    ///Assignment of SmartDigraph to another one is \e not allowed.
  135.82 -    ///Use DigraphCopy() instead.
  135.83 +    /// \brief Assignment of a digraph to another one is \e not allowed.
  135.84 +    /// Use DigraphCopy instead.
  135.85      void operator=(const SmartDigraph &) {}
  135.86  
  135.87    public:
  135.88 @@ -225,79 +216,49 @@
  135.89  
  135.90      ///Add a new node to the digraph.
  135.91  
  135.92 -    /// \return the new node.
  135.93 -    ///
  135.94 +    ///This function adds a new node to the digraph.
  135.95 +    ///\return The new node.
  135.96      Node addNode() { return Parent::addNode(); }
  135.97  
  135.98      ///Add a new arc to the digraph.
  135.99  
 135.100 -    ///Add a new arc to the digraph with source node \c s
 135.101 +    ///This function adds a new arc to the digraph with source node \c s
 135.102      ///and target node \c t.
 135.103 -    ///\return the new arc.
 135.104 -    Arc addArc(const Node& s, const Node& t) {
 135.105 +    ///\return The new arc.
 135.106 +    Arc addArc(Node s, Node t) {
 135.107        return Parent::addArc(s, t);
 135.108      }
 135.109  
 135.110 -    /// \brief Using this it is possible to avoid the superfluous memory
 135.111 -    /// allocation.
 135.112 -
 135.113 -    /// Using this it is possible to avoid the superfluous memory
 135.114 -    /// allocation: if you know that the digraph you want to build will
 135.115 -    /// be very large (e.g. it will contain millions of nodes and/or arcs)
 135.116 -    /// then it is worth reserving space for this amount before starting
 135.117 -    /// to build the digraph.
 135.118 -    /// \sa reserveArc
 135.119 -    void reserveNode(int n) { nodes.reserve(n); };
 135.120 -
 135.121 -    /// \brief Using this it is possible to avoid the superfluous memory
 135.122 -    /// allocation.
 135.123 -
 135.124 -    /// Using this it is possible to avoid the superfluous memory
 135.125 -    /// allocation: if you know that the digraph you want to build will
 135.126 -    /// be very large (e.g. it will contain millions of nodes and/or arcs)
 135.127 -    /// then it is worth reserving space for this amount before starting
 135.128 -    /// to build the digraph.
 135.129 -    /// \sa reserveNode
 135.130 -    void reserveArc(int m) { arcs.reserve(m); };
 135.131 -
 135.132      /// \brief Node validity check
 135.133      ///
 135.134 -    /// This function gives back true if the given node is valid,
 135.135 -    /// ie. it is a real node of the graph.
 135.136 +    /// This function gives back \c true if the given node is valid,
 135.137 +    /// i.e. it is a real node of the digraph.
 135.138      ///
 135.139      /// \warning A removed node (using Snapshot) could become valid again
 135.140 -    /// when new nodes are added to the graph.
 135.141 +    /// if new nodes are added to the digraph.
 135.142      bool valid(Node n) const { return Parent::valid(n); }
 135.143  
 135.144      /// \brief Arc validity check
 135.145      ///
 135.146 -    /// This function gives back true if the given arc is valid,
 135.147 -    /// ie. it is a real arc of the graph.
 135.148 +    /// This function gives back \c true if the given arc is valid,
 135.149 +    /// i.e. it is a real arc of the digraph.
 135.150      ///
 135.151      /// \warning A removed arc (using Snapshot) could become valid again
 135.152 -    /// when new arcs are added to the graph.
 135.153 +    /// if new arcs are added to the graph.
 135.154      bool valid(Arc a) const { return Parent::valid(a); }
 135.155  
 135.156 -    ///Clear the digraph.
 135.157 -
 135.158 -    ///Erase all the nodes and arcs from the digraph.
 135.159 -    ///
 135.160 -    void clear() {
 135.161 -      Parent::clear();
 135.162 -    }
 135.163 -
 135.164      ///Split a node.
 135.165  
 135.166 -    ///This function splits a node. First a new node is added to the digraph,
 135.167 -    ///then the source of each outgoing arc of \c n is moved to this new node.
 135.168 -    ///If \c connect is \c true (this is the default value), then a new arc
 135.169 -    ///from \c n to the newly created node is also added.
 135.170 +    ///This function splits the given node. First, a new node is added
 135.171 +    ///to the digraph, then the source of each outgoing arc of node \c n
 135.172 +    ///is moved to this new node.
 135.173 +    ///If the second parameter \c connect is \c true (this is the default
 135.174 +    ///value), then a new arc from node \c n to the newly created node
 135.175 +    ///is also added.
 135.176      ///\return The newly created node.
 135.177      ///
 135.178 -    ///\note The <tt>Arc</tt>s
 135.179 -    ///referencing a moved arc remain
 135.180 -    ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
 135.181 -    ///may be invalidated.
 135.182 +    ///\note All iterators remain valid.
 135.183 +    ///
 135.184      ///\warning This functionality cannot be used together with the Snapshot
 135.185      ///feature.
 135.186      Node split(Node n, bool connect = true)
 135.187 @@ -305,11 +266,41 @@
 135.188        Node b = addNode();
 135.189        nodes[b._id].first_out=nodes[n._id].first_out;
 135.190        nodes[n._id].first_out=-1;
 135.191 -      for(int i=nodes[b._id].first_out;i!=-1;i++) arcs[i].source=b._id;
 135.192 +      for(int i=nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) {
 135.193 +        arcs[i].source=b._id;
 135.194 +      }
 135.195        if(connect) addArc(n,b);
 135.196        return b;
 135.197      }
 135.198  
 135.199 +    ///Clear the digraph.
 135.200 +
 135.201 +    ///This function erases all nodes and arcs from the digraph.
 135.202 +    ///
 135.203 +    void clear() {
 135.204 +      Parent::clear();
 135.205 +    }
 135.206 +
 135.207 +    /// Reserve memory for nodes.
 135.208 +
 135.209 +    /// Using this function, it is possible to avoid superfluous memory
 135.210 +    /// allocation: if you know that the digraph you want to build will
 135.211 +    /// be large (e.g. it will contain millions of nodes and/or arcs),
 135.212 +    /// then it is worth reserving space for this amount before starting
 135.213 +    /// to build the digraph.
 135.214 +    /// \sa reserveArc()
 135.215 +    void reserveNode(int n) { nodes.reserve(n); };
 135.216 +
 135.217 +    /// Reserve memory for arcs.
 135.218 +
 135.219 +    /// Using this function, it is possible to avoid superfluous memory
 135.220 +    /// allocation: if you know that the digraph you want to build will
 135.221 +    /// be large (e.g. it will contain millions of nodes and/or arcs),
 135.222 +    /// then it is worth reserving space for this amount before starting
 135.223 +    /// to build the digraph.
 135.224 +    /// \sa reserveNode()
 135.225 +    void reserveArc(int m) { arcs.reserve(m); };
 135.226 +
 135.227    public:
 135.228  
 135.229      class Snapshot;
 135.230 @@ -334,20 +325,23 @@
 135.231  
 135.232    public:
 135.233  
 135.234 -    ///Class to make a snapshot of the digraph and to restrore to it later.
 135.235 +    ///Class to make a snapshot of the digraph and to restore it later.
 135.236  
 135.237 -    ///Class to make a snapshot of the digraph and to restrore to it later.
 135.238 +    ///Class to make a snapshot of the digraph and to restore it later.
 135.239      ///
 135.240      ///The newly added nodes and arcs can be removed using the
 135.241 -    ///restore() function.
 135.242 -    ///\note After you restore a state, you cannot restore
 135.243 -    ///a later state, in other word you cannot add again the arcs deleted
 135.244 -    ///by restore() using another one Snapshot instance.
 135.245 +    ///restore() function. This is the only way for deleting nodes and/or
 135.246 +    ///arcs from a SmartDigraph structure.
 135.247      ///
 135.248 -    ///\warning If you do not use correctly the snapshot that can cause
 135.249 -    ///either broken program, invalid state of the digraph, valid but
 135.250 -    ///not the restored digraph or no change. Because the runtime performance
 135.251 -    ///the validity of the snapshot is not stored.
 135.252 +    ///\note After a state is restored, you cannot restore a later state, 
 135.253 +    ///i.e. you cannot add the removed nodes and arcs again using
 135.254 +    ///another Snapshot instance.
 135.255 +    ///
 135.256 +    ///\warning Node splitting cannot be restored.
 135.257 +    ///\warning The validity of the snapshot is not stored due to
 135.258 +    ///performance reasons. If you do not use the snapshot correctly,
 135.259 +    ///it can cause broken program, invalid or not restored state of
 135.260 +    ///the digraph or no change.
 135.261      class Snapshot
 135.262      {
 135.263        SmartDigraph *_graph;
 135.264 @@ -359,39 +353,32 @@
 135.265        ///Default constructor.
 135.266  
 135.267        ///Default constructor.
 135.268 -      ///To actually make a snapshot you must call save().
 135.269 -      ///
 135.270 +      ///You have to call save() to actually make a snapshot.
 135.271        Snapshot() : _graph(0) {}
 135.272        ///Constructor that immediately makes a snapshot
 135.273  
 135.274 -      ///This constructor immediately makes a snapshot of the digraph.
 135.275 -      ///\param graph The digraph we make a snapshot of.
 135.276 -      Snapshot(SmartDigraph &graph) : _graph(&graph) {
 135.277 +      ///This constructor immediately makes a snapshot of the given digraph.
 135.278 +      ///
 135.279 +      Snapshot(SmartDigraph &gr) : _graph(&gr) {
 135.280          node_num=_graph->nodes.size();
 135.281          arc_num=_graph->arcs.size();
 135.282        }
 135.283  
 135.284        ///Make a snapshot.
 135.285  
 135.286 -      ///Make a snapshot of the digraph.
 135.287 -      ///
 135.288 -      ///This function can be called more than once. In case of a repeated
 135.289 +      ///This function makes a snapshot of the given digraph.
 135.290 +      ///It can be called more than once. In case of a repeated
 135.291        ///call, the previous snapshot gets lost.
 135.292 -      ///\param graph The digraph we make the snapshot of.
 135.293 -      void save(SmartDigraph &graph)
 135.294 -      {
 135.295 -        _graph=&graph;
 135.296 +      void save(SmartDigraph &gr) {
 135.297 +        _graph=&gr;
 135.298          node_num=_graph->nodes.size();
 135.299          arc_num=_graph->arcs.size();
 135.300        }
 135.301  
 135.302        ///Undo the changes until a snapshot.
 135.303  
 135.304 -      ///Undo the changes until a snapshot created by save().
 135.305 -      ///
 135.306 -      ///\note After you restored a state, you cannot restore
 135.307 -      ///a later state, in other word you cannot add again the arcs deleted
 135.308 -      ///by restore().
 135.309 +      ///This function undos the changes until the last snapshot
 135.310 +      ///created by save() or Snapshot(SmartDigraph&).
 135.311        void restore()
 135.312        {
 135.313          _graph->restoreSnapshot(*this);
 135.314 @@ -420,7 +407,7 @@
 135.315  
 135.316    public:
 135.317  
 135.318 -    typedef SmartGraphBase Digraph;
 135.319 +    typedef SmartGraphBase Graph;
 135.320  
 135.321      class Node;
 135.322      class Arc;
 135.323 @@ -464,8 +451,8 @@
 135.324        explicit Arc(int id) { _id = id;}
 135.325  
 135.326      public:
 135.327 -      operator Edge() const { 
 135.328 -        return _id != -1 ? edgeFromId(_id / 2) : INVALID; 
 135.329 +      operator Edge() const {
 135.330 +        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
 135.331        }
 135.332  
 135.333        Arc() {}
 135.334 @@ -480,6 +467,13 @@
 135.335      SmartGraphBase()
 135.336        : nodes(), arcs() {}
 135.337  
 135.338 +    typedef True NodeNumTag;
 135.339 +    typedef True EdgeNumTag;
 135.340 +    typedef True ArcNumTag;
 135.341 +
 135.342 +    int nodeNum() const { return nodes.size(); }
 135.343 +    int edgeNum() const { return arcs.size() / 2; }
 135.344 +    int arcNum() const { return arcs.size(); }
 135.345  
 135.346      int maxNodeId() const { return nodes.size()-1; }
 135.347      int maxEdgeId() const { return arcs.size() / 2 - 1; }
 135.348 @@ -503,7 +497,7 @@
 135.349        node._id = nodes.size() - 1;
 135.350      }
 135.351  
 135.352 -    void next(Node& node) const {
 135.353 +    static void next(Node& node) {
 135.354        --node._id;
 135.355      }
 135.356  
 135.357 @@ -511,7 +505,7 @@
 135.358        arc._id = arcs.size() - 1;
 135.359      }
 135.360  
 135.361 -    void next(Arc& arc) const {
 135.362 +    static void next(Arc& arc) {
 135.363        --arc._id;
 135.364      }
 135.365  
 135.366 @@ -519,7 +513,7 @@
 135.367        arc._id = arcs.size() / 2 - 1;
 135.368      }
 135.369  
 135.370 -    void next(Edge& arc) const {
 135.371 +    static void next(Edge& arc) {
 135.372        --arc._id;
 135.373      }
 135.374  
 135.375 @@ -616,95 +610,107 @@
 135.376    ///
 135.377    /// \brief A smart undirected graph class.
 135.378    ///
 135.379 -  /// This is a simple and fast graph implementation.
 135.380 -  /// It is also quite memory efficient, but at the price
 135.381 -  /// that <b> it does support only limited (only stack-like)
 135.382 -  /// node and arc deletions</b>.
 135.383 -  /// Except from this it conforms to
 135.384 -  /// the \ref concepts::Graph "Graph concept".
 135.385 +  /// \ref SmartGraph is a simple and fast graph implementation.
 135.386 +  /// It is also quite memory efficient but at the price
 135.387 +  /// that it does not support node and edge deletion 
 135.388 +  /// (except for the Snapshot feature).
 135.389    ///
 135.390 -  /// It also has an
 135.391 -  /// important extra feature that
 135.392 -  /// its maps are real \ref concepts::ReferenceMap "reference map"s.
 135.393 +  /// This type fully conforms to the \ref concepts::Graph "Graph concept"
 135.394 +  /// and it also provides some additional functionalities.
 135.395 +  /// Most of its member functions and nested classes are documented
 135.396 +  /// only in the concept class.
 135.397    ///
 135.398 -  /// \sa concepts::Graph.
 135.399 -  ///
 135.400 +  /// \sa concepts::Graph
 135.401 +  /// \sa SmartDigraph
 135.402    class SmartGraph : public ExtendedSmartGraphBase {
 135.403 +    typedef ExtendedSmartGraphBase Parent;
 135.404 +
 135.405    private:
 135.406 -
 135.407 -    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
 135.408 -
 135.409 -    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
 135.410 -    ///
 135.411 +    /// Graphs are \e not copy constructible. Use GraphCopy instead.
 135.412      SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
 135.413 -
 135.414 -    ///\brief Assignment of SmartGraph to another one is \e not allowed.
 135.415 -    ///Use GraphCopy() instead.
 135.416 -
 135.417 -    ///Assignment of SmartGraph to another one is \e not allowed.
 135.418 -    ///Use GraphCopy() instead.
 135.419 +    /// \brief Assignment of a graph to another one is \e not allowed.
 135.420 +    /// Use GraphCopy instead.
 135.421      void operator=(const SmartGraph &) {}
 135.422  
 135.423    public:
 135.424  
 135.425 -    typedef ExtendedSmartGraphBase Parent;
 135.426 -
 135.427      /// Constructor
 135.428  
 135.429      /// Constructor.
 135.430      ///
 135.431      SmartGraph() {}
 135.432  
 135.433 -    ///Add a new node to the graph.
 135.434 -
 135.435 -    /// \return the new node.
 135.436 +    /// \brief Add a new node to the graph.
 135.437      ///
 135.438 +    /// This function adds a new node to the graph.
 135.439 +    /// \return The new node.
 135.440      Node addNode() { return Parent::addNode(); }
 135.441  
 135.442 -    ///Add a new edge to the graph.
 135.443 -
 135.444 -    ///Add a new edge to the graph with node \c s
 135.445 -    ///and \c t.
 135.446 -    ///\return the new edge.
 135.447 -    Edge addEdge(const Node& s, const Node& t) {
 135.448 -      return Parent::addEdge(s, t);
 135.449 +    /// \brief Add a new edge to the graph.
 135.450 +    ///
 135.451 +    /// This function adds a new edge to the graph between nodes
 135.452 +    /// \c u and \c v with inherent orientation from node \c u to
 135.453 +    /// node \c v.
 135.454 +    /// \return The new edge.
 135.455 +    Edge addEdge(Node u, Node v) {
 135.456 +      return Parent::addEdge(u, v);
 135.457      }
 135.458  
 135.459      /// \brief Node validity check
 135.460      ///
 135.461 -    /// This function gives back true if the given node is valid,
 135.462 -    /// ie. it is a real node of the graph.
 135.463 +    /// This function gives back \c true if the given node is valid,
 135.464 +    /// i.e. it is a real node of the graph.
 135.465      ///
 135.466      /// \warning A removed node (using Snapshot) could become valid again
 135.467 -    /// when new nodes are added to the graph.
 135.468 +    /// if new nodes are added to the graph.
 135.469      bool valid(Node n) const { return Parent::valid(n); }
 135.470  
 135.471 +    /// \brief Edge validity check
 135.472 +    ///
 135.473 +    /// This function gives back \c true if the given edge is valid,
 135.474 +    /// i.e. it is a real edge of the graph.
 135.475 +    ///
 135.476 +    /// \warning A removed edge (using Snapshot) could become valid again
 135.477 +    /// if new edges are added to the graph.
 135.478 +    bool valid(Edge e) const { return Parent::valid(e); }
 135.479 +
 135.480      /// \brief Arc validity check
 135.481      ///
 135.482 -    /// This function gives back true if the given arc is valid,
 135.483 -    /// ie. it is a real arc of the graph.
 135.484 +    /// This function gives back \c true if the given arc is valid,
 135.485 +    /// i.e. it is a real arc of the graph.
 135.486      ///
 135.487      /// \warning A removed arc (using Snapshot) could become valid again
 135.488 -    /// when new edges are added to the graph.
 135.489 +    /// if new edges are added to the graph.
 135.490      bool valid(Arc a) const { return Parent::valid(a); }
 135.491  
 135.492 -    /// \brief Edge validity check
 135.493 -    ///
 135.494 -    /// This function gives back true if the given edge is valid,
 135.495 -    /// ie. it is a real edge of the graph.
 135.496 -    ///
 135.497 -    /// \warning A removed edge (using Snapshot) could become valid again
 135.498 -    /// when new edges are added to the graph.
 135.499 -    bool valid(Edge e) const { return Parent::valid(e); }
 135.500 -
 135.501      ///Clear the graph.
 135.502  
 135.503 -    ///Erase all the nodes and edges from the graph.
 135.504 +    ///This function erases all nodes and arcs from the graph.
 135.505      ///
 135.506      void clear() {
 135.507        Parent::clear();
 135.508      }
 135.509  
 135.510 +    /// Reserve memory for nodes.
 135.511 +
 135.512 +    /// Using this function, it is possible to avoid superfluous memory
 135.513 +    /// allocation: if you know that the graph you want to build will
 135.514 +    /// be large (e.g. it will contain millions of nodes and/or edges),
 135.515 +    /// then it is worth reserving space for this amount before starting
 135.516 +    /// to build the graph.
 135.517 +    /// \sa reserveEdge()
 135.518 +    void reserveNode(int n) { nodes.reserve(n); };
 135.519 +
 135.520 +    /// Reserve memory for edges.
 135.521 +
 135.522 +    /// Using this function, it is possible to avoid superfluous memory
 135.523 +    /// allocation: if you know that the graph you want to build will
 135.524 +    /// be large (e.g. it will contain millions of nodes and/or edges),
 135.525 +    /// then it is worth reserving space for this amount before starting
 135.526 +    /// to build the graph.
 135.527 +    /// \sa reserveNode()
 135.528 +    void reserveEdge(int m) { arcs.reserve(2 * m); };
 135.529 +
 135.530    public:
 135.531  
 135.532      class Snapshot;
 135.533 @@ -728,8 +734,8 @@
 135.534          dir.push_back(arcFromId(n));
 135.535          dir.push_back(arcFromId(n-1));
 135.536          Parent::notifier(Arc()).erase(dir);
 135.537 -        nodes[arcs[n].target].first_out=arcs[n].next_out;
 135.538 -        nodes[arcs[n-1].target].first_out=arcs[n-1].next_out;
 135.539 +        nodes[arcs[n-1].target].first_out=arcs[n].next_out;
 135.540 +        nodes[arcs[n].target].first_out=arcs[n-1].next_out;
 135.541          arcs.pop_back();
 135.542          arcs.pop_back();
 135.543        }
 135.544 @@ -743,21 +749,22 @@
 135.545  
 135.546    public:
 135.547  
 135.548 -    ///Class to make a snapshot of the digraph and to restrore to it later.
 135.549 +    ///Class to make a snapshot of the graph and to restore it later.
 135.550  
 135.551 -    ///Class to make a snapshot of the digraph and to restrore to it later.
 135.552 +    ///Class to make a snapshot of the graph and to restore it later.
 135.553      ///
 135.554 -    ///The newly added nodes and arcs can be removed using the
 135.555 -    ///restore() function.
 135.556 +    ///The newly added nodes and edges can be removed using the
 135.557 +    ///restore() function. This is the only way for deleting nodes and/or
 135.558 +    ///edges from a SmartGraph structure.
 135.559      ///
 135.560 -    ///\note After you restore a state, you cannot restore
 135.561 -    ///a later state, in other word you cannot add again the arcs deleted
 135.562 -    ///by restore() using another one Snapshot instance.
 135.563 +    ///\note After a state is restored, you cannot restore a later state, 
 135.564 +    ///i.e. you cannot add the removed nodes and edges again using
 135.565 +    ///another Snapshot instance.
 135.566      ///
 135.567 -    ///\warning If you do not use correctly the snapshot that can cause
 135.568 -    ///either broken program, invalid state of the digraph, valid but
 135.569 -    ///not the restored digraph or no change. Because the runtime performance
 135.570 -    ///the validity of the snapshot is not stored.
 135.571 +    ///\warning The validity of the snapshot is not stored due to
 135.572 +    ///performance reasons. If you do not use the snapshot correctly,
 135.573 +    ///it can cause broken program, invalid or not restored state of
 135.574 +    ///the graph or no change.
 135.575      class Snapshot
 135.576      {
 135.577        SmartGraph *_graph;
 135.578 @@ -769,36 +776,30 @@
 135.579        ///Default constructor.
 135.580  
 135.581        ///Default constructor.
 135.582 -      ///To actually make a snapshot you must call save().
 135.583 -      ///
 135.584 +      ///You have to call save() to actually make a snapshot.
 135.585        Snapshot() : _graph(0) {}
 135.586        ///Constructor that immediately makes a snapshot
 135.587  
 135.588 -      ///This constructor immediately makes a snapshot of the digraph.
 135.589 -      ///\param graph The digraph we make a snapshot of.
 135.590 -      Snapshot(SmartGraph &graph) {
 135.591 -        graph.saveSnapshot(*this);
 135.592 +      /// This constructor immediately makes a snapshot of the given graph.
 135.593 +      ///
 135.594 +      Snapshot(SmartGraph &gr) {
 135.595 +        gr.saveSnapshot(*this);
 135.596        }
 135.597  
 135.598        ///Make a snapshot.
 135.599  
 135.600 -      ///Make a snapshot of the graph.
 135.601 -      ///
 135.602 -      ///This function can be called more than once. In case of a repeated
 135.603 +      ///This function makes a snapshot of the given graph.
 135.604 +      ///It can be called more than once. In case of a repeated
 135.605        ///call, the previous snapshot gets lost.
 135.606 -      ///\param graph The digraph we make the snapshot of.
 135.607 -      void save(SmartGraph &graph)
 135.608 +      void save(SmartGraph &gr)
 135.609        {
 135.610 -        graph.saveSnapshot(*this);
 135.611 +        gr.saveSnapshot(*this);
 135.612        }
 135.613  
 135.614 -      ///Undo the changes until a snapshot.
 135.615 +      ///Undo the changes until the last snapshot.
 135.616  
 135.617 -      ///Undo the changes until a snapshot created by save().
 135.618 -      ///
 135.619 -      ///\note After you restored a state, you cannot restore
 135.620 -      ///a later state, in other word you cannot add again the arcs deleted
 135.621 -      ///by restore().
 135.622 +      ///This function undos the changes until the last snapshot
 135.623 +      ///created by save() or Snapshot(SmartGraph&).
 135.624        void restore()
 135.625        {
 135.626          _graph->restoreSnapshot(*this);
   136.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   136.2 +++ b/lemon/soplex.cc	Thu Nov 05 15:50:01 2009 +0100
   136.3 @@ -0,0 +1,465 @@
   136.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   136.5 + *
   136.6 + * This file is a part of LEMON, a generic C++ optimization library.
   136.7 + *
   136.8 + * Copyright (C) 2003-2008
   136.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  136.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  136.11 + *
  136.12 + * Permission to use, modify and distribute this software is granted
  136.13 + * provided that this copyright notice appears in all copies. For
  136.14 + * precise terms see the accompanying LICENSE file.
  136.15 + *
  136.16 + * This software is provided "AS IS" with no warranty of any kind,
  136.17 + * express or implied, and with no claim as to its suitability for any
  136.18 + * purpose.
  136.19 + *
  136.20 + */
  136.21 +
  136.22 +#include <iostream>
  136.23 +#include <lemon/soplex.h>
  136.24 +
  136.25 +#include <soplex.h>
  136.26 +#include <spxout.h>
  136.27 +
  136.28 +
  136.29 +///\file
  136.30 +///\brief Implementation of the LEMON-SOPLEX lp solver interface.
  136.31 +namespace lemon {
  136.32 +
  136.33 +  SoplexLp::SoplexLp() {
  136.34 +    soplex = new soplex::SoPlex;
  136.35 +    messageLevel(MESSAGE_NOTHING);
  136.36 +  }
  136.37 +
  136.38 +  SoplexLp::~SoplexLp() {
  136.39 +    delete soplex;
  136.40 +  }
  136.41 +
  136.42 +  SoplexLp::SoplexLp(const SoplexLp& lp) {
  136.43 +    rows = lp.rows;
  136.44 +    cols = lp.cols;
  136.45 +
  136.46 +    soplex = new soplex::SoPlex;
  136.47 +    (*static_cast<soplex::SPxLP*>(soplex)) = *(lp.soplex);
  136.48 +
  136.49 +    _col_names = lp._col_names;
  136.50 +    _col_names_ref = lp._col_names_ref;
  136.51 +
  136.52 +    _row_names = lp._row_names;
  136.53 +    _row_names_ref = lp._row_names_ref;
  136.54 +
  136.55 +    messageLevel(MESSAGE_NOTHING);
  136.56 +  }
  136.57 +
  136.58 +  void SoplexLp::_clear_temporals() {
  136.59 +    _primal_values.clear();
  136.60 +    _dual_values.clear();
  136.61 +  }
  136.62 +
  136.63 +  SoplexLp* SoplexLp::newSolver() const {
  136.64 +    SoplexLp* newlp = new SoplexLp();
  136.65 +    return newlp;
  136.66 +  }
  136.67 +
  136.68 +  SoplexLp* SoplexLp::cloneSolver() const {
  136.69 +    SoplexLp* newlp = new SoplexLp(*this);
  136.70 +    return newlp;
  136.71 +  }
  136.72 +
  136.73 +  const char* SoplexLp::_solverName() const { return "SoplexLp"; }
  136.74 +
  136.75 +  int SoplexLp::_addCol() {
  136.76 +    soplex::LPCol c;
  136.77 +    c.setLower(-soplex::infinity);
  136.78 +    c.setUpper(soplex::infinity);
  136.79 +    soplex->addCol(c);
  136.80 +
  136.81 +    _col_names.push_back(std::string());
  136.82 +
  136.83 +    return soplex->nCols() - 1;
  136.84 +  }
  136.85 +
  136.86 +  int SoplexLp::_addRow() {
  136.87 +    soplex::LPRow r;
  136.88 +    r.setLhs(-soplex::infinity);
  136.89 +    r.setRhs(soplex::infinity);
  136.90 +    soplex->addRow(r);
  136.91 +
  136.92 +    _row_names.push_back(std::string());
  136.93 +
  136.94 +    return soplex->nRows() - 1;
  136.95 +  }
  136.96 +
  136.97 +  int SoplexLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
  136.98 +    soplex::DSVector v;
  136.99 +    for (ExprIterator it = b; it != e; ++it) {
 136.100 +      v.add(it->first, it->second);
 136.101 +    }
 136.102 +    soplex::LPRow r(l, v, u);
 136.103 +    soplex->addRow(r);
 136.104 +
 136.105 +    _row_names.push_back(std::string());
 136.106 +
 136.107 +    return soplex->nRows() - 1;
 136.108 +  }
 136.109 +
 136.110 +
 136.111 +  void SoplexLp::_eraseCol(int i) {
 136.112 +    soplex->removeCol(i);
 136.113 +    _col_names_ref.erase(_col_names[i]);
 136.114 +    _col_names[i] = _col_names.back();
 136.115 +    _col_names_ref[_col_names.back()] = i;
 136.116 +    _col_names.pop_back();
 136.117 +  }
 136.118 +
 136.119 +  void SoplexLp::_eraseRow(int i) {
 136.120 +    soplex->removeRow(i);
 136.121 +    _row_names_ref.erase(_row_names[i]);
 136.122 +    _row_names[i] = _row_names.back();
 136.123 +    _row_names_ref[_row_names.back()] = i;
 136.124 +    _row_names.pop_back();
 136.125 +  }
 136.126 +
 136.127 +  void SoplexLp::_eraseColId(int i) {
 136.128 +    cols.eraseIndex(i);
 136.129 +    cols.relocateIndex(i, cols.maxIndex());
 136.130 +  }
 136.131 +  void SoplexLp::_eraseRowId(int i) {
 136.132 +    rows.eraseIndex(i);
 136.133 +    rows.relocateIndex(i, rows.maxIndex());
 136.134 +  }
 136.135 +
 136.136 +  void SoplexLp::_getColName(int c, std::string &name) const {
 136.137 +    name = _col_names[c];
 136.138 +  }
 136.139 +
 136.140 +  void SoplexLp::_setColName(int c, const std::string &name) {
 136.141 +    _col_names_ref.erase(_col_names[c]);
 136.142 +    _col_names[c] = name;
 136.143 +    if (!name.empty()) {
 136.144 +      _col_names_ref.insert(std::make_pair(name, c));
 136.145 +    }
 136.146 +  }
 136.147 +
 136.148 +  int SoplexLp::_colByName(const std::string& name) const {
 136.149 +    std::map<std::string, int>::const_iterator it =
 136.150 +      _col_names_ref.find(name);
 136.151 +    if (it != _col_names_ref.end()) {
 136.152 +      return it->second;
 136.153 +    } else {
 136.154 +      return -1;
 136.155 +    }
 136.156 +  }
 136.157 +
 136.158 +  void SoplexLp::_getRowName(int r, std::string &name) const {
 136.159 +    name = _row_names[r];
 136.160 +  }
 136.161 +
 136.162 +  void SoplexLp::_setRowName(int r, const std::string &name) {
 136.163 +    _row_names_ref.erase(_row_names[r]);
 136.164 +    _row_names[r] = name;
 136.165 +    if (!name.empty()) {
 136.166 +      _row_names_ref.insert(std::make_pair(name, r));
 136.167 +    }
 136.168 +  }
 136.169 +
 136.170 +  int SoplexLp::_rowByName(const std::string& name) const {
 136.171 +    std::map<std::string, int>::const_iterator it =
 136.172 +      _row_names_ref.find(name);
 136.173 +    if (it != _row_names_ref.end()) {
 136.174 +      return it->second;
 136.175 +    } else {
 136.176 +      return -1;
 136.177 +    }
 136.178 +  }
 136.179 +
 136.180 +
 136.181 +  void SoplexLp::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
 136.182 +    for (int j = 0; j < soplex->nCols(); ++j) {
 136.183 +      soplex->changeElement(i, j, 0.0);
 136.184 +    }
 136.185 +    for(ExprIterator it = b; it != e; ++it) {
 136.186 +      soplex->changeElement(i, it->first, it->second);
 136.187 +    }
 136.188 +  }
 136.189 +
 136.190 +  void SoplexLp::_getRowCoeffs(int i, InsertIterator b) const {
 136.191 +    const soplex::SVector& vec = soplex->rowVector(i);
 136.192 +    for (int k = 0; k < vec.size(); ++k) {
 136.193 +      *b = std::make_pair(vec.index(k), vec.value(k));
 136.194 +      ++b;
 136.195 +    }
 136.196 +  }
 136.197 +
 136.198 +  void SoplexLp::_setColCoeffs(int j, ExprIterator b, ExprIterator e) {
 136.199 +    for (int i = 0; i < soplex->nRows(); ++i) {
 136.200 +      soplex->changeElement(i, j, 0.0);
 136.201 +    }
 136.202 +    for(ExprIterator it = b; it != e; ++it) {
 136.203 +      soplex->changeElement(it->first, j, it->second);
 136.204 +    }
 136.205 +  }
 136.206 +
 136.207 +  void SoplexLp::_getColCoeffs(int i, InsertIterator b) const {
 136.208 +    const soplex::SVector& vec = soplex->colVector(i);
 136.209 +    for (int k = 0; k < vec.size(); ++k) {
 136.210 +      *b = std::make_pair(vec.index(k), vec.value(k));
 136.211 +      ++b;
 136.212 +    }
 136.213 +  }
 136.214 +
 136.215 +  void SoplexLp::_setCoeff(int i, int j, Value value) {
 136.216 +    soplex->changeElement(i, j, value);
 136.217 +  }
 136.218 +
 136.219 +  SoplexLp::Value SoplexLp::_getCoeff(int i, int j) const {
 136.220 +    return soplex->rowVector(i)[j];
 136.221 +  }
 136.222 +
 136.223 +  void SoplexLp::_setColLowerBound(int i, Value value) {
 136.224 +    LEMON_ASSERT(value != INF, "Invalid bound");
 136.225 +    soplex->changeLower(i, value != -INF ? value : -soplex::infinity);
 136.226 +  }
 136.227 +
 136.228 +  SoplexLp::Value SoplexLp::_getColLowerBound(int i) const {
 136.229 +    double value = soplex->lower(i);
 136.230 +    return value != -soplex::infinity ? value : -INF;
 136.231 +  }
 136.232 +
 136.233 +  void SoplexLp::_setColUpperBound(int i, Value value) {
 136.234 +    LEMON_ASSERT(value != -INF, "Invalid bound");
 136.235 +    soplex->changeUpper(i, value != INF ? value : soplex::infinity);
 136.236 +  }
 136.237 +
 136.238 +  SoplexLp::Value SoplexLp::_getColUpperBound(int i) const {
 136.239 +    double value = soplex->upper(i);
 136.240 +    return value != soplex::infinity ? value : INF;
 136.241 +  }
 136.242 +
 136.243 +  void SoplexLp::_setRowLowerBound(int i, Value lb) {
 136.244 +    LEMON_ASSERT(lb != INF, "Invalid bound");
 136.245 +    soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity, soplex->rhs(i));
 136.246 +  }
 136.247 +
 136.248 +  SoplexLp::Value SoplexLp::_getRowLowerBound(int i) const {
 136.249 +    double res = soplex->lhs(i);
 136.250 +    return res == -soplex::infinity ? -INF : res;
 136.251 +  }
 136.252 +
 136.253 +  void SoplexLp::_setRowUpperBound(int i, Value ub) {
 136.254 +    LEMON_ASSERT(ub != -INF, "Invalid bound");
 136.255 +    soplex->changeRange(i, soplex->lhs(i), ub != INF ? ub : soplex::infinity);
 136.256 +  }
 136.257 +
 136.258 +  SoplexLp::Value SoplexLp::_getRowUpperBound(int i) const {
 136.259 +    double res = soplex->rhs(i);
 136.260 +    return res == soplex::infinity ? INF : res;
 136.261 +  }
 136.262 +
 136.263 +  void SoplexLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
 136.264 +    for (int j = 0; j < soplex->nCols(); ++j) {
 136.265 +      soplex->changeObj(j, 0.0);
 136.266 +    }
 136.267 +    for (ExprIterator it = b; it != e; ++it) {
 136.268 +      soplex->changeObj(it->first, it->second);
 136.269 +    }
 136.270 +  }
 136.271 +
 136.272 +  void SoplexLp::_getObjCoeffs(InsertIterator b) const {
 136.273 +    for (int j = 0; j < soplex->nCols(); ++j) {
 136.274 +      Value coef = soplex->obj(j);
 136.275 +      if (coef != 0.0) {
 136.276 +        *b = std::make_pair(j, coef);
 136.277 +        ++b;
 136.278 +      }
 136.279 +    }
 136.280 +  }
 136.281 +
 136.282 +  void SoplexLp::_setObjCoeff(int i, Value obj_coef) {
 136.283 +    soplex->changeObj(i, obj_coef);
 136.284 +  }
 136.285 +
 136.286 +  SoplexLp::Value SoplexLp::_getObjCoeff(int i) const {
 136.287 +    return soplex->obj(i);
 136.288 +  }
 136.289 +
 136.290 +  SoplexLp::SolveExitStatus SoplexLp::_solve() {
 136.291 +
 136.292 +    _clear_temporals();
 136.293 +    
 136.294 +    _applyMessageLevel();
 136.295 +
 136.296 +    soplex::SPxSolver::Status status = soplex->solve();
 136.297 +
 136.298 +    switch (status) {
 136.299 +    case soplex::SPxSolver::OPTIMAL:
 136.300 +    case soplex::SPxSolver::INFEASIBLE:
 136.301 +    case soplex::SPxSolver::UNBOUNDED:
 136.302 +      return SOLVED;
 136.303 +    default:
 136.304 +      return UNSOLVED;
 136.305 +    }
 136.306 +  }
 136.307 +
 136.308 +  SoplexLp::Value SoplexLp::_getPrimal(int i) const {
 136.309 +    if (_primal_values.empty()) {
 136.310 +      _primal_values.resize(soplex->nCols());
 136.311 +      soplex::Vector pv(_primal_values.size(), &_primal_values.front());
 136.312 +      soplex->getPrimal(pv);
 136.313 +    }
 136.314 +    return _primal_values[i];
 136.315 +  }
 136.316 +
 136.317 +  SoplexLp::Value SoplexLp::_getDual(int i) const {
 136.318 +    if (_dual_values.empty()) {
 136.319 +      _dual_values.resize(soplex->nRows());
 136.320 +      soplex::Vector dv(_dual_values.size(), &_dual_values.front());
 136.321 +      soplex->getDual(dv);
 136.322 +    }
 136.323 +    return _dual_values[i];
 136.324 +  }
 136.325 +
 136.326 +  SoplexLp::Value SoplexLp::_getPrimalValue() const {
 136.327 +    return soplex->objValue();
 136.328 +  }
 136.329 +
 136.330 +  SoplexLp::VarStatus SoplexLp::_getColStatus(int i) const {
 136.331 +    switch (soplex->getBasisColStatus(i)) {
 136.332 +    case soplex::SPxSolver::BASIC:
 136.333 +      return BASIC;
 136.334 +    case soplex::SPxSolver::ON_UPPER:
 136.335 +      return UPPER;
 136.336 +    case soplex::SPxSolver::ON_LOWER:
 136.337 +      return LOWER;
 136.338 +    case soplex::SPxSolver::FIXED:
 136.339 +      return FIXED;
 136.340 +    case soplex::SPxSolver::ZERO:
 136.341 +      return FREE;
 136.342 +    default:
 136.343 +      LEMON_ASSERT(false, "Wrong column status");
 136.344 +      return VarStatus();
 136.345 +    }
 136.346 +  }
 136.347 +
 136.348 +  SoplexLp::VarStatus SoplexLp::_getRowStatus(int i) const {
 136.349 +    switch (soplex->getBasisRowStatus(i)) {
 136.350 +    case soplex::SPxSolver::BASIC:
 136.351 +      return BASIC;
 136.352 +    case soplex::SPxSolver::ON_UPPER:
 136.353 +      return UPPER;
 136.354 +    case soplex::SPxSolver::ON_LOWER:
 136.355 +      return LOWER;
 136.356 +    case soplex::SPxSolver::FIXED:
 136.357 +      return FIXED;
 136.358 +    case soplex::SPxSolver::ZERO:
 136.359 +      return FREE;
 136.360 +    default:
 136.361 +      LEMON_ASSERT(false, "Wrong row status");
 136.362 +      return VarStatus();
 136.363 +    }
 136.364 +  }
 136.365 +
 136.366 +  SoplexLp::Value SoplexLp::_getPrimalRay(int i) const {
 136.367 +    if (_primal_ray.empty()) {
 136.368 +      _primal_ray.resize(soplex->nCols());
 136.369 +      soplex::Vector pv(_primal_ray.size(), &_primal_ray.front());
 136.370 +      soplex->getDualfarkas(pv);
 136.371 +    }
 136.372 +    return _primal_ray[i];
 136.373 +  }
 136.374 +
 136.375 +  SoplexLp::Value SoplexLp::_getDualRay(int i) const {
 136.376 +    if (_dual_ray.empty()) {
 136.377 +      _dual_ray.resize(soplex->nRows());
 136.378 +      soplex::Vector dv(_dual_ray.size(), &_dual_ray.front());
 136.379 +      soplex->getDualfarkas(dv);
 136.380 +    }
 136.381 +    return _dual_ray[i];
 136.382 +  }
 136.383 +
 136.384 +  SoplexLp::ProblemType SoplexLp::_getPrimalType() const {
 136.385 +    switch (soplex->status()) {
 136.386 +    case soplex::SPxSolver::OPTIMAL:
 136.387 +      return OPTIMAL;
 136.388 +    case soplex::SPxSolver::UNBOUNDED:
 136.389 +      return UNBOUNDED;
 136.390 +    case soplex::SPxSolver::INFEASIBLE:
 136.391 +      return INFEASIBLE;
 136.392 +    default:
 136.393 +      return UNDEFINED;
 136.394 +    }
 136.395 +  }
 136.396 +
 136.397 +  SoplexLp::ProblemType SoplexLp::_getDualType() const {
 136.398 +    switch (soplex->status()) {
 136.399 +    case soplex::SPxSolver::OPTIMAL:
 136.400 +      return OPTIMAL;
 136.401 +    case soplex::SPxSolver::UNBOUNDED:
 136.402 +      return UNBOUNDED;
 136.403 +    case soplex::SPxSolver::INFEASIBLE:
 136.404 +      return INFEASIBLE;
 136.405 +    default:
 136.406 +      return UNDEFINED;
 136.407 +    }
 136.408 +  }
 136.409 +
 136.410 +  void SoplexLp::_setSense(Sense sense) {
 136.411 +    switch (sense) {
 136.412 +    case MIN:
 136.413 +      soplex->changeSense(soplex::SPxSolver::MINIMIZE);
 136.414 +      break;
 136.415 +    case MAX:
 136.416 +      soplex->changeSense(soplex::SPxSolver::MAXIMIZE);
 136.417 +    }
 136.418 +  }
 136.419 +
 136.420 +  SoplexLp::Sense SoplexLp::_getSense() const {
 136.421 +    switch (soplex->spxSense()) {
 136.422 +    case soplex::SPxSolver::MAXIMIZE:
 136.423 +      return MAX;
 136.424 +    case soplex::SPxSolver::MINIMIZE:
 136.425 +      return MIN;
 136.426 +    default:
 136.427 +      LEMON_ASSERT(false, "Wrong sense.");
 136.428 +      return SoplexLp::Sense();
 136.429 +    }
 136.430 +  }
 136.431 +
 136.432 +  void SoplexLp::_clear() {
 136.433 +    soplex->clear();
 136.434 +    _col_names.clear();
 136.435 +    _col_names_ref.clear();
 136.436 +    _row_names.clear();
 136.437 +    _row_names_ref.clear();
 136.438 +    cols.clear();
 136.439 +    rows.clear();
 136.440 +    _clear_temporals();
 136.441 +  }
 136.442 +
 136.443 +  void SoplexLp::_messageLevel(MessageLevel level) {
 136.444 +    switch (level) {
 136.445 +    case MESSAGE_NOTHING:
 136.446 +      _message_level = -1;
 136.447 +      break;
 136.448 +    case MESSAGE_ERROR:
 136.449 +      _message_level = soplex::SPxOut::ERROR;
 136.450 +      break;
 136.451 +    case MESSAGE_WARNING:
 136.452 +      _message_level = soplex::SPxOut::WARNING;
 136.453 +      break;
 136.454 +    case MESSAGE_NORMAL:
 136.455 +      _message_level = soplex::SPxOut::INFO2;
 136.456 +      break;
 136.457 +    case MESSAGE_VERBOSE:
 136.458 +      _message_level = soplex::SPxOut::DEBUG;
 136.459 +      break;
 136.460 +    }
 136.461 +  }
 136.462 +
 136.463 +  void SoplexLp::_applyMessageLevel() {
 136.464 +    soplex::Param::setVerbose(_message_level);
 136.465 +  }
 136.466 +
 136.467 +} //namespace lemon
 136.468 +
   137.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   137.2 +++ b/lemon/soplex.h	Thu Nov 05 15:50:01 2009 +0100
   137.3 @@ -0,0 +1,158 @@
   137.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   137.5 + *
   137.6 + * This file is a part of LEMON, a generic C++ optimization library.
   137.7 + *
   137.8 + * Copyright (C) 2003-2008
   137.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  137.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  137.11 + *
  137.12 + * Permission to use, modify and distribute this software is granted
  137.13 + * provided that this copyright notice appears in all copies. For
  137.14 + * precise terms see the accompanying LICENSE file.
  137.15 + *
  137.16 + * This software is provided "AS IS" with no warranty of any kind,
  137.17 + * express or implied, and with no claim as to its suitability for any
  137.18 + * purpose.
  137.19 + *
  137.20 + */
  137.21 +
  137.22 +#ifndef LEMON_SOPLEX_H
  137.23 +#define LEMON_SOPLEX_H
  137.24 +
  137.25 +///\file
  137.26 +///\brief Header of the LEMON-SOPLEX lp solver interface.
  137.27 +
  137.28 +#include <vector>
  137.29 +#include <string>
  137.30 +
  137.31 +#include <lemon/lp_base.h>
  137.32 +
  137.33 +// Forward declaration
  137.34 +namespace soplex {
  137.35 +  class SoPlex;
  137.36 +}
  137.37 +
  137.38 +namespace lemon {
  137.39 +
  137.40 +  /// \ingroup lp_group
  137.41 +  ///
  137.42 +  /// \brief Interface for the SOPLEX solver
  137.43 +  ///
  137.44 +  /// This class implements an interface for the SoPlex LP solver.
  137.45 +  /// The SoPlex library is an object oriented lp solver library
  137.46 +  /// developed at the Konrad-Zuse-Zentrum für Informationstechnik
  137.47 +  /// Berlin (ZIB). You can find detailed information about it at the
  137.48 +  /// <tt>http://soplex.zib.de</tt> address.
  137.49 +  class SoplexLp : public LpSolver {
  137.50 +  private:
  137.51 +
  137.52 +    soplex::SoPlex* soplex;
  137.53 +
  137.54 +    std::vector<std::string> _col_names;
  137.55 +    std::map<std::string, int> _col_names_ref;
  137.56 +
  137.57 +    std::vector<std::string> _row_names;
  137.58 +    std::map<std::string, int> _row_names_ref;
  137.59 +
  137.60 +  private:
  137.61 +
  137.62 +    // these values cannot be retrieved element by element
  137.63 +    mutable std::vector<Value> _primal_values;
  137.64 +    mutable std::vector<Value> _dual_values;
  137.65 +
  137.66 +    mutable std::vector<Value> _primal_ray;
  137.67 +    mutable std::vector<Value> _dual_ray;
  137.68 +
  137.69 +    void _clear_temporals();
  137.70 +
  137.71 +  public:
  137.72 +
  137.73 +    /// \e
  137.74 +    SoplexLp();
  137.75 +    /// \e
  137.76 +    SoplexLp(const SoplexLp&);
  137.77 +    /// \e
  137.78 +    ~SoplexLp();
  137.79 +    /// \e
  137.80 +    virtual SoplexLp* newSolver() const;
  137.81 +    /// \e
  137.82 +    virtual SoplexLp* cloneSolver() const;
  137.83 +
  137.84 +  protected:
  137.85 +
  137.86 +    virtual const char* _solverName() const;
  137.87 +
  137.88 +    virtual int _addCol();
  137.89 +    virtual int _addRow();
  137.90 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
  137.91 +
  137.92 +    virtual void _eraseCol(int i);
  137.93 +    virtual void _eraseRow(int i);
  137.94 +
  137.95 +    virtual void _eraseColId(int i);
  137.96 +    virtual void _eraseRowId(int i);
  137.97 +
  137.98 +    virtual void _getColName(int col, std::string& name) const;
  137.99 +    virtual void _setColName(int col, const std::string& name);
 137.100 +    virtual int _colByName(const std::string& name) const;
 137.101 +
 137.102 +    virtual void _getRowName(int row, std::string& name) const;
 137.103 +    virtual void _setRowName(int row, const std::string& name);
 137.104 +    virtual int _rowByName(const std::string& name) const;
 137.105 +
 137.106 +    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
 137.107 +    virtual void _getRowCoeffs(int i, InsertIterator b) const;
 137.108 +
 137.109 +    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
 137.110 +    virtual void _getColCoeffs(int i, InsertIterator b) const;
 137.111 +
 137.112 +    virtual void _setCoeff(int row, int col, Value value);
 137.113 +    virtual Value _getCoeff(int row, int col) const;
 137.114 +
 137.115 +    virtual void _setColLowerBound(int i, Value value);
 137.116 +    virtual Value _getColLowerBound(int i) const;
 137.117 +    virtual void _setColUpperBound(int i, Value value);
 137.118 +    virtual Value _getColUpperBound(int i) const;
 137.119 +
 137.120 +    virtual void _setRowLowerBound(int i, Value value);
 137.121 +    virtual Value _getRowLowerBound(int i) const;
 137.122 +    virtual void _setRowUpperBound(int i, Value value);
 137.123 +    virtual Value _getRowUpperBound(int i) const;
 137.124 +
 137.125 +    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
 137.126 +    virtual void _getObjCoeffs(InsertIterator b) const;
 137.127 +
 137.128 +    virtual void _setObjCoeff(int i, Value obj_coef);
 137.129 +    virtual Value _getObjCoeff(int i) const;
 137.130 +
 137.131 +    virtual void _setSense(Sense sense);
 137.132 +    virtual Sense _getSense() const;
 137.133 +
 137.134 +    virtual SolveExitStatus _solve();
 137.135 +    virtual Value _getPrimal(int i) const;
 137.136 +    virtual Value _getDual(int i) const;
 137.137 +
 137.138 +    virtual Value _getPrimalValue() const;
 137.139 +
 137.140 +    virtual Value _getPrimalRay(int i) const;
 137.141 +    virtual Value _getDualRay(int i) const;
 137.142 +
 137.143 +    virtual VarStatus _getColStatus(int i) const;
 137.144 +    virtual VarStatus _getRowStatus(int i) const;
 137.145 +
 137.146 +    virtual ProblemType _getPrimalType() const;
 137.147 +    virtual ProblemType _getDualType() const;
 137.148 +
 137.149 +    virtual void _clear();
 137.150 +
 137.151 +    void _messageLevel(MessageLevel m);
 137.152 +    void _applyMessageLevel();
 137.153 +
 137.154 +    int _message_level;
 137.155 +
 137.156 +  };
 137.157 +
 137.158 +} //END OF NAMESPACE LEMON
 137.159 +
 137.160 +#endif //LEMON_SOPLEX_H
 137.161 +
   138.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   138.2 +++ b/lemon/static_graph.h	Thu Nov 05 15:50:01 2009 +0100
   138.3 @@ -0,0 +1,474 @@
   138.4 +/* -*- C++ -*-
   138.5 + *
   138.6 + * This file is a part of LEMON, a generic C++ optimization library
   138.7 + *
   138.8 + * Copyright (C) 2003-2008
   138.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  138.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  138.11 + *
  138.12 + * Permission to use, modify and distribute this software is granted
  138.13 + * provided that this copyright notice appears in all copies. For
  138.14 + * precise terms see the accompanying LICENSE file.
  138.15 + *
  138.16 + * This software is provided "AS IS" with no warranty of any kind,
  138.17 + * express or implied, and with no claim as to its suitability for any
  138.18 + * purpose.
  138.19 + *
  138.20 + */
  138.21 +
  138.22 +#ifndef LEMON_STATIC_GRAPH_H
  138.23 +#define LEMON_STATIC_GRAPH_H
  138.24 +
  138.25 +///\ingroup graphs
  138.26 +///\file
  138.27 +///\brief StaticDigraph class.
  138.28 +
  138.29 +#include <lemon/core.h>
  138.30 +#include <lemon/bits/graph_extender.h>
  138.31 +
  138.32 +namespace lemon {
  138.33 +
  138.34 +  class StaticDigraphBase {
  138.35 +  public:
  138.36 +
  138.37 +    StaticDigraphBase() 
  138.38 +      : built(false), node_num(0), arc_num(0), 
  138.39 +        node_first_out(NULL), node_first_in(NULL),
  138.40 +        arc_source(NULL), arc_target(NULL), 
  138.41 +        arc_next_in(NULL), arc_next_out(NULL) {}
  138.42 +    
  138.43 +    ~StaticDigraphBase() {
  138.44 +      if (built) {
  138.45 +        delete[] node_first_out;
  138.46 +        delete[] node_first_in;
  138.47 +        delete[] arc_source;
  138.48 +        delete[] arc_target;
  138.49 +        delete[] arc_next_out;
  138.50 +        delete[] arc_next_in;
  138.51 +      }
  138.52 +    }
  138.53 +
  138.54 +    class Node {
  138.55 +      friend class StaticDigraphBase;
  138.56 +    protected:
  138.57 +      int id;
  138.58 +      Node(int _id) : id(_id) {}
  138.59 +    public:
  138.60 +      Node() {}
  138.61 +      Node (Invalid) : id(-1) {}
  138.62 +      bool operator==(const Node& node) const { return id == node.id; }
  138.63 +      bool operator!=(const Node& node) const { return id != node.id; }
  138.64 +      bool operator<(const Node& node) const { return id < node.id; }
  138.65 +    };
  138.66 +
  138.67 +    class Arc {
  138.68 +      friend class StaticDigraphBase;      
  138.69 +    protected:
  138.70 +      int id;
  138.71 +      Arc(int _id) : id(_id) {}
  138.72 +    public:
  138.73 +      Arc() { }
  138.74 +      Arc (Invalid) : id(-1) {}
  138.75 +      bool operator==(const Arc& arc) const { return id == arc.id; }
  138.76 +      bool operator!=(const Arc& arc) const { return id != arc.id; }
  138.77 +      bool operator<(const Arc& arc) const { return id < arc.id; }
  138.78 +    };
  138.79 +
  138.80 +    Node source(const Arc& e) const { return Node(arc_source[e.id]); }
  138.81 +    Node target(const Arc& e) const { return Node(arc_target[e.id]); }
  138.82 +
  138.83 +    void first(Node& n) const { n.id = node_num - 1; }
  138.84 +    static void next(Node& n) { --n.id; }
  138.85 +
  138.86 +    void first(Arc& e) const { e.id = arc_num - 1; }
  138.87 +    static void next(Arc& e) { --e.id; }
  138.88 +
  138.89 +    void firstOut(Arc& e, const Node& n) const { 
  138.90 +      e.id = node_first_out[n.id] != node_first_out[n.id + 1] ? 
  138.91 +        node_first_out[n.id] : -1;
  138.92 +    }
  138.93 +    void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; }
  138.94 +
  138.95 +    void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; }
  138.96 +    void nextIn(Arc& e) const { e.id = arc_next_in[e.id]; }
  138.97 +
  138.98 +    static int id(const Node& n) { return n.id; }
  138.99 +    static Node nodeFromId(int id) { return Node(id); }
 138.100 +    int maxNodeId() const { return node_num - 1; }
 138.101 +
 138.102 +    static int id(const Arc& e) { return e.id; }
 138.103 +    static Arc arcFromId(int id) { return Arc(id); }
 138.104 +    int maxArcId() const { return arc_num - 1; }
 138.105 +
 138.106 +    typedef True NodeNumTag;
 138.107 +    typedef True ArcNumTag;
 138.108 +
 138.109 +    int nodeNum() const { return node_num; }
 138.110 +    int arcNum() const { return arc_num; }
 138.111 +
 138.112 +  private:
 138.113 +
 138.114 +    template <typename Digraph, typename NodeRefMap>
 138.115 +    class ArcLess {
 138.116 +    public:
 138.117 +      typedef typename Digraph::Arc Arc;
 138.118 +
 138.119 +      ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef) 
 138.120 +        : digraph(_graph), nodeRef(_nodeRef) {}
 138.121 +      
 138.122 +      bool operator()(const Arc& left, const Arc& right) const {
 138.123 +	return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
 138.124 +      }
 138.125 +    private:
 138.126 +      const Digraph& digraph;
 138.127 +      const NodeRefMap& nodeRef;
 138.128 +    };
 138.129 +    
 138.130 +  public:
 138.131 +
 138.132 +    typedef True BuildTag;
 138.133 +    
 138.134 +    void clear() {
 138.135 +      if (built) {
 138.136 +        delete[] node_first_out;
 138.137 +        delete[] node_first_in;
 138.138 +        delete[] arc_source;
 138.139 +        delete[] arc_target;
 138.140 +        delete[] arc_next_out;
 138.141 +        delete[] arc_next_in;
 138.142 +      }
 138.143 +      built = false;
 138.144 +      node_num = 0;
 138.145 +      arc_num = 0;
 138.146 +    }
 138.147 +    
 138.148 +    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
 138.149 +    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
 138.150 +      typedef typename Digraph::Node GNode;
 138.151 +      typedef typename Digraph::Arc GArc;
 138.152 +
 138.153 +      built = true;
 138.154 +
 138.155 +      node_num = countNodes(digraph);
 138.156 +      arc_num = countArcs(digraph);
 138.157 +
 138.158 +      node_first_out = new int[node_num + 1];
 138.159 +      node_first_in = new int[node_num];
 138.160 +
 138.161 +      arc_source = new int[arc_num];
 138.162 +      arc_target = new int[arc_num];
 138.163 +      arc_next_out = new int[arc_num];
 138.164 +      arc_next_in = new int[arc_num];
 138.165 +
 138.166 +      int node_index = 0;
 138.167 +      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
 138.168 +        nodeRef[n] = Node(node_index);
 138.169 +        node_first_in[node_index] = -1;
 138.170 +        ++node_index;
 138.171 +      }
 138.172 +
 138.173 +      ArcLess<Digraph, NodeRefMap> arcLess(digraph, nodeRef);
 138.174 +
 138.175 +      int arc_index = 0;
 138.176 +      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
 138.177 +        int source = nodeRef[n].id;
 138.178 +        std::vector<GArc> arcs;
 138.179 +        for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) {
 138.180 +          arcs.push_back(e);
 138.181 +        }
 138.182 +        if (!arcs.empty()) {
 138.183 +          node_first_out[source] = arc_index;
 138.184 +          std::sort(arcs.begin(), arcs.end(), arcLess);
 138.185 +          for (typename std::vector<GArc>::iterator it = arcs.begin();
 138.186 +               it != arcs.end(); ++it) {
 138.187 +            int target = nodeRef[digraph.target(*it)].id;
 138.188 +            arcRef[*it] = Arc(arc_index);
 138.189 +            arc_source[arc_index] = source; 
 138.190 +            arc_target[arc_index] = target;
 138.191 +            arc_next_in[arc_index] = node_first_in[target];
 138.192 +            node_first_in[target] = arc_index;
 138.193 +            arc_next_out[arc_index] = arc_index + 1;
 138.194 +            ++arc_index;
 138.195 +          }
 138.196 +          arc_next_out[arc_index - 1] = -1;
 138.197 +        } else {
 138.198 +          node_first_out[source] = arc_index;
 138.199 +        }
 138.200 +      }
 138.201 +      node_first_out[node_num] = arc_num;
 138.202 +    }
 138.203 +    
 138.204 +    template <typename ArcListIterator>
 138.205 +    void build(int n, ArcListIterator first, ArcListIterator last) {
 138.206 +      built = true;
 138.207 +
 138.208 +      node_num = n;
 138.209 +      arc_num = std::distance(first, last);
 138.210 +
 138.211 +      node_first_out = new int[node_num + 1];
 138.212 +      node_first_in = new int[node_num];
 138.213 +
 138.214 +      arc_source = new int[arc_num];
 138.215 +      arc_target = new int[arc_num];
 138.216 +      arc_next_out = new int[arc_num];
 138.217 +      arc_next_in = new int[arc_num];
 138.218 +      
 138.219 +      for (int i = 0; i != node_num; ++i) {
 138.220 +        node_first_in[i] = -1;
 138.221 +      }      
 138.222 +      
 138.223 +      int arc_index = 0;
 138.224 +      for (int i = 0; i != node_num; ++i) {
 138.225 +        node_first_out[i] = arc_index;
 138.226 +        for ( ; first != last && (*first).first == i; ++first) {
 138.227 +          int j = (*first).second;
 138.228 +          LEMON_ASSERT(j >= 0 && j < node_num,
 138.229 +            "Wrong arc list for StaticDigraph::build()");
 138.230 +          arc_source[arc_index] = i;
 138.231 +          arc_target[arc_index] = j;
 138.232 +          arc_next_in[arc_index] = node_first_in[j];
 138.233 +          node_first_in[j] = arc_index;
 138.234 +          arc_next_out[arc_index] = arc_index + 1;
 138.235 +          ++arc_index;
 138.236 +        }
 138.237 +        if (arc_index > node_first_out[i])
 138.238 +          arc_next_out[arc_index - 1] = -1;
 138.239 +      }
 138.240 +      LEMON_ASSERT(first == last,
 138.241 +        "Wrong arc list for StaticDigraph::build()");
 138.242 +      node_first_out[node_num] = arc_num;
 138.243 +    }
 138.244 +
 138.245 +  protected:
 138.246 +
 138.247 +    void fastFirstOut(Arc& e, const Node& n) const {
 138.248 +      e.id = node_first_out[n.id];
 138.249 +    }
 138.250 +
 138.251 +    static void fastNextOut(Arc& e) {
 138.252 +      ++e.id;
 138.253 +    }
 138.254 +    void fastLastOut(Arc& e, const Node& n) const {
 138.255 +      e.id = node_first_out[n.id + 1];
 138.256 +    }
 138.257 +
 138.258 +  protected:
 138.259 +    bool built;
 138.260 +    int node_num;
 138.261 +    int arc_num;
 138.262 +    int *node_first_out;
 138.263 +    int *node_first_in;
 138.264 +    int *arc_source;
 138.265 +    int *arc_target;
 138.266 +    int *arc_next_in;
 138.267 +    int *arc_next_out;
 138.268 +  };
 138.269 +
 138.270 +  typedef DigraphExtender<StaticDigraphBase> ExtendedStaticDigraphBase;
 138.271 +
 138.272 +
 138.273 +  /// \ingroup graphs
 138.274 +  ///
 138.275 +  /// \brief A static directed graph class.
 138.276 +  ///
 138.277 +  /// \ref StaticDigraph is a highly efficient digraph implementation,
 138.278 +  /// but it is fully static.
 138.279 +  /// It stores only two \c int values for each node and only four \c int
 138.280 +  /// values for each arc. Moreover it provides faster item iteration than
 138.281 +  /// \ref ListDigraph and \ref SmartDigraph, especially using \c OutArcIt
 138.282 +  /// iterators, since its arcs are stored in an appropriate order.
 138.283 +  /// However it only provides build() and clear() functions and does not
 138.284 +  /// support any other modification of the digraph.
 138.285 +  ///
 138.286 +  /// Since this digraph structure is completely static, its nodes and arcs
 138.287 +  /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt>
 138.288 +  /// and <tt>[0..arcNum()-1]</tt>, respectively. 
 138.289 +  /// The index of an item is the same as its ID, it can be obtained
 138.290 +  /// using the corresponding \ref index() or \ref concepts::Digraph::id()
 138.291 +  /// "id()" function. A node or arc with a certain index can be obtained
 138.292 +  /// using node() or arc().
 138.293 +  ///
 138.294 +  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
 138.295 +  /// Most of its member functions and nested classes are documented
 138.296 +  /// only in the concept class.
 138.297 +  ///
 138.298 +  /// \sa concepts::Digraph
 138.299 +  class StaticDigraph : public ExtendedStaticDigraphBase {
 138.300 +  public:
 138.301 +
 138.302 +    typedef ExtendedStaticDigraphBase Parent;
 138.303 +  
 138.304 +  public:
 138.305 +  
 138.306 +    /// \brief Constructor
 138.307 +    ///
 138.308 +    /// Default constructor.
 138.309 +    StaticDigraph() : Parent() {}
 138.310 +
 138.311 +    /// \brief The node with the given index.
 138.312 +    ///
 138.313 +    /// This function returns the node with the given index.
 138.314 +    /// \sa index()
 138.315 +    static Node node(int ix) { return Parent::nodeFromId(ix); }
 138.316 +
 138.317 +    /// \brief The arc with the given index.
 138.318 +    ///
 138.319 +    /// This function returns the arc with the given index.
 138.320 +    /// \sa index()
 138.321 +    static Arc arc(int ix) { return Parent::arcFromId(ix); }
 138.322 +
 138.323 +    /// \brief The index of the given node.
 138.324 +    ///
 138.325 +    /// This function returns the index of the the given node.
 138.326 +    /// \sa node()
 138.327 +    static int index(Node node) { return Parent::id(node); }
 138.328 +
 138.329 +    /// \brief The index of the given arc.
 138.330 +    ///
 138.331 +    /// This function returns the index of the the given arc.
 138.332 +    /// \sa arc()
 138.333 +    static int index(Arc arc) { return Parent::id(arc); }
 138.334 +
 138.335 +    /// \brief Number of nodes.
 138.336 +    ///
 138.337 +    /// This function returns the number of nodes.
 138.338 +    int nodeNum() const { return node_num; }
 138.339 +
 138.340 +    /// \brief Number of arcs.
 138.341 +    ///
 138.342 +    /// This function returns the number of arcs.
 138.343 +    int arcNum() const { return arc_num; }
 138.344 +
 138.345 +    /// \brief Build the digraph copying another digraph.
 138.346 +    ///
 138.347 +    /// This function builds the digraph copying another digraph of any
 138.348 +    /// kind. It can be called more than once, but in such case, the whole
 138.349 +    /// structure and all maps will be cleared and rebuilt.
 138.350 +    ///
 138.351 +    /// This method also makes possible to copy a digraph to a StaticDigraph
 138.352 +    /// structure using \ref DigraphCopy.
 138.353 +    /// 
 138.354 +    /// \param digraph An existing digraph to be copied.
 138.355 +    /// \param nodeRef The node references will be copied into this map.
 138.356 +    /// Its key type must be \c Digraph::Node and its value type must be
 138.357 +    /// \c StaticDigraph::Node.
 138.358 +    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
 138.359 +    /// concept.
 138.360 +    /// \param arcRef The arc references will be copied into this map.
 138.361 +    /// Its key type must be \c Digraph::Arc and its value type must be
 138.362 +    /// \c StaticDigraph::Arc.
 138.363 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
 138.364 +    ///
 138.365 +    /// \note If you do not need the arc references, then you could use
 138.366 +    /// \ref NullMap for the last parameter. However the node references
 138.367 +    /// are required by the function itself, thus they must be readable
 138.368 +    /// from the map.
 138.369 +    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
 138.370 +    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
 138.371 +      if (built) Parent::clear();
 138.372 +      Parent::build(digraph, nodeRef, arcRef);
 138.373 +    }
 138.374 +  
 138.375 +    /// \brief Build the digraph from an arc list.
 138.376 +    ///
 138.377 +    /// This function builds the digraph from the given arc list.
 138.378 +    /// It can be called more than once, but in such case, the whole
 138.379 +    /// structure and all maps will be cleared and rebuilt.
 138.380 +    ///
 138.381 +    /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
 138.382 +    /// specified by STL compatible itartors whose \c value_type must be
 138.383 +    /// <tt>std::pair<int,int></tt>.
 138.384 +    /// Each arc must be specified by a pair of integer indices
 138.385 +    /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
 138.386 +    /// non-decreasing order with respect to their first values.</i>
 138.387 +    /// If the k-th pair in the list is <tt>(i,j)</tt>, then
 138.388 +    /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
 138.389 +    ///
 138.390 +    /// \param n The number of nodes.
 138.391 +    /// \param begin An iterator pointing to the beginning of the arc list.
 138.392 +    /// \param end An iterator pointing to the end of the arc list.
 138.393 +    ///
 138.394 +    /// For example, a simple digraph can be constructed like this.
 138.395 +    /// \code
 138.396 +    ///   std::vector<std::pair<int,int> > arcs;
 138.397 +    ///   arcs.push_back(std::make_pair(0,1));
 138.398 +    ///   arcs.push_back(std::make_pair(0,2));
 138.399 +    ///   arcs.push_back(std::make_pair(1,3));
 138.400 +    ///   arcs.push_back(std::make_pair(1,2));
 138.401 +    ///   arcs.push_back(std::make_pair(3,0));
 138.402 +    ///   StaticDigraph gr;
 138.403 +    ///   gr.build(4, arcs.begin(), arcs.end());
 138.404 +    /// \endcode
 138.405 +    template <typename ArcListIterator>
 138.406 +    void build(int n, ArcListIterator begin, ArcListIterator end) {
 138.407 +      if (built) Parent::clear();
 138.408 +      StaticDigraphBase::build(n, begin, end);
 138.409 +      notifier(Node()).build();
 138.410 +      notifier(Arc()).build();
 138.411 +    }
 138.412 +
 138.413 +    /// \brief Clear the digraph.
 138.414 +    ///
 138.415 +    /// This function erases all nodes and arcs from the digraph.
 138.416 +    void clear() {
 138.417 +      Parent::clear();
 138.418 +    }
 138.419 +
 138.420 +  protected:
 138.421 +
 138.422 +    using Parent::fastFirstOut;
 138.423 +    using Parent::fastNextOut;
 138.424 +    using Parent::fastLastOut;
 138.425 +    
 138.426 +  public:
 138.427 +
 138.428 +    class OutArcIt : public Arc {
 138.429 +    public:
 138.430 +
 138.431 +      OutArcIt() { }
 138.432 +
 138.433 +      OutArcIt(Invalid i) : Arc(i) { }
 138.434 +
 138.435 +      OutArcIt(const StaticDigraph& digraph, const Node& node) {
 138.436 +	digraph.fastFirstOut(*this, node);
 138.437 +	digraph.fastLastOut(last, node);
 138.438 +        if (last == *this) *this = INVALID;
 138.439 +      }
 138.440 +
 138.441 +      OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) {
 138.442 +        if (arc != INVALID) {
 138.443 +          digraph.fastLastOut(last, digraph.source(arc));
 138.444 +        }
 138.445 +      }
 138.446 +
 138.447 +      OutArcIt& operator++() { 
 138.448 +        StaticDigraph::fastNextOut(*this);
 138.449 +        if (last == *this) *this = INVALID;
 138.450 +        return *this; 
 138.451 +      }
 138.452 +
 138.453 +    private:
 138.454 +      Arc last;
 138.455 +    };
 138.456 +
 138.457 +    Node baseNode(const OutArcIt &arc) const {
 138.458 +      return Parent::source(static_cast<const Arc&>(arc));
 138.459 +    }
 138.460 +
 138.461 +    Node runningNode(const OutArcIt &arc) const {
 138.462 +      return Parent::target(static_cast<const Arc&>(arc));
 138.463 +    }
 138.464 +
 138.465 +    Node baseNode(const InArcIt &arc) const {
 138.466 +      return Parent::target(static_cast<const Arc&>(arc));
 138.467 +    }
 138.468 +
 138.469 +    Node runningNode(const InArcIt &arc) const {
 138.470 +      return Parent::source(static_cast<const Arc&>(arc));
 138.471 +    }
 138.472 +
 138.473 +  };
 138.474 +
 138.475 +}
 138.476 +
 138.477 +#endif
   139.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   139.2 +++ b/lemon/suurballe.h	Thu Nov 05 15:50:01 2009 +0100
   139.3 @@ -0,0 +1,535 @@
   139.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   139.5 + *
   139.6 + * This file is a part of LEMON, a generic C++ optimization library.
   139.7 + *
   139.8 + * Copyright (C) 2003-2009
   139.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  139.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  139.11 + *
  139.12 + * Permission to use, modify and distribute this software is granted
  139.13 + * provided that this copyright notice appears in all copies. For
  139.14 + * precise terms see the accompanying LICENSE file.
  139.15 + *
  139.16 + * This software is provided "AS IS" with no warranty of any kind,
  139.17 + * express or implied, and with no claim as to its suitability for any
  139.18 + * purpose.
  139.19 + *
  139.20 + */
  139.21 +
  139.22 +#ifndef LEMON_SUURBALLE_H
  139.23 +#define LEMON_SUURBALLE_H
  139.24 +
  139.25 +///\ingroup shortest_path
  139.26 +///\file
  139.27 +///\brief An algorithm for finding arc-disjoint paths between two
  139.28 +/// nodes having minimum total length.
  139.29 +
  139.30 +#include <vector>
  139.31 +#include <limits>
  139.32 +#include <lemon/bin_heap.h>
  139.33 +#include <lemon/path.h>
  139.34 +#include <lemon/list_graph.h>
  139.35 +#include <lemon/maps.h>
  139.36 +
  139.37 +namespace lemon {
  139.38 +
  139.39 +  /// \addtogroup shortest_path
  139.40 +  /// @{
  139.41 +
  139.42 +  /// \brief Algorithm for finding arc-disjoint paths between two nodes
  139.43 +  /// having minimum total length.
  139.44 +  ///
  139.45 +  /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
  139.46 +  /// finding arc-disjoint paths having minimum total length (cost)
  139.47 +  /// from a given source node to a given target node in a digraph.
  139.48 +  ///
  139.49 +  /// Note that this problem is a special case of the \ref min_cost_flow
  139.50 +  /// "minimum cost flow problem". This implementation is actually an
  139.51 +  /// efficient specialized version of the \ref CapacityScaling
  139.52 +  /// "Successive Shortest Path" algorithm directly for this problem.
  139.53 +  /// Therefore this class provides query functions for flow values and
  139.54 +  /// node potentials (the dual solution) just like the minimum cost flow
  139.55 +  /// algorithms.
  139.56 +  ///
  139.57 +  /// \tparam GR The digraph type the algorithm runs on.
  139.58 +  /// \tparam LEN The type of the length map.
  139.59 +  /// The default value is <tt>GR::ArcMap<int></tt>.
  139.60 +  ///
  139.61 +  /// \warning Length values should be \e non-negative \e integers.
  139.62 +  ///
  139.63 +  /// \note For finding node-disjoint paths this algorithm can be used
  139.64 +  /// along with the \ref SplitNodes adaptor.
  139.65 +#ifdef DOXYGEN
  139.66 +  template <typename GR, typename LEN>
  139.67 +#else
  139.68 +  template < typename GR,
  139.69 +             typename LEN = typename GR::template ArcMap<int> >
  139.70 +#endif
  139.71 +  class Suurballe
  139.72 +  {
  139.73 +    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
  139.74 +
  139.75 +    typedef ConstMap<Arc, int> ConstArcMap;
  139.76 +    typedef typename GR::template NodeMap<Arc> PredMap;
  139.77 +
  139.78 +  public:
  139.79 +
  139.80 +    /// The type of the digraph the algorithm runs on.
  139.81 +    typedef GR Digraph;
  139.82 +    /// The type of the length map.
  139.83 +    typedef LEN LengthMap;
  139.84 +    /// The type of the lengths.
  139.85 +    typedef typename LengthMap::Value Length;
  139.86 +#ifdef DOXYGEN
  139.87 +    /// The type of the flow map.
  139.88 +    typedef GR::ArcMap<int> FlowMap;
  139.89 +    /// The type of the potential map.
  139.90 +    typedef GR::NodeMap<Length> PotentialMap;
  139.91 +#else
  139.92 +    /// The type of the flow map.
  139.93 +    typedef typename Digraph::template ArcMap<int> FlowMap;
  139.94 +    /// The type of the potential map.
  139.95 +    typedef typename Digraph::template NodeMap<Length> PotentialMap;
  139.96 +#endif
  139.97 +
  139.98 +    /// The type of the path structures.
  139.99 +    typedef SimplePath<GR> Path;
 139.100 +
 139.101 +  private:
 139.102 +
 139.103 +    // ResidualDijkstra is a special implementation of the
 139.104 +    // Dijkstra algorithm for finding shortest paths in the
 139.105 +    // residual network with respect to the reduced arc lengths
 139.106 +    // and modifying the node potentials according to the
 139.107 +    // distance of the nodes.
 139.108 +    class ResidualDijkstra
 139.109 +    {
 139.110 +      typedef typename Digraph::template NodeMap<int> HeapCrossRef;
 139.111 +      typedef BinHeap<Length, HeapCrossRef> Heap;
 139.112 +
 139.113 +    private:
 139.114 +
 139.115 +      // The digraph the algorithm runs on
 139.116 +      const Digraph &_graph;
 139.117 +
 139.118 +      // The main maps
 139.119 +      const FlowMap &_flow;
 139.120 +      const LengthMap &_length;
 139.121 +      PotentialMap &_potential;
 139.122 +
 139.123 +      // The distance map
 139.124 +      PotentialMap _dist;
 139.125 +      // The pred arc map
 139.126 +      PredMap &_pred;
 139.127 +      // The processed (i.e. permanently labeled) nodes
 139.128 +      std::vector<Node> _proc_nodes;
 139.129 +
 139.130 +      Node _s;
 139.131 +      Node _t;
 139.132 +
 139.133 +    public:
 139.134 +
 139.135 +      /// Constructor.
 139.136 +      ResidualDijkstra( const Digraph &graph,
 139.137 +                        const FlowMap &flow,
 139.138 +                        const LengthMap &length,
 139.139 +                        PotentialMap &potential,
 139.140 +                        PredMap &pred,
 139.141 +                        Node s, Node t ) :
 139.142 +        _graph(graph), _flow(flow), _length(length), _potential(potential),
 139.143 +        _dist(graph), _pred(pred), _s(s), _t(t) {}
 139.144 +
 139.145 +      /// \brief Run the algorithm. It returns \c true if a path is found
 139.146 +      /// from the source node to the target node.
 139.147 +      bool run() {
 139.148 +        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
 139.149 +        Heap heap(heap_cross_ref);
 139.150 +        heap.push(_s, 0);
 139.151 +        _pred[_s] = INVALID;
 139.152 +        _proc_nodes.clear();
 139.153 +
 139.154 +        // Process nodes
 139.155 +        while (!heap.empty() && heap.top() != _t) {
 139.156 +          Node u = heap.top(), v;
 139.157 +          Length d = heap.prio() + _potential[u], nd;
 139.158 +          _dist[u] = heap.prio();
 139.159 +          heap.pop();
 139.160 +          _proc_nodes.push_back(u);
 139.161 +
 139.162 +          // Traverse outgoing arcs
 139.163 +          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
 139.164 +            if (_flow[e] == 0) {
 139.165 +              v = _graph.target(e);
 139.166 +              switch(heap.state(v)) {
 139.167 +              case Heap::PRE_HEAP:
 139.168 +                heap.push(v, d + _length[e] - _potential[v]);
 139.169 +                _pred[v] = e;
 139.170 +                break;
 139.171 +              case Heap::IN_HEAP:
 139.172 +                nd = d + _length[e] - _potential[v];
 139.173 +                if (nd < heap[v]) {
 139.174 +                  heap.decrease(v, nd);
 139.175 +                  _pred[v] = e;
 139.176 +                }
 139.177 +                break;
 139.178 +              case Heap::POST_HEAP:
 139.179 +                break;
 139.180 +              }
 139.181 +            }
 139.182 +          }
 139.183 +
 139.184 +          // Traverse incoming arcs
 139.185 +          for (InArcIt e(_graph, u); e != INVALID; ++e) {
 139.186 +            if (_flow[e] == 1) {
 139.187 +              v = _graph.source(e);
 139.188 +              switch(heap.state(v)) {
 139.189 +              case Heap::PRE_HEAP:
 139.190 +                heap.push(v, d - _length[e] - _potential[v]);
 139.191 +                _pred[v] = e;
 139.192 +                break;
 139.193 +              case Heap::IN_HEAP:
 139.194 +                nd = d - _length[e] - _potential[v];
 139.195 +                if (nd < heap[v]) {
 139.196 +                  heap.decrease(v, nd);
 139.197 +                  _pred[v] = e;
 139.198 +                }
 139.199 +                break;
 139.200 +              case Heap::POST_HEAP:
 139.201 +                break;
 139.202 +              }
 139.203 +            }
 139.204 +          }
 139.205 +        }
 139.206 +        if (heap.empty()) return false;
 139.207 +
 139.208 +        // Update potentials of processed nodes
 139.209 +        Length t_dist = heap.prio();
 139.210 +        for (int i = 0; i < int(_proc_nodes.size()); ++i)
 139.211 +          _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
 139.212 +        return true;
 139.213 +      }
 139.214 +
 139.215 +    }; //class ResidualDijkstra
 139.216 +
 139.217 +  private:
 139.218 +
 139.219 +    // The digraph the algorithm runs on
 139.220 +    const Digraph &_graph;
 139.221 +    // The length map
 139.222 +    const LengthMap &_length;
 139.223 +
 139.224 +    // Arc map of the current flow
 139.225 +    FlowMap *_flow;
 139.226 +    bool _local_flow;
 139.227 +    // Node map of the current potentials
 139.228 +    PotentialMap *_potential;
 139.229 +    bool _local_potential;
 139.230 +
 139.231 +    // The source node
 139.232 +    Node _source;
 139.233 +    // The target node
 139.234 +    Node _target;
 139.235 +
 139.236 +    // Container to store the found paths
 139.237 +    std::vector< SimplePath<Digraph> > paths;
 139.238 +    int _path_num;
 139.239 +
 139.240 +    // The pred arc map
 139.241 +    PredMap _pred;
 139.242 +    // Implementation of the Dijkstra algorithm for finding augmenting
 139.243 +    // shortest paths in the residual network
 139.244 +    ResidualDijkstra *_dijkstra;
 139.245 +
 139.246 +  public:
 139.247 +
 139.248 +    /// \brief Constructor.
 139.249 +    ///
 139.250 +    /// Constructor.
 139.251 +    ///
 139.252 +    /// \param graph The digraph the algorithm runs on.
 139.253 +    /// \param length The length (cost) values of the arcs.
 139.254 +    Suurballe( const Digraph &graph,
 139.255 +               const LengthMap &length ) :
 139.256 +      _graph(graph), _length(length), _flow(0), _local_flow(false),
 139.257 +      _potential(0), _local_potential(false), _pred(graph)
 139.258 +    {
 139.259 +      LEMON_ASSERT(std::numeric_limits<Length>::is_integer,
 139.260 +        "The length type of Suurballe must be integer");
 139.261 +    }
 139.262 +
 139.263 +    /// Destructor.
 139.264 +    ~Suurballe() {
 139.265 +      if (_local_flow) delete _flow;
 139.266 +      if (_local_potential) delete _potential;
 139.267 +      delete _dijkstra;
 139.268 +    }
 139.269 +
 139.270 +    /// \brief Set the flow map.
 139.271 +    ///
 139.272 +    /// This function sets the flow map.
 139.273 +    /// If it is not used before calling \ref run() or \ref init(),
 139.274 +    /// an instance will be allocated automatically. The destructor
 139.275 +    /// deallocates this automatically allocated map, of course.
 139.276 +    ///
 139.277 +    /// The found flow contains only 0 and 1 values, since it is the
 139.278 +    /// union of the found arc-disjoint paths.
 139.279 +    ///
 139.280 +    /// \return <tt>(*this)</tt>
 139.281 +    Suurballe& flowMap(FlowMap &map) {
 139.282 +      if (_local_flow) {
 139.283 +        delete _flow;
 139.284 +        _local_flow = false;
 139.285 +      }
 139.286 +      _flow = &map;
 139.287 +      return *this;
 139.288 +    }
 139.289 +
 139.290 +    /// \brief Set the potential map.
 139.291 +    ///
 139.292 +    /// This function sets the potential map.
 139.293 +    /// If it is not used before calling \ref run() or \ref init(),
 139.294 +    /// an instance will be allocated automatically. The destructor
 139.295 +    /// deallocates this automatically allocated map, of course.
 139.296 +    ///
 139.297 +    /// The node potentials provide the dual solution of the underlying
 139.298 +    /// \ref min_cost_flow "minimum cost flow problem".
 139.299 +    ///
 139.300 +    /// \return <tt>(*this)</tt>
 139.301 +    Suurballe& potentialMap(PotentialMap &map) {
 139.302 +      if (_local_potential) {
 139.303 +        delete _potential;
 139.304 +        _local_potential = false;
 139.305 +      }
 139.306 +      _potential = &map;
 139.307 +      return *this;
 139.308 +    }
 139.309 +
 139.310 +    /// \name Execution Control
 139.311 +    /// The simplest way to execute the algorithm is to call the run()
 139.312 +    /// function.
 139.313 +    /// \n
 139.314 +    /// If you only need the flow that is the union of the found
 139.315 +    /// arc-disjoint paths, you may call init() and findFlow().
 139.316 +
 139.317 +    /// @{
 139.318 +
 139.319 +    /// \brief Run the algorithm.
 139.320 +    ///
 139.321 +    /// This function runs the algorithm.
 139.322 +    ///
 139.323 +    /// \param s The source node.
 139.324 +    /// \param t The target node.
 139.325 +    /// \param k The number of paths to be found.
 139.326 +    ///
 139.327 +    /// \return \c k if there are at least \c k arc-disjoint paths from
 139.328 +    /// \c s to \c t in the digraph. Otherwise it returns the number of
 139.329 +    /// arc-disjoint paths found.
 139.330 +    ///
 139.331 +    /// \note Apart from the return value, <tt>s.run(s, t, k)</tt> is
 139.332 +    /// just a shortcut of the following code.
 139.333 +    /// \code
 139.334 +    ///   s.init(s);
 139.335 +    ///   s.findFlow(t, k);
 139.336 +    ///   s.findPaths();
 139.337 +    /// \endcode
 139.338 +    int run(const Node& s, const Node& t, int k = 2) {
 139.339 +      init(s);
 139.340 +      findFlow(t, k);
 139.341 +      findPaths();
 139.342 +      return _path_num;
 139.343 +    }
 139.344 +
 139.345 +    /// \brief Initialize the algorithm.
 139.346 +    ///
 139.347 +    /// This function initializes the algorithm.
 139.348 +    ///
 139.349 +    /// \param s The source node.
 139.350 +    void init(const Node& s) {
 139.351 +      _source = s;
 139.352 +
 139.353 +      // Initialize maps
 139.354 +      if (!_flow) {
 139.355 +        _flow = new FlowMap(_graph);
 139.356 +        _local_flow = true;
 139.357 +      }
 139.358 +      if (!_potential) {
 139.359 +        _potential = new PotentialMap(_graph);
 139.360 +        _local_potential = true;
 139.361 +      }
 139.362 +      for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
 139.363 +      for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
 139.364 +    }
 139.365 +
 139.366 +    /// \brief Execute the algorithm to find an optimal flow.
 139.367 +    ///
 139.368 +    /// This function executes the successive shortest path algorithm to
 139.369 +    /// find a minimum cost flow, which is the union of \c k (or less)
 139.370 +    /// arc-disjoint paths.
 139.371 +    ///
 139.372 +    /// \param t The target node.
 139.373 +    /// \param k The number of paths to be found.
 139.374 +    ///
 139.375 +    /// \return \c k if there are at least \c k arc-disjoint paths from
 139.376 +    /// the source node to the given node \c t in the digraph.
 139.377 +    /// Otherwise it returns the number of arc-disjoint paths found.
 139.378 +    ///
 139.379 +    /// \pre \ref init() must be called before using this function.
 139.380 +    int findFlow(const Node& t, int k = 2) {
 139.381 +      _target = t;
 139.382 +      _dijkstra =
 139.383 +        new ResidualDijkstra( _graph, *_flow, _length, *_potential, _pred,
 139.384 +                              _source, _target );
 139.385 +
 139.386 +      // Find shortest paths
 139.387 +      _path_num = 0;
 139.388 +      while (_path_num < k) {
 139.389 +        // Run Dijkstra
 139.390 +        if (!_dijkstra->run()) break;
 139.391 +        ++_path_num;
 139.392 +
 139.393 +        // Set the flow along the found shortest path
 139.394 +        Node u = _target;
 139.395 +        Arc e;
 139.396 +        while ((e = _pred[u]) != INVALID) {
 139.397 +          if (u == _graph.target(e)) {
 139.398 +            (*_flow)[e] = 1;
 139.399 +            u = _graph.source(e);
 139.400 +          } else {
 139.401 +            (*_flow)[e] = 0;
 139.402 +            u = _graph.target(e);
 139.403 +          }
 139.404 +        }
 139.405 +      }
 139.406 +      return _path_num;
 139.407 +    }
 139.408 +
 139.409 +    /// \brief Compute the paths from the flow.
 139.410 +    ///
 139.411 +    /// This function computes the paths from the found minimum cost flow,
 139.412 +    /// which is the union of some arc-disjoint paths.
 139.413 +    ///
 139.414 +    /// \pre \ref init() and \ref findFlow() must be called before using
 139.415 +    /// this function.
 139.416 +    void findPaths() {
 139.417 +      FlowMap res_flow(_graph);
 139.418 +      for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
 139.419 +
 139.420 +      paths.clear();
 139.421 +      paths.resize(_path_num);
 139.422 +      for (int i = 0; i < _path_num; ++i) {
 139.423 +        Node n = _source;
 139.424 +        while (n != _target) {
 139.425 +          OutArcIt e(_graph, n);
 139.426 +          for ( ; res_flow[e] == 0; ++e) ;
 139.427 +          n = _graph.target(e);
 139.428 +          paths[i].addBack(e);
 139.429 +          res_flow[e] = 0;
 139.430 +        }
 139.431 +      }
 139.432 +    }
 139.433 +
 139.434 +    /// @}
 139.435 +
 139.436 +    /// \name Query Functions
 139.437 +    /// The results of the algorithm can be obtained using these
 139.438 +    /// functions.
 139.439 +    /// \n The algorithm should be executed before using them.
 139.440 +
 139.441 +    /// @{
 139.442 +
 139.443 +    /// \brief Return the total length of the found paths.
 139.444 +    ///
 139.445 +    /// This function returns the total length of the found paths, i.e.
 139.446 +    /// the total cost of the found flow.
 139.447 +    /// The complexity of the function is O(e).
 139.448 +    ///
 139.449 +    /// \pre \ref run() or \ref findFlow() must be called before using
 139.450 +    /// this function.
 139.451 +    Length totalLength() const {
 139.452 +      Length c = 0;
 139.453 +      for (ArcIt e(_graph); e != INVALID; ++e)
 139.454 +        c += (*_flow)[e] * _length[e];
 139.455 +      return c;
 139.456 +    }
 139.457 +
 139.458 +    /// \brief Return the flow value on the given arc.
 139.459 +    ///
 139.460 +    /// This function returns the flow value on the given arc.
 139.461 +    /// It is \c 1 if the arc is involved in one of the found arc-disjoint
 139.462 +    /// paths, otherwise it is \c 0.
 139.463 +    ///
 139.464 +    /// \pre \ref run() or \ref findFlow() must be called before using
 139.465 +    /// this function.
 139.466 +    int flow(const Arc& arc) const {
 139.467 +      return (*_flow)[arc];
 139.468 +    }
 139.469 +
 139.470 +    /// \brief Return a const reference to an arc map storing the
 139.471 +    /// found flow.
 139.472 +    ///
 139.473 +    /// This function returns a const reference to an arc map storing
 139.474 +    /// the flow that is the union of the found arc-disjoint paths.
 139.475 +    ///
 139.476 +    /// \pre \ref run() or \ref findFlow() must be called before using
 139.477 +    /// this function.
 139.478 +    const FlowMap& flowMap() const {
 139.479 +      return *_flow;
 139.480 +    }
 139.481 +
 139.482 +    /// \brief Return the potential of the given node.
 139.483 +    ///
 139.484 +    /// This function returns the potential of the given node.
 139.485 +    /// The node potentials provide the dual solution of the
 139.486 +    /// underlying \ref min_cost_flow "minimum cost flow problem".
 139.487 +    ///
 139.488 +    /// \pre \ref run() or \ref findFlow() must be called before using
 139.489 +    /// this function.
 139.490 +    Length potential(const Node& node) const {
 139.491 +      return (*_potential)[node];
 139.492 +    }
 139.493 +
 139.494 +    /// \brief Return a const reference to a node map storing the
 139.495 +    /// found potentials (the dual solution).
 139.496 +    ///
 139.497 +    /// This function returns a const reference to a node map storing
 139.498 +    /// the found potentials that provide the dual solution of the
 139.499 +    /// underlying \ref min_cost_flow "minimum cost flow problem".
 139.500 +    ///
 139.501 +    /// \pre \ref run() or \ref findFlow() must be called before using
 139.502 +    /// this function.
 139.503 +    const PotentialMap& potentialMap() const {
 139.504 +      return *_potential;
 139.505 +    }
 139.506 +
 139.507 +    /// \brief Return the number of the found paths.
 139.508 +    ///
 139.509 +    /// This function returns the number of the found paths.
 139.510 +    ///
 139.511 +    /// \pre \ref run() or \ref findFlow() must be called before using
 139.512 +    /// this function.
 139.513 +    int pathNum() const {
 139.514 +      return _path_num;
 139.515 +    }
 139.516 +
 139.517 +    /// \brief Return a const reference to the specified path.
 139.518 +    ///
 139.519 +    /// This function returns a const reference to the specified path.
 139.520 +    ///
 139.521 +    /// \param i The function returns the <tt>i</tt>-th path.
 139.522 +    /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
 139.523 +    ///
 139.524 +    /// \pre \ref run() or \ref findPaths() must be called before using
 139.525 +    /// this function.
 139.526 +    Path path(int i) const {
 139.527 +      return paths[i];
 139.528 +    }
 139.529 +
 139.530 +    /// @}
 139.531 +
 139.532 +  }; //class Suurballe
 139.533 +
 139.534 +  ///@}
 139.535 +
 139.536 +} //namespace lemon
 139.537 +
 139.538 +#endif //LEMON_SUURBALLE_H
   140.1 --- a/lemon/time_measure.h	Fri Oct 16 10:21:37 2009 +0200
   140.2 +++ b/lemon/time_measure.h	Thu Nov 05 15:50:01 2009 +0100
   140.3 @@ -2,7 +2,7 @@
   140.4   *
   140.5   * This file is a part of LEMON, a generic C++ optimization library.
   140.6   *
   140.7 - * Copyright (C) 2003-2008
   140.8 + * Copyright (C) 2003-2009
   140.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  140.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  140.11   *
  140.12 @@ -287,7 +287,7 @@
  140.13      ///
  140.14      Timer(bool run=true) :_running(run) {_reset();}
  140.15  
  140.16 -    ///\name Control the state of the timer
  140.17 +    ///\name Control the State of the Timer
  140.18      ///Basically a Timer can be either running or stopped,
  140.19      ///but it provides a bit finer control on the execution.
  140.20      ///The \ref lemon::Timer "Timer" also counts the number of
  140.21 @@ -395,7 +395,7 @@
  140.22  
  140.23      ///@}
  140.24  
  140.25 -    ///\name Query Functions for the ellapsed time
  140.26 +    ///\name Query Functions for the Ellapsed Time
  140.27  
  140.28      ///@{
  140.29  
   141.1 --- a/lemon/tolerance.h	Fri Oct 16 10:21:37 2009 +0200
   141.2 +++ b/lemon/tolerance.h	Thu Nov 05 15:50:01 2009 +0100
   141.3 @@ -2,7 +2,7 @@
   141.4   *
   141.5   * This file is a part of LEMON, a generic C++ optimization library.
   141.6   *
   141.7 - * Copyright (C) 2003-2008
   141.8 + * Copyright (C) 2003-2009
   141.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  141.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  141.11   *
   142.1 --- a/lemon/unionfind.h	Fri Oct 16 10:21:37 2009 +0200
   142.2 +++ b/lemon/unionfind.h	Thu Nov 05 15:50:01 2009 +0100
   142.3 @@ -2,7 +2,7 @@
   142.4   *
   142.5   * This file is a part of LEMON, a generic C++ optimization library.
   142.6   *
   142.7 - * Copyright (C) 2003-2008
   142.8 + * Copyright (C) 2003-2009
   142.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  142.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  142.11   *
  142.12 @@ -51,11 +51,13 @@
  142.13    ///
  142.14    /// \pre You need to add all the elements by the \ref insert()
  142.15    /// method.
  142.16 -  template <typename _ItemIntMap>
  142.17 +  template <typename IM>
  142.18    class UnionFind {
  142.19    public:
  142.20  
  142.21 -    typedef _ItemIntMap ItemIntMap;
  142.22 +    ///\e
  142.23 +    typedef IM ItemIntMap;
  142.24 +    ///\e
  142.25      typedef typename ItemIntMap::Key Item;
  142.26  
  142.27    private:
  142.28 @@ -170,11 +172,13 @@
  142.29    /// \pre You need to add all the elements by the \ref insert()
  142.30    /// method.
  142.31    ///
  142.32 -  template <typename _ItemIntMap>
  142.33 +  template <typename IM>
  142.34    class UnionFindEnum {
  142.35    public:
  142.36  
  142.37 -    typedef _ItemIntMap ItemIntMap;
  142.38 +    ///\e
  142.39 +    typedef IM ItemIntMap;
  142.40 +    ///\e
  142.41      typedef typename ItemIntMap::Key Item;
  142.42  
  142.43    private:
  142.44 @@ -627,11 +631,13 @@
  142.45    ///
  142.46    /// \pre You need to add all the elements by the \ref insert()
  142.47    /// method.
  142.48 -  template <typename _ItemIntMap>
  142.49 +  template <typename IM>
  142.50    class ExtendFindEnum {
  142.51    public:
  142.52  
  142.53 -    typedef _ItemIntMap ItemIntMap;
  142.54 +    ///\e
  142.55 +    typedef IM ItemIntMap;
  142.56 +    ///\e
  142.57      typedef typename ItemIntMap::Key Item;
  142.58  
  142.59    private:
  142.60 @@ -948,18 +954,18 @@
  142.61    ///
  142.62    /// \pre You need to add all the elements by the \ref insert()
  142.63    /// method.
  142.64 -  ///
  142.65 -  template <typename _Value, typename _ItemIntMap,
  142.66 -            typename _Comp = std::less<_Value> >
  142.67 +  template <typename V, typename IM, typename Comp = std::less<V> >
  142.68    class HeapUnionFind {
  142.69    public:
  142.70  
  142.71 -    typedef _Value Value;
  142.72 -    typedef typename _ItemIntMap::Key Item;
  142.73 -
  142.74 -    typedef _ItemIntMap ItemIntMap;
  142.75 -
  142.76 -    typedef _Comp Comp;
  142.77 +    ///\e
  142.78 +    typedef V Value;
  142.79 +    ///\e
  142.80 +    typedef typename IM::Key Item;
  142.81 +    ///\e
  142.82 +    typedef IM ItemIntMap;
  142.83 +    ///\e
  142.84 +    typedef Comp Compare;
  142.85  
  142.86    private:
  142.87  
  142.88 @@ -1189,7 +1195,7 @@
  142.89                int ld = nodes[nodes[jd].next].left;
  142.90                popLeft(nodes[jd].next);
  142.91                pushRight(jd, ld);
  142.92 -              if (less(ld, nodes[jd].left) || 
  142.93 +              if (less(ld, nodes[jd].left) ||
  142.94                    nodes[ld].item == nodes[pd].item) {
  142.95                  nodes[jd].item = nodes[ld].item;
  142.96                  nodes[jd].prio = nodes[ld].prio;
  142.97 @@ -1601,7 +1607,7 @@
  142.98  
  142.99      /// \brief Gives back the priority of the current item.
 142.100      ///
 142.101 -    /// \return Gives back the priority of the current item.
 142.102 +    /// Gives back the priority of the current item.
 142.103      const Value& operator[](const Item& item) const {
 142.104        return nodes[index[item]].prio;
 142.105      }
 142.106 @@ -1646,7 +1652,7 @@
 142.107  
 142.108      /// \brief Gives back the minimum priority of the class.
 142.109      ///
 142.110 -    /// \return Gives back the minimum priority of the class.
 142.111 +    /// Gives back the minimum priority of the class.
 142.112      const Value& classPrio(int cls) const {
 142.113        return nodes[~(classes[cls].parent)].prio;
 142.114      }
 142.115 @@ -1660,9 +1666,9 @@
 142.116  
 142.117      /// \brief Gives back a representant item of the class.
 142.118      ///
 142.119 +    /// Gives back a representant item of the class.
 142.120      /// The representant is indpendent from the priorities of the
 142.121      /// items.
 142.122 -    /// \return Gives back a representant item of the class.
 142.123      const Item& classRep(int id) const {
 142.124        int parent = classes[id].parent;
 142.125        return nodes[parent >= 0 ? classes[id].depth : leftNode(id)].item;
   143.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   143.2 +++ b/m4/lx_check_coin.m4	Thu Nov 05 15:50:01 2009 +0100
   143.3 @@ -0,0 +1,136 @@
   143.4 +AC_DEFUN([LX_CHECK_COIN],
   143.5 +[
   143.6 +  AC_ARG_WITH([coin],
   143.7 +AS_HELP_STRING([--with-coin@<:@=PREFIX@:>@], [search for CLP under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
   143.8 +AS_HELP_STRING([--without-coin], [disable checking for CLP]),
   143.9 +              [], [with_coin=yes])
  143.10 +
  143.11 +  AC_ARG_WITH([coin-includedir],
  143.12 +AS_HELP_STRING([--with-coin-includedir=DIR], [search for CLP headers in DIR]),
  143.13 +              [], [with_coin_includedir=no])
  143.14 +
  143.15 +  AC_ARG_WITH([coin-libdir],
  143.16 +AS_HELP_STRING([--with-coin-libdir=DIR], [search for CLP libraries in DIR]),
  143.17 +              [], [with_coin_libdir=no])
  143.18 +
  143.19 +  lx_clp_found=no
  143.20 +  if test x"$with_coin" != x"no"; then
  143.21 +    AC_MSG_CHECKING([for CLP])
  143.22 +
  143.23 +    if test x"$with_coin_includedir" != x"no"; then
  143.24 +      CLP_CXXFLAGS="-I$with_coin_includedir"
  143.25 +    elif test x"$with_coin" != x"yes"; then
  143.26 +      CLP_CXXFLAGS="-I$with_coin/include"
  143.27 +    fi
  143.28 +
  143.29 +    if test x"$with_coin_libdir" != x"no"; then
  143.30 +      CLP_LDFLAGS="-L$with_coin_libdir"
  143.31 +    elif test x"$with_coin" != x"yes"; then
  143.32 +      CLP_LDFLAGS="-L$with_coin/lib"
  143.33 +    fi
  143.34 +    CLP_LIBS="-lClp -lCoinUtils -lm"
  143.35 +
  143.36 +    lx_save_cxxflags="$CXXFLAGS"
  143.37 +    lx_save_ldflags="$LDFLAGS"
  143.38 +    lx_save_libs="$LIBS"
  143.39 +    CXXFLAGS="$CLP_CXXFLAGS"
  143.40 +    LDFLAGS="$CLP_LDFLAGS"
  143.41 +    LIBS="$CLP_LIBS"
  143.42 +
  143.43 +    lx_clp_test_prog='
  143.44 +      #include <coin/ClpModel.hpp>
  143.45 +
  143.46 +      int main(int argc, char** argv)
  143.47 +      {
  143.48 +        ClpModel clp;
  143.49 +        return 0;
  143.50 +      }'
  143.51 +
  143.52 +    AC_LANG_PUSH(C++)
  143.53 +    AC_LINK_IFELSE([$lx_clp_test_prog], [lx_clp_found=yes], [lx_clp_found=no])
  143.54 +    AC_LANG_POP(C++)
  143.55 +
  143.56 +    CXXFLAGS="$lx_save_cxxflags"
  143.57 +    LDFLAGS="$lx_save_ldflags"
  143.58 +    LIBS="$lx_save_libs"
  143.59 +
  143.60 +    if test x"$lx_clp_found" = x"yes"; then
  143.61 +      AC_DEFINE([LEMON_HAVE_CLP], [1], [Define to 1 if you have CLP.])
  143.62 +      lx_lp_found=yes
  143.63 +      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
  143.64 +      AC_MSG_RESULT([yes])
  143.65 +    else
  143.66 +      CLP_CXXFLAGS=""
  143.67 +      CLP_LDFLAGS=""
  143.68 +      CLP_LIBS=""
  143.69 +      AC_MSG_RESULT([no])
  143.70 +    fi
  143.71 +  fi
  143.72 +  CLP_LIBS="$CLP_LDFLAGS $CLP_LIBS"
  143.73 +  AC_SUBST(CLP_CXXFLAGS)
  143.74 +  AC_SUBST(CLP_LIBS)
  143.75 +  AM_CONDITIONAL([HAVE_CLP], [test x"$lx_clp_found" = x"yes"])
  143.76 +
  143.77 +
  143.78 +  lx_cbc_found=no
  143.79 +  if test x"$lx_clp_found" = x"yes"; then
  143.80 +    if test x"$with_coin" != x"no"; then
  143.81 +      AC_MSG_CHECKING([for CBC])
  143.82 +
  143.83 +      if test x"$with_coin_includedir" != x"no"; then
  143.84 +        CBC_CXXFLAGS="-I$with_coin_includedir"
  143.85 +      elif test x"$with_coin" != x"yes"; then
  143.86 +        CBC_CXXFLAGS="-I$with_coin/include"
  143.87 +      fi
  143.88 +
  143.89 +      if test x"$with_coin_libdir" != x"no"; then
  143.90 +        CBC_LDFLAGS="-L$with_coin_libdir"
  143.91 +      elif test x"$with_coin" != x"yes"; then
  143.92 +        CBC_LDFLAGS="-L$with_coin/lib"
  143.93 +      fi
  143.94 +      CBC_LIBS="-lOsi -lCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
  143.95 +
  143.96 +      lx_save_cxxflags="$CXXFLAGS"
  143.97 +      lx_save_ldflags="$LDFLAGS"
  143.98 +      lx_save_libs="$LIBS"
  143.99 +      CXXFLAGS="$CBC_CXXFLAGS"
 143.100 +      LDFLAGS="$CBC_LDFLAGS"
 143.101 +      LIBS="$CBC_LIBS"
 143.102 +
 143.103 +      lx_cbc_test_prog='
 143.104 +        #include <coin/CbcModel.hpp>
 143.105 +
 143.106 +        int main(int argc, char** argv)
 143.107 +        {
 143.108 +          CbcModel cbc;
 143.109 +          return 0;
 143.110 +        }'
 143.111 +
 143.112 +      AC_LANG_PUSH(C++)
 143.113 +      AC_LINK_IFELSE([$lx_cbc_test_prog], [lx_cbc_found=yes], [lx_cbc_found=no])
 143.114 +      AC_LANG_POP(C++)
 143.115 +
 143.116 +      CXXFLAGS="$lx_save_cxxflags"
 143.117 +      LDFLAGS="$lx_save_ldflags"
 143.118 +      LIBS="$lx_save_libs"
 143.119 +
 143.120 +      if test x"$lx_cbc_found" = x"yes"; then
 143.121 +        AC_DEFINE([LEMON_HAVE_CBC], [1], [Define to 1 if you have CBC.])
 143.122 +        lx_lp_found=yes
 143.123 +        AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
 143.124 +        lx_mip_found=yes
 143.125 +        AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
 143.126 +        AC_MSG_RESULT([yes])
 143.127 +      else
 143.128 +        CBC_CXXFLAGS=""
 143.129 +        CBC_LDFLAGS=""
 143.130 +        CBC_LIBS=""
 143.131 +        AC_MSG_RESULT([no])
 143.132 +      fi
 143.133 +    fi
 143.134 +  fi
 143.135 +  CBC_LIBS="$CBC_LDFLAGS $CBC_LIBS"
 143.136 +  AC_SUBST(CBC_CXXFLAGS)
 143.137 +  AC_SUBST(CBC_LIBS)
 143.138 +  AM_CONDITIONAL([HAVE_CBC], [test x"$lx_cbc_found" = x"yes"])
 143.139 +])
   144.1 --- a/m4/lx_check_cplex.m4	Fri Oct 16 10:21:37 2009 +0200
   144.2 +++ b/m4/lx_check_cplex.m4	Thu Nov 05 15:50:01 2009 +0100
   144.3 @@ -62,6 +62,10 @@
   144.4  
   144.5      if test x"$lx_cplex_found" = x"yes"; then
   144.6        AC_DEFINE([LEMON_HAVE_CPLEX], [1], [Define to 1 if you have CPLEX.])
   144.7 +      lx_lp_found=yes
   144.8 +      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
   144.9 +      lx_mip_found=yes
  144.10 +      AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
  144.11        AC_MSG_RESULT([yes])
  144.12      else
  144.13        CPLEX_CFLAGS=""
   145.1 --- a/m4/lx_check_glpk.m4	Fri Oct 16 10:21:37 2009 +0200
   145.2 +++ b/m4/lx_check_glpk.m4	Thu Nov 05 15:50:01 2009 +0100
   145.3 @@ -42,6 +42,11 @@
   145.4        #include <glpk.h>
   145.5        }
   145.6  
   145.7 +      #if (GLP_MAJOR_VERSION < 4) \
   145.8 +         || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION < 33)
   145.9 +      #error Supported GLPK versions: 4.33 or above
  145.10 +      #endif
  145.11 +
  145.12        int main(int argc, char** argv)
  145.13        {
  145.14          LPX *lp;
  145.15 @@ -60,6 +65,10 @@
  145.16  
  145.17      if test x"$lx_glpk_found" = x"yes"; then
  145.18        AC_DEFINE([LEMON_HAVE_GLPK], [1], [Define to 1 if you have GLPK.])
  145.19 +      lx_lp_found=yes
  145.20 +      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
  145.21 +      lx_mip_found=yes
  145.22 +      AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
  145.23        AC_MSG_RESULT([yes])
  145.24      else
  145.25        GLPK_CFLAGS=""
   146.1 --- a/m4/lx_check_soplex.m4	Fri Oct 16 10:21:37 2009 +0200
   146.2 +++ b/m4/lx_check_soplex.m4	Thu Nov 05 15:50:01 2009 +0100
   146.3 @@ -20,7 +20,7 @@
   146.4      if test x"$with_soplex_includedir" != x"no"; then
   146.5        SOPLEX_CXXFLAGS="-I$with_soplex_includedir"
   146.6      elif test x"$with_soplex" != x"yes"; then
   146.7 -      SOPLEX_CXXFLAGS="-I$with_soplex/include"
   146.8 +      SOPLEX_CXXFLAGS="-I$with_soplex/src"
   146.9      fi
  146.10  
  146.11      if test x"$with_soplex_libdir" != x"no"; then
  146.12 @@ -38,7 +38,7 @@
  146.13      LIBS="$SOPLEX_LIBS"
  146.14  
  146.15      lx_soplex_test_prog='
  146.16 -      #include <soplex/soplex.h>
  146.17 +      #include <soplex.h>
  146.18  
  146.19        int main(int argc, char** argv)
  146.20        {
  146.21 @@ -56,6 +56,8 @@
  146.22  
  146.23      if test x"$lx_soplex_found" = x"yes"; then
  146.24        AC_DEFINE([LEMON_HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.])
  146.25 +      lx_lp_found=yes
  146.26 +      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
  146.27        AC_MSG_RESULT([yes])
  146.28      else
  146.29        SOPLEX_CXXFLAGS=""
   147.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   147.2 +++ b/scripts/bib2dox.py	Thu Nov 05 15:50:01 2009 +0100
   147.3 @@ -0,0 +1,811 @@
   147.4 +#!/usr/bin/env /usr/local/Python/bin/python2.1
   147.5 +"""
   147.6 +  BibTeX to Doxygen converter
   147.7 +  Usage: python bib2dox.py bibfile.bib > bibfile.dox
   147.8 +
   147.9 +  This code is the modification of the BibTeX to XML converter
  147.10 +  by Vidar Bronken Gundersen et al. See the original copyright notices below. 
  147.11 +
  147.12 +  **********************************************************************
  147.13 +
  147.14 +  Decoder for bibliographic data, BibTeX
  147.15 +  Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
  147.16 +
  147.17 +  v.8
  147.18 +  (c)2002-06-23 Vidar Bronken Gundersen
  147.19 +  http://bibtexml.sf.net/
  147.20 +  Reuse approved as long as this notification is kept.
  147.21 +  Licence: GPL.
  147.22 +
  147.23 +  Contributions/thanks to:
  147.24 +  Egon Willighagen, http://sf.net/projects/jreferences/
  147.25 +  Richard Mahoney (for providing a test case)
  147.26 +
  147.27 +  Editted by Sara Sprenkle to be more robust and handle more bibtex features.
  147.28 +  (c) 2003-01-15
  147.29 +
  147.30 +  1.  Changed bibtex: tags to bibxml: tags.
  147.31 +  2.  Use xmlns:bibxml="http://bibtexml.sf.net/"
  147.32 +  3.  Allow spaces between @type and first {
  147.33 +  4.  "author" fields with multiple authors split by " and "
  147.34 +      are put in separate xml "bibxml:author" tags.
  147.35 +  5.  Option for Titles: words are capitalized
  147.36 +      only if first letter in title or capitalized inside braces
  147.37 +  6.  Removes braces from within field values
  147.38 +  7.  Ignores comments in bibtex file (including @comment{ or % )
  147.39 +  8.  Replaces some special latex tags, e.g., replaces ~ with '&#160;'
  147.40 +  9.  Handles bibtex @string abbreviations
  147.41 +        --> includes bibtex's default abbreviations for months
  147.42 +        --> does concatenation of abbr # " more " and " more " # abbr
  147.43 +  10. Handles @type( ... ) or @type{ ... }
  147.44 +  11. The keywords field is split on , or ; and put into separate xml
  147.45 +      "bibxml:keywords" tags
  147.46 +  12. Ignores @preamble
  147.47 +
  147.48 +  Known Limitations
  147.49 +  1.  Does not transform Latex encoding like math mode and special
  147.50 +      latex symbols.
  147.51 +  2.  Does not parse author fields into first and last names.
  147.52 +      E.g., It does not do anything special to an author whose name is
  147.53 +      in the form LAST_NAME, FIRST_NAME
  147.54 +      In "author" tag, will show up as
  147.55 +      <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
  147.56 +  3.  Does not handle "crossref" fields other than to print
  147.57 +      <bibxml:crossref>...</bibxml:crossref>
  147.58 +  4.  Does not inform user of the input's format errors.  You just won't
  147.59 +      be able to transform the file later with XSL
  147.60 +
  147.61 +  You will have to manually edit the XML output if you need to handle
  147.62 +  these (and unknown) limitations.
  147.63 +
  147.64 +"""
  147.65 +
  147.66 +import string, re
  147.67 +
  147.68 +# set of valid name characters
  147.69 +valid_name_chars = '[\w\-:]'
  147.70 +
  147.71 +#
  147.72 +# define global regular expression variables
  147.73 +#
  147.74 +author_rex = re.compile('\s+and\s+')
  147.75 +rembraces_rex = re.compile('[{}]')
  147.76 +capitalize_rex = re.compile('({[^}]*})')
  147.77 +
  147.78 +# used by bibtexkeywords(data)
  147.79 +keywords_rex = re.compile('[,;]')
  147.80 +
  147.81 +# used by concat_line(line)
  147.82 +concatsplit_rex = re.compile('\s*#\s*')
  147.83 +
  147.84 +# split on {, }, or " in verify_out_of_braces
  147.85 +delimiter_rex = re.compile('([{}"])',re.I)
  147.86 +
  147.87 +field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
  147.88 +data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
  147.89 +
  147.90 +url_rex = re.compile('\\\url\{([^}]*)\}')
  147.91 +
  147.92 +#
  147.93 +# styles for html formatting
  147.94 +#
  147.95 +divstyle = 'margin-top: -4ex; margin-left: 8em;'
  147.96 +
  147.97 +#
  147.98 +# return the string parameter without braces
  147.99 +#
 147.100 +def transformurls(str):
 147.101 +    return url_rex.sub(r'<a href="\1">\1</a>', str)
 147.102 +
 147.103 +#
 147.104 +# return the string parameter without braces
 147.105 +#
 147.106 +def removebraces(str):
 147.107 +    return rembraces_rex.sub('', str)
 147.108 +
 147.109 +#
 147.110 +# latex-specific replacements
 147.111 +# (do this after braces were removed)
 147.112 +#
 147.113 +def latexreplacements(line):
 147.114 +    line = string.replace(line, '~', '&nbsp;')
 147.115 +    line = string.replace(line, '\\\'a', '&aacute;')
 147.116 +    line = string.replace(line, '\\"a', '&auml;')
 147.117 +    line = string.replace(line, '\\\'e', '&eacute;')
 147.118 +    line = string.replace(line, '\\"e', '&euml;')
 147.119 +    line = string.replace(line, '\\\'i', '&iacute;')
 147.120 +    line = string.replace(line, '\\"i', '&iuml;')
 147.121 +    line = string.replace(line, '\\\'o', '&oacute;')
 147.122 +    line = string.replace(line, '\\"o', '&ouml;')
 147.123 +    line = string.replace(line, '\\\'u', '&uacute;')
 147.124 +    line = string.replace(line, '\\"u', '&uuml;')
 147.125 +    line = string.replace(line, '\\H o', '&otilde;')
 147.126 +    line = string.replace(line, '\\H u', '&uuml;')   # &utilde; does not exist
 147.127 +    line = string.replace(line, '\\\'A', '&Aacute;')
 147.128 +    line = string.replace(line, '\\"A', '&Auml;')
 147.129 +    line = string.replace(line, '\\\'E', '&Eacute;')
 147.130 +    line = string.replace(line, '\\"E', '&Euml;')
 147.131 +    line = string.replace(line, '\\\'I', '&Iacute;')
 147.132 +    line = string.replace(line, '\\"I', '&Iuml;')
 147.133 +    line = string.replace(line, '\\\'O', '&Oacute;')
 147.134 +    line = string.replace(line, '\\"O', '&Ouml;')
 147.135 +    line = string.replace(line, '\\\'U', '&Uacute;')
 147.136 +    line = string.replace(line, '\\"U', '&Uuml;')
 147.137 +    line = string.replace(line, '\\H O', '&Otilde;')
 147.138 +    line = string.replace(line, '\\H U', '&Uuml;')   # &Utilde; does not exist
 147.139 +
 147.140 +    return line
 147.141 +
 147.142 +#
 147.143 +# copy characters form a string decoding html expressions (&xyz;)
 147.144 +#
 147.145 +def copychars(str, ifrom, count):
 147.146 +    result = ''
 147.147 +    i = ifrom
 147.148 +    c = 0
 147.149 +    html_spec = False
 147.150 +    while (i < len(str)) and (c < count):
 147.151 +        if str[i] == '&':
 147.152 +            html_spec = True;
 147.153 +            if i+1 < len(str):
 147.154 +                result += str[i+1]
 147.155 +            c += 1
 147.156 +            i += 2
 147.157 +        else:
 147.158 +            if not html_spec:
 147.159 +                if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
 147.160 +                   ((str[i] >= 'a') and (str[i] <= 'z')):
 147.161 +                    result += str[i]
 147.162 +                    c += 1
 147.163 +            elif str[i] == ';':
 147.164 +                html_spec = False;
 147.165 +            i += 1
 147.166 +    
 147.167 +    return result
 147.168 +
 147.169 +
 147.170 +# 
 147.171 +# Handle a list of authors (separated by 'and').
 147.172 +# It gives back an array of the follwing values:
 147.173 +#  - num: the number of authors,
 147.174 +#  - list: the list of the author names,
 147.175 +#  - text: the bibtex text (separated by commas and/or 'and')
 147.176 +#  - abbrev: abbreviation that can be used for indicate the
 147.177 +#    bibliography entries
 147.178 +#
 147.179 +def bibtexauthor(data):
 147.180 +    result = {}
 147.181 +    bibtex = ''
 147.182 +    result['list'] = author_rex.split(data)
 147.183 +    result['num'] = len(result['list'])
 147.184 +    for i, author in enumerate(result['list']):
 147.185 +        # general transformations
 147.186 +        author = latexreplacements(removebraces(author.strip()))
 147.187 +        # transform "Xyz, A. B." to "A. B. Xyz"
 147.188 +        pos = author.find(',')
 147.189 +        if pos != -1:
 147.190 +            author = author[pos+1:].strip() + ' ' + author[:pos].strip()
 147.191 +        result['list'][i] = author
 147.192 +        bibtex += author + '#'
 147.193 +    bibtex = bibtex[:-1]
 147.194 +    if result['num'] > 1:
 147.195 +        ix = bibtex.rfind('#')
 147.196 +        if result['num'] == 2:
 147.197 +            bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
 147.198 +        else:
 147.199 +            bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
 147.200 +    bibtex = bibtex.replace('#', ', ')
 147.201 +    result['text'] = bibtex
 147.202 +    
 147.203 +    result['abbrev'] = ''
 147.204 +    for author in result['list']:
 147.205 +        pos = author.rfind(' ') + 1
 147.206 +        count = 1
 147.207 +        if result['num'] == 1:
 147.208 +            count = 3
 147.209 +        result['abbrev'] += copychars(author, pos, count)
 147.210 +
 147.211 +    return result
 147.212 +
 147.213 +
 147.214 +#
 147.215 +# data = title string
 147.216 +# @return the capitalized title (first letter is capitalized), rest are capitalized
 147.217 +# only if capitalized inside braces
 147.218 +#
 147.219 +def capitalizetitle(data):
 147.220 +    title_list = capitalize_rex.split(data)
 147.221 +    title = ''
 147.222 +    count = 0
 147.223 +    for phrase in title_list:
 147.224 +         check = string.lstrip(phrase)
 147.225 +
 147.226 +         # keep phrase's capitalization the same
 147.227 +         if check.find('{') == 0:
 147.228 +              title += removebraces(phrase)
 147.229 +         else:
 147.230 +         # first word --> capitalize first letter (after spaces)
 147.231 +              if count == 0:
 147.232 +                  title += check.capitalize()
 147.233 +              else:
 147.234 +                  title += phrase.lower()
 147.235 +         count = count + 1
 147.236 +
 147.237 +    return title
 147.238 +
 147.239 +
 147.240 +#
 147.241 +# @return the bibtex for the title
 147.242 +# @param data --> title string
 147.243 +# braces are removed from title
 147.244 +#
 147.245 +def bibtextitle(data, entrytype):
 147.246 +    if entrytype in ('book', 'inbook'):
 147.247 +        title = removebraces(data.strip())
 147.248 +    else:
 147.249 +        title = removebraces(capitalizetitle(data.strip()))
 147.250 +    bibtex = title
 147.251 +    return bibtex
 147.252 +
 147.253 +
 147.254 +#
 147.255 +# function to compare entry lists
 147.256 +#
 147.257 +def entry_cmp(x, y):
 147.258 +    return cmp(x[0], y[0])
 147.259 +
 147.260 +
 147.261 +#
 147.262 +# print the XML for the transformed "filecont_source"
 147.263 +#
 147.264 +def bibtexdecoder(filecont_source):
 147.265 +    filecont = []
 147.266 +    file = []
 147.267 +    
 147.268 +    # want @<alphanumeric chars><spaces>{<spaces><any chars>,
 147.269 +    pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
 147.270 +    endtype_rex = re.compile('}\s*$')
 147.271 +    endtag_rex = re.compile('^\s*}\s*$')
 147.272 +
 147.273 +    bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
 147.274 +    bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
 147.275 +
 147.276 +    quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
 147.277 +    quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
 147.278 +
 147.279 +    for line in filecont_source:
 147.280 +        line = line[:-1]
 147.281 +
 147.282 +        # encode character entities
 147.283 +        line = string.replace(line, '&', '&amp;')
 147.284 +        line = string.replace(line, '<', '&lt;')
 147.285 +        line = string.replace(line, '>', '&gt;')
 147.286 +
 147.287 +        # start entry: publication type (store for later use)
 147.288 +        if pubtype_rex.match(line):
 147.289 +        # want @<alphanumeric chars><spaces>{<spaces><any chars>,
 147.290 +            entrycont = {}
 147.291 +            entry = []
 147.292 +            entrytype = pubtype_rex.sub('\g<1>',line)
 147.293 +            entrytype = string.lower(entrytype)
 147.294 +            entryid   = pubtype_rex.sub('\g<2>', line)
 147.295 +
 147.296 +        # end entry if just a }
 147.297 +        elif endtype_rex.match(line):
 147.298 +            # generate doxygen code for the entry
 147.299 +
 147.300 +            # enty type related formattings
 147.301 +            if entrytype in ('book', 'inbook'):
 147.302 +                entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
 147.303 +                if not entrycont.has_key('author'):
 147.304 +                    entrycont['author'] = entrycont['editor']
 147.305 +                    entrycont['author']['text'] += ', editors'
 147.306 +            elif entrytype == 'article':
 147.307 +                entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
 147.308 +            elif entrytype in ('inproceedings', 'incollection', 'conference'):
 147.309 +                entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
 147.310 +            elif entrytype == 'techreport':
 147.311 +                if not entrycont.has_key('type'):
 147.312 +                    entrycont['type'] = 'Technical report'
 147.313 +            elif entrytype == 'mastersthesis':
 147.314 +                entrycont['type'] = 'Master\'s thesis'
 147.315 +            elif entrytype == 'phdthesis':
 147.316 +                entrycont['type'] = 'PhD thesis'
 147.317 +
 147.318 +            for eline in entrycont:
 147.319 +                if eline != '':
 147.320 +                    eline = latexreplacements(eline)
 147.321 +
 147.322 +            if entrycont.has_key('pages') and (entrycont['pages'] != ''):
 147.323 +                entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
 147.324 +
 147.325 +            if entrycont.has_key('author') and (entrycont['author'] != ''):
 147.326 +                entry.append(entrycont['author']['text'] + '.')
 147.327 +            if entrycont.has_key('title') and (entrycont['title'] != ''):
 147.328 +                entry.append(entrycont['title'] + '.')
 147.329 +            if entrycont.has_key('journal') and (entrycont['journal'] != ''):
 147.330 +                entry.append(entrycont['journal'] + ',')
 147.331 +            if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
 147.332 +                entry.append('In ' + entrycont['booktitle'] + ',')
 147.333 +            if entrycont.has_key('type') and (entrycont['type'] != ''):
 147.334 +                eline = entrycont['type']
 147.335 +                if entrycont.has_key('number') and (entrycont['number'] != ''):
 147.336 +                    eline += ' ' + entrycont['number']
 147.337 +                eline += ','
 147.338 +                entry.append(eline)
 147.339 +            if entrycont.has_key('institution') and (entrycont['institution'] != ''):
 147.340 +                entry.append(entrycont['institution'] + ',')
 147.341 +            if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
 147.342 +                entry.append(entrycont['publisher'] + ',')
 147.343 +            if entrycont.has_key('school') and (entrycont['school'] != ''):
 147.344 +                entry.append(entrycont['school'] + ',')
 147.345 +            if entrycont.has_key('address') and (entrycont['address'] != ''):
 147.346 +                entry.append(entrycont['address'] + ',')
 147.347 +            if entrycont.has_key('edition') and (entrycont['edition'] != ''):
 147.348 +                entry.append(entrycont['edition'] + ' edition,')
 147.349 +            if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
 147.350 +                entry.append(entrycont['howpublished'] + ',')
 147.351 +            if entrycont.has_key('volume') and (entrycont['volume'] != ''):
 147.352 +                eline = entrycont['volume'];
 147.353 +                if entrycont.has_key('number') and (entrycont['number'] != ''):
 147.354 +                    eline += '(' + entrycont['number'] + ')'
 147.355 +                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
 147.356 +                    eline += ':' + entrycont['pages']
 147.357 +                eline += ','
 147.358 +                entry.append(eline)
 147.359 +            else:
 147.360 +                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
 147.361 +                    entry.append('pages ' + entrycont['pages'] + ',')
 147.362 +            if entrycont.has_key('year') and (entrycont['year'] != ''):
 147.363 +                if entrycont.has_key('month') and (entrycont['month'] != ''):
 147.364 +                    entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
 147.365 +                else:
 147.366 +                    entry.append(entrycont['year'] + '.')
 147.367 +            if entrycont.has_key('note') and (entrycont['note'] != ''):
 147.368 +                entry.append(entrycont['note'] + '.')
 147.369 +            if entrycont.has_key('url') and (entrycont['url'] != ''):
 147.370 +                entry.append(entrycont['url'] + '.')
 147.371 +
 147.372 +            # generate keys for sorting and for the output
 147.373 +            sortkey = ''
 147.374 +            bibkey = ''
 147.375 +            if entrycont.has_key('author'):
 147.376 +                for author in entrycont['author']['list']:
 147.377 +                    sortkey += copychars(author, author.rfind(' ')+1, len(author))
 147.378 +                bibkey = entrycont['author']['abbrev']
 147.379 +            else:
 147.380 +                bibkey = 'x'
 147.381 +            if entrycont.has_key('year'):
 147.382 +                sortkey += entrycont['year']
 147.383 +                bibkey += entrycont['year'][-2:]
 147.384 +            if entrycont.has_key('title'):
 147.385 +                sortkey += entrycont['title']
 147.386 +            if entrycont.has_key('key'):
 147.387 +                sortkey = entrycont['key'] + sortkey
 147.388 +                bibkey = entrycont['key']
 147.389 +            entry.insert(0, sortkey)
 147.390 +            entry.insert(1, bibkey)
 147.391 +            entry.insert(2, entryid)
 147.392 +           
 147.393 +            # add the entry to the file contents
 147.394 +            filecont.append(entry)
 147.395 +
 147.396 +        else:
 147.397 +            # field, publication info
 147.398 +            field = ''
 147.399 +            data = ''
 147.400 +            
 147.401 +            # field = {data} entries
 147.402 +            if bracedata_rex.match(line):
 147.403 +                field = bracefield_rex.sub('\g<1>', line)
 147.404 +                field = string.lower(field)
 147.405 +                data =  bracedata_rex.sub('\g<2>', line)
 147.406 +
 147.407 +            # field = "data" entries
 147.408 +            elif quotedata_rex.match(line):
 147.409 +                field = quotefield_rex.sub('\g<1>', line)
 147.410 +                field = string.lower(field)
 147.411 +                data =  quotedata_rex.sub('\g<2>', line)
 147.412 +
 147.413 +            # field = data entries
 147.414 +            elif data_rex.match(line):
 147.415 +                field = field_rex.sub('\g<1>', line)
 147.416 +                field = string.lower(field)
 147.417 +                data =  data_rex.sub('\g<2>', line)
 147.418 +
 147.419 +            if field == 'url':
 147.420 +                data = '\\url{' + data.strip() + '}'
 147.421 +            
 147.422 +            if field in ('author', 'editor'):
 147.423 +                entrycont[field] = bibtexauthor(data)
 147.424 +                line = ''
 147.425 +            elif field == 'title':
 147.426 +                line = bibtextitle(data, entrytype)
 147.427 +            elif field != '':
 147.428 +                line = removebraces(transformurls(data.strip()))
 147.429 +
 147.430 +            if line != '':
 147.431 +                line = latexreplacements(line)
 147.432 +                entrycont[field] = line
 147.433 +
 147.434 +
 147.435 +    # sort entries
 147.436 +    filecont.sort(entry_cmp)
 147.437 +    
 147.438 +    # count the bibtex keys
 147.439 +    keytable = {}
 147.440 +    counttable = {}
 147.441 +    for entry in filecont:
 147.442 +        bibkey = entry[1]
 147.443 +        if not keytable.has_key(bibkey):
 147.444 +            keytable[bibkey] = 1
 147.445 +        else:
 147.446 +            keytable[bibkey] += 1
 147.447 +
 147.448 +    for bibkey in keytable.keys():
 147.449 +        counttable[bibkey] = 0
 147.450 +    
 147.451 +    # generate output
 147.452 +    for entry in filecont:
 147.453 +        # generate output key form the bibtex key
 147.454 +        bibkey = entry[1]
 147.455 +        entryid = entry[2]
 147.456 +        if keytable[bibkey] == 1:
 147.457 +            outkey = bibkey
 147.458 +        else:
 147.459 +            outkey = bibkey + chr(97 + counttable[bibkey])
 147.460 +        counttable[bibkey] += 1
 147.461 +        
 147.462 +        # append the entry code to the output
 147.463 +        file.append('\\section ' + entryid + ' [' + outkey + ']')
 147.464 +        file.append('<div style="' + divstyle + '">')
 147.465 +        for line in entry[3:]:
 147.466 +            file.append(line)
 147.467 +        file.append('</div>')
 147.468 +        file.append('')
 147.469 +
 147.470 +    return file
 147.471 +
 147.472 +
 147.473 +#
 147.474 +# return 1 iff abbr is in line but not inside braces or quotes
 147.475 +# assumes that abbr appears only once on the line (out of braces and quotes)
 147.476 +#
 147.477 +def verify_out_of_braces(line, abbr):
 147.478 +
 147.479 +    phrase_split = delimiter_rex.split(line)
 147.480 +
 147.481 +    abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
 147.482 +
 147.483 +    open_brace = 0
 147.484 +    open_quote = 0
 147.485 +
 147.486 +    for phrase in phrase_split:
 147.487 +        if phrase == "{":
 147.488 +            open_brace = open_brace + 1
 147.489 +        elif phrase == "}":
 147.490 +            open_brace = open_brace - 1
 147.491 +        elif phrase == '"':
 147.492 +            if open_quote == 1:
 147.493 +                open_quote = 0
 147.494 +            else:
 147.495 +                open_quote = 1
 147.496 +        elif abbr_rex.search(phrase):
 147.497 +            if open_brace == 0 and open_quote == 0:
 147.498 +                return 1
 147.499 +
 147.500 +    return 0
 147.501 +
 147.502 +
 147.503 +#
 147.504 +# a line in the form phrase1 # phrase2 # ... # phrasen
 147.505 +# is returned as phrase1 phrase2 ... phrasen
 147.506 +# with the correct punctuation
 147.507 +# Bug: Doesn't always work with multiple abbreviations plugged in
 147.508 +#
 147.509 +def concat_line(line):
 147.510 +    # only look at part after equals
 147.511 +    field = field_rex.sub('\g<1>',line)
 147.512 +    rest = field_rex.sub('\g<2>',line)
 147.513 +
 147.514 +    concat_line = field + ' ='
 147.515 +
 147.516 +    pound_split = concatsplit_rex.split(rest)
 147.517 +
 147.518 +    phrase_count = 0
 147.519 +    length = len(pound_split)
 147.520 +
 147.521 +    for phrase in pound_split:
 147.522 +        phrase = phrase.strip()
 147.523 +        if phrase_count != 0:
 147.524 +            if phrase.startswith('"') or phrase.startswith('{'):
 147.525 +                phrase = phrase[1:]
 147.526 +        elif phrase.startswith('"'):
 147.527 +            phrase = phrase.replace('"','{',1)
 147.528 +
 147.529 +        if phrase_count != length-1:
 147.530 +            if phrase.endswith('"') or phrase.endswith('}'):
 147.531 +                phrase = phrase[:-1]
 147.532 +        else:
 147.533 +            if phrase.endswith('"'):
 147.534 +                phrase = phrase[:-1]
 147.535 +                phrase = phrase + "}"
 147.536 +            elif phrase.endswith('",'):
 147.537 +                phrase = phrase[:-2]
 147.538 +                phrase = phrase + "},"
 147.539 +
 147.540 +        # if phrase did have \#, add the \# back
 147.541 +        if phrase.endswith('\\'):
 147.542 +            phrase = phrase + "#"
 147.543 +        concat_line = concat_line + ' ' + phrase
 147.544 +
 147.545 +        phrase_count = phrase_count + 1
 147.546 +
 147.547 +    return concat_line
 147.548 +
 147.549 +
 147.550 +#
 147.551 +# substitute abbreviations into filecont
 147.552 +# @param filecont_source - string of data from file
 147.553 +#
 147.554 +def bibtex_replace_abbreviations(filecont_source):
 147.555 +    filecont = filecont_source.splitlines()
 147.556 +
 147.557 +    #  These are defined in bibtex, so we'll define them too
 147.558 +    abbr_list = ['jan','feb','mar','apr','may','jun',
 147.559 +                 'jul','aug','sep','oct','nov','dec']
 147.560 +    value_list = ['January','February','March','April',
 147.561 +                  'May','June','July','August','September',
 147.562 +                  'October','November','December']
 147.563 +
 147.564 +    abbr_rex = []
 147.565 +    total_abbr_count = 0
 147.566 +
 147.567 +    front = '\\b'
 147.568 +    back = '(,?)\\b'
 147.569 +
 147.570 +    for x in abbr_list:
 147.571 +        abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
 147.572 +        total_abbr_count = total_abbr_count + 1
 147.573 +
 147.574 +
 147.575 +    abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
 147.576 +                             re.I)
 147.577 +
 147.578 +    comment_rex = re.compile('@comment\s*{',re.I)
 147.579 +    preamble_rex = re.compile('@preamble\s*{',re.I)
 147.580 +
 147.581 +    waiting_for_end_string = 0
 147.582 +    i = 0
 147.583 +    filecont2 = ''
 147.584 +
 147.585 +    for line in filecont:
 147.586 +        if line == ' ' or line == '':
 147.587 +            continue
 147.588 +
 147.589 +        if waiting_for_end_string:
 147.590 +            if re.search('}',line):
 147.591 +                waiting_for_end_string = 0
 147.592 +                continue
 147.593 +
 147.594 +        if abbrdef_rex.search(line):
 147.595 +            abbr = abbrdef_rex.sub('\g<1>', line)
 147.596 +
 147.597 +            if abbr_list.count(abbr) == 0:
 147.598 +                val = abbrdef_rex.sub('\g<2>', line)
 147.599 +                abbr_list.append(abbr)
 147.600 +                value_list.append(string.strip(val))
 147.601 +                abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
 147.602 +                total_abbr_count = total_abbr_count + 1
 147.603 +            waiting_for_end_string = 1
 147.604 +            continue
 147.605 +
 147.606 +        if comment_rex.search(line):
 147.607 +            waiting_for_end_string = 1
 147.608 +            continue
 147.609 +
 147.610 +        if preamble_rex.search(line):
 147.611 +            waiting_for_end_string = 1
 147.612 +            continue
 147.613 +
 147.614 +
 147.615 +        # replace subsequent abbreviations with the value
 147.616 +        abbr_count = 0
 147.617 +
 147.618 +        for x in abbr_list:
 147.619 +
 147.620 +            if abbr_rex[abbr_count].search(line):
 147.621 +                if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
 147.622 +                    line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
 147.623 +                # Check for # concatenations
 147.624 +                if concatsplit_rex.search(line):
 147.625 +                    line = concat_line(line)
 147.626 +            abbr_count = abbr_count + 1
 147.627 +
 147.628 +
 147.629 +        filecont2 = filecont2 + line + '\n'
 147.630 +        i = i+1
 147.631 +
 147.632 +
 147.633 +    # Do one final pass over file
 147.634 +
 147.635 +    # make sure that didn't end up with {" or }" after the substitution
 147.636 +    filecont2 = filecont2.replace('{"','{{')
 147.637 +    filecont2 = filecont2.replace('"}','}}')
 147.638 +
 147.639 +    afterquotevalue_rex = re.compile('"\s*,\s*')
 147.640 +    afterbrace_rex = re.compile('"\s*}')
 147.641 +    afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
 147.642 +
 147.643 +    # add new lines to data that changed because of abbreviation substitutions
 147.644 +    filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
 147.645 +    filecont2 = afterbrace_rex.sub('"\n}', filecont2)
 147.646 +    filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
 147.647 +
 147.648 +    return filecont2
 147.649 +
 147.650 +#
 147.651 +# convert @type( ... ) to @type{ ... }
 147.652 +#
 147.653 +def no_outer_parens(filecont):
 147.654 +
 147.655 +    # do checking for open parens
 147.656 +    # will convert to braces
 147.657 +    paren_split = re.split('([(){}])',filecont)
 147.658 +
 147.659 +    open_paren_count = 0
 147.660 +    open_type = 0
 147.661 +    look_next = 0
 147.662 +
 147.663 +    # rebuild filecont
 147.664 +    filecont = ''
 147.665 +
 147.666 +    at_rex = re.compile('@\w*')
 147.667 +
 147.668 +    for phrase in paren_split:
 147.669 +        if look_next == 1:
 147.670 +            if phrase == '(':
 147.671 +                phrase = '{'
 147.672 +                open_paren_count = open_paren_count + 1
 147.673 +            else:
 147.674 +                open_type = 0
 147.675 +            look_next = 0
 147.676 +
 147.677 +        if phrase == '(':
 147.678 +            open_paren_count = open_paren_count + 1
 147.679 +
 147.680 +        elif phrase == ')':
 147.681 +            open_paren_count = open_paren_count - 1
 147.682 +            if open_type == 1 and open_paren_count == 0:
 147.683 +                phrase = '}'
 147.684 +                open_type = 0
 147.685 +
 147.686 +        elif at_rex.search( phrase ):
 147.687 +            open_type = 1
 147.688 +            look_next = 1
 147.689 +
 147.690 +        filecont = filecont + phrase
 147.691 +
 147.692 +    return filecont
 147.693 +
 147.694 +
 147.695 +#
 147.696 +# make all whitespace into just one space
 147.697 +# format the bibtex file into a usable form.
 147.698 +#
 147.699 +def bibtexwasher(filecont_source):
 147.700 +
 147.701 +    space_rex = re.compile('\s+')
 147.702 +    comment_rex = re.compile('\s*%')
 147.703 +
 147.704 +    filecont = []
 147.705 +
 147.706 +    # remove trailing and excessive whitespace
 147.707 +    # ignore comments
 147.708 +    for line in filecont_source:
 147.709 +        line = string.strip(line)
 147.710 +        line = space_rex.sub(' ', line)
 147.711 +        # ignore comments
 147.712 +        if not comment_rex.match(line) and line != '':
 147.713 +            filecont.append(' '+ line)
 147.714 +
 147.715 +    filecont = string.join(filecont, '')
 147.716 +
 147.717 +    # the file is in one long string
 147.718 +
 147.719 +    filecont = no_outer_parens(filecont)
 147.720 +
 147.721 +    #
 147.722 +    # split lines according to preferred syntax scheme
 147.723 +    #
 147.724 +    filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
 147.725 +
 147.726 +    # add new lines after commas that are after values
 147.727 +    filecont = re.sub('"\s*,', '",\n', filecont)
 147.728 +    filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
 147.729 +    filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
 147.730 +                          '\n\n\g<1>\g<2>,\n', filecont)
 147.731 +
 147.732 +    # add new lines after }
 147.733 +    filecont = re.sub('"\s*}','"\n}\n', filecont)
 147.734 +    filecont = re.sub('}\s*,','},\n', filecont)
 147.735 +
 147.736 +
 147.737 +    filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
 147.738 +
 147.739 +    # character encoding, reserved latex characters
 147.740 +    filecont = re.sub('{\\\&}', '&', filecont)
 147.741 +    filecont = re.sub('\\\&', '&', filecont)
 147.742 +
 147.743 +    # do checking for open braces to get format correct
 147.744 +    open_brace_count = 0
 147.745 +    brace_split = re.split('([{}])',filecont)
 147.746 +
 147.747 +    # rebuild filecont
 147.748 +    filecont = ''
 147.749 +
 147.750 +    for phrase in brace_split:
 147.751 +        if phrase == '{':
 147.752 +            open_brace_count = open_brace_count + 1
 147.753 +        elif phrase == '}':
 147.754 +            open_brace_count = open_brace_count - 1
 147.755 +            if open_brace_count == 0:
 147.756 +                filecont = filecont + '\n'
 147.757 +
 147.758 +        filecont = filecont + phrase
 147.759 +
 147.760 +    filecont2 = bibtex_replace_abbreviations(filecont)
 147.761 +
 147.762 +    # gather
 147.763 +    filecont = filecont2.splitlines()
 147.764 +    i=0
 147.765 +    j=0         # count the number of blank lines
 147.766 +    for line in filecont:
 147.767 +        # ignore blank lines
 147.768 +        if line == '' or line == ' ':
 147.769 +            j = j+1
 147.770 +            continue
 147.771 +        filecont[i] = line + '\n'
 147.772 +        i = i+1
 147.773 +
 147.774 +    # get rid of the extra stuff at the end of the array
 147.775 +    # (The extra stuff are duplicates that are in the array because
 147.776 +    # blank lines were removed.)
 147.777 +    length = len( filecont)
 147.778 +    filecont[length-j:length] = []
 147.779 +
 147.780 +    return filecont
 147.781 +
 147.782 +
 147.783 +def filehandler(filepath):
 147.784 +    try:
 147.785 +        fd = open(filepath, 'r')
 147.786 +        filecont_source = fd.readlines()
 147.787 +        fd.close()
 147.788 +    except:
 147.789 +        print 'Could not open file:', filepath
 147.790 +    washeddata = bibtexwasher(filecont_source)
 147.791 +    outdata = bibtexdecoder(washeddata)
 147.792 +    print '/**'
 147.793 +    print '\page references References'
 147.794 +    print
 147.795 +    for line in outdata:
 147.796 +        print line
 147.797 +    print '*/'
 147.798 +
 147.799 +
 147.800 +# main program
 147.801 +
 147.802 +def main():
 147.803 +    import sys
 147.804 +    if sys.argv[1:]:
 147.805 +        filepath = sys.argv[1]
 147.806 +    else:
 147.807 +        print "No input file"
 147.808 +        sys.exit()
 147.809 +    filehandler(filepath)
 147.810 +
 147.811 +if __name__ == "__main__": main()
 147.812 +
 147.813 +
 147.814 +# end python script
   148.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   148.2 +++ b/scripts/bootstrap.sh	Thu Nov 05 15:50:01 2009 +0100
   148.3 @@ -0,0 +1,134 @@
   148.4 +#!/bin/bash
   148.5 +#
   148.6 +# This file is a part of LEMON, a generic C++ optimization library.
   148.7 +#
   148.8 +# Copyright (C) 2003-2009
   148.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  148.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
  148.11 +#
  148.12 +# Permission to use, modify and distribute this software is granted
  148.13 +# provided that this copyright notice appears in all copies. For
  148.14 +# precise terms see the accompanying LICENSE file.
  148.15 +#
  148.16 +# This software is provided "AS IS" with no warranty of any kind,
  148.17 +# express or implied, and with no claim as to its suitability for any
  148.18 +# purpose.
  148.19 +
  148.20 +
  148.21 +if [ ! -f ~/.lemon-bootstrap ]; then
  148.22 +    echo 'Create ~/.lemon-bootstrap'.
  148.23 +    cat >~/.lemon-bootstrap <<EOF
  148.24 +#
  148.25 +# Default settings for bootstraping the LEMON source code repository
  148.26 +#
  148.27 +EOF
  148.28 +fi
  148.29 +
  148.30 +source ~/.lemon-bootstrap
  148.31 +if [ -f ../../../.lemon-bootstrap ]; then source ../../../.lemon-bootstrap; fi
  148.32 +if [ -f ../../.lemon-bootstrap ]; then source ../../.lemon-bootstrap; fi
  148.33 +if [ -f ../.lemon-bootstrap ]; then source ../.lemon-bootstrap; fi
  148.34 +if [ -f ./.lemon-bootstrap ]; then source ./.lemon-bootstrap; fi
  148.35 +
  148.36 +
  148.37 +function augment_config() { 
  148.38 +    if [ "x${!1}" == "x" ]; then
  148.39 +        eval $1=$2
  148.40 +        echo Add "'$1'" to '~/.lemon-bootstrap'.
  148.41 +        echo >>~/.lemon-bootstrap
  148.42 +        echo $3 >>~/.lemon-bootstrap
  148.43 +        echo $1=$2 >>~/.lemon-bootstrap
  148.44 +    fi
  148.45 +}
  148.46 +
  148.47 +augment_config LEMON_INSTALL_PREFIX /usr/local \
  148.48 +    "# LEMON installation prefix"
  148.49 +
  148.50 +augment_config COIN_OR_PREFIX /usr/local/coin-or \
  148.51 +    "# COIN-OR installation root prefix (used for CLP/CBC)"
  148.52 +
  148.53 +augment_config SOPLEX_PREFIX /usr/local/soplex \
  148.54 +    "# Soplex build prefix"
  148.55 +
  148.56 +
  148.57 +function ask() {
  148.58 +echo -n "$1 [$2]? "
  148.59 +read _an
  148.60 +if [ "x$_an" == "x" ]; then
  148.61 +    ret="$2"
  148.62 +else
  148.63 +    ret=$_an
  148.64 +fi
  148.65 +}
  148.66 +
  148.67 +function yesorno() {
  148.68 +    ret='rossz'
  148.69 +    while [ "$ret" != "y" -a "$ret" != "n" -a "$ret" != "yes" -a "$ret" != "no" ]; do
  148.70 +        ask "$1" "$2"
  148.71 +    done
  148.72 +    if [ "$ret" != "y" -a "$ret" != "yes" ]; then
  148.73 +        return 1
  148.74 +    else
  148.75 +        return 0
  148.76 +    fi
  148.77 +}
  148.78 +
  148.79 +if yesorno "External build" "n"
  148.80 +then
  148.81 +    CONFIGURE_PATH=".."
  148.82 +else
  148.83 +    CONFIGURE_PATH="."
  148.84 +    if yesorno "Autoreconf" "y"
  148.85 +    then
  148.86 +        AUTORE=yes
  148.87 +    else
  148.88 +        AUTORE=no
  148.89 +    fi
  148.90 +fi
  148.91 +
  148.92 +if yesorno "Optimize" "n" 
  148.93 +then
  148.94 +    opt_flags=' -O2'
  148.95 +else
  148.96 +    opt_flags=''
  148.97 +fi
  148.98 +
  148.99 +if yesorno "Stop on warning" "y" 
 148.100 +then
 148.101 +    werror_flags=' -Werror'
 148.102 +else
 148.103 +    werror_flags=''
 148.104 +fi
 148.105 +
 148.106 +cxx_flags="CXXFLAGS=-ggdb$opt_flags$werror_flags"
 148.107 +
 148.108 +if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then
 148.109 +    if yesorno "Use COIN-OR (CBC/CLP)" "n"
 148.110 +    then
 148.111 +        coin_flag="--with-coin=$COIN_OR_PREFIX"
 148.112 +    else
 148.113 +        coin_flag=""
 148.114 +    fi
 148.115 +else
 148.116 +    coin_flag=""        
 148.117 +fi
 148.118 +
 148.119 +if [ -f ${SOPLEX_PREFIX}/src/soplex.h ]; then
 148.120 +    if yesorno "Use Soplex" "n"
 148.121 +    then
 148.122 +        soplex_flag="--with-soplex=$SOPLEX_PREFIX"
 148.123 +    else
 148.124 +        soplex_flag=""
 148.125 +    fi
 148.126 +else
 148.127 +    soplex_flag=""
 148.128 +fi
 148.129 +
 148.130 +if [ "x$AUTORE" == "xyes" ]; then
 148.131 +    autoreconf -vif;
 148.132 +fi
 148.133 +${CONFIGURE_PATH}/configure --prefix=$LEMON_INSTALL_PREFIX \
 148.134 +"$cxx_flags" \
 148.135 +$coin_flag \
 148.136 +$soplex_flag \
 148.137 +$*
   149.1 --- a/scripts/chg-len.py	Fri Oct 16 10:21:37 2009 +0200
   149.2 +++ b/scripts/chg-len.py	Thu Nov 05 15:50:01 2009 +0100
   149.3 @@ -1,7 +1,25 @@
   149.4  #! /usr/bin/env python
   149.5 +#
   149.6 +# This file is a part of LEMON, a generic C++ optimization library.
   149.7 +#
   149.8 +# Copyright (C) 2003-2009
   149.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  149.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
  149.11 +#
  149.12 +# Permission to use, modify and distribute this software is granted
  149.13 +# provided that this copyright notice appears in all copies. For
  149.14 +# precise terms see the accompanying LICENSE file.
  149.15 +#
  149.16 +# This software is provided "AS IS" with no warranty of any kind,
  149.17 +# express or implied, and with no claim as to its suitability for any
  149.18 +# purpose.
  149.19  
  149.20  import sys
  149.21 -import os
  149.22 +
  149.23 +from mercurial import ui, hg
  149.24 +from mercurial import util
  149.25 +
  149.26 +util.rcpath = lambda : []
  149.27  
  149.28  if len(sys.argv)>1 and sys.argv[1] in ["-h","--help"]:
  149.29      print """
  149.30 @@ -9,32 +27,20 @@
  149.31  in the revision graph from revison 0 to the current one.
  149.32  """
  149.33      exit(0)
  149.34 -plist = os.popen("HGRCPATH='' hg parents --template='{rev}\n'").readlines()
  149.35 -if len(plist)>1:
  149.36 -    print "You are in the process of merging"
  149.37 -    exit(1)
  149.38 -PAR = int(plist[0])
  149.39  
  149.40 -f = os.popen("HGRCPATH='' hg log -r 0:tip --template='{rev} {parents}\n'").\
  149.41 -    readlines()
  149.42 -REV = -1
  149.43 -lengths=[]
  149.44 -for l in f:
  149.45 -    REV+=1
  149.46 -    s = l.split()
  149.47 -    rev = int(s[0])
  149.48 -    if REV != rev:
  149.49 -        print "Something is seriously wrong"
  149.50 -        exit(1)
  149.51 -    if len(s) == 1:
  149.52 -        par1 = par2 = rev - 1
  149.53 -    elif len(s) == 2:
  149.54 -        par1 = par2 = int(s[1].split(":")[0])
  149.55 +u = ui.ui()
  149.56 +r = hg.repository(u, ".")
  149.57 +N = r.changectx(".").rev()
  149.58 +lengths=[0]*(N+1)
  149.59 +for i in range(N+1):
  149.60 +    p=r.changectx(i).parents()
  149.61 +    if p[0]:
  149.62 +        p0=lengths[p[0].rev()]
  149.63      else:
  149.64 -        par1 = int(s[1].split(":")[0])
  149.65 -        par2 = int(s[2].split(":")[0])
  149.66 -    if rev == 0:
  149.67 -        lengths.append(0)
  149.68 +        p0=-1
  149.69 +    if len(p)>1 and p[1]:
  149.70 +        p1=lengths[p[1].rev()]
  149.71      else:
  149.72 -        lengths.append(max(lengths[par1],lengths[par2])+1)
  149.73 -print lengths[PAR]
  149.74 +        p1=-1
  149.75 +    lengths[i]=max(p0,p1)+1
  149.76 +print lengths[N]
   150.1 --- a/scripts/mk-release.sh	Fri Oct 16 10:21:37 2009 +0200
   150.2 +++ b/scripts/mk-release.sh	Thu Nov 05 15:50:01 2009 +0100
   150.3 @@ -1,4 +1,18 @@
   150.4  #!/bin/bash
   150.5 +#
   150.6 +# This file is a part of LEMON, a generic C++ optimization library.
   150.7 +#
   150.8 +# Copyright (C) 2003-2009
   150.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  150.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
  150.11 +#
  150.12 +# Permission to use, modify and distribute this software is granted
  150.13 +# provided that this copyright notice appears in all copies. For
  150.14 +# precise terms see the accompanying LICENSE file.
  150.15 +#
  150.16 +# This software is provided "AS IS" with no warranty of any kind,
  150.17 +# express or implied, and with no claim as to its suitability for any
  150.18 +# purpose.
  150.19  
  150.20  set -e
  150.21  
  150.22 @@ -14,7 +28,7 @@
  150.23  echo '*****************************************************************'
  150.24  
  150.25  autoreconf -vif
  150.26 -./configure --enable-demo
  150.27 +./configure
  150.28  
  150.29  make
  150.30  make html
   151.1 --- a/scripts/unify-sources.sh	Fri Oct 16 10:21:37 2009 +0200
   151.2 +++ b/scripts/unify-sources.sh	Thu Nov 05 15:50:01 2009 +0100
   151.3 @@ -1,17 +1,220 @@
   151.4  #!/bin/bash
   151.5 +#
   151.6 +# This file is a part of LEMON, a generic C++ optimization library.
   151.7 +#
   151.8 +# Copyright (C) 2003-2009
   151.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  151.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
  151.11 +#
  151.12 +# Permission to use, modify and distribute this software is granted
  151.13 +# provided that this copyright notice appears in all copies. For
  151.14 +# precise terms see the accompanying LICENSE file.
  151.15 +#
  151.16 +# This software is provided "AS IS" with no warranty of any kind,
  151.17 +# express or implied, and with no claim as to its suitability for any
  151.18 +# purpose.
  151.19  
  151.20 -YEAR=`date +2003-%Y`
  151.21 +YEAR=`date +%Y`
  151.22  HGROOT=`hg root`
  151.23  
  151.24 -function update_header() {
  151.25 +function hg_year() {
  151.26 +    if [ -n "$(hg st $1)" ]; then
  151.27 +        echo $YEAR
  151.28 +    else
  151.29 +        hg log -l 1 --template='{date|isodate}\n' $1 |
  151.30 +        cut -d '-' -f 1
  151.31 +    fi
  151.32 +}
  151.33 +
  151.34 +# file enumaration modes
  151.35 +
  151.36 +function all_files() {
  151.37 +    hg status -a -m -c |
  151.38 +    cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
  151.39 +    while read file; do echo $HGROOT/$file; done
  151.40 +}
  151.41 +
  151.42 +function modified_files() {
  151.43 +    hg status -a -m |
  151.44 +    cut -d ' ' -f 2 | grep -E  '(\.(cc|h|dox)$|Makefile\.am$)' |
  151.45 +    while read file; do echo $HGROOT/$file; done
  151.46 +}
  151.47 +
  151.48 +function changed_files() {
  151.49 +    {
  151.50 +        if [ -n "$HG_PARENT1" ]
  151.51 +        then
  151.52 +            hg status --rev $HG_PARENT1:$HG_NODE -a -m
  151.53 +        fi
  151.54 +        if [ -n "$HG_PARENT2" ]
  151.55 +        then
  151.56 +            hg status --rev $HG_PARENT2:$HG_NODE -a -m
  151.57 +        fi
  151.58 +    } | cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' | 
  151.59 +    sort | uniq |
  151.60 +    while read file; do echo $HGROOT/$file; done
  151.61 +}
  151.62 +
  151.63 +function given_files() {
  151.64 +    for file in $GIVEN_FILES
  151.65 +    do
  151.66 +	echo $file
  151.67 +    done
  151.68 +}
  151.69 +
  151.70 +# actions
  151.71 +
  151.72 +function update_action() {
  151.73 +    if ! diff -q $1 $2 >/dev/null
  151.74 +    then
  151.75 +	echo -n " [$3 updated]"
  151.76 +	rm $2
  151.77 +	mv $1 $2
  151.78 +	CHANGED=YES
  151.79 +    fi
  151.80 +}
  151.81 +
  151.82 +function update_warning() {
  151.83 +    echo -n " [$2 warning]"
  151.84 +    WARNED=YES
  151.85 +}
  151.86 +
  151.87 +function update_init() {
  151.88 +    echo Update source files...
  151.89 +    TOTAL_FILES=0
  151.90 +    CHANGED_FILES=0
  151.91 +    WARNED_FILES=0
  151.92 +}
  151.93 +
  151.94 +function update_done() {
  151.95 +    echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
  151.96 +    echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
  151.97 +}
  151.98 +
  151.99 +function update_begin() {
 151.100 +    ((TOTAL_FILES++))
 151.101 +    CHANGED=NO
 151.102 +    WARNED=NO
 151.103 +}
 151.104 +
 151.105 +function update_end() {
 151.106 +    if [ $CHANGED == YES ]
 151.107 +    then
 151.108 +	((++CHANGED_FILES))
 151.109 +    fi
 151.110 +    if [ $WARNED == YES ]
 151.111 +    then
 151.112 +	((++WARNED_FILES))
 151.113 +    fi
 151.114 +}
 151.115 +
 151.116 +function check_action() {
 151.117 +    if [ "$3" == 'tabs' ]
 151.118 +    then
 151.119 +        if echo $2 | grep -q -v -E 'Makefile\.am$'
 151.120 +        then
 151.121 +            PATTERN=$(echo -e '\t')
 151.122 +        else
 151.123 +            PATTERN='        '
 151.124 +        fi
 151.125 +    elif [ "$3" == 'trailing spaces' ]
 151.126 +    then
 151.127 +        PATTERN='\ +$'
 151.128 +    else
 151.129 +        PATTERN='*'
 151.130 +    fi
 151.131 +
 151.132 +    if ! diff -q $1 $2 >/dev/null
 151.133 +    then
 151.134 +        if [ "$PATTERN" == '*' ]
 151.135 +        then
 151.136 +            diff $1 $2 | grep '^[0-9]' | sed "s|^\(.*\)c.*$|$2:\1: check failed: $3|g" |
 151.137 +              sed "s/:\([0-9]*\),\([0-9]*\):\(.*\)$/:\1:\3 (until line \2)/g"
 151.138 +        else
 151.139 +            grep -n -E "$PATTERN" $2 | sed "s|^\([0-9]*\):.*$|$2:\1: check failed: $3|g"
 151.140 +        fi
 151.141 +        FAILED=YES
 151.142 +    fi
 151.143 +}
 151.144 +
 151.145 +function check_warning() {
 151.146 +    if [ "$2" == 'long lines' ]
 151.147 +    then
 151.148 +        grep -n -E '.{81,}' $1 | sed "s|^\([0-9]*\):.*$|$1:\1: warning: $2|g"
 151.149 +    else
 151.150 +        echo "$1: warning: $2"
 151.151 +    fi
 151.152 +    WARNED=YES
 151.153 +}
 151.154 +
 151.155 +function check_init() {
 151.156 +    echo Check source files...
 151.157 +    FAILED_FILES=0
 151.158 +    WARNED_FILES=0
 151.159 +    TOTAL_FILES=0
 151.160 +}
 151.161 +
 151.162 +function check_done() {
 151.163 +    echo $FAILED_FILES out of $TOTAL_FILES files has been failed.
 151.164 +    echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
 151.165 +
 151.166 +    if [ $WARNED_FILES -gt 0 -o $FAILED_FILES -gt 0 ]
 151.167 +    then
 151.168 +	if [ "$WARNING" == 'INTERACTIVE' ]
 151.169 +	then
 151.170 +	    echo -n "Are the files with errors/warnings acceptable? (yes/no) "
 151.171 +	    while read answer
 151.172 +	    do
 151.173 +		if [ "$answer" == 'yes' ]
 151.174 +		then
 151.175 +		    return 0
 151.176 +		elif [ "$answer" == 'no' ]
 151.177 +		then
 151.178 +		    return 1
 151.179 +		fi
 151.180 +		echo -n "Are the files with errors/warnings acceptable? (yes/no) "
 151.181 +	    done
 151.182 +	elif [ "$WARNING" == 'WERROR' ]
 151.183 +	then
 151.184 +	    return 1
 151.185 +	fi
 151.186 +    fi
 151.187 +}
 151.188 +
 151.189 +function check_begin() {
 151.190 +    ((TOTAL_FILES++))
 151.191 +    FAILED=NO
 151.192 +    WARNED=NO
 151.193 +}
 151.194 +
 151.195 +function check_end() {
 151.196 +    if [ $FAILED == YES ]
 151.197 +    then
 151.198 +	((++FAILED_FILES))
 151.199 +    fi
 151.200 +    if [ $WARNED == YES ]
 151.201 +    then
 151.202 +	((++WARNED_FILES))
 151.203 +    fi
 151.204 +}
 151.205 +
 151.206 +
 151.207 +
 151.208 +# checks
 151.209 +
 151.210 +function header_check() {
 151.211 +    if echo $1 | grep -q -E 'Makefile\.am$'
 151.212 +    then
 151.213 +	return
 151.214 +    fi
 151.215 +
 151.216      TMP_FILE=`mktemp`
 151.217 -    FILE_NAME=$1
 151.218  
 151.219      (echo "/* -*- mode: C++; indent-tabs-mode: nil; -*-
 151.220   *
 151.221   * This file is a part of LEMON, a generic C++ optimization library.
 151.222   *
 151.223 - * Copyright (C) "$YEAR"
 151.224 + * Copyright (C) 2003-"$(hg_year $1)"
 151.225   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 151.226   * (Egervary Research Group on Combinatorial Optimization, EGRES).
 151.227   *
 151.228 @@ -25,110 +228,163 @@
 151.229   *
 151.230   */
 151.231  "
 151.232 -	awk 'BEGIN { pm=0; }
 151.233 +    awk 'BEGIN { pm=0; }
 151.234       pm==3 { print }
 151.235       /\/\* / && pm==0 { pm=1;}
 151.236       /[^:blank:]/ && (pm==0 || pm==2) { pm=3; print;}
 151.237       /\*\// && pm==1 { pm=2;}
 151.238      ' $1
 151.239 -	) >$TMP_FILE
 151.240 +    ) >$TMP_FILE
 151.241  
 151.242 -    HEADER_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
 151.243 -
 151.244 -    rm $FILE_NAME
 151.245 -    mv $TMP_FILE $FILE_NAME
 151.246 +    "$ACTION"_action "$TMP_FILE" "$1" header
 151.247  }
 151.248  
 151.249 -function update_tabs() {
 151.250 +function tabs_check() {
 151.251 +    if echo $1 | grep -q -v -E 'Makefile\.am$'
 151.252 +    then
 151.253 +        OLD_PATTERN=$(echo -e '\t')
 151.254 +        NEW_PATTERN='        '
 151.255 +    else
 151.256 +        OLD_PATTERN='        '
 151.257 +        NEW_PATTERN=$(echo -e '\t')
 151.258 +    fi
 151.259      TMP_FILE=`mktemp`
 151.260 -    FILE_NAME=$1
 151.261 +    cat $1 | sed -e "s/$OLD_PATTERN/$NEW_PATTERN/g" >$TMP_FILE
 151.262  
 151.263 -    cat $1 |
 151.264 -    sed -e 's/\t/        /g' >$TMP_FILE
 151.265 -
 151.266 -    TABS_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
 151.267 -
 151.268 -    rm $FILE_NAME
 151.269 -    mv $TMP_FILE $FILE_NAME
 151.270 +    "$ACTION"_action "$TMP_FILE" "$1" 'tabs'
 151.271  }
 151.272  
 151.273 -function remove_trailing_space() {
 151.274 +function spaces_check() {
 151.275      TMP_FILE=`mktemp`
 151.276 -    FILE_NAME=$1
 151.277 +    cat $1 | sed -e 's/ \+$//g' >$TMP_FILE
 151.278  
 151.279 -    cat $1 |
 151.280 -    sed -e 's/ \+$//g' >$TMP_FILE
 151.281 -
 151.282 -    SPACES_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
 151.283 -
 151.284 -    rm $FILE_NAME
 151.285 -    mv $TMP_FILE $FILE_NAME
 151.286 +    "$ACTION"_action "$TMP_FILE" "$1" 'trailing spaces'
 151.287  }
 151.288  
 151.289 -function long_line_test() {
 151.290 -    cat $1 |grep -q -E '.{81,}'
 151.291 -}
 151.292 -
 151.293 -function update_file() {
 151.294 -    echo -n '    update' $i ...
 151.295 -
 151.296 -    update_header $1
 151.297 -    update_tabs $1
 151.298 -    remove_trailing_space $1
 151.299 -
 151.300 -    CHANGED=NO;
 151.301 -    if [[ $HEADER_CH = YES ]];
 151.302 +function long_lines_check() {
 151.303 +    if cat $1 | grep -q -E '.{81,}'
 151.304      then
 151.305 -	echo -n '  [header updated]'
 151.306 -	CHANGED=YES;
 151.307 -    fi
 151.308 -    if [[ $TABS_CH = YES ]];
 151.309 -    then
 151.310 -	echo -n ' [tabs removed]'
 151.311 -	CHANGED=YES;
 151.312 -    fi
 151.313 -    if [[ $SPACES_CH = YES ]];
 151.314 -    then
 151.315 -	echo -n ' [trailing spaces removed]'
 151.316 -	CHANGED=YES;
 151.317 -    fi
 151.318 -    if long_line_test $1 ;
 151.319 -    then
 151.320 -	echo -n ' [LONG LINES]'
 151.321 -	((LONG_LINE_FILES++))
 151.322 -    fi
 151.323 -    echo
 151.324 -    if [[ $CHANGED = YES ]];
 151.325 -    then
 151.326 -	((CHANGED_FILES++))
 151.327 +	"$ACTION"_warning $1 'long lines'
 151.328      fi
 151.329  }
 151.330  
 151.331 -CHANGED_FILES=0
 151.332 -TOTAL_FILES=0
 151.333 -LONG_LINE_FILES=0
 151.334 -if [ $# == 0 ]; then
 151.335 -    echo Update all source files...
 151.336 -    for i in `hg manifest|grep -E  '\.(cc|h|dox)$'`
 151.337 +# process the file
 151.338 +
 151.339 +function process_file() {
 151.340 +    if [ "$ACTION" == 'update' ]
 151.341 +    then
 151.342 +        echo -n "    $ACTION $1..."
 151.343 +    else
 151.344 +        echo "	  $ACTION $1..."
 151.345 +    fi
 151.346 +
 151.347 +    CHECKING="header tabs spaces long_lines"
 151.348 +
 151.349 +    "$ACTION"_begin $1
 151.350 +    for check in $CHECKING
 151.351      do
 151.352 -	update_file $HGROOT/$i
 151.353 -	((TOTAL_FILES++))
 151.354 +	"$check"_check $1
 151.355      done
 151.356 -    echo '  done.'
 151.357 -else
 151.358 -    for i in $*
 151.359 +    "$ACTION"_end $1
 151.360 +    if [ "$ACTION" == 'update' ]
 151.361 +    then
 151.362 +        echo
 151.363 +    fi
 151.364 +}
 151.365 +
 151.366 +function process_all {
 151.367 +    "$ACTION"_init
 151.368 +    while read file
 151.369      do
 151.370 -	update_file $i
 151.371 -	((TOTAL_FILES++))
 151.372 -    done
 151.373 +	process_file $file
 151.374 +    done < <($FILES)
 151.375 +    "$ACTION"_done
 151.376 +}
 151.377 +
 151.378 +while [ $# -gt 0 ]
 151.379 +do
 151.380 +    
 151.381 +    if [ "$1" == '--help' ] || [ "$1" == '-h' ]
 151.382 +    then
 151.383 +	echo -n \
 151.384 +"Usage:
 151.385 +  $0 [OPTIONS] [files]
 151.386 +Options:
 151.387 +  --dry-run|-n
 151.388 +     Check the files, but do not modify them.
 151.389 +  --interactive|-i
 151.390 +     If --dry-run is specified and the checker emits warnings,
 151.391 +     then the user is asked if the warnings should be considered
 151.392 +     errors.
 151.393 +  --werror|-w
 151.394 +     Make all warnings into errors.
 151.395 +  --all|-a
 151.396 +     Check all source files in the repository.
 151.397 +  --modified|-m
 151.398 +     Check only the modified (and new) source files. This option is
 151.399 +     useful to check the modification before making a commit.
 151.400 +  --changed|-c
 151.401 +     Check only the changed source files compared to the parent(s) of
 151.402 +     the current hg node.  This option is useful as hg hook script.
 151.403 +     To automatically check all your changes before making a commit,
 151.404 +     add the following section to the appropriate .hg/hgrc file.
 151.405 +
 151.406 +       [hooks]
 151.407 +       pretxncommit.checksources = scripts/unify-sources.sh -c -n -i
 151.408 +
 151.409 +  --help|-h
 151.410 +     Print this help message.
 151.411 +  files
 151.412 +     The files to check/unify. If no file names are given, the modified
 151.413 +     source files will be checked/unified (just like using the
 151.414 +     --modified|-m option).
 151.415 +"
 151.416 +        exit 0
 151.417 +    elif [ "$1" == '--dry-run' ] || [ "$1" == '-n' ]
 151.418 +    then
 151.419 +	[ -n "$ACTION" ] && echo "Conflicting action options" >&2 && exit 1
 151.420 +	ACTION=check
 151.421 +    elif [ "$1" == "--all" ] || [ "$1" == '-a' ]
 151.422 +    then
 151.423 +	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
 151.424 +	FILES=all_files
 151.425 +    elif [ "$1" == "--changed" ] || [ "$1" == '-c' ]
 151.426 +    then
 151.427 +	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
 151.428 +	FILES=changed_files
 151.429 +    elif [ "$1" == "--modified" ] || [ "$1" == '-m' ]
 151.430 +    then
 151.431 +	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
 151.432 +	FILES=modified_files
 151.433 +    elif [ "$1" == "--interactive" ] || [ "$1" == "-i" ]
 151.434 +    then
 151.435 +	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
 151.436 +	WARNING='INTERACTIVE'
 151.437 +    elif [ "$1" == "--werror" ] || [ "$1" == "-w" ]
 151.438 +    then
 151.439 +	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
 151.440 +	WARNING='WERROR'
 151.441 +    elif [ $(echo x$1 | cut -c 2) == '-' ]
 151.442 +    then
 151.443 +	echo "Invalid option $1" >&2 && exit 1
 151.444 +    else
 151.445 +	[ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
 151.446 +	GIVEN_FILES=$@
 151.447 +	FILES=given_files
 151.448 +	break
 151.449 +    fi
 151.450 +    
 151.451 +    shift
 151.452 +done
 151.453 +
 151.454 +if [ -z $FILES ]
 151.455 +then
 151.456 +    FILES=modified_files
 151.457  fi
 151.458 -echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
 151.459 -if [[ $LONG_LINE_FILES -gt 1 ]]; then
 151.460 -    echo
 151.461 -    echo WARNING: $LONG_LINE_FILES files contains long lines!    
 151.462 -    echo
 151.463 -elif [[ $LONG_LINE_FILES -gt 0 ]]; then
 151.464 -    echo
 151.465 -    echo WARNING: a file contains long lines!
 151.466 -    echo
 151.467 +
 151.468 +if [ -z $ACTION ]
 151.469 +then
 151.470 +    ACTION=update
 151.471  fi
 151.472 +
 151.473 +process_all
   152.1 --- a/test/CMakeLists.txt	Fri Oct 16 10:21:37 2009 +0200
   152.2 +++ b/test/CMakeLists.txt	Thu Nov 05 15:50:01 2009 +0100
   152.3 @@ -1,31 +1,121 @@
   152.4  INCLUDE_DIRECTORIES(
   152.5 -  ${CMAKE_SOURCE_DIR}
   152.6 +  ${PROJECT_SOURCE_DIR}
   152.7    ${PROJECT_BINARY_DIR}
   152.8  )
   152.9  
  152.10 -LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
  152.11 +LINK_DIRECTORIES(
  152.12 +  ${PROJECT_BINARY_DIR}/lemon
  152.13 +)
  152.14  
  152.15  SET(TESTS
  152.16 +  adaptors_test
  152.17 +  bellman_ford_test
  152.18    bfs_test
  152.19 +  circulation_test
  152.20 +  connectivity_test
  152.21    counter_test
  152.22    dfs_test
  152.23    digraph_test
  152.24    dijkstra_test
  152.25    dim_test
  152.26 +  edge_set_test
  152.27    error_test
  152.28 +  euler_test
  152.29 +  gomory_hu_test
  152.30    graph_copy_test
  152.31    graph_test
  152.32    graph_utils_test
  152.33 +  hao_orlin_test
  152.34    heap_test
  152.35    kruskal_test
  152.36    maps_test
  152.37 +  matching_test
  152.38 +  min_cost_arborescence_test
  152.39 +  min_cost_flow_test
  152.40 +  min_mean_cycle_test
  152.41 +  path_test
  152.42 +  preflow_test
  152.43 +  radix_sort_test
  152.44    random_test
  152.45 -  path_test
  152.46 +  suurballe_test
  152.47    time_measure_test
  152.48 -  unionfind_test)
  152.49 +  unionfind_test
  152.50 +)
  152.51 +
  152.52 +IF(LEMON_HAVE_LP)
  152.53 +  ADD_EXECUTABLE(lp_test lp_test.cc)
  152.54 +  SET(LP_TEST_LIBS lemon)
  152.55 +
  152.56 +  IF(LEMON_HAVE_GLPK)
  152.57 +    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
  152.58 +  ENDIF()
  152.59 +  IF(LEMON_HAVE_CPLEX)
  152.60 +    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
  152.61 +  ENDIF()
  152.62 +  IF(LEMON_HAVE_CLP)
  152.63 +    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
  152.64 +  ENDIF()
  152.65 +
  152.66 +  TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
  152.67 +  ADD_TEST(lp_test lp_test)
  152.68 +
  152.69 +  IF(WIN32 AND LEMON_HAVE_GLPK)
  152.70 +    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
  152.71 +    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
  152.72 +    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
  152.73 +      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
  152.74 +      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
  152.75 +      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
  152.76 +    )
  152.77 +  ENDIF()
  152.78 +
  152.79 +  IF(WIN32 AND LEMON_HAVE_CPLEX)
  152.80 +    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
  152.81 +    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
  152.82 +    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
  152.83 +      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
  152.84 +    )
  152.85 +  ENDIF()
  152.86 +ENDIF()
  152.87 +
  152.88 +IF(LEMON_HAVE_MIP)
  152.89 +  ADD_EXECUTABLE(mip_test mip_test.cc)
  152.90 +  SET(MIP_TEST_LIBS lemon)
  152.91 +
  152.92 +  IF(LEMON_HAVE_GLPK)
  152.93 +    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
  152.94 +  ENDIF()
  152.95 +  IF(LEMON_HAVE_CPLEX)
  152.96 +    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
  152.97 +  ENDIF()
  152.98 +  IF(LEMON_HAVE_CBC)
  152.99 +    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
 152.100 +  ENDIF()
 152.101 +
 152.102 +  TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
 152.103 +  ADD_TEST(mip_test mip_test)
 152.104 +
 152.105 +  IF(WIN32 AND LEMON_HAVE_GLPK)
 152.106 +    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
 152.107 +    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
 152.108 +    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
 152.109 +      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
 152.110 +      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
 152.111 +      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
 152.112 +    )
 152.113 +  ENDIF()
 152.114 +
 152.115 +  IF(WIN32 AND LEMON_HAVE_CPLEX)
 152.116 +    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
 152.117 +    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
 152.118 +    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
 152.119 +      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
 152.120 +    )
 152.121 +  ENDIF()
 152.122 +ENDIF()
 152.123  
 152.124  FOREACH(TEST_NAME ${TESTS})
 152.125    ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
 152.126    TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
 152.127    ADD_TEST(${TEST_NAME} ${TEST_NAME})
 152.128 -ENDFOREACH(TEST_NAME)
 152.129 +ENDFOREACH()
   153.1 --- a/test/Makefile.am	Fri Oct 16 10:21:37 2009 +0200
   153.2 +++ b/test/Makefile.am	Thu Nov 05 15:50:01 2009 +0100
   153.3 @@ -3,46 +3,87 @@
   153.4  
   153.5  noinst_HEADERS += \
   153.6  	test/graph_test.h \
   153.7 -        test/test_tools.h
   153.8 +	test/test_tools.h
   153.9  
  153.10  check_PROGRAMS += \
  153.11 +	test/adaptors_test \
  153.12 +	test/bellman_ford_test \
  153.13  	test/bfs_test \
  153.14 -        test/counter_test \
  153.15 +	test/circulation_test \
  153.16 +	test/connectivity_test \
  153.17 +	test/counter_test \
  153.18  	test/dfs_test \
  153.19  	test/digraph_test \
  153.20  	test/dijkstra_test \
  153.21 -        test/dim_test \
  153.22 +	test/dim_test \
  153.23 +	test/edge_set_test \
  153.24  	test/error_test \
  153.25 +	test/euler_test \
  153.26 +	test/gomory_hu_test \
  153.27  	test/graph_copy_test \
  153.28  	test/graph_test \
  153.29  	test/graph_utils_test \
  153.30 +	test/hao_orlin_test \
  153.31  	test/heap_test \
  153.32  	test/kruskal_test \
  153.33 -        test/maps_test \
  153.34 -        test/random_test \
  153.35 -        test/path_test \
  153.36 -        test/test_tools_fail \
  153.37 -        test/test_tools_pass \
  153.38 -        test/time_measure_test \
  153.39 +	test/maps_test \
  153.40 +	test/matching_test \
  153.41 +	test/min_cost_arborescence_test \
  153.42 +	test/min_cost_flow_test \
  153.43 +	test/min_mean_cycle_test \
  153.44 +	test/path_test \
  153.45 +	test/preflow_test \
  153.46 +	test/radix_sort_test \
  153.47 +	test/random_test \
  153.48 +	test/suurballe_test \
  153.49 +	test/test_tools_fail \
  153.50 +	test/test_tools_pass \
  153.51 +	test/time_measure_test \
  153.52  	test/unionfind_test
  153.53  
  153.54 +test_test_tools_pass_DEPENDENCIES = demo
  153.55 +
  153.56 +if HAVE_LP
  153.57 +check_PROGRAMS += test/lp_test
  153.58 +endif HAVE_LP
  153.59 +if HAVE_MIP
  153.60 +check_PROGRAMS += test/mip_test
  153.61 +endif HAVE_MIP
  153.62 +
  153.63  TESTS += $(check_PROGRAMS)
  153.64  XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
  153.65  
  153.66 +test_adaptors_test_SOURCES = test/adaptors_test.cc
  153.67 +test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
  153.68  test_bfs_test_SOURCES = test/bfs_test.cc
  153.69 +test_circulation_test_SOURCES = test/circulation_test.cc
  153.70  test_counter_test_SOURCES = test/counter_test.cc
  153.71 +test_connectivity_test_SOURCES = test/connectivity_test.cc
  153.72  test_dfs_test_SOURCES = test/dfs_test.cc
  153.73  test_digraph_test_SOURCES = test/digraph_test.cc
  153.74  test_dijkstra_test_SOURCES = test/dijkstra_test.cc
  153.75  test_dim_test_SOURCES = test/dim_test.cc
  153.76 +test_edge_set_test_SOURCES = test/edge_set_test.cc
  153.77  test_error_test_SOURCES = test/error_test.cc
  153.78 +test_euler_test_SOURCES = test/euler_test.cc
  153.79 +test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
  153.80  test_graph_copy_test_SOURCES = test/graph_copy_test.cc
  153.81  test_graph_test_SOURCES = test/graph_test.cc
  153.82  test_graph_utils_test_SOURCES = test/graph_utils_test.cc
  153.83  test_heap_test_SOURCES = test/heap_test.cc
  153.84  test_kruskal_test_SOURCES = test/kruskal_test.cc
  153.85 +test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
  153.86 +test_lp_test_SOURCES = test/lp_test.cc
  153.87  test_maps_test_SOURCES = test/maps_test.cc
  153.88 +test_mip_test_SOURCES = test/mip_test.cc
  153.89 +test_matching_test_SOURCES = test/matching_test.cc
  153.90 +test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
  153.91 +test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
  153.92 +test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
  153.93  test_path_test_SOURCES = test/path_test.cc
  153.94 +test_preflow_test_SOURCES = test/preflow_test.cc
  153.95 +test_radix_sort_test_SOURCES = test/radix_sort_test.cc
  153.96 +test_suurballe_test_SOURCES = test/suurballe_test.cc
  153.97  test_random_test_SOURCES = test/random_test.cc
  153.98  test_test_tools_fail_SOURCES = test/test_tools_fail.cc
  153.99  test_test_tools_pass_SOURCES = test/test_tools_pass.cc
   154.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   154.2 +++ b/test/adaptors_test.cc	Thu Nov 05 15:50:01 2009 +0100
   154.3 @@ -0,0 +1,1463 @@
   154.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   154.5 + *
   154.6 + * This file is a part of LEMON, a generic C++ optimization library.
   154.7 + *
   154.8 + * Copyright (C) 2003-2009
   154.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  154.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  154.11 + *
  154.12 + * Permission to use, modify and distribute this software is granted
  154.13 + * provided that this copyright notice appears in all copies. For
  154.14 + * precise terms see the accompanying LICENSE file.
  154.15 + *
  154.16 + * This software is provided "AS IS" with no warranty of any kind,
  154.17 + * express or implied, and with no claim as to its suitability for any
  154.18 + * purpose.
  154.19 + *
  154.20 + */
  154.21 +
  154.22 +#include <iostream>
  154.23 +#include <limits>
  154.24 +
  154.25 +#include <lemon/list_graph.h>
  154.26 +#include <lemon/grid_graph.h>
  154.27 +#include <lemon/bfs.h>
  154.28 +#include <lemon/path.h>
  154.29 +
  154.30 +#include <lemon/concepts/digraph.h>
  154.31 +#include <lemon/concepts/graph.h>
  154.32 +#include <lemon/concepts/graph_components.h>
  154.33 +#include <lemon/concepts/maps.h>
  154.34 +#include <lemon/concept_check.h>
  154.35 +
  154.36 +#include <lemon/adaptors.h>
  154.37 +
  154.38 +#include "test/test_tools.h"
  154.39 +#include "test/graph_test.h"
  154.40 +
  154.41 +using namespace lemon;
  154.42 +
  154.43 +void checkReverseDigraph() {
  154.44 +  // Check concepts
  154.45 +  checkConcept<concepts::Digraph, ReverseDigraph<concepts::Digraph> >();
  154.46 +  checkConcept<concepts::Digraph, ReverseDigraph<ListDigraph> >();
  154.47 +  checkConcept<concepts::AlterableDigraphComponent<>,
  154.48 +               ReverseDigraph<ListDigraph> >();
  154.49 +  checkConcept<concepts::ExtendableDigraphComponent<>,
  154.50 +               ReverseDigraph<ListDigraph> >();
  154.51 +  checkConcept<concepts::ErasableDigraphComponent<>,
  154.52 +               ReverseDigraph<ListDigraph> >();
  154.53 +  checkConcept<concepts::ClearableDigraphComponent<>,
  154.54 +               ReverseDigraph<ListDigraph> >();
  154.55 +
  154.56 +  // Create a digraph and an adaptor
  154.57 +  typedef ListDigraph Digraph;
  154.58 +  typedef ReverseDigraph<Digraph> Adaptor;
  154.59 +
  154.60 +  Digraph digraph;
  154.61 +  Adaptor adaptor(digraph);
  154.62 +
  154.63 +  // Add nodes and arcs to the original digraph
  154.64 +  Digraph::Node n1 = digraph.addNode();
  154.65 +  Digraph::Node n2 = digraph.addNode();
  154.66 +  Digraph::Node n3 = digraph.addNode();
  154.67 +
  154.68 +  Digraph::Arc a1 = digraph.addArc(n1, n2);
  154.69 +  Digraph::Arc a2 = digraph.addArc(n1, n3);
  154.70 +  Digraph::Arc a3 = digraph.addArc(n2, n3);
  154.71 +
  154.72 +  // Check the adaptor
  154.73 +  checkGraphNodeList(adaptor, 3);
  154.74 +  checkGraphArcList(adaptor, 3);
  154.75 +  checkGraphConArcList(adaptor, 3);
  154.76 +
  154.77 +  checkGraphOutArcList(adaptor, n1, 0);
  154.78 +  checkGraphOutArcList(adaptor, n2, 1);
  154.79 +  checkGraphOutArcList(adaptor, n3, 2);
  154.80 +
  154.81 +  checkGraphInArcList(adaptor, n1, 2);
  154.82 +  checkGraphInArcList(adaptor, n2, 1);
  154.83 +  checkGraphInArcList(adaptor, n3, 0);
  154.84 +
  154.85 +  checkNodeIds(adaptor);
  154.86 +  checkArcIds(adaptor);
  154.87 +
  154.88 +  checkGraphNodeMap(adaptor);
  154.89 +  checkGraphArcMap(adaptor);
  154.90 +
  154.91 +  // Check the orientation of the arcs
  154.92 +  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
  154.93 +    check(adaptor.source(a) == digraph.target(a), "Wrong reverse");
  154.94 +    check(adaptor.target(a) == digraph.source(a), "Wrong reverse");
  154.95 +  }
  154.96 +
  154.97 +  // Add and erase nodes and arcs in the digraph through the adaptor
  154.98 +  Adaptor::Node n4 = adaptor.addNode();
  154.99 +
 154.100 +  Adaptor::Arc a4 = adaptor.addArc(n4, n3);
 154.101 +  Adaptor::Arc a5 = adaptor.addArc(n2, n4);
 154.102 +  Adaptor::Arc a6 = adaptor.addArc(n2, n4);
 154.103 +  Adaptor::Arc a7 = adaptor.addArc(n1, n4);
 154.104 +  Adaptor::Arc a8 = adaptor.addArc(n1, n2);
 154.105 +
 154.106 +  adaptor.erase(a1);
 154.107 +  adaptor.erase(n3);
 154.108 +
 154.109 +  // Check the adaptor
 154.110 +  checkGraphNodeList(adaptor, 3);
 154.111 +  checkGraphArcList(adaptor, 4);
 154.112 +  checkGraphConArcList(adaptor, 4);
 154.113 +
 154.114 +  checkGraphOutArcList(adaptor, n1, 2);
 154.115 +  checkGraphOutArcList(adaptor, n2, 2);
 154.116 +  checkGraphOutArcList(adaptor, n4, 0);
 154.117 +
 154.118 +  checkGraphInArcList(adaptor, n1, 0);
 154.119 +  checkGraphInArcList(adaptor, n2, 1);
 154.120 +  checkGraphInArcList(adaptor, n4, 3);
 154.121 +
 154.122 +  checkNodeIds(adaptor);
 154.123 +  checkArcIds(adaptor);
 154.124 +
 154.125 +  checkGraphNodeMap(adaptor);
 154.126 +  checkGraphArcMap(adaptor);
 154.127 +
 154.128 +  // Check the digraph
 154.129 +  checkGraphNodeList(digraph, 3);
 154.130 +  checkGraphArcList(digraph, 4);
 154.131 +  checkGraphConArcList(digraph, 4);
 154.132 +
 154.133 +  checkGraphOutArcList(digraph, n1, 0);
 154.134 +  checkGraphOutArcList(digraph, n2, 1);
 154.135 +  checkGraphOutArcList(digraph, n4, 3);
 154.136 +
 154.137 +  checkGraphInArcList(digraph, n1, 2);
 154.138 +  checkGraphInArcList(digraph, n2, 2);
 154.139 +  checkGraphInArcList(digraph, n4, 0);
 154.140 +
 154.141 +  checkNodeIds(digraph);
 154.142 +  checkArcIds(digraph);
 154.143 +
 154.144 +  checkGraphNodeMap(digraph);
 154.145 +  checkGraphArcMap(digraph);
 154.146 +
 154.147 +  // Check the conversion of nodes and arcs
 154.148 +  Digraph::Node nd = n4;
 154.149 +  nd = n4;
 154.150 +  Adaptor::Node na = n1;
 154.151 +  na = n2;
 154.152 +  Digraph::Arc ad = a4;
 154.153 +  ad = a5;
 154.154 +  Adaptor::Arc aa = a1;
 154.155 +  aa = a2;
 154.156 +}
 154.157 +
 154.158 +void checkSubDigraph() {
 154.159 +  // Check concepts
 154.160 +  checkConcept<concepts::Digraph, SubDigraph<concepts::Digraph> >();
 154.161 +  checkConcept<concepts::Digraph, SubDigraph<ListDigraph> >();
 154.162 +  checkConcept<concepts::AlterableDigraphComponent<>,
 154.163 +               SubDigraph<ListDigraph> >();
 154.164 +  checkConcept<concepts::ExtendableDigraphComponent<>,
 154.165 +               SubDigraph<ListDigraph> >();
 154.166 +  checkConcept<concepts::ErasableDigraphComponent<>,
 154.167 +               SubDigraph<ListDigraph> >();
 154.168 +  checkConcept<concepts::ClearableDigraphComponent<>,
 154.169 +               SubDigraph<ListDigraph> >();
 154.170 +
 154.171 +  // Create a digraph and an adaptor
 154.172 +  typedef ListDigraph Digraph;
 154.173 +  typedef Digraph::NodeMap<bool> NodeFilter;
 154.174 +  typedef Digraph::ArcMap<bool> ArcFilter;
 154.175 +  typedef SubDigraph<Digraph, NodeFilter, ArcFilter> Adaptor;
 154.176 +
 154.177 +  Digraph digraph;
 154.178 +  NodeFilter node_filter(digraph);
 154.179 +  ArcFilter arc_filter(digraph);
 154.180 +  Adaptor adaptor(digraph, node_filter, arc_filter);
 154.181 +
 154.182 +  // Add nodes and arcs to the original digraph and the adaptor
 154.183 +  Digraph::Node n1 = digraph.addNode();
 154.184 +  Digraph::Node n2 = digraph.addNode();
 154.185 +  Adaptor::Node n3 = adaptor.addNode();
 154.186 +
 154.187 +  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
 154.188 +
 154.189 +  Digraph::Arc a1 = digraph.addArc(n1, n2);
 154.190 +  Digraph::Arc a2 = digraph.addArc(n1, n3);
 154.191 +  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
 154.192 +
 154.193 +  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
 154.194 +
 154.195 +  checkGraphNodeList(adaptor, 3);
 154.196 +  checkGraphArcList(adaptor, 3);
 154.197 +  checkGraphConArcList(adaptor, 3);
 154.198 +
 154.199 +  checkGraphOutArcList(adaptor, n1, 2);
 154.200 +  checkGraphOutArcList(adaptor, n2, 1);
 154.201 +  checkGraphOutArcList(adaptor, n3, 0);
 154.202 +
 154.203 +  checkGraphInArcList(adaptor, n1, 0);
 154.204 +  checkGraphInArcList(adaptor, n2, 1);
 154.205 +  checkGraphInArcList(adaptor, n3, 2);
 154.206 +
 154.207 +  checkNodeIds(adaptor);
 154.208 +  checkArcIds(adaptor);
 154.209 +
 154.210 +  checkGraphNodeMap(adaptor);
 154.211 +  checkGraphArcMap(adaptor);
 154.212 +
 154.213 +  // Hide an arc
 154.214 +  adaptor.status(a2, false);
 154.215 +  adaptor.disable(a3);
 154.216 +  if (!adaptor.status(a3)) adaptor.enable(a3);
 154.217 +
 154.218 +  checkGraphNodeList(adaptor, 3);
 154.219 +  checkGraphArcList(adaptor, 2);
 154.220 +  checkGraphConArcList(adaptor, 2);
 154.221 +
 154.222 +  checkGraphOutArcList(adaptor, n1, 1);
 154.223 +  checkGraphOutArcList(adaptor, n2, 1);
 154.224 +  checkGraphOutArcList(adaptor, n3, 0);
 154.225 +
 154.226 +  checkGraphInArcList(adaptor, n1, 0);
 154.227 +  checkGraphInArcList(adaptor, n2, 1);
 154.228 +  checkGraphInArcList(adaptor, n3, 1);
 154.229 +
 154.230 +  checkNodeIds(adaptor);
 154.231 +  checkArcIds(adaptor);
 154.232 +
 154.233 +  checkGraphNodeMap(adaptor);
 154.234 +  checkGraphArcMap(adaptor);
 154.235 +
 154.236 +  // Hide a node
 154.237 +  adaptor.status(n1, false);
 154.238 +  adaptor.disable(n3);
 154.239 +  if (!adaptor.status(n3)) adaptor.enable(n3);
 154.240 +
 154.241 +  checkGraphNodeList(adaptor, 2);
 154.242 +  checkGraphArcList(adaptor, 1);
 154.243 +  checkGraphConArcList(adaptor, 1);
 154.244 +
 154.245 +  checkGraphOutArcList(adaptor, n2, 1);
 154.246 +  checkGraphOutArcList(adaptor, n3, 0);
 154.247 +
 154.248 +  checkGraphInArcList(adaptor, n2, 0);
 154.249 +  checkGraphInArcList(adaptor, n3, 1);
 154.250 +
 154.251 +  checkNodeIds(adaptor);
 154.252 +  checkArcIds(adaptor);
 154.253 +
 154.254 +  checkGraphNodeMap(adaptor);
 154.255 +  checkGraphArcMap(adaptor);
 154.256 +
 154.257 +  // Hide all nodes and arcs
 154.258 +  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
 154.259 +  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
 154.260 +
 154.261 +  checkGraphNodeList(adaptor, 0);
 154.262 +  checkGraphArcList(adaptor, 0);
 154.263 +  checkGraphConArcList(adaptor, 0);
 154.264 +
 154.265 +  checkNodeIds(adaptor);
 154.266 +  checkArcIds(adaptor);
 154.267 +
 154.268 +  checkGraphNodeMap(adaptor);
 154.269 +  checkGraphArcMap(adaptor);
 154.270 +
 154.271 +  // Check the conversion of nodes and arcs
 154.272 +  Digraph::Node nd = n3;
 154.273 +  nd = n3;
 154.274 +  Adaptor::Node na = n1;
 154.275 +  na = n2;
 154.276 +  Digraph::Arc ad = a3;
 154.277 +  ad = a3;
 154.278 +  Adaptor::Arc aa = a1;
 154.279 +  aa = a2;
 154.280 +}
 154.281 +
 154.282 +void checkFilterNodes1() {
 154.283 +  // Check concepts
 154.284 +  checkConcept<concepts::Digraph, FilterNodes<concepts::Digraph> >();
 154.285 +  checkConcept<concepts::Digraph, FilterNodes<ListDigraph> >();
 154.286 +  checkConcept<concepts::AlterableDigraphComponent<>,
 154.287 +               FilterNodes<ListDigraph> >();
 154.288 +  checkConcept<concepts::ExtendableDigraphComponent<>,
 154.289 +               FilterNodes<ListDigraph> >();
 154.290 +  checkConcept<concepts::ErasableDigraphComponent<>,
 154.291 +               FilterNodes<ListDigraph> >();
 154.292 +  checkConcept<concepts::ClearableDigraphComponent<>,
 154.293 +               FilterNodes<ListDigraph> >();
 154.294 +
 154.295 +  // Create a digraph and an adaptor
 154.296 +  typedef ListDigraph Digraph;
 154.297 +  typedef Digraph::NodeMap<bool> NodeFilter;
 154.298 +  typedef FilterNodes<Digraph, NodeFilter> Adaptor;
 154.299 +
 154.300 +  Digraph digraph;
 154.301 +  NodeFilter node_filter(digraph);
 154.302 +  Adaptor adaptor(digraph, node_filter);
 154.303 +
 154.304 +  // Add nodes and arcs to the original digraph and the adaptor
 154.305 +  Digraph::Node n1 = digraph.addNode();
 154.306 +  Digraph::Node n2 = digraph.addNode();
 154.307 +  Adaptor::Node n3 = adaptor.addNode();
 154.308 +
 154.309 +  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
 154.310 +
 154.311 +  Digraph::Arc a1 = digraph.addArc(n1, n2);
 154.312 +  Digraph::Arc a2 = digraph.addArc(n1, n3);
 154.313 +  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
 154.314 +
 154.315 +  checkGraphNodeList(adaptor, 3);
 154.316 +  checkGraphArcList(adaptor, 3);
 154.317 +  checkGraphConArcList(adaptor, 3);
 154.318 +
 154.319 +  checkGraphOutArcList(adaptor, n1, 2);
 154.320 +  checkGraphOutArcList(adaptor, n2, 1);
 154.321 +  checkGraphOutArcList(adaptor, n3, 0);
 154.322 +
 154.323 +  checkGraphInArcList(adaptor, n1, 0);
 154.324 +  checkGraphInArcList(adaptor, n2, 1);
 154.325 +  checkGraphInArcList(adaptor, n3, 2);
 154.326 +
 154.327 +  checkNodeIds(adaptor);
 154.328 +  checkArcIds(adaptor);
 154.329 +
 154.330 +  checkGraphNodeMap(adaptor);
 154.331 +  checkGraphArcMap(adaptor);
 154.332 +
 154.333 +  // Hide a node
 154.334 +  adaptor.status(n1, false);
 154.335 +  adaptor.disable(n3);
 154.336 +  if (!adaptor.status(n3)) adaptor.enable(n3);
 154.337 +
 154.338 +  checkGraphNodeList(adaptor, 2);
 154.339 +  checkGraphArcList(adaptor, 1);
 154.340 +  checkGraphConArcList(adaptor, 1);
 154.341 +
 154.342 +  checkGraphOutArcList(adaptor, n2, 1);
 154.343 +  checkGraphOutArcList(adaptor, n3, 0);
 154.344 +
 154.345 +  checkGraphInArcList(adaptor, n2, 0);
 154.346 +  checkGraphInArcList(adaptor, n3, 1);
 154.347 +
 154.348 +  checkNodeIds(adaptor);
 154.349 +  checkArcIds(adaptor);
 154.350 +
 154.351 +  checkGraphNodeMap(adaptor);
 154.352 +  checkGraphArcMap(adaptor);
 154.353 +
 154.354 +  // Hide all nodes
 154.355 +  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
 154.356 +
 154.357 +  checkGraphNodeList(adaptor, 0);
 154.358 +  checkGraphArcList(adaptor, 0);
 154.359 +  checkGraphConArcList(adaptor, 0);
 154.360 +
 154.361 +  checkNodeIds(adaptor);
 154.362 +  checkArcIds(adaptor);
 154.363 +
 154.364 +  checkGraphNodeMap(adaptor);
 154.365 +  checkGraphArcMap(adaptor);
 154.366 +
 154.367 +  // Check the conversion of nodes and arcs
 154.368 +  Digraph::Node nd = n3;
 154.369 +  nd = n3;
 154.370 +  Adaptor::Node na = n1;
 154.371 +  na = n2;
 154.372 +  Digraph::Arc ad = a3;
 154.373 +  ad = a3;
 154.374 +  Adaptor::Arc aa = a1;
 154.375 +  aa = a2;
 154.376 +}
 154.377 +
 154.378 +void checkFilterArcs() {
 154.379 +  // Check concepts
 154.380 +  checkConcept<concepts::Digraph, FilterArcs<concepts::Digraph> >();
 154.381 +  checkConcept<concepts::Digraph, FilterArcs<ListDigraph> >();
 154.382 +  checkConcept<concepts::AlterableDigraphComponent<>,
 154.383 +               FilterArcs<ListDigraph> >();
 154.384 +  checkConcept<concepts::ExtendableDigraphComponent<>,
 154.385 +               FilterArcs<ListDigraph> >();
 154.386 +  checkConcept<concepts::ErasableDigraphComponent<>,
 154.387 +               FilterArcs<ListDigraph> >();
 154.388 +  checkConcept<concepts::ClearableDigraphComponent<>,
 154.389 +               FilterArcs<ListDigraph> >();
 154.390 +
 154.391 +  // Create a digraph and an adaptor
 154.392 +  typedef ListDigraph Digraph;
 154.393 +  typedef Digraph::ArcMap<bool> ArcFilter;
 154.394 +  typedef FilterArcs<Digraph, ArcFilter> Adaptor;
 154.395 +
 154.396 +  Digraph digraph;
 154.397 +  ArcFilter arc_filter(digraph);
 154.398 +  Adaptor adaptor(digraph, arc_filter);
 154.399 +
 154.400 +  // Add nodes and arcs to the original digraph and the adaptor
 154.401 +  Digraph::Node n1 = digraph.addNode();
 154.402 +  Digraph::Node n2 = digraph.addNode();
 154.403 +  Adaptor::Node n3 = adaptor.addNode();
 154.404 +
 154.405 +  Digraph::Arc a1 = digraph.addArc(n1, n2);
 154.406 +  Digraph::Arc a2 = digraph.addArc(n1, n3);
 154.407 +  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
 154.408 +
 154.409 +  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
 154.410 +
 154.411 +  checkGraphNodeList(adaptor, 3);
 154.412 +  checkGraphArcList(adaptor, 3);
 154.413 +  checkGraphConArcList(adaptor, 3);
 154.414 +
 154.415 +  checkGraphOutArcList(adaptor, n1, 2);
 154.416 +  checkGraphOutArcList(adaptor, n2, 1);
 154.417 +  checkGraphOutArcList(adaptor, n3, 0);
 154.418 +
 154.419 +  checkGraphInArcList(adaptor, n1, 0);
 154.420 +  checkGraphInArcList(adaptor, n2, 1);
 154.421 +  checkGraphInArcList(adaptor, n3, 2);
 154.422 +
 154.423 +  checkNodeIds(adaptor);
 154.424 +  checkArcIds(adaptor);
 154.425 +
 154.426 +  checkGraphNodeMap(adaptor);
 154.427 +  checkGraphArcMap(adaptor);
 154.428 +
 154.429 +  // Hide an arc
 154.430 +  adaptor.status(a2, false);
 154.431 +  adaptor.disable(a3);
 154.432 +  if (!adaptor.status(a3)) adaptor.enable(a3);
 154.433 +
 154.434 +  checkGraphNodeList(adaptor, 3);
 154.435 +  checkGraphArcList(adaptor, 2);
 154.436 +  checkGraphConArcList(adaptor, 2);
 154.437 +
 154.438 +  checkGraphOutArcList(adaptor, n1, 1);
 154.439 +  checkGraphOutArcList(adaptor, n2, 1);
 154.440 +  checkGraphOutArcList(adaptor, n3, 0);
 154.441 +
 154.442 +  checkGraphInArcList(adaptor, n1, 0);
 154.443 +  checkGraphInArcList(adaptor, n2, 1);
 154.444 +  checkGraphInArcList(adaptor, n3, 1);
 154.445 +
 154.446 +  checkNodeIds(adaptor);
 154.447 +  checkArcIds(adaptor);
 154.448 +
 154.449 +  checkGraphNodeMap(adaptor);
 154.450 +  checkGraphArcMap(adaptor);
 154.451 +
 154.452 +  // Hide all arcs
 154.453 +  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
 154.454 +
 154.455 +  checkGraphNodeList(adaptor, 3);
 154.456 +  checkGraphArcList(adaptor, 0);
 154.457 +  checkGraphConArcList(adaptor, 0);
 154.458 +
 154.459 +  checkNodeIds(adaptor);
 154.460 +  checkArcIds(adaptor);
 154.461 +
 154.462 +  checkGraphNodeMap(adaptor);
 154.463 +  checkGraphArcMap(adaptor);
 154.464 +
 154.465 +  // Check the conversion of nodes and arcs
 154.466 +  Digraph::Node nd = n3;
 154.467 +  nd = n3;
 154.468 +  Adaptor::Node na = n1;
 154.469 +  na = n2;
 154.470 +  Digraph::Arc ad = a3;
 154.471 +  ad = a3;
 154.472 +  Adaptor::Arc aa = a1;
 154.473 +  aa = a2;
 154.474 +}
 154.475 +
 154.476 +void checkUndirector() {
 154.477 +  // Check concepts
 154.478 +  checkConcept<concepts::Graph, Undirector<concepts::Digraph> >();
 154.479 +  checkConcept<concepts::Graph, Undirector<ListDigraph> >();
 154.480 +  checkConcept<concepts::AlterableGraphComponent<>,
 154.481 +               Undirector<ListDigraph> >();
 154.482 +  checkConcept<concepts::ExtendableGraphComponent<>,
 154.483 +               Undirector<ListDigraph> >();
 154.484 +  checkConcept<concepts::ErasableGraphComponent<>,
 154.485 +               Undirector<ListDigraph> >();
 154.486 +  checkConcept<concepts::ClearableGraphComponent<>,
 154.487 +               Undirector<ListDigraph> >();
 154.488 +
 154.489 +
 154.490 +  // Create a digraph and an adaptor
 154.491 +  typedef ListDigraph Digraph;
 154.492 +  typedef Undirector<Digraph> Adaptor;
 154.493 +
 154.494 +  Digraph digraph;
 154.495 +  Adaptor adaptor(digraph);
 154.496 +
 154.497 +  // Add nodes and arcs/edges to the original digraph and the adaptor
 154.498 +  Digraph::Node n1 = digraph.addNode();
 154.499 +  Digraph::Node n2 = digraph.addNode();
 154.500 +  Adaptor::Node n3 = adaptor.addNode();
 154.501 +
 154.502 +  Digraph::Arc a1 = digraph.addArc(n1, n2);
 154.503 +  Digraph::Arc a2 = digraph.addArc(n1, n3);
 154.504 +  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
 154.505 +
 154.506 +  // Check the original digraph
 154.507 +  checkGraphNodeList(digraph, 3);
 154.508 +  checkGraphArcList(digraph, 3);
 154.509 +  checkGraphConArcList(digraph, 3);
 154.510 +
 154.511 +  checkGraphOutArcList(digraph, n1, 2);
 154.512 +  checkGraphOutArcList(digraph, n2, 1);
 154.513 +  checkGraphOutArcList(digraph, n3, 0);
 154.514 +
 154.515 +  checkGraphInArcList(digraph, n1, 0);
 154.516 +  checkGraphInArcList(digraph, n2, 1);
 154.517 +  checkGraphInArcList(digraph, n3, 2);
 154.518 +
 154.519 +  checkNodeIds(digraph);
 154.520 +  checkArcIds(digraph);
 154.521 +
 154.522 +  checkGraphNodeMap(digraph);
 154.523 +  checkGraphArcMap(digraph);
 154.524 +
 154.525 +  // Check the adaptor
 154.526 +  checkGraphNodeList(adaptor, 3);
 154.527 +  checkGraphArcList(adaptor, 6);
 154.528 +  checkGraphEdgeList(adaptor, 3);
 154.529 +  checkGraphConArcList(adaptor, 6);
 154.530 +  checkGraphConEdgeList(adaptor, 3);
 154.531 +
 154.532 +  checkGraphIncEdgeArcLists(adaptor, n1, 2);
 154.533 +  checkGraphIncEdgeArcLists(adaptor, n2, 2);
 154.534 +  checkGraphIncEdgeArcLists(adaptor, n3, 2);
 154.535 +
 154.536 +  checkNodeIds(adaptor);
 154.537 +  checkArcIds(adaptor);
 154.538 +  checkEdgeIds(adaptor);
 154.539 +
 154.540 +  checkGraphNodeMap(adaptor);
 154.541 +  checkGraphArcMap(adaptor);
 154.542 +  checkGraphEdgeMap(adaptor);
 154.543 +
 154.544 +  // Check the edges of the adaptor
 154.545 +  for (Adaptor::EdgeIt e(adaptor); e != INVALID; ++e) {
 154.546 +    check(adaptor.u(e) == digraph.source(e), "Wrong undir");
 154.547 +    check(adaptor.v(e) == digraph.target(e), "Wrong undir");
 154.548 +  }
 154.549 +
 154.550 +  // Check CombinedArcMap
 154.551 +  typedef Adaptor::CombinedArcMap
 154.552 +    <Digraph::ArcMap<int>, Digraph::ArcMap<int> > IntCombinedMap;
 154.553 +  typedef Adaptor::CombinedArcMap
 154.554 +    <Digraph::ArcMap<bool>, Digraph::ArcMap<bool> > BoolCombinedMap;
 154.555 +  checkConcept<concepts::ReferenceMap<Adaptor::Arc, int, int&, const int&>,
 154.556 +    IntCombinedMap>();
 154.557 +  checkConcept<concepts::ReferenceMap<Adaptor::Arc, bool, bool&, const bool&>,
 154.558 +    BoolCombinedMap>();
 154.559 +
 154.560 +  Digraph::ArcMap<int> fw_map(digraph), bk_map(digraph);
 154.561 +  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
 154.562 +    fw_map[a] = digraph.id(a);
 154.563 +    bk_map[a] = -digraph.id(a);
 154.564 +  }
 154.565 +
 154.566 +  Adaptor::CombinedArcMap<Digraph::ArcMap<int>, Digraph::ArcMap<int> >
 154.567 +    comb_map(fw_map, bk_map);
 154.568 +  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
 154.569 +    if (adaptor.source(a) == digraph.source(a)) {
 154.570 +      check(comb_map[a] == fw_map[a], "Wrong combined map");
 154.571 +    } else {
 154.572 +      check(comb_map[a] == bk_map[a], "Wrong combined map");
 154.573 +    }
 154.574 +  }
 154.575 +
 154.576 +  // Check the conversion of nodes and arcs/edges
 154.577 +  Digraph::Node nd = n3;
 154.578 +  nd = n3;
 154.579 +  Adaptor::Node na = n1;
 154.580 +  na = n2;
 154.581 +  Digraph::Arc ad = e3;
 154.582 +  ad = e3;
 154.583 +  Adaptor::Edge ea = a1;
 154.584 +  ea = a2;
 154.585 +}
 154.586 +
 154.587 +void checkResidualDigraph() {
 154.588 +  // Check concepts
 154.589 +  checkConcept<concepts::Digraph, ResidualDigraph<concepts::Digraph> >();
 154.590 +  checkConcept<concepts::Digraph, ResidualDigraph<ListDigraph> >();
 154.591 +
 154.592 +  // Create a digraph and an adaptor
 154.593 +  typedef ListDigraph Digraph;
 154.594 +  typedef Digraph::ArcMap<int> IntArcMap;
 154.595 +  typedef ResidualDigraph<Digraph, IntArcMap> Adaptor;
 154.596 +
 154.597 +  Digraph digraph;
 154.598 +  IntArcMap capacity(digraph), flow(digraph);
 154.599 +  Adaptor adaptor(digraph, capacity, flow);
 154.600 +
 154.601 +  Digraph::Node n1 = digraph.addNode();
 154.602 +  Digraph::Node n2 = digraph.addNode();
 154.603 +  Digraph::Node n3 = digraph.addNode();
 154.604 +  Digraph::Node n4 = digraph.addNode();
 154.605 +
 154.606 +  Digraph::Arc a1 = digraph.addArc(n1, n2);
 154.607 +  Digraph::Arc a2 = digraph.addArc(n1, n3);
 154.608 +  Digraph::Arc a3 = digraph.addArc(n1, n4);
 154.609 +  Digraph::Arc a4 = digraph.addArc(n2, n3);
 154.610 +  Digraph::Arc a5 = digraph.addArc(n2, n4);
 154.611 +  Digraph::Arc a6 = digraph.addArc(n3, n4);
 154.612 +
 154.613 +  capacity[a1] = 8;
 154.614 +  capacity[a2] = 6;
 154.615 +  capacity[a3] = 4;
 154.616 +  capacity[a4] = 4;
 154.617 +  capacity[a5] = 6;
 154.618 +  capacity[a6] = 10;
 154.619 +
 154.620 +  // Check the adaptor with various flow values
 154.621 +  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
 154.622 +    flow[a] = 0;
 154.623 +  }
 154.624 +
 154.625 +  checkGraphNodeList(adaptor, 4);
 154.626 +  checkGraphArcList(adaptor, 6);
 154.627 +  checkGraphConArcList(adaptor, 6);
 154.628 +
 154.629 +  checkGraphOutArcList(adaptor, n1, 3);
 154.630 +  checkGraphOutArcList(adaptor, n2, 2);
 154.631 +  checkGraphOutArcList(adaptor, n3, 1);
 154.632 +  checkGraphOutArcList(adaptor, n4, 0);
 154.633 +
 154.634 +  checkGraphInArcList(adaptor, n1, 0);
 154.635 +  checkGraphInArcList(adaptor, n2, 1);
 154.636 +  checkGraphInArcList(adaptor, n3, 2);
 154.637 +  checkGraphInArcList(adaptor, n4, 3);
 154.638 +
 154.639 +  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
 154.640 +    flow[a] = capacity[a] / 2;
 154.641 +  }
 154.642 +
 154.643 +  checkGraphNodeList(adaptor, 4);
 154.644 +  checkGraphArcList(adaptor, 12);
 154.645 +  checkGraphConArcList(adaptor, 12);
 154.646 +
 154.647 +  checkGraphOutArcList(adaptor, n1, 3);
 154.648 +  checkGraphOutArcList(adaptor, n2, 3);
 154.649 +  checkGraphOutArcList(adaptor, n3, 3);
 154.650 +  checkGraphOutArcList(adaptor, n4, 3);
 154.651 +
 154.652 +  checkGraphInArcList(adaptor, n1, 3);
 154.653 +  checkGraphInArcList(adaptor, n2, 3);
 154.654 +  checkGraphInArcList(adaptor, n3, 3);
 154.655 +  checkGraphInArcList(adaptor, n4, 3);
 154.656 +
 154.657 +  checkNodeIds(adaptor);
 154.658 +  checkArcIds(adaptor);
 154.659 +
 154.660 +  checkGraphNodeMap(adaptor);
 154.661 +  checkGraphArcMap(adaptor);
 154.662 +
 154.663 +  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
 154.664 +    flow[a] = capacity[a];
 154.665 +  }
 154.666 +
 154.667 +  checkGraphNodeList(adaptor, 4);
 154.668 +  checkGraphArcList(adaptor, 6);
 154.669 +  checkGraphConArcList(adaptor, 6);
 154.670 +
 154.671 +  checkGraphOutArcList(adaptor, n1, 0);
 154.672 +  checkGraphOutArcList(adaptor, n2, 1);
 154.673 +  checkGraphOutArcList(adaptor, n3, 2);
 154.674 +  checkGraphOutArcList(adaptor, n4, 3);
 154.675 +
 154.676 +  checkGraphInArcList(adaptor, n1, 3);
 154.677 +  checkGraphInArcList(adaptor, n2, 2);
 154.678 +  checkGraphInArcList(adaptor, n3, 1);
 154.679 +  checkGraphInArcList(adaptor, n4, 0);
 154.680 +
 154.681 +  // Saturate all backward arcs
 154.682 +  // (set the flow to zero on all forward arcs)
 154.683 +  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
 154.684 +    if (adaptor.backward(a))
 154.685 +      adaptor.augment(a, adaptor.residualCapacity(a));
 154.686 +  }
 154.687 +
 154.688 +  checkGraphNodeList(adaptor, 4);
 154.689 +  checkGraphArcList(adaptor, 6);
 154.690 +  checkGraphConArcList(adaptor, 6);
 154.691 +
 154.692 +  checkGraphOutArcList(adaptor, n1, 3);
 154.693 +  checkGraphOutArcList(adaptor, n2, 2);
 154.694 +  checkGraphOutArcList(adaptor, n3, 1);
 154.695 +  checkGraphOutArcList(adaptor, n4, 0);
 154.696 +
 154.697 +  checkGraphInArcList(adaptor, n1, 0);
 154.698 +  checkGraphInArcList(adaptor, n2, 1);
 154.699 +  checkGraphInArcList(adaptor, n3, 2);
 154.700 +  checkGraphInArcList(adaptor, n4, 3);
 154.701 +
 154.702 +  // Find maximum flow by augmenting along shortest paths
 154.703 +  int flow_value = 0;
 154.704 +  Adaptor::ResidualCapacity res_cap(adaptor);
 154.705 +  while (true) {
 154.706 +
 154.707 +    Bfs<Adaptor> bfs(adaptor);
 154.708 +    bfs.run(n1, n4);
 154.709 +
 154.710 +    if (!bfs.reached(n4)) break;
 154.711 +
 154.712 +    Path<Adaptor> p = bfs.path(n4);
 154.713 +
 154.714 +    int min = std::numeric_limits<int>::max();
 154.715 +    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
 154.716 +      if (res_cap[a] < min) min = res_cap[a];
 154.717 +    }
 154.718 +
 154.719 +    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
 154.720 +      adaptor.augment(a, min);
 154.721 +    }
 154.722 +    flow_value += min;
 154.723 +  }
 154.724 +
 154.725 +  check(flow_value == 18, "Wrong flow with res graph adaptor");
 154.726 +
 154.727 +  // Check forward() and backward()
 154.728 +  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
 154.729 +    check(adaptor.forward(a) != adaptor.backward(a),
 154.730 +          "Wrong forward() or backward()");
 154.731 +    check((adaptor.forward(a) && adaptor.forward(Digraph::Arc(a)) == a) ||
 154.732 +          (adaptor.backward(a) && adaptor.backward(Digraph::Arc(a)) == a),
 154.733 +          "Wrong forward() or backward()");
 154.734 +  }
 154.735 +
 154.736 +  // Check the conversion of nodes and arcs
 154.737 +  Digraph::Node nd = Adaptor::NodeIt(adaptor);
 154.738 +  nd = ++Adaptor::NodeIt(adaptor);
 154.739 +  Adaptor::Node na = n1;
 154.740 +  na = n2;
 154.741 +  Digraph::Arc ad = Adaptor::ArcIt(adaptor);
 154.742 +  ad = ++Adaptor::ArcIt(adaptor);
 154.743 +}
 154.744 +
 154.745 +void checkSplitNodes() {
 154.746 +  // Check concepts
 154.747 +  checkConcept<concepts::Digraph, SplitNodes<concepts::Digraph> >();
 154.748 +  checkConcept<concepts::Digraph, SplitNodes<ListDigraph> >();
 154.749 +
 154.750 +  // Create a digraph and an adaptor
 154.751 +  typedef ListDigraph Digraph;
 154.752 +  typedef SplitNodes<Digraph> Adaptor;
 154.753 +
 154.754 +  Digraph digraph;
 154.755 +  Adaptor adaptor(digraph);
 154.756 +
 154.757 +  Digraph::Node n1 = digraph.addNode();
 154.758 +  Digraph::Node n2 = digraph.addNode();
 154.759 +  Digraph::Node n3 = digraph.addNode();
 154.760 +
 154.761 +  Digraph::Arc a1 = digraph.addArc(n1, n2);
 154.762 +  Digraph::Arc a2 = digraph.addArc(n1, n3);
 154.763 +  Digraph::Arc a3 = digraph.addArc(n2, n3);
 154.764 +
 154.765 +  checkGraphNodeList(adaptor, 6);
 154.766 +  checkGraphArcList(adaptor, 6);
 154.767 +  checkGraphConArcList(adaptor, 6);
 154.768 +
 154.769 +  checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
 154.770 +  checkGraphOutArcList(adaptor, adaptor.outNode(n1), 2);
 154.771 +  checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
 154.772 +  checkGraphOutArcList(adaptor, adaptor.outNode(n2), 1);
 154.773 +  checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
 154.774 +  checkGraphOutArcList(adaptor, adaptor.outNode(n3), 0);
 154.775 +
 154.776 +  checkGraphInArcList(adaptor, adaptor.inNode(n1), 0);
 154.777 +  checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
 154.778 +  checkGraphInArcList(adaptor, adaptor.inNode(n2), 1);
 154.779 +  checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
 154.780 +  checkGraphInArcList(adaptor, adaptor.inNode(n3), 2);
 154.781 +  checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
 154.782 +
 154.783 +  checkNodeIds(adaptor);
 154.784 +  checkArcIds(adaptor);
 154.785 +
 154.786 +  checkGraphNodeMap(adaptor);
 154.787 +  checkGraphArcMap(adaptor);
 154.788 +
 154.789 +  // Check split
 154.790 +  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
 154.791 +    if (adaptor.origArc(a)) {
 154.792 +      Digraph::Arc oa = a;
 154.793 +      check(adaptor.source(a) == adaptor.outNode(digraph.source(oa)),
 154.794 +            "Wrong split");
 154.795 +      check(adaptor.target(a) == adaptor.inNode(digraph.target(oa)),
 154.796 +            "Wrong split");
 154.797 +    } else {
 154.798 +      Digraph::Node on = a;
 154.799 +      check(adaptor.source(a) == adaptor.inNode(on), "Wrong split");
 154.800 +      check(adaptor.target(a) == adaptor.outNode(on), "Wrong split");
 154.801 +    }
 154.802 +  }
 154.803 +
 154.804 +  // Check combined node map
 154.805 +  typedef Adaptor::CombinedNodeMap
 154.806 +    <Digraph::NodeMap<int>, Digraph::NodeMap<int> > IntCombinedNodeMap;
 154.807 +  typedef Adaptor::CombinedNodeMap
 154.808 +    <Digraph::NodeMap<bool>, Digraph::NodeMap<bool> > BoolCombinedNodeMap;
 154.809 +  checkConcept<concepts::ReferenceMap<Adaptor::Node, int, int&, const int&>,
 154.810 +    IntCombinedNodeMap>();
 154.811 +//checkConcept<concepts::ReferenceMap<Adaptor::Node, bool, bool&, const bool&>,
 154.812 +//  BoolCombinedNodeMap>();
 154.813 +  checkConcept<concepts::ReadWriteMap<Adaptor::Node, bool>,
 154.814 +    BoolCombinedNodeMap>();
 154.815 +
 154.816 +  Digraph::NodeMap<int> in_map(digraph), out_map(digraph);
 154.817 +  for (Digraph::NodeIt n(digraph); n != INVALID; ++n) {
 154.818 +    in_map[n] = digraph.id(n);
 154.819 +    out_map[n] = -digraph.id(n);
 154.820 +  }
 154.821 +
 154.822 +  Adaptor::CombinedNodeMap<Digraph::NodeMap<int>, Digraph::NodeMap<int> >
 154.823 +    node_map(in_map, out_map);
 154.824 +  for (Adaptor::NodeIt n(adaptor); n != INVALID; ++n) {
 154.825 +    if (adaptor.inNode(n)) {
 154.826 +      check(node_map[n] == in_map[n], "Wrong combined node map");
 154.827 +    } else {
 154.828 +      check(node_map[n] == out_map[n], "Wrong combined node map");
 154.829 +    }
 154.830 +  }
 154.831 +
 154.832 +  // Check combined arc map
 154.833 +  typedef Adaptor::CombinedArcMap
 154.834 +    <Digraph::ArcMap<int>, Digraph::NodeMap<int> > IntCombinedArcMap;
 154.835 +  typedef Adaptor::CombinedArcMap
 154.836 +    <Digraph::ArcMap<bool>, Digraph::NodeMap<bool> > BoolCombinedArcMap;
 154.837 +  checkConcept<concepts::ReferenceMap<Adaptor::Arc, int, int&, const int&>,
 154.838 +    IntCombinedArcMap>();
 154.839 +//checkConcept<concepts::ReferenceMap<Adaptor::Arc, bool, bool&, const bool&>,
 154.840 +//  BoolCombinedArcMap>();
 154.841 +  checkConcept<concepts::ReadWriteMap<Adaptor::Arc, bool>,
 154.842 +    BoolCombinedArcMap>();
 154.843 +
 154.844 +  Digraph::ArcMap<int> a_map(digraph);
 154.845 +  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
 154.846 +    a_map[a] = digraph.id(a);
 154.847 +  }
 154.848 +
 154.849 +  Adaptor::CombinedArcMap<Digraph::ArcMap<int>, Digraph::NodeMap<int> >
 154.850 +    arc_map(a_map, out_map);
 154.851 +  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
 154.852 +    check(arc_map[adaptor.arc(a)] == a_map[a],  "Wrong combined arc map");
 154.853 +  }
 154.854 +  for (Digraph::NodeIt n(digraph); n != INVALID; ++n) {
 154.855 +    check(arc_map[adaptor.arc(n)] == out_map[n],  "Wrong combined arc map");
 154.856 +  }
 154.857 +
 154.858 +  // Check the conversion of nodes
 154.859 +  Digraph::Node nd = adaptor.inNode(n1);
 154.860 +  check (nd == n1, "Wrong node conversion");
 154.861 +  nd = adaptor.outNode(n2);
 154.862 +  check (nd == n2, "Wrong node conversion");
 154.863 +}
 154.864 +
 154.865 +void checkSubGraph() {
 154.866 +  // Check concepts
 154.867 +  checkConcept<concepts::Graph, SubGraph<concepts::Graph> >();
 154.868 +  checkConcept<concepts::Graph, SubGraph<ListGraph> >();
 154.869 +  checkConcept<concepts::AlterableGraphComponent<>,
 154.870 +               SubGraph<ListGraph> >();
 154.871 +  checkConcept<concepts::ExtendableGraphComponent<>,
 154.872 +               SubGraph<ListGraph> >();
 154.873 +  checkConcept<concepts::ErasableGraphComponent<>,
 154.874 +               SubGraph<ListGraph> >();
 154.875 +  checkConcept<concepts::ClearableGraphComponent<>,
 154.876 +               SubGraph<ListGraph> >();
 154.877 +
 154.878 +  // Create a graph and an adaptor
 154.879 +  typedef ListGraph Graph;
 154.880 +  typedef Graph::NodeMap<bool> NodeFilter;
 154.881 +  typedef Graph::EdgeMap<bool> EdgeFilter;
 154.882 +  typedef SubGraph<Graph, NodeFilter, EdgeFilter> Adaptor;
 154.883 +
 154.884 +  Graph graph;
 154.885 +  NodeFilter node_filter(graph);
 154.886 +  EdgeFilter edge_filter(graph);
 154.887 +  Adaptor adaptor(graph, node_filter, edge_filter);
 154.888 +
 154.889 +  // Add nodes and edges to the original graph and the adaptor
 154.890 +  Graph::Node n1 = graph.addNode();
 154.891 +  Graph::Node n2 = graph.addNode();
 154.892 +  Adaptor::Node n3 = adaptor.addNode();
 154.893 +  Adaptor::Node n4 = adaptor.addNode();
 154.894 +
 154.895 +  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
 154.896 +
 154.897 +  Graph::Edge e1 = graph.addEdge(n1, n2);
 154.898 +  Graph::Edge e2 = graph.addEdge(n1, n3);
 154.899 +  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
 154.900 +  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
 154.901 +
 154.902 +  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
 154.903 +
 154.904 +  checkGraphNodeList(adaptor, 4);
 154.905 +  checkGraphArcList(adaptor, 8);
 154.906 +  checkGraphEdgeList(adaptor, 4);
 154.907 +  checkGraphConArcList(adaptor, 8);
 154.908 +  checkGraphConEdgeList(adaptor, 4);
 154.909 +
 154.910 +  checkGraphIncEdgeArcLists(adaptor, n1, 2);
 154.911 +  checkGraphIncEdgeArcLists(adaptor, n2, 2);
 154.912 +  checkGraphIncEdgeArcLists(adaptor, n3, 3);
 154.913 +  checkGraphIncEdgeArcLists(adaptor, n4, 1);
 154.914 +
 154.915 +  checkNodeIds(adaptor);
 154.916 +  checkArcIds(adaptor);
 154.917 +  checkEdgeIds(adaptor);
 154.918 +
 154.919 +  checkGraphNodeMap(adaptor);
 154.920 +  checkGraphArcMap(adaptor);
 154.921 +  checkGraphEdgeMap(adaptor);
 154.922 +
 154.923 +  // Hide an edge
 154.924 +  adaptor.status(e2, false);
 154.925 +  adaptor.disable(e3);
 154.926 +  if (!adaptor.status(e3)) adaptor.enable(e3);
 154.927 +
 154.928 +  checkGraphNodeList(adaptor, 4);
 154.929 +  checkGraphArcList(adaptor, 6);
 154.930 +  checkGraphEdgeList(adaptor, 3);
 154.931 +  checkGraphConArcList(adaptor, 6);
 154.932 +  checkGraphConEdgeList(adaptor, 3);
 154.933 +
 154.934 +  checkGraphIncEdgeArcLists(adaptor, n1, 1);
 154.935 +  checkGraphIncEdgeArcLists(adaptor, n2, 2);
 154.936 +  checkGraphIncEdgeArcLists(adaptor, n3, 2);
 154.937 +  checkGraphIncEdgeArcLists(adaptor, n4, 1);
 154.938 +
 154.939 +  checkNodeIds(adaptor);
 154.940 +  checkArcIds(adaptor);
 154.941 +  checkEdgeIds(adaptor);
 154.942 +
 154.943 +  checkGraphNodeMap(adaptor);
 154.944 +  checkGraphArcMap(adaptor);
 154.945 +  checkGraphEdgeMap(adaptor);
 154.946 +
 154.947 +  // Hide a node
 154.948 +  adaptor.status(n1, false);
 154.949 +  adaptor.disable(n3);
 154.950 +  if (!adaptor.status(n3)) adaptor.enable(n3);
 154.951 +
 154.952 +  checkGraphNodeList(adaptor, 3);
 154.953 +  checkGraphArcList(adaptor, 4);
 154.954 +  checkGraphEdgeList(adaptor, 2);
 154.955 +  checkGraphConArcList(adaptor, 4);
 154.956 +  checkGraphConEdgeList(adaptor, 2);
 154.957 +
 154.958 +  checkGraphIncEdgeArcLists(adaptor, n2, 1);
 154.959 +  checkGraphIncEdgeArcLists(adaptor, n3, 2);
 154.960 +  checkGraphIncEdgeArcLists(adaptor, n4, 1);
 154.961 +
 154.962 +  checkNodeIds(adaptor);
 154.963 +  checkArcIds(adaptor);
 154.964 +  checkEdgeIds(adaptor);
 154.965 +
 154.966 +  checkGraphNodeMap(adaptor);
 154.967 +  checkGraphArcMap(adaptor);
 154.968 +  checkGraphEdgeMap(adaptor);
 154.969 +
 154.970 +  // Hide all nodes and edges
 154.971 +  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
 154.972 +  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
 154.973 +
 154.974 +  checkGraphNodeList(adaptor, 0);
 154.975 +  checkGraphArcList(adaptor, 0);
 154.976 +  checkGraphEdgeList(adaptor, 0);
 154.977 +  checkGraphConArcList(adaptor, 0);
 154.978 +  checkGraphConEdgeList(adaptor, 0);
 154.979 +
 154.980 +  checkNodeIds(adaptor);
 154.981 +  checkArcIds(adaptor);
 154.982 +  checkEdgeIds(adaptor);
 154.983 +
 154.984 +  checkGraphNodeMap(adaptor);
 154.985 +  checkGraphArcMap(adaptor);
 154.986 +  checkGraphEdgeMap(adaptor);
 154.987 +
 154.988 +  // Check the conversion of nodes and edges
 154.989 +  Graph::Node ng = n3;
 154.990 +  ng = n4;
 154.991 +  Adaptor::Node na = n1;
 154.992 +  na = n2;
 154.993 +  Graph::Edge eg = e3;
 154.994 +  eg = e4;
 154.995 +  Adaptor::Edge ea = e1;
 154.996 +  ea = e2;
 154.997 +}
 154.998 +
 154.999 +void checkFilterNodes2() {
154.1000 +  // Check concepts
154.1001 +  checkConcept<concepts::Graph, FilterNodes<concepts::Graph> >();
154.1002 +  checkConcept<concepts::Graph, FilterNodes<ListGraph> >();
154.1003 +  checkConcept<concepts::AlterableGraphComponent<>,
154.1004 +               FilterNodes<ListGraph> >();
154.1005 +  checkConcept<concepts::ExtendableGraphComponent<>,
154.1006 +               FilterNodes<ListGraph> >();
154.1007 +  checkConcept<concepts::ErasableGraphComponent<>,
154.1008 +               FilterNodes<ListGraph> >();
154.1009 +  checkConcept<concepts::ClearableGraphComponent<>,
154.1010 +               FilterNodes<ListGraph> >();
154.1011 +
154.1012 +  // Create a graph and an adaptor
154.1013 +  typedef ListGraph Graph;
154.1014 +  typedef Graph::NodeMap<bool> NodeFilter;
154.1015 +  typedef FilterNodes<Graph, NodeFilter> Adaptor;
154.1016 +
154.1017 +  // Add nodes and edges to the original graph and the adaptor
154.1018 +  Graph graph;
154.1019 +  NodeFilter node_filter(graph);
154.1020 +  Adaptor adaptor(graph, node_filter);
154.1021 +
154.1022 +  Graph::Node n1 = graph.addNode();
154.1023 +  Graph::Node n2 = graph.addNode();
154.1024 +  Adaptor::Node n3 = adaptor.addNode();
154.1025 +  Adaptor::Node n4 = adaptor.addNode();
154.1026 +
154.1027 +  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
154.1028 +
154.1029 +  Graph::Edge e1 = graph.addEdge(n1, n2);
154.1030 +  Graph::Edge e2 = graph.addEdge(n1, n3);
154.1031 +  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
154.1032 +  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
154.1033 +
154.1034 +  checkGraphNodeList(adaptor, 4);
154.1035 +  checkGraphArcList(adaptor, 8);
154.1036 +  checkGraphEdgeList(adaptor, 4);
154.1037 +  checkGraphConArcList(adaptor, 8);
154.1038 +  checkGraphConEdgeList(adaptor, 4);
154.1039 +
154.1040 +  checkGraphIncEdgeArcLists(adaptor, n1, 2);
154.1041 +  checkGraphIncEdgeArcLists(adaptor, n2, 2);
154.1042 +  checkGraphIncEdgeArcLists(adaptor, n3, 3);
154.1043 +  checkGraphIncEdgeArcLists(adaptor, n4, 1);
154.1044 +
154.1045 +  checkNodeIds(adaptor);
154.1046 +  checkArcIds(adaptor);
154.1047 +  checkEdgeIds(adaptor);
154.1048 +
154.1049 +  checkGraphNodeMap(adaptor);
154.1050 +  checkGraphArcMap(adaptor);
154.1051 +  checkGraphEdgeMap(adaptor);
154.1052 +
154.1053 +  // Hide a node
154.1054 +  adaptor.status(n1, false);
154.1055 +  adaptor.disable(n3);
154.1056 +  if (!adaptor.status(n3)) adaptor.enable(n3);
154.1057 +
154.1058 +  checkGraphNodeList(adaptor, 3);
154.1059 +  checkGraphArcList(adaptor, 4);
154.1060 +  checkGraphEdgeList(adaptor, 2);
154.1061 +  checkGraphConArcList(adaptor, 4);
154.1062 +  checkGraphConEdgeList(adaptor, 2);
154.1063 +
154.1064 +  checkGraphIncEdgeArcLists(adaptor, n2, 1);
154.1065 +  checkGraphIncEdgeArcLists(adaptor, n3, 2);
154.1066 +  checkGraphIncEdgeArcLists(adaptor, n4, 1);
154.1067 +
154.1068 +  checkNodeIds(adaptor);
154.1069 +  checkArcIds(adaptor);
154.1070 +  checkEdgeIds(adaptor);
154.1071 +
154.1072 +  checkGraphNodeMap(adaptor);
154.1073 +  checkGraphArcMap(adaptor);
154.1074 +  checkGraphEdgeMap(adaptor);
154.1075 +
154.1076 +  // Hide all nodes
154.1077 +  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
154.1078 +
154.1079 +  checkGraphNodeList(adaptor, 0);
154.1080 +  checkGraphArcList(adaptor, 0);
154.1081 +  checkGraphEdgeList(adaptor, 0);
154.1082 +  checkGraphConArcList(adaptor, 0);
154.1083 +  checkGraphConEdgeList(adaptor, 0);
154.1084 +
154.1085 +  checkNodeIds(adaptor);
154.1086 +  checkArcIds(adaptor);
154.1087 +  checkEdgeIds(adaptor);
154.1088 +
154.1089 +  checkGraphNodeMap(adaptor);
154.1090 +  checkGraphArcMap(adaptor);
154.1091 +  checkGraphEdgeMap(adaptor);
154.1092 +
154.1093 +  // Check the conversion of nodes and edges
154.1094 +  Graph::Node ng = n3;
154.1095 +  ng = n4;
154.1096 +  Adaptor::Node na = n1;
154.1097 +  na = n2;
154.1098 +  Graph::Edge eg = e3;
154.1099 +  eg = e4;
154.1100 +  Adaptor::Edge ea = e1;
154.1101 +  ea = e2;
154.1102 +}
154.1103 +
154.1104 +void checkFilterEdges() {
154.1105 +  // Check concepts
154.1106 +  checkConcept<concepts::Graph, FilterEdges<concepts::Graph> >();
154.1107 +  checkConcept<concepts::Graph, FilterEdges<ListGraph> >();
154.1108 +  checkConcept<concepts::AlterableGraphComponent<>,
154.1109 +               FilterEdges<ListGraph> >();
154.1110 +  checkConcept<concepts::ExtendableGraphComponent<>,
154.1111 +               FilterEdges<ListGraph> >();
154.1112 +  checkConcept<concepts::ErasableGraphComponent<>,
154.1113 +               FilterEdges<ListGraph> >();
154.1114 +  checkConcept<concepts::ClearableGraphComponent<>,
154.1115 +               FilterEdges<ListGraph> >();
154.1116 +
154.1117 +  // Create a graph and an adaptor
154.1118 +  typedef ListGraph Graph;
154.1119 +  typedef Graph::EdgeMap<bool> EdgeFilter;
154.1120 +  typedef FilterEdges<Graph, EdgeFilter> Adaptor;
154.1121 +
154.1122 +  Graph graph;
154.1123 +  EdgeFilter edge_filter(graph);
154.1124 +  Adaptor adaptor(graph, edge_filter);
154.1125 +
154.1126 +  // Add nodes and edges to the original graph and the adaptor
154.1127 +  Graph::Node n1 = graph.addNode();
154.1128 +  Graph::Node n2 = graph.addNode();
154.1129 +  Adaptor::Node n3 = adaptor.addNode();
154.1130 +  Adaptor::Node n4 = adaptor.addNode();
154.1131 +
154.1132 +  Graph::Edge e1 = graph.addEdge(n1, n2);
154.1133 +  Graph::Edge e2 = graph.addEdge(n1, n3);
154.1134 +  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
154.1135 +  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
154.1136 +
154.1137 +  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
154.1138 +
154.1139 +  checkGraphNodeList(adaptor, 4);
154.1140 +  checkGraphArcList(adaptor, 8);
154.1141 +  checkGraphEdgeList(adaptor, 4);
154.1142 +  checkGraphConArcList(adaptor, 8);
154.1143 +  checkGraphConEdgeList(adaptor, 4);
154.1144 +
154.1145 +  checkGraphIncEdgeArcLists(adaptor, n1, 2);
154.1146 +  checkGraphIncEdgeArcLists(adaptor, n2, 2);
154.1147 +  checkGraphIncEdgeArcLists(adaptor, n3, 3);
154.1148 +  checkGraphIncEdgeArcLists(adaptor, n4, 1);
154.1149 +
154.1150 +  checkNodeIds(adaptor);
154.1151 +  checkArcIds(adaptor);
154.1152 +  checkEdgeIds(adaptor);
154.1153 +
154.1154 +  checkGraphNodeMap(adaptor);
154.1155 +  checkGraphArcMap(adaptor);
154.1156 +  checkGraphEdgeMap(adaptor);
154.1157 +
154.1158 +  // Hide an edge
154.1159 +  adaptor.status(e2, false);
154.1160 +  adaptor.disable(e3);
154.1161 +  if (!adaptor.status(e3)) adaptor.enable(e3);
154.1162 +
154.1163 +  checkGraphNodeList(adaptor, 4);
154.1164 +  checkGraphArcList(adaptor, 6);
154.1165 +  checkGraphEdgeList(adaptor, 3);
154.1166 +  checkGraphConArcList(adaptor, 6);
154.1167 +  checkGraphConEdgeList(adaptor, 3);
154.1168 +
154.1169 +  checkGraphIncEdgeArcLists(adaptor, n1, 1);
154.1170 +  checkGraphIncEdgeArcLists(adaptor, n2, 2);
154.1171 +  checkGraphIncEdgeArcLists(adaptor, n3, 2);
154.1172 +  checkGraphIncEdgeArcLists(adaptor, n4, 1);
154.1173 +
154.1174 +  checkNodeIds(adaptor);
154.1175 +  checkArcIds(adaptor);
154.1176 +  checkEdgeIds(adaptor);
154.1177 +
154.1178 +  checkGraphNodeMap(adaptor);
154.1179 +  checkGraphArcMap(adaptor);
154.1180 +  checkGraphEdgeMap(adaptor);
154.1181 +
154.1182 +  // Hide all edges
154.1183 +  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
154.1184 +
154.1185 +  checkGraphNodeList(adaptor, 4);
154.1186 +  checkGraphArcList(adaptor, 0);
154.1187 +  checkGraphEdgeList(adaptor, 0);
154.1188 +  checkGraphConArcList(adaptor, 0);
154.1189 +  checkGraphConEdgeList(adaptor, 0);
154.1190 +
154.1191 +  checkNodeIds(adaptor);
154.1192 +  checkArcIds(adaptor);
154.1193 +  checkEdgeIds(adaptor);
154.1194 +
154.1195 +  checkGraphNodeMap(adaptor);
154.1196 +  checkGraphArcMap(adaptor);
154.1197 +  checkGraphEdgeMap(adaptor);
154.1198 +
154.1199 +  // Check the conversion of nodes and edges
154.1200 +  Graph::Node ng = n3;
154.1201 +  ng = n4;
154.1202 +  Adaptor::Node na = n1;
154.1203 +  na = n2;
154.1204 +  Graph::Edge eg = e3;
154.1205 +  eg = e4;
154.1206 +  Adaptor::Edge ea = e1;
154.1207 +  ea = e2;
154.1208 +}
154.1209 +
154.1210 +void checkOrienter() {
154.1211 +  // Check concepts
154.1212 +  checkConcept<concepts::Digraph, Orienter<concepts::Graph> >();
154.1213 +  checkConcept<concepts::Digraph, Orienter<ListGraph> >();
154.1214 +  checkConcept<concepts::AlterableDigraphComponent<>,
154.1215 +               Orienter<ListGraph> >();
154.1216 +  checkConcept<concepts::ExtendableDigraphComponent<>,
154.1217 +               Orienter<ListGraph> >();
154.1218 +  checkConcept<concepts::ErasableDigraphComponent<>,
154.1219 +               Orienter<ListGraph> >();
154.1220 +  checkConcept<concepts::ClearableDigraphComponent<>,
154.1221 +               Orienter<ListGraph> >();
154.1222 +
154.1223 +  // Create a graph and an adaptor
154.1224 +  typedef ListGraph Graph;
154.1225 +  typedef ListGraph::EdgeMap<bool> DirMap;
154.1226 +  typedef Orienter<Graph> Adaptor;
154.1227 +
154.1228 +  Graph graph;
154.1229 +  DirMap dir(graph);
154.1230 +  Adaptor adaptor(graph, dir);
154.1231 +
154.1232 +  // Add nodes and edges to the original graph and the adaptor
154.1233 +  Graph::Node n1 = graph.addNode();
154.1234 +  Graph::Node n2 = graph.addNode();
154.1235 +  Adaptor::Node n3 = adaptor.addNode();
154.1236 +
154.1237 +  Graph::Edge e1 = graph.addEdge(n1, n2);
154.1238 +  Graph::Edge e2 = graph.addEdge(n1, n3);
154.1239 +  Adaptor::Arc e3 = adaptor.addArc(n2, n3);
154.1240 +
154.1241 +  dir[e1] = dir[e2] = dir[e3] = true;
154.1242 +
154.1243 +  // Check the original graph
154.1244 +  checkGraphNodeList(graph, 3);
154.1245 +  checkGraphArcList(graph, 6);
154.1246 +  checkGraphConArcList(graph, 6);
154.1247 +  checkGraphEdgeList(graph, 3);
154.1248 +  checkGraphConEdgeList(graph, 3);
154.1249 +
154.1250 +  checkGraphIncEdgeArcLists(graph, n1, 2);
154.1251 +  checkGraphIncEdgeArcLists(graph, n2, 2);
154.1252 +  checkGraphIncEdgeArcLists(graph, n3, 2);
154.1253 +
154.1254 +  checkNodeIds(graph);
154.1255 +  checkArcIds(graph);
154.1256 +  checkEdgeIds(graph);
154.1257 +
154.1258 +  checkGraphNodeMap(graph);
154.1259 +  checkGraphArcMap(graph);
154.1260 +  checkGraphEdgeMap(graph);
154.1261 +
154.1262 +  // Check the adaptor
154.1263 +  checkGraphNodeList(adaptor, 3);
154.1264 +  checkGraphArcList(adaptor, 3);
154.1265 +  checkGraphConArcList(adaptor, 3);
154.1266 +
154.1267 +  checkGraphOutArcList(adaptor, n1, 2);
154.1268 +  checkGraphOutArcList(adaptor, n2, 1);
154.1269 +  checkGraphOutArcList(adaptor, n3, 0);
154.1270 +
154.1271 +  checkGraphInArcList(adaptor, n1, 0);
154.1272 +  checkGraphInArcList(adaptor, n2, 1);
154.1273 +  checkGraphInArcList(adaptor, n3, 2);
154.1274 +
154.1275 +  checkNodeIds(adaptor);
154.1276 +  checkArcIds(adaptor);
154.1277 +
154.1278 +  checkGraphNodeMap(adaptor);
154.1279 +  checkGraphArcMap(adaptor);
154.1280 +
154.1281 +  // Check direction changing
154.1282 +  {
154.1283 +    dir[e1] = true;
154.1284 +    Adaptor::Node u = adaptor.source(e1);
154.1285 +    Adaptor::Node v = adaptor.target(e1);
154.1286 +
154.1287 +    dir[e1] = false;
154.1288 +    check (u == adaptor.target(e1), "Wrong dir");
154.1289 +    check (v == adaptor.source(e1), "Wrong dir");
154.1290 +
154.1291 +    check ((u == n1 && v == n2) || (u == n2 && v == n1), "Wrong dir");
154.1292 +    dir[e1] = n1 == u;
154.1293 +  }
154.1294 +
154.1295 +  {
154.1296 +    dir[e2] = true;
154.1297 +    Adaptor::Node u = adaptor.source(e2);
154.1298 +    Adaptor::Node v = adaptor.target(e2);
154.1299 +
154.1300 +    dir[e2] = false;
154.1301 +    check (u == adaptor.target(e2), "Wrong dir");
154.1302 +    check (v == adaptor.source(e2), "Wrong dir");
154.1303 +
154.1304 +    check ((u == n1 && v == n3) || (u == n3 && v == n1), "Wrong dir");
154.1305 +    dir[e2] = n3 == u;
154.1306 +  }
154.1307 +
154.1308 +  {
154.1309 +    dir[e3] = true;
154.1310 +    Adaptor::Node u = adaptor.source(e3);
154.1311 +    Adaptor::Node v = adaptor.target(e3);
154.1312 +
154.1313 +    dir[e3] = false;
154.1314 +    check (u == adaptor.target(e3), "Wrong dir");
154.1315 +    check (v == adaptor.source(e3), "Wrong dir");
154.1316 +
154.1317 +    check ((u == n2 && v == n3) || (u == n3 && v == n2), "Wrong dir");
154.1318 +    dir[e3] = n2 == u;
154.1319 +  }
154.1320 +
154.1321 +  // Check the adaptor again
154.1322 +  checkGraphNodeList(adaptor, 3);
154.1323 +  checkGraphArcList(adaptor, 3);
154.1324 +  checkGraphConArcList(adaptor, 3);
154.1325 +
154.1326 +  checkGraphOutArcList(adaptor, n1, 1);
154.1327 +  checkGraphOutArcList(adaptor, n2, 1);
154.1328 +  checkGraphOutArcList(adaptor, n3, 1);
154.1329 +
154.1330 +  checkGraphInArcList(adaptor, n1, 1);
154.1331 +  checkGraphInArcList(adaptor, n2, 1);
154.1332 +  checkGraphInArcList(adaptor, n3, 1);
154.1333 +
154.1334 +  checkNodeIds(adaptor);
154.1335 +  checkArcIds(adaptor);
154.1336 +
154.1337 +  checkGraphNodeMap(adaptor);
154.1338 +  checkGraphArcMap(adaptor);
154.1339 +
154.1340 +  // Check reverseArc()
154.1341 +  adaptor.reverseArc(e2);
154.1342 +  adaptor.reverseArc(e3);
154.1343 +  adaptor.reverseArc(e2);
154.1344 +
154.1345 +  checkGraphNodeList(adaptor, 3);
154.1346 +  checkGraphArcList(adaptor, 3);
154.1347 +  checkGraphConArcList(adaptor, 3);
154.1348 +
154.1349 +  checkGraphOutArcList(adaptor, n1, 1);
154.1350 +  checkGraphOutArcList(adaptor, n2, 0);
154.1351 +  checkGraphOutArcList(adaptor, n3, 2);
154.1352 +
154.1353 +  checkGraphInArcList(adaptor, n1, 1);
154.1354 +  checkGraphInArcList(adaptor, n2, 2);
154.1355 +  checkGraphInArcList(adaptor, n3, 0);
154.1356 +
154.1357 +  // Check the conversion of nodes and arcs/edges
154.1358 +  Graph::Node ng = n3;
154.1359 +  ng = n3;
154.1360 +  Adaptor::Node na = n1;
154.1361 +  na = n2;
154.1362 +  Graph::Edge eg = e3;
154.1363 +  eg = e3;
154.1364 +  Adaptor::Arc aa = e1;
154.1365 +  aa = e2;
154.1366 +}
154.1367 +
154.1368 +void checkCombiningAdaptors() {
154.1369 +  // Create a grid graph
154.1370 +  GridGraph graph(2,2);
154.1371 +  GridGraph::Node n1 = graph(0,0);
154.1372 +  GridGraph::Node n2 = graph(0,1);
154.1373 +  GridGraph::Node n3 = graph(1,0);
154.1374 +  GridGraph::Node n4 = graph(1,1);
154.1375 +
154.1376 +  GridGraph::EdgeMap<bool> dir_map(graph);
154.1377 +  dir_map[graph.right(n1)] = graph.u(graph.right(n1)) != n1;
154.1378 +  dir_map[graph.up(n1)] = graph.u(graph.up(n1)) == n1;
154.1379 +  dir_map[graph.left(n4)] = graph.u(graph.left(n4)) == n4;
154.1380 +  dir_map[graph.down(n4)] = graph.u(graph.down(n4)) == n4;
154.1381 +
154.1382 +  // Apply several adaptors on the grid graph
154.1383 +  typedef SplitNodes<Orienter< const GridGraph, GridGraph::EdgeMap<bool> > >
154.1384 +    SplitGridGraph;
154.1385 +  typedef Undirector<const SplitGridGraph> USplitGridGraph;
154.1386 +  checkConcept<concepts::Digraph, SplitGridGraph>();
154.1387 +  checkConcept<concepts::Graph, USplitGridGraph>();
154.1388 +
154.1389 +  SplitGridGraph adaptor = splitNodes(orienter(graph, dir_map));
154.1390 +  USplitGridGraph uadaptor = undirector(adaptor);
154.1391 +
154.1392 +  // Check adaptor
154.1393 +  checkGraphNodeList(adaptor, 8);
154.1394 +  checkGraphArcList(adaptor, 8);
154.1395 +  checkGraphConArcList(adaptor, 8);
154.1396 +
154.1397 +  checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
154.1398 +  checkGraphOutArcList(adaptor, adaptor.outNode(n1), 1);
154.1399 +  checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
154.1400 +  checkGraphOutArcList(adaptor, adaptor.outNode(n2), 0);
154.1401 +  checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
154.1402 +  checkGraphOutArcList(adaptor, adaptor.outNode(n3), 1);
154.1403 +  checkGraphOutArcList(adaptor, adaptor.inNode(n4), 1);
154.1404 +  checkGraphOutArcList(adaptor, adaptor.outNode(n4), 2);
154.1405 +
154.1406 +  checkGraphInArcList(adaptor, adaptor.inNode(n1), 1);
154.1407 +  checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
154.1408 +  checkGraphInArcList(adaptor, adaptor.inNode(n2), 2);
154.1409 +  checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
154.1410 +  checkGraphInArcList(adaptor, adaptor.inNode(n3), 1);
154.1411 +  checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
154.1412 +  checkGraphInArcList(adaptor, adaptor.inNode(n4), 0);
154.1413 +  checkGraphInArcList(adaptor, adaptor.outNode(n4), 1);
154.1414 +
154.1415 +  checkNodeIds(adaptor);
154.1416 +  checkArcIds(adaptor);
154.1417 +
154.1418 +  checkGraphNodeMap(adaptor);
154.1419 +  checkGraphArcMap(adaptor);
154.1420 +
154.1421 +  // Check uadaptor
154.1422 +  checkGraphNodeList(uadaptor, 8);
154.1423 +  checkGraphEdgeList(uadaptor, 8);
154.1424 +  checkGraphArcList(uadaptor, 16);
154.1425 +  checkGraphConEdgeList(uadaptor, 8);
154.1426 +  checkGraphConArcList(uadaptor, 16);
154.1427 +
154.1428 +  checkNodeIds(uadaptor);
154.1429 +  checkEdgeIds(uadaptor);
154.1430 +  checkArcIds(uadaptor);
154.1431 +
154.1432 +  checkGraphNodeMap(uadaptor);
154.1433 +  checkGraphEdgeMap(uadaptor);
154.1434 +  checkGraphArcMap(uadaptor);
154.1435 +
154.1436 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n1), 2);
154.1437 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n1), 2);
154.1438 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n2), 3);
154.1439 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n2), 1);
154.1440 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n3), 2);
154.1441 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n3), 2);
154.1442 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n4), 1);
154.1443 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n4), 3);
154.1444 +}
154.1445 +
154.1446 +int main(int, const char **) {
154.1447 +  // Check the digraph adaptors (using ListDigraph)
154.1448 +  checkReverseDigraph();
154.1449 +  checkSubDigraph();
154.1450 +  checkFilterNodes1();
154.1451 +  checkFilterArcs();
154.1452 +  checkUndirector();
154.1453 +  checkResidualDigraph();
154.1454 +  checkSplitNodes();
154.1455 +
154.1456 +  // Check the graph adaptors (using ListGraph)
154.1457 +  checkSubGraph();
154.1458 +  checkFilterNodes2();
154.1459 +  checkFilterEdges();
154.1460 +  checkOrienter();
154.1461 +
154.1462 +  // Combine adaptors (using GridGraph)
154.1463 +  checkCombiningAdaptors();
154.1464 +
154.1465 +  return 0;
154.1466 +}
   155.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   155.2 +++ b/test/bellman_ford_test.cc	Thu Nov 05 15:50:01 2009 +0100
   155.3 @@ -0,0 +1,285 @@
   155.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   155.5 + *
   155.6 + * This file is a part of LEMON, a generic C++ optimization library.
   155.7 + *
   155.8 + * Copyright (C) 2003-2009
   155.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  155.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  155.11 + *
  155.12 + * Permission to use, modify and distribute this software is granted
  155.13 + * provided that this copyright notice appears in all copies. For
  155.14 + * precise terms see the accompanying LICENSE file.
  155.15 + *
  155.16 + * This software is provided "AS IS" with no warranty of any kind,
  155.17 + * express or implied, and with no claim as to its suitability for any
  155.18 + * purpose.
  155.19 + *
  155.20 + */
  155.21 +
  155.22 +#include <lemon/concepts/digraph.h>
  155.23 +#include <lemon/smart_graph.h>
  155.24 +#include <lemon/list_graph.h>
  155.25 +#include <lemon/lgf_reader.h>
  155.26 +#include <lemon/bellman_ford.h>
  155.27 +#include <lemon/path.h>
  155.28 +
  155.29 +#include "graph_test.h"
  155.30 +#include "test_tools.h"
  155.31 +
  155.32 +using namespace lemon;
  155.33 +
  155.34 +char test_lgf[] =
  155.35 +  "@nodes\n"
  155.36 +  "label\n"
  155.37 +  "0\n"
  155.38 +  "1\n"
  155.39 +  "2\n"
  155.40 +  "3\n"
  155.41 +  "4\n"
  155.42 +  "@arcs\n"
  155.43 +  "    length\n"
  155.44 +  "0 1 3\n"
  155.45 +  "1 2 -3\n"
  155.46 +  "1 2 -5\n"
  155.47 +  "1 3 -2\n"
  155.48 +  "0 2 -1\n"
  155.49 +  "1 2 -4\n"
  155.50 +  "0 3 2\n"
  155.51 +  "4 2 -5\n"
  155.52 +  "2 3 1\n"
  155.53 +  "@attributes\n"
  155.54 +  "source 0\n"
  155.55 +  "target 3\n";
  155.56 +
  155.57 +
  155.58 +void checkBellmanFordCompile()
  155.59 +{
  155.60 +  typedef int Value;
  155.61 +  typedef concepts::Digraph Digraph;
  155.62 +  typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
  155.63 +  typedef BellmanFord<Digraph, LengthMap> BF;
  155.64 +  typedef Digraph::Node Node;
  155.65 +  typedef Digraph::Arc Arc;
  155.66 +
  155.67 +  Digraph gr;
  155.68 +  Node s, t, n;
  155.69 +  Arc e;
  155.70 +  Value l;
  155.71 +  int k;
  155.72 +  bool b;
  155.73 +  BF::DistMap d(gr);
  155.74 +  BF::PredMap p(gr);
  155.75 +  LengthMap length;
  155.76 +  concepts::Path<Digraph> pp;
  155.77 +
  155.78 +  {
  155.79 +    BF bf_test(gr,length);
  155.80 +    const BF& const_bf_test = bf_test;
  155.81 +
  155.82 +    bf_test.run(s);
  155.83 +    bf_test.run(s,k);
  155.84 +
  155.85 +    bf_test.init();
  155.86 +    bf_test.addSource(s);
  155.87 +    bf_test.addSource(s, 1);
  155.88 +    b = bf_test.processNextRound();
  155.89 +    b = bf_test.processNextWeakRound();
  155.90 +
  155.91 +    bf_test.start();
  155.92 +    bf_test.checkedStart();
  155.93 +    bf_test.limitedStart(k);
  155.94 +
  155.95 +    l  = const_bf_test.dist(t);
  155.96 +    e  = const_bf_test.predArc(t);
  155.97 +    s  = const_bf_test.predNode(t);
  155.98 +    b  = const_bf_test.reached(t);
  155.99 +    d  = const_bf_test.distMap();
 155.100 +    p  = const_bf_test.predMap();
 155.101 +    pp = const_bf_test.path(t);
 155.102 +    pp = const_bf_test.negativeCycle();
 155.103 +    
 155.104 +    for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {}
 155.105 +  }
 155.106 +  {
 155.107 +    BF::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
 155.108 +      ::SetDistMap<concepts::ReadWriteMap<Node,Value> >
 155.109 +      ::SetOperationTraits<BellmanFordDefaultOperationTraits<Value> >
 155.110 +      ::Create bf_test(gr,length);
 155.111 +
 155.112 +    LengthMap length_map;
 155.113 +    concepts::ReadWriteMap<Node,Arc> pred_map;
 155.114 +    concepts::ReadWriteMap<Node,Value> dist_map;
 155.115 +    
 155.116 +    bf_test
 155.117 +      .lengthMap(length_map)
 155.118 +      .predMap(pred_map)
 155.119 +      .distMap(dist_map);
 155.120 +
 155.121 +    bf_test.run(s);
 155.122 +    bf_test.run(s,k);
 155.123 +
 155.124 +    bf_test.init();
 155.125 +    bf_test.addSource(s);
 155.126 +    bf_test.addSource(s, 1);
 155.127 +    b = bf_test.processNextRound();
 155.128 +    b = bf_test.processNextWeakRound();
 155.129 +
 155.130 +    bf_test.start();
 155.131 +    bf_test.checkedStart();
 155.132 +    bf_test.limitedStart(k);
 155.133 +
 155.134 +    l  = bf_test.dist(t);
 155.135 +    e  = bf_test.predArc(t);
 155.136 +    s  = bf_test.predNode(t);
 155.137 +    b  = bf_test.reached(t);
 155.138 +    pp = bf_test.path(t);
 155.139 +    pp = bf_test.negativeCycle();
 155.140 +  }
 155.141 +}
 155.142 +
 155.143 +void checkBellmanFordFunctionCompile()
 155.144 +{
 155.145 +  typedef int Value;
 155.146 +  typedef concepts::Digraph Digraph;
 155.147 +  typedef Digraph::Arc Arc;
 155.148 +  typedef Digraph::Node Node;
 155.149 +  typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
 155.150 +
 155.151 +  Digraph g;
 155.152 +  bool b;
 155.153 +  bellmanFord(g,LengthMap()).run(Node());
 155.154 +  b = bellmanFord(g,LengthMap()).run(Node(),Node());
 155.155 +  bellmanFord(g,LengthMap())
 155.156 +    .predMap(concepts::ReadWriteMap<Node,Arc>())
 155.157 +    .distMap(concepts::ReadWriteMap<Node,Value>())
 155.158 +    .run(Node());
 155.159 +  b=bellmanFord(g,LengthMap())
 155.160 +    .predMap(concepts::ReadWriteMap<Node,Arc>())
 155.161 +    .distMap(concepts::ReadWriteMap<Node,Value>())
 155.162 +    .path(concepts::Path<Digraph>())
 155.163 +    .dist(Value())
 155.164 +    .run(Node(),Node());
 155.165 +}
 155.166 +
 155.167 +
 155.168 +template <typename Digraph, typename Value>
 155.169 +void checkBellmanFord() {
 155.170 +  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 155.171 +  typedef typename Digraph::template ArcMap<Value> LengthMap;
 155.172 +
 155.173 +  Digraph gr;
 155.174 +  Node s, t;
 155.175 +  LengthMap length(gr);
 155.176 +
 155.177 +  std::istringstream input(test_lgf);
 155.178 +  digraphReader(gr, input).
 155.179 +    arcMap("length", length).
 155.180 +    node("source", s).
 155.181 +    node("target", t).
 155.182 +    run();
 155.183 +
 155.184 +  BellmanFord<Digraph, LengthMap>
 155.185 +    bf(gr, length);
 155.186 +  bf.run(s);
 155.187 +  Path<Digraph> p = bf.path(t);
 155.188 +
 155.189 +  check(bf.reached(t) && bf.dist(t) == -1, "Bellman-Ford found a wrong path.");
 155.190 +  check(p.length() == 3, "path() found a wrong path.");
 155.191 +  check(checkPath(gr, p), "path() found a wrong path.");
 155.192 +  check(pathSource(gr, p) == s, "path() found a wrong path.");
 155.193 +  check(pathTarget(gr, p) == t, "path() found a wrong path.");
 155.194 +  
 155.195 +  ListPath<Digraph> path;
 155.196 +  Value dist;
 155.197 +  bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t);
 155.198 +
 155.199 +  check(reached && dist == -1, "Bellman-Ford found a wrong path.");
 155.200 +  check(path.length() == 3, "path() found a wrong path.");
 155.201 +  check(checkPath(gr, path), "path() found a wrong path.");
 155.202 +  check(pathSource(gr, path) == s, "path() found a wrong path.");
 155.203 +  check(pathTarget(gr, path) == t, "path() found a wrong path.");
 155.204 +
 155.205 +  for(ArcIt e(gr); e!=INVALID; ++e) {
 155.206 +    Node u=gr.source(e);
 155.207 +    Node v=gr.target(e);
 155.208 +    check(!bf.reached(u) || (bf.dist(v) - bf.dist(u) <= length[e]),
 155.209 +          "Wrong output. dist(target)-dist(source)-arc_length=" <<
 155.210 +          bf.dist(v) - bf.dist(u) - length[e]);
 155.211 +  }
 155.212 +
 155.213 +  for(NodeIt v(gr); v!=INVALID; ++v) {
 155.214 +    if (bf.reached(v)) {
 155.215 +      check(v==s || bf.predArc(v)!=INVALID, "Wrong tree.");
 155.216 +      if (bf.predArc(v)!=INVALID ) {
 155.217 +        Arc e=bf.predArc(v);
 155.218 +        Node u=gr.source(e);
 155.219 +        check(u==bf.predNode(v),"Wrong tree.");
 155.220 +        check(bf.dist(v) - bf.dist(u) == length[e],
 155.221 +              "Wrong distance! Difference: " <<
 155.222 +              bf.dist(v) - bf.dist(u) - length[e]);
 155.223 +      }
 155.224 +    }
 155.225 +  }
 155.226 +}
 155.227 +
 155.228 +void checkBellmanFordNegativeCycle() {
 155.229 +  DIGRAPH_TYPEDEFS(SmartDigraph);
 155.230 +
 155.231 +  SmartDigraph gr;
 155.232 +  IntArcMap length(gr);
 155.233 +  
 155.234 +  Node n1 = gr.addNode();
 155.235 +  Node n2 = gr.addNode();
 155.236 +  Node n3 = gr.addNode();
 155.237 +  Node n4 = gr.addNode();
 155.238 +  
 155.239 +  Arc a1 = gr.addArc(n1, n2);
 155.240 +  Arc a2 = gr.addArc(n2, n2);
 155.241 +  
 155.242 +  length[a1] = 2;
 155.243 +  length[a2] = -1;
 155.244 +  
 155.245 +  {
 155.246 +    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
 155.247 +    bf.run(n1);
 155.248 +    StaticPath<SmartDigraph> p = bf.negativeCycle();
 155.249 +    check(p.length() == 1 && p.front() == p.back() && p.front() == a2,
 155.250 +          "Wrong negative cycle.");
 155.251 +  }
 155.252 + 
 155.253 +  length[a2] = 0;
 155.254 +  
 155.255 +  {
 155.256 +    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
 155.257 +    bf.run(n1);
 155.258 +    check(bf.negativeCycle().empty(),
 155.259 +          "Negative cycle should not be found.");
 155.260 +  }
 155.261 +  
 155.262 +  length[gr.addArc(n1, n3)] = 5;
 155.263 +  length[gr.addArc(n4, n3)] = 1;
 155.264 +  length[gr.addArc(n2, n4)] = 2;
 155.265 +  length[gr.addArc(n3, n2)] = -4;
 155.266 +  
 155.267 +  {
 155.268 +    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
 155.269 +    bf.init();
 155.270 +    bf.addSource(n1);
 155.271 +    for (int i = 0; i < 4; ++i) {
 155.272 +      check(bf.negativeCycle().empty(),
 155.273 +            "Negative cycle should not be found.");
 155.274 +      bf.processNextRound();
 155.275 +    }
 155.276 +    StaticPath<SmartDigraph> p = bf.negativeCycle();
 155.277 +    check(p.length() == 3, "Wrong negative cycle.");
 155.278 +    check(length[p.nth(0)] + length[p.nth(1)] + length[p.nth(2)] == -1,
 155.279 +          "Wrong negative cycle.");
 155.280 +  }
 155.281 +}
 155.282 +
 155.283 +int main() {
 155.284 +  checkBellmanFord<ListDigraph, int>();
 155.285 +  checkBellmanFord<SmartDigraph, double>();
 155.286 +  checkBellmanFordNegativeCycle();
 155.287 +  return 0;
 155.288 +}
   156.1 --- a/test/bfs_test.cc	Fri Oct 16 10:21:37 2009 +0200
   156.2 +++ b/test/bfs_test.cc	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   156.8 + * Copyright (C) 2003-2009
   156.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  156.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  156.11   *
  156.12 @@ -58,41 +58,80 @@
  156.13    typedef Digraph::Arc Arc;
  156.14  
  156.15    Digraph G;
  156.16 -  Node s, t;
  156.17 +  Node s, t, n;
  156.18    Arc e;
  156.19 -  int l;
  156.20 +  int l, i;
  156.21    bool b;
  156.22    BType::DistMap d(G);
  156.23    BType::PredMap p(G);
  156.24    Path<Digraph> pp;
  156.25 +  concepts::ReadMap<Node,bool> nm;
  156.26  
  156.27    {
  156.28      BType bfs_test(G);
  156.29 +    const BType& const_bfs_test = bfs_test;
  156.30  
  156.31      bfs_test.run(s);
  156.32      bfs_test.run(s,t);
  156.33      bfs_test.run();
  156.34  
  156.35 -    l  = bfs_test.dist(t);
  156.36 -    e  = bfs_test.predArc(t);
  156.37 -    s  = bfs_test.predNode(t);
  156.38 -    b  = bfs_test.reached(t);
  156.39 -    d  = bfs_test.distMap();
  156.40 -    p  = bfs_test.predMap();
  156.41 -    pp = bfs_test.path(t);
  156.42 +    bfs_test.init();
  156.43 +    bfs_test.addSource(s);
  156.44 +    n = bfs_test.processNextNode();
  156.45 +    n = bfs_test.processNextNode(t, b);
  156.46 +    n = bfs_test.processNextNode(nm, n);
  156.47 +    n = const_bfs_test.nextNode();
  156.48 +    b = const_bfs_test.emptyQueue();
  156.49 +    i = const_bfs_test.queueSize();
  156.50 +    
  156.51 +    bfs_test.start();
  156.52 +    bfs_test.start(t);
  156.53 +    bfs_test.start(nm);
  156.54 +
  156.55 +    l  = const_bfs_test.dist(t);
  156.56 +    e  = const_bfs_test.predArc(t);
  156.57 +    s  = const_bfs_test.predNode(t);
  156.58 +    b  = const_bfs_test.reached(t);
  156.59 +    d  = const_bfs_test.distMap();
  156.60 +    p  = const_bfs_test.predMap();
  156.61 +    pp = const_bfs_test.path(t);
  156.62    }
  156.63    {
  156.64      BType
  156.65        ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
  156.66        ::SetDistMap<concepts::ReadWriteMap<Node,int> >
  156.67        ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
  156.68 +      ::SetStandardProcessedMap
  156.69        ::SetProcessedMap<concepts::WriteMap<Node,bool> >
  156.70 -      ::SetStandardProcessedMap
  156.71        ::Create bfs_test(G);
  156.72 +      
  156.73 +    concepts::ReadWriteMap<Node,Arc> pred_map;
  156.74 +    concepts::ReadWriteMap<Node,int> dist_map;
  156.75 +    concepts::ReadWriteMap<Node,bool> reached_map;
  156.76 +    concepts::WriteMap<Node,bool> processed_map;
  156.77 +    
  156.78 +    bfs_test
  156.79 +      .predMap(pred_map)
  156.80 +      .distMap(dist_map)
  156.81 +      .reachedMap(reached_map)
  156.82 +      .processedMap(processed_map);
  156.83  
  156.84      bfs_test.run(s);
  156.85      bfs_test.run(s,t);
  156.86      bfs_test.run();
  156.87 +    
  156.88 +    bfs_test.init();
  156.89 +    bfs_test.addSource(s);
  156.90 +    n = bfs_test.processNextNode();
  156.91 +    n = bfs_test.processNextNode(t, b);
  156.92 +    n = bfs_test.processNextNode(nm, n);
  156.93 +    n = bfs_test.nextNode();
  156.94 +    b = bfs_test.emptyQueue();
  156.95 +    i = bfs_test.queueSize();
  156.96 +    
  156.97 +    bfs_test.start();
  156.98 +    bfs_test.start(t);
  156.99 +    bfs_test.start(nm);
 156.100  
 156.101      l  = bfs_test.dist(t);
 156.102      e  = bfs_test.predArc(t);
   157.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   157.2 +++ b/test/circulation_test.cc	Thu Nov 05 15:50:01 2009 +0100
   157.3 @@ -0,0 +1,168 @@
   157.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   157.5 + *
   157.6 + * This file is a part of LEMON, a generic C++ optimization library.
   157.7 + *
   157.8 + * Copyright (C) 2003-2009
   157.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  157.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  157.11 + *
  157.12 + * Permission to use, modify and distribute this software is granted
  157.13 + * provided that this copyright notice appears in all copies. For
  157.14 + * precise terms see the accompanying LICENSE file.
  157.15 + *
  157.16 + * This software is provided "AS IS" with no warranty of any kind,
  157.17 + * express or implied, and with no claim as to its suitability for any
  157.18 + * purpose.
  157.19 + *
  157.20 + */
  157.21 +
  157.22 +#include <iostream>
  157.23 +
  157.24 +#include "test_tools.h"
  157.25 +#include <lemon/list_graph.h>
  157.26 +#include <lemon/circulation.h>
  157.27 +#include <lemon/lgf_reader.h>
  157.28 +#include <lemon/concepts/digraph.h>
  157.29 +#include <lemon/concepts/maps.h>
  157.30 +
  157.31 +using namespace lemon;
  157.32 +
  157.33 +char test_lgf[] =
  157.34 +  "@nodes\n"
  157.35 +  "label\n"
  157.36 +  "0\n"
  157.37 +  "1\n"
  157.38 +  "2\n"
  157.39 +  "3\n"
  157.40 +  "4\n"
  157.41 +  "5\n"
  157.42 +  "@arcs\n"
  157.43 +  "     lcap  ucap\n"
  157.44 +  "0 1  2  10\n"
  157.45 +  "0 2  2  6\n"
  157.46 +  "1 3  4  7\n"
  157.47 +  "1 4  0  5\n"
  157.48 +  "2 4  1  3\n"
  157.49 +  "3 5  3  8\n"
  157.50 +  "4 5  3  7\n"
  157.51 +  "@attributes\n"
  157.52 +  "source 0\n"
  157.53 +  "sink   5\n";
  157.54 +
  157.55 +void checkCirculationCompile()
  157.56 +{
  157.57 +  typedef int VType;
  157.58 +  typedef concepts::Digraph Digraph;
  157.59 +
  157.60 +  typedef Digraph::Node Node;
  157.61 +  typedef Digraph::Arc Arc;
  157.62 +  typedef concepts::ReadMap<Arc,VType> CapMap;
  157.63 +  typedef concepts::ReadMap<Node,VType> SupplyMap;
  157.64 +  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
  157.65 +  typedef concepts::WriteMap<Node,bool> BarrierMap;
  157.66 +
  157.67 +  typedef Elevator<Digraph, Digraph::Node> Elev;
  157.68 +  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
  157.69 +
  157.70 +  Digraph g;
  157.71 +  Node n;
  157.72 +  Arc a;
  157.73 +  CapMap lcap, ucap;
  157.74 +  SupplyMap supply;
  157.75 +  FlowMap flow;
  157.76 +  BarrierMap bar;
  157.77 +  VType v;
  157.78 +  bool b;
  157.79 +
  157.80 +  typedef Circulation<Digraph, CapMap, CapMap, SupplyMap>
  157.81 +            ::SetFlowMap<FlowMap>
  157.82 +            ::SetElevator<Elev>
  157.83 +            ::SetStandardElevator<LinkedElev>
  157.84 +            ::Create CirculationType;
  157.85 +  CirculationType circ_test(g, lcap, ucap, supply);
  157.86 +  const CirculationType& const_circ_test = circ_test;
  157.87 +   
  157.88 +  circ_test
  157.89 +    .lowerMap(lcap)
  157.90 +    .upperMap(ucap)
  157.91 +    .supplyMap(supply)
  157.92 +    .flowMap(flow);
  157.93 +  
  157.94 +  const CirculationType::Elevator& elev = const_circ_test.elevator();
  157.95 +  circ_test.elevator(const_cast<CirculationType::Elevator&>(elev));
  157.96 +  CirculationType::Tolerance tol = const_circ_test.tolerance();
  157.97 +  circ_test.tolerance(tol);
  157.98 +
  157.99 +  circ_test.init();
 157.100 +  circ_test.greedyInit();
 157.101 +  circ_test.start();
 157.102 +  circ_test.run();
 157.103 +
 157.104 +  v = const_circ_test.flow(a);
 157.105 +  const FlowMap& fm = const_circ_test.flowMap();
 157.106 +  b = const_circ_test.barrier(n);
 157.107 +  const_circ_test.barrierMap(bar);
 157.108 +  
 157.109 +  ignore_unused_variable_warning(fm);
 157.110 +}
 157.111 +
 157.112 +template <class G, class LM, class UM, class DM>
 157.113 +void checkCirculation(const G& g, const LM& lm, const UM& um,
 157.114 +                      const DM& dm, bool find)
 157.115 +{
 157.116 +  Circulation<G, LM, UM, DM> circ(g, lm, um, dm);
 157.117 +  bool ret = circ.run();
 157.118 +  if (find) {
 157.119 +    check(ret, "A feasible solution should have been found.");
 157.120 +    check(circ.checkFlow(), "The found flow is corrupt.");
 157.121 +    check(!circ.checkBarrier(), "A barrier should not have been found.");
 157.122 +  } else {
 157.123 +    check(!ret, "A feasible solution should not have been found.");
 157.124 +    check(circ.checkBarrier(), "The found barrier is corrupt.");
 157.125 +  }
 157.126 +}
 157.127 +
 157.128 +int main (int, char*[])
 157.129 +{
 157.130 +  typedef ListDigraph Digraph;
 157.131 +  DIGRAPH_TYPEDEFS(Digraph);
 157.132 +
 157.133 +  Digraph g;
 157.134 +  IntArcMap lo(g), up(g);
 157.135 +  IntNodeMap delta(g, 0);
 157.136 +  Node s, t;
 157.137 +
 157.138 +  std::istringstream input(test_lgf);
 157.139 +  DigraphReader<Digraph>(g,input).
 157.140 +    arcMap("lcap", lo).
 157.141 +    arcMap("ucap", up).
 157.142 +    node("source",s).
 157.143 +    node("sink",t).
 157.144 +    run();
 157.145 +
 157.146 +  delta[s] = 7; delta[t] = -7;
 157.147 +  checkCirculation(g, lo, up, delta, true);
 157.148 +
 157.149 +  delta[s] = 13; delta[t] = -13;
 157.150 +  checkCirculation(g, lo, up, delta, true);
 157.151 +
 157.152 +  delta[s] = 6; delta[t] = -6;
 157.153 +  checkCirculation(g, lo, up, delta, false);
 157.154 +
 157.155 +  delta[s] = 14; delta[t] = -14;
 157.156 +  checkCirculation(g, lo, up, delta, false);
 157.157 +
 157.158 +  delta[s] = 7; delta[t] = -13;
 157.159 +  checkCirculation(g, lo, up, delta, true);
 157.160 +
 157.161 +  delta[s] = 5; delta[t] = -15;
 157.162 +  checkCirculation(g, lo, up, delta, true);
 157.163 +
 157.164 +  delta[s] = 10; delta[t] = -11;
 157.165 +  checkCirculation(g, lo, up, delta, true);
 157.166 +
 157.167 +  delta[s] = 11; delta[t] = -10;
 157.168 +  checkCirculation(g, lo, up, delta, false);
 157.169 +
 157.170 +  return 0;
 157.171 +}
   158.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   158.2 +++ b/test/connectivity_test.cc	Thu Nov 05 15:50:01 2009 +0100
   158.3 @@ -0,0 +1,297 @@
   158.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   158.5 + *
   158.6 + * This file is a part of LEMON, a generic C++ optimization library.
   158.7 + *
   158.8 + * Copyright (C) 2003-2009
   158.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  158.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  158.11 + *
  158.12 + * Permission to use, modify and distribute this software is granted
  158.13 + * provided that this copyright notice appears in all copies. For
  158.14 + * precise terms see the accompanying LICENSE file.
  158.15 + *
  158.16 + * This software is provided "AS IS" with no warranty of any kind,
  158.17 + * express or implied, and with no claim as to its suitability for any
  158.18 + * purpose.
  158.19 + *
  158.20 + */
  158.21 +
  158.22 +#include <lemon/connectivity.h>
  158.23 +#include <lemon/list_graph.h>
  158.24 +#include <lemon/adaptors.h>
  158.25 +
  158.26 +#include "test_tools.h"
  158.27 +
  158.28 +using namespace lemon;
  158.29 +
  158.30 +
  158.31 +int main()
  158.32 +{
  158.33 +  typedef ListDigraph Digraph;
  158.34 +  typedef Undirector<Digraph> Graph;
  158.35 +  
  158.36 +  {
  158.37 +    Digraph d;
  158.38 +    Digraph::NodeMap<int> order(d);
  158.39 +    Graph g(d);
  158.40 +    
  158.41 +    check(stronglyConnected(d), "The empty digraph is strongly connected");
  158.42 +    check(countStronglyConnectedComponents(d) == 0,
  158.43 +          "The empty digraph has 0 strongly connected component");
  158.44 +    check(connected(g), "The empty graph is connected");
  158.45 +    check(countConnectedComponents(g) == 0,
  158.46 +          "The empty graph has 0 connected component");
  158.47 +
  158.48 +    check(biNodeConnected(g), "The empty graph is bi-node-connected");
  158.49 +    check(countBiNodeConnectedComponents(g) == 0,
  158.50 +          "The empty graph has 0 bi-node-connected component");
  158.51 +    check(biEdgeConnected(g), "The empty graph is bi-edge-connected");
  158.52 +    check(countBiEdgeConnectedComponents(g) == 0,
  158.53 +          "The empty graph has 0 bi-edge-connected component");
  158.54 +          
  158.55 +    check(dag(d), "The empty digraph is DAG.");
  158.56 +    check(checkedTopologicalSort(d, order), "The empty digraph is DAG.");
  158.57 +    check(loopFree(d), "The empty digraph is loop-free.");
  158.58 +    check(parallelFree(d), "The empty digraph is parallel-free.");
  158.59 +    check(simpleGraph(d), "The empty digraph is simple.");
  158.60 +
  158.61 +    check(acyclic(g), "The empty graph is acyclic.");
  158.62 +    check(tree(g), "The empty graph is tree.");
  158.63 +    check(bipartite(g), "The empty graph is bipartite.");
  158.64 +    check(loopFree(g), "The empty graph is loop-free.");
  158.65 +    check(parallelFree(g), "The empty graph is parallel-free.");
  158.66 +    check(simpleGraph(g), "The empty graph is simple.");
  158.67 +  }
  158.68 +
  158.69 +  {
  158.70 +    Digraph d;
  158.71 +    Digraph::NodeMap<int> order(d);
  158.72 +    Graph g(d);
  158.73 +    Digraph::Node n = d.addNode();
  158.74 +
  158.75 +    check(stronglyConnected(d), "This digraph is strongly connected");
  158.76 +    check(countStronglyConnectedComponents(d) == 1,
  158.77 +          "This digraph has 1 strongly connected component");
  158.78 +    check(connected(g), "This graph is connected");
  158.79 +    check(countConnectedComponents(g) == 1,
  158.80 +          "This graph has 1 connected component");
  158.81 +
  158.82 +    check(biNodeConnected(g), "This graph is bi-node-connected");
  158.83 +    check(countBiNodeConnectedComponents(g) == 0,
  158.84 +          "This graph has 0 bi-node-connected component");
  158.85 +    check(biEdgeConnected(g), "This graph is bi-edge-connected");
  158.86 +    check(countBiEdgeConnectedComponents(g) == 1,
  158.87 +          "This graph has 1 bi-edge-connected component");
  158.88 +          
  158.89 +    check(dag(d), "This digraph is DAG.");
  158.90 +    check(checkedTopologicalSort(d, order), "This digraph is DAG.");
  158.91 +    check(loopFree(d), "This digraph is loop-free.");
  158.92 +    check(parallelFree(d), "This digraph is parallel-free.");
  158.93 +    check(simpleGraph(d), "This digraph is simple.");
  158.94 +
  158.95 +    check(acyclic(g), "This graph is acyclic.");
  158.96 +    check(tree(g), "This graph is tree.");
  158.97 +    check(bipartite(g), "This graph is bipartite.");
  158.98 +    check(loopFree(g), "This graph is loop-free.");
  158.99 +    check(parallelFree(g), "This graph is parallel-free.");
 158.100 +    check(simpleGraph(g), "This graph is simple.");
 158.101 +  }
 158.102 +
 158.103 +  {
 158.104 +    Digraph d;
 158.105 +    Digraph::NodeMap<int> order(d);
 158.106 +    Graph g(d);
 158.107 +    
 158.108 +    Digraph::Node n1 = d.addNode();
 158.109 +    Digraph::Node n2 = d.addNode();
 158.110 +    Digraph::Node n3 = d.addNode();
 158.111 +    Digraph::Node n4 = d.addNode();
 158.112 +    Digraph::Node n5 = d.addNode();
 158.113 +    Digraph::Node n6 = d.addNode();
 158.114 +    
 158.115 +    d.addArc(n1, n3);
 158.116 +    d.addArc(n3, n2);
 158.117 +    d.addArc(n2, n1);
 158.118 +    d.addArc(n4, n2);
 158.119 +    d.addArc(n4, n3);
 158.120 +    d.addArc(n5, n6);
 158.121 +    d.addArc(n6, n5);
 158.122 +
 158.123 +    check(!stronglyConnected(d), "This digraph is not strongly connected");
 158.124 +    check(countStronglyConnectedComponents(d) == 3,
 158.125 +          "This digraph has 3 strongly connected components");
 158.126 +    check(!connected(g), "This graph is not connected");
 158.127 +    check(countConnectedComponents(g) == 2,
 158.128 +          "This graph has 2 connected components");
 158.129 +
 158.130 +    check(!dag(d), "This digraph is not DAG.");
 158.131 +    check(!checkedTopologicalSort(d, order), "This digraph is not DAG.");
 158.132 +    check(loopFree(d), "This digraph is loop-free.");
 158.133 +    check(parallelFree(d), "This digraph is parallel-free.");
 158.134 +    check(simpleGraph(d), "This digraph is simple.");
 158.135 +
 158.136 +    check(!acyclic(g), "This graph is not acyclic.");
 158.137 +    check(!tree(g), "This graph is not tree.");
 158.138 +    check(!bipartite(g), "This graph is not bipartite.");
 158.139 +    check(loopFree(g), "This graph is loop-free.");
 158.140 +    check(!parallelFree(g), "This graph is not parallel-free.");
 158.141 +    check(!simpleGraph(g), "This graph is not simple.");
 158.142 +    
 158.143 +    d.addArc(n3, n3);
 158.144 +    
 158.145 +    check(!loopFree(d), "This digraph is not loop-free.");
 158.146 +    check(!loopFree(g), "This graph is not loop-free.");
 158.147 +    check(!simpleGraph(d), "This digraph is not simple.");
 158.148 +    
 158.149 +    d.addArc(n3, n2);
 158.150 +    
 158.151 +    check(!parallelFree(d), "This digraph is not parallel-free.");
 158.152 +  }
 158.153 +  
 158.154 +  {
 158.155 +    Digraph d;
 158.156 +    Digraph::ArcMap<bool> cutarcs(d, false);
 158.157 +    Graph g(d);
 158.158 +    
 158.159 +    Digraph::Node n1 = d.addNode();
 158.160 +    Digraph::Node n2 = d.addNode();
 158.161 +    Digraph::Node n3 = d.addNode();
 158.162 +    Digraph::Node n4 = d.addNode();
 158.163 +    Digraph::Node n5 = d.addNode();
 158.164 +    Digraph::Node n6 = d.addNode();
 158.165 +    Digraph::Node n7 = d.addNode();
 158.166 +    Digraph::Node n8 = d.addNode();
 158.167 +
 158.168 +    d.addArc(n1, n2);
 158.169 +    d.addArc(n5, n1);
 158.170 +    d.addArc(n2, n8);
 158.171 +    d.addArc(n8, n5);
 158.172 +    d.addArc(n6, n4);
 158.173 +    d.addArc(n4, n6);
 158.174 +    d.addArc(n2, n5);
 158.175 +    d.addArc(n1, n8);
 158.176 +    d.addArc(n6, n7);
 158.177 +    d.addArc(n7, n6);
 158.178 +   
 158.179 +    check(!stronglyConnected(d), "This digraph is not strongly connected");
 158.180 +    check(countStronglyConnectedComponents(d) == 3,
 158.181 +          "This digraph has 3 strongly connected components");
 158.182 +    Digraph::NodeMap<int> scomp1(d);
 158.183 +    check(stronglyConnectedComponents(d, scomp1) == 3,
 158.184 +          "This digraph has 3 strongly connected components");
 158.185 +    check(scomp1[n1] != scomp1[n3] && scomp1[n1] != scomp1[n4] &&
 158.186 +          scomp1[n3] != scomp1[n4], "Wrong stronglyConnectedComponents()");
 158.187 +    check(scomp1[n1] == scomp1[n2] && scomp1[n1] == scomp1[n5] &&
 158.188 +          scomp1[n1] == scomp1[n8], "Wrong stronglyConnectedComponents()");
 158.189 +    check(scomp1[n4] == scomp1[n6] && scomp1[n4] == scomp1[n7],
 158.190 +          "Wrong stronglyConnectedComponents()");
 158.191 +    Digraph::ArcMap<bool> scut1(d, false);
 158.192 +    check(stronglyConnectedCutArcs(d, scut1) == 0,
 158.193 +          "This digraph has 0 strongly connected cut arc.");
 158.194 +    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
 158.195 +      check(!scut1[a], "Wrong stronglyConnectedCutArcs()");
 158.196 +    }
 158.197 +
 158.198 +    check(!connected(g), "This graph is not connected");
 158.199 +    check(countConnectedComponents(g) == 3,
 158.200 +          "This graph has 3 connected components");
 158.201 +    Graph::NodeMap<int> comp(g);
 158.202 +    check(connectedComponents(g, comp) == 3,
 158.203 +          "This graph has 3 connected components");
 158.204 +    check(comp[n1] != comp[n3] && comp[n1] != comp[n4] &&
 158.205 +          comp[n3] != comp[n4], "Wrong connectedComponents()");
 158.206 +    check(comp[n1] == comp[n2] && comp[n1] == comp[n5] &&
 158.207 +          comp[n1] == comp[n8], "Wrong connectedComponents()");
 158.208 +    check(comp[n4] == comp[n6] && comp[n4] == comp[n7],
 158.209 +          "Wrong connectedComponents()");
 158.210 +
 158.211 +    cutarcs[d.addArc(n3, n1)] = true;
 158.212 +    cutarcs[d.addArc(n3, n5)] = true;
 158.213 +    cutarcs[d.addArc(n3, n8)] = true;
 158.214 +    cutarcs[d.addArc(n8, n6)] = true;
 158.215 +    cutarcs[d.addArc(n8, n7)] = true;
 158.216 +
 158.217 +    check(!stronglyConnected(d), "This digraph is not strongly connected");
 158.218 +    check(countStronglyConnectedComponents(d) == 3,
 158.219 +          "This digraph has 3 strongly connected components");
 158.220 +    Digraph::NodeMap<int> scomp2(d);
 158.221 +    check(stronglyConnectedComponents(d, scomp2) == 3,
 158.222 +          "This digraph has 3 strongly connected components");
 158.223 +    check(scomp2[n3] == 0, "Wrong stronglyConnectedComponents()");
 158.224 +    check(scomp2[n1] == 1 && scomp2[n2] == 1 && scomp2[n5] == 1 &&
 158.225 +          scomp2[n8] == 1, "Wrong stronglyConnectedComponents()");
 158.226 +    check(scomp2[n4] == 2 && scomp2[n6] == 2 && scomp2[n7] == 2,
 158.227 +          "Wrong stronglyConnectedComponents()");
 158.228 +    Digraph::ArcMap<bool> scut2(d, false);
 158.229 +    check(stronglyConnectedCutArcs(d, scut2) == 5,
 158.230 +          "This digraph has 5 strongly connected cut arcs.");
 158.231 +    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
 158.232 +      check(scut2[a] == cutarcs[a], "Wrong stronglyConnectedCutArcs()");
 158.233 +    }
 158.234 +  }
 158.235 +
 158.236 +  {
 158.237 +    // DAG example for topological sort from the book New Algorithms
 158.238 +    // (T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein)
 158.239 +    Digraph d;
 158.240 +    Digraph::NodeMap<int> order(d);
 158.241 +    
 158.242 +    Digraph::Node belt = d.addNode();
 158.243 +    Digraph::Node trousers = d.addNode();
 158.244 +    Digraph::Node necktie = d.addNode();
 158.245 +    Digraph::Node coat = d.addNode();
 158.246 +    Digraph::Node socks = d.addNode();
 158.247 +    Digraph::Node shirt = d.addNode();
 158.248 +    Digraph::Node shoe = d.addNode();
 158.249 +    Digraph::Node watch = d.addNode();
 158.250 +    Digraph::Node pants = d.addNode();
 158.251 +
 158.252 +    d.addArc(socks, shoe);
 158.253 +    d.addArc(pants, shoe);
 158.254 +    d.addArc(pants, trousers);
 158.255 +    d.addArc(trousers, shoe);
 158.256 +    d.addArc(trousers, belt);
 158.257 +    d.addArc(belt, coat);
 158.258 +    d.addArc(shirt, belt);
 158.259 +    d.addArc(shirt, necktie);
 158.260 +    d.addArc(necktie, coat);
 158.261 +    
 158.262 +    check(dag(d), "This digraph is DAG.");
 158.263 +    topologicalSort(d, order);
 158.264 +    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
 158.265 +      check(order[d.source(a)] < order[d.target(a)],
 158.266 +            "Wrong topologicalSort()");
 158.267 +    }
 158.268 +  }
 158.269 +
 158.270 +  {
 158.271 +    ListGraph g;
 158.272 +    ListGraph::NodeMap<bool> map(g);
 158.273 +    
 158.274 +    ListGraph::Node n1 = g.addNode();
 158.275 +    ListGraph::Node n2 = g.addNode();
 158.276 +    ListGraph::Node n3 = g.addNode();
 158.277 +    ListGraph::Node n4 = g.addNode();
 158.278 +    ListGraph::Node n5 = g.addNode();
 158.279 +    ListGraph::Node n6 = g.addNode();
 158.280 +    ListGraph::Node n7 = g.addNode();
 158.281 +
 158.282 +    g.addEdge(n1, n3);
 158.283 +    g.addEdge(n1, n4);
 158.284 +    g.addEdge(n2, n5);
 158.285 +    g.addEdge(n3, n6);
 158.286 +    g.addEdge(n4, n6);
 158.287 +    g.addEdge(n4, n7);
 158.288 +    g.addEdge(n5, n7);
 158.289 +   
 158.290 +    check(bipartite(g), "This graph is bipartite");
 158.291 +    check(bipartitePartitions(g, map), "This graph is bipartite");
 158.292 +    
 158.293 +    check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7],
 158.294 +          "Wrong bipartitePartitions()");
 158.295 +    check(map[n3] == map[n4] && map[n3] == map[n5],
 158.296 +          "Wrong bipartitePartitions()");
 158.297 +  }
 158.298 +
 158.299 +  return 0;
 158.300 +}
   159.1 --- a/test/counter_test.cc	Fri Oct 16 10:21:37 2009 +0200
   159.2 +++ b/test/counter_test.cc	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   159.8 + * Copyright (C) 2003-2009
   159.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  159.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  159.11   *
  159.12 @@ -18,59 +18,86 @@
  159.13  
  159.14  #include <lemon/counter.h>
  159.15  #include <vector>
  159.16 +#include <sstream>
  159.17 +
  159.18 +#include "test/test_tools.h"
  159.19  
  159.20  using namespace lemon;
  159.21  
  159.22  template <typename T>
  159.23  void bubbleSort(std::vector<T>& v) {
  159.24 -  Counter op("Bubble Sort - Operations: ");
  159.25 -  Counter::NoSubCounter as(op, "Assignments: ");
  159.26 -  Counter::NoSubCounter co(op, "Comparisons: ");
  159.27 -  for (int i = v.size()-1; i > 0; --i) {
  159.28 -    for (int j = 0; j < i; ++j) {
  159.29 -      if (v[j] > v[j+1]) {
  159.30 -        T tmp = v[j];
  159.31 -        v[j] = v[j+1];
  159.32 -        v[j+1] = tmp;
  159.33 -        as += 3;
  159.34 +  std::stringstream s1, s2, s3;
  159.35 +  {
  159.36 +    Counter op("Bubble Sort - Operations: ", s1);
  159.37 +    Counter::SubCounter as(op, "Assignments: ", s2);
  159.38 +    Counter::SubCounter co(op, "Comparisons: ", s3);
  159.39 +    for (int i = v.size()-1; i > 0; --i) {
  159.40 +      for (int j = 0; j < i; ++j) {
  159.41 +        if (v[j] > v[j+1]) {
  159.42 +          T tmp = v[j];
  159.43 +          v[j] = v[j+1];
  159.44 +          v[j+1] = tmp;
  159.45 +          as += 3;
  159.46 +        }
  159.47 +        ++co;
  159.48        }
  159.49 -      ++co;
  159.50      }
  159.51    }
  159.52 +  check(s1.str() == "Bubble Sort - Operations: 102\n", "Wrong counter");
  159.53 +  check(s2.str() == "Assignments: 57\n", "Wrong subcounter");
  159.54 +  check(s3.str() == "Comparisons: 45\n", "Wrong subcounter");
  159.55  }
  159.56  
  159.57  template <typename T>
  159.58  void insertionSort(std::vector<T>& v) {
  159.59 -  Counter op("Insertion Sort - Operations: ");
  159.60 -  Counter::NoSubCounter as(op, "Assignments: ");
  159.61 -  Counter::NoSubCounter co(op, "Comparisons: ");
  159.62 -  for (int i = 1; i < int(v.size()); ++i) {
  159.63 -    T value = v[i];
  159.64 -    ++as;
  159.65 -    int j = i;
  159.66 -    while (j > 0 && v[j-1] > value) {
  159.67 -      v[j] = v[j-1];
  159.68 -      --j;
  159.69 -      ++co; ++as;
  159.70 +  std::stringstream s1, s2, s3;
  159.71 +  {
  159.72 +    Counter op("Insertion Sort - Operations: ", s1);
  159.73 +    Counter::SubCounter as(op, "Assignments: ", s2);
  159.74 +    Counter::SubCounter co(op, "Comparisons: ", s3);
  159.75 +    for (int i = 1; i < int(v.size()); ++i) {
  159.76 +      T value = v[i];
  159.77 +      ++as;
  159.78 +      int j = i;
  159.79 +      while (j > 0 && v[j-1] > value) {
  159.80 +        v[j] = v[j-1];
  159.81 +        --j;
  159.82 +        ++co; ++as;
  159.83 +      }
  159.84 +      v[j] = value;
  159.85 +      ++as;
  159.86      }
  159.87 -    v[j] = value;
  159.88 -    ++as;
  159.89    }
  159.90 +  check(s1.str() == "Insertion Sort - Operations: 56\n", "Wrong counter");
  159.91 +  check(s2.str() == "Assignments: 37\n", "Wrong subcounter");
  159.92 +  check(s3.str() == "Comparisons: 19\n", "Wrong subcounter");
  159.93  }
  159.94  
  159.95  template <typename MyCounter>
  159.96 -void counterTest() {
  159.97 -  MyCounter c("Main Counter: ");
  159.98 -  c++;
  159.99 -  typename MyCounter::SubCounter d(c, "SubCounter: ");
 159.100 -  d++;
 159.101 -  typename MyCounter::SubCounter::NoSubCounter e(d, "SubSubCounter: ");
 159.102 -  e++;
 159.103 -  d+=3;
 159.104 -  c-=4;
 159.105 -  e-=2;
 159.106 -  c.reset(2);
 159.107 -  c.reset();
 159.108 +void counterTest(bool output) {
 159.109 +  std::stringstream s1, s2, s3;
 159.110 +  {
 159.111 +    MyCounter c("Main Counter: ", s1);
 159.112 +    c++;
 159.113 +    typename MyCounter::SubCounter d(c, "SubCounter: ", s2);
 159.114 +    d++;
 159.115 +    typename MyCounter::SubCounter::NoSubCounter e(d, "SubSubCounter: ", s3);
 159.116 +    e++;
 159.117 +    d+=3;
 159.118 +    c-=4;
 159.119 +    e-=2;
 159.120 +    c.reset(2);
 159.121 +    c.reset();
 159.122 +  }
 159.123 +  if (output) {
 159.124 +    check(s1.str() == "Main Counter: 3\n", "Wrong Counter");
 159.125 +    check(s2.str() == "SubCounter: 3\n", "Wrong SubCounter");
 159.126 +    check(s3.str() == "", "Wrong NoSubCounter");
 159.127 +  } else {
 159.128 +    check(s1.str() == "", "Wrong NoCounter");
 159.129 +    check(s2.str() == "", "Wrong SubCounter");
 159.130 +    check(s3.str() == "", "Wrong NoSubCounter");
 159.131 +  }
 159.132  }
 159.133  
 159.134  void init(std::vector<int>& v) {
 159.135 @@ -80,8 +107,8 @@
 159.136  
 159.137  int main()
 159.138  {
 159.139 -  counterTest<Counter>();
 159.140 -  counterTest<NoCounter>();
 159.141 +  counterTest<Counter>(true);
 159.142 +  counterTest<NoCounter>(false);
 159.143  
 159.144    std::vector<int> x(10);
 159.145    init(x); bubbleSort(x);
   160.1 --- a/test/dfs_test.cc	Fri Oct 16 10:21:37 2009 +0200
   160.2 +++ b/test/dfs_test.cc	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   160.8 + * Copyright (C) 2003-2009
   160.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  160.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  160.11   *
  160.12 @@ -62,39 +62,74 @@
  160.13    Digraph G;
  160.14    Node s, t;
  160.15    Arc e;
  160.16 -  int l;
  160.17 +  int l, i;
  160.18    bool b;
  160.19    DType::DistMap d(G);
  160.20    DType::PredMap p(G);
  160.21    Path<Digraph> pp;
  160.22 +  concepts::ReadMap<Arc,bool> am;
  160.23  
  160.24    {
  160.25      DType dfs_test(G);
  160.26 +    const DType& const_dfs_test = dfs_test;
  160.27  
  160.28      dfs_test.run(s);
  160.29      dfs_test.run(s,t);
  160.30      dfs_test.run();
  160.31  
  160.32 -    l  = dfs_test.dist(t);
  160.33 -    e  = dfs_test.predArc(t);
  160.34 -    s  = dfs_test.predNode(t);
  160.35 -    b  = dfs_test.reached(t);
  160.36 -    d  = dfs_test.distMap();
  160.37 -    p  = dfs_test.predMap();
  160.38 -    pp = dfs_test.path(t);
  160.39 +    dfs_test.init();
  160.40 +    dfs_test.addSource(s);
  160.41 +    e = dfs_test.processNextArc();
  160.42 +    e = const_dfs_test.nextArc();
  160.43 +    b = const_dfs_test.emptyQueue();
  160.44 +    i = const_dfs_test.queueSize();
  160.45 +    
  160.46 +    dfs_test.start();
  160.47 +    dfs_test.start(t);
  160.48 +    dfs_test.start(am);
  160.49 +
  160.50 +    l  = const_dfs_test.dist(t);
  160.51 +    e  = const_dfs_test.predArc(t);
  160.52 +    s  = const_dfs_test.predNode(t);
  160.53 +    b  = const_dfs_test.reached(t);
  160.54 +    d  = const_dfs_test.distMap();
  160.55 +    p  = const_dfs_test.predMap();
  160.56 +    pp = const_dfs_test.path(t);
  160.57    }
  160.58    {
  160.59      DType
  160.60        ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
  160.61        ::SetDistMap<concepts::ReadWriteMap<Node,int> >
  160.62        ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
  160.63 +      ::SetStandardProcessedMap
  160.64        ::SetProcessedMap<concepts::WriteMap<Node,bool> >
  160.65 -      ::SetStandardProcessedMap
  160.66        ::Create dfs_test(G);
  160.67  
  160.68 +    concepts::ReadWriteMap<Node,Arc> pred_map;
  160.69 +    concepts::ReadWriteMap<Node,int> dist_map;
  160.70 +    concepts::ReadWriteMap<Node,bool> reached_map;
  160.71 +    concepts::WriteMap<Node,bool> processed_map;
  160.72 +    
  160.73 +    dfs_test
  160.74 +      .predMap(pred_map)
  160.75 +      .distMap(dist_map)
  160.76 +      .reachedMap(reached_map)
  160.77 +      .processedMap(processed_map);
  160.78 +
  160.79      dfs_test.run(s);
  160.80      dfs_test.run(s,t);
  160.81      dfs_test.run();
  160.82 +    dfs_test.init();
  160.83 +
  160.84 +    dfs_test.addSource(s);
  160.85 +    e = dfs_test.processNextArc();
  160.86 +    e = dfs_test.nextArc();
  160.87 +    b = dfs_test.emptyQueue();
  160.88 +    i = dfs_test.queueSize();
  160.89 +    
  160.90 +    dfs_test.start();
  160.91 +    dfs_test.start(t);
  160.92 +    dfs_test.start(am);
  160.93  
  160.94      l  = dfs_test.dist(t);
  160.95      e  = dfs_test.predArc(t);
   161.1 --- a/test/digraph_test.cc	Fri Oct 16 10:21:37 2009 +0200
   161.2 +++ b/test/digraph_test.cc	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   161.8 + * Copyright (C) 2003-2009
   161.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  161.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  161.11   *
  161.12 @@ -19,8 +19,8 @@
  161.13  #include <lemon/concepts/digraph.h>
  161.14  #include <lemon/list_graph.h>
  161.15  #include <lemon/smart_graph.h>
  161.16 -//#include <lemon/full_graph.h>
  161.17 -//#include <lemon/hypercube_graph.h>
  161.18 +#include <lemon/static_graph.h>
  161.19 +#include <lemon/full_graph.h>
  161.20  
  161.21  #include "test_tools.h"
  161.22  #include "graph_test.h"
  161.23 @@ -29,13 +29,16 @@
  161.24  using namespace lemon::concepts;
  161.25  
  161.26  template <class Digraph>
  161.27 -void checkDigraph() {
  161.28 +void checkDigraphBuild() {
  161.29    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
  161.30    Digraph G;
  161.31  
  161.32    checkGraphNodeList(G, 0);
  161.33    checkGraphArcList(G, 0);
  161.34  
  161.35 +  G.reserveNode(3);
  161.36 +  G.reserveArc(4);
  161.37 +
  161.38    Node
  161.39      n1 = G.addNode(),
  161.40      n2 = G.addNode(),
  161.41 @@ -58,7 +61,208 @@
  161.42  
  161.43    checkGraphConArcList(G, 1);
  161.44  
  161.45 -  Arc a2 = G.addArc(n2, n1), a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
  161.46 +  Arc a2 = G.addArc(n2, n1),
  161.47 +      a3 = G.addArc(n2, n3),
  161.48 +      a4 = G.addArc(n2, n3);
  161.49 +
  161.50 +  checkGraphNodeList(G, 3);
  161.51 +  checkGraphArcList(G, 4);
  161.52 +
  161.53 +  checkGraphOutArcList(G, n1, 1);
  161.54 +  checkGraphOutArcList(G, n2, 3);
  161.55 +  checkGraphOutArcList(G, n3, 0);
  161.56 +
  161.57 +  checkGraphInArcList(G, n1, 1);
  161.58 +  checkGraphInArcList(G, n2, 1);
  161.59 +  checkGraphInArcList(G, n3, 2);
  161.60 +
  161.61 +  checkGraphConArcList(G, 4);
  161.62 +
  161.63 +  checkNodeIds(G);
  161.64 +  checkArcIds(G);
  161.65 +  checkGraphNodeMap(G);
  161.66 +  checkGraphArcMap(G);
  161.67 +}
  161.68 +
  161.69 +template <class Digraph>
  161.70 +void checkDigraphSplit() {
  161.71 +  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
  161.72 +
  161.73 +  Digraph G;
  161.74 +  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
  161.75 +  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
  161.76 +      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
  161.77 +
  161.78 +  Node n4 = G.split(n2);
  161.79 +
  161.80 +  check(G.target(OutArcIt(G, n2)) == n4 &&
  161.81 +        G.source(InArcIt(G, n4)) == n2,
  161.82 +        "Wrong split.");
  161.83 +
  161.84 +  checkGraphNodeList(G, 4);
  161.85 +  checkGraphArcList(G, 5);
  161.86 +
  161.87 +  checkGraphOutArcList(G, n1, 1);
  161.88 +  checkGraphOutArcList(G, n2, 1);
  161.89 +  checkGraphOutArcList(G, n3, 0);
  161.90 +  checkGraphOutArcList(G, n4, 3);
  161.91 +
  161.92 +  checkGraphInArcList(G, n1, 1);
  161.93 +  checkGraphInArcList(G, n2, 1);
  161.94 +  checkGraphInArcList(G, n3, 2);
  161.95 +  checkGraphInArcList(G, n4, 1);
  161.96 +
  161.97 +  checkGraphConArcList(G, 5);
  161.98 +}
  161.99 +
 161.100 +template <class Digraph>
 161.101 +void checkDigraphAlter() {
 161.102 +  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 161.103 +
 161.104 +  Digraph G;
 161.105 +  Node n1 = G.addNode(), n2 = G.addNode(),
 161.106 +       n3 = G.addNode(), n4 = G.addNode();
 161.107 +  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
 161.108 +      a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3),
 161.109 +      a5 = G.addArc(n2, n4);
 161.110 +
 161.111 +  checkGraphNodeList(G, 4);
 161.112 +  checkGraphArcList(G, 5);
 161.113 +
 161.114 +  // Check changeSource() and changeTarget()
 161.115 +  G.changeTarget(a4, n1);
 161.116 +
 161.117 +  checkGraphNodeList(G, 4);
 161.118 +  checkGraphArcList(G, 5);
 161.119 +
 161.120 +  checkGraphOutArcList(G, n1, 1);
 161.121 +  checkGraphOutArcList(G, n2, 1);
 161.122 +  checkGraphOutArcList(G, n3, 0);
 161.123 +  checkGraphOutArcList(G, n4, 3);
 161.124 +
 161.125 +  checkGraphInArcList(G, n1, 2);
 161.126 +  checkGraphInArcList(G, n2, 1);
 161.127 +  checkGraphInArcList(G, n3, 1);
 161.128 +  checkGraphInArcList(G, n4, 1);
 161.129 +
 161.130 +  checkGraphConArcList(G, 5);
 161.131 +
 161.132 +  G.changeSource(a4, n3);
 161.133 +
 161.134 +  checkGraphNodeList(G, 4);
 161.135 +  checkGraphArcList(G, 5);
 161.136 +
 161.137 +  checkGraphOutArcList(G, n1, 1);
 161.138 +  checkGraphOutArcList(G, n2, 1);
 161.139 +  checkGraphOutArcList(G, n3, 1);
 161.140 +  checkGraphOutArcList(G, n4, 2);
 161.141 +
 161.142 +  checkGraphInArcList(G, n1, 2);
 161.143 +  checkGraphInArcList(G, n2, 1);
 161.144 +  checkGraphInArcList(G, n3, 1);
 161.145 +  checkGraphInArcList(G, n4, 1);
 161.146 +
 161.147 +  checkGraphConArcList(G, 5);
 161.148 +
 161.149 +  // Check contract()
 161.150 +  G.contract(n2, n4, false);
 161.151 +
 161.152 +  checkGraphNodeList(G, 3);
 161.153 +  checkGraphArcList(G, 5);
 161.154 +
 161.155 +  checkGraphOutArcList(G, n1, 1);
 161.156 +  checkGraphOutArcList(G, n2, 3);
 161.157 +  checkGraphOutArcList(G, n3, 1);
 161.158 +
 161.159 +  checkGraphInArcList(G, n1, 2);
 161.160 +  checkGraphInArcList(G, n2, 2);
 161.161 +  checkGraphInArcList(G, n3, 1);
 161.162 +
 161.163 +  checkGraphConArcList(G, 5);
 161.164 +
 161.165 +  G.contract(n2, n1);
 161.166 +
 161.167 +  checkGraphNodeList(G, 2);
 161.168 +  checkGraphArcList(G, 3);
 161.169 +
 161.170 +  checkGraphOutArcList(G, n2, 2);
 161.171 +  checkGraphOutArcList(G, n3, 1);
 161.172 +
 161.173 +  checkGraphInArcList(G, n2, 2);
 161.174 +  checkGraphInArcList(G, n3, 1);
 161.175 +
 161.176 +  checkGraphConArcList(G, 3);
 161.177 +}
 161.178 +
 161.179 +template <class Digraph>
 161.180 +void checkDigraphErase() {
 161.181 +  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 161.182 +
 161.183 +  Digraph G;
 161.184 +  Node n1 = G.addNode(), n2 = G.addNode(),
 161.185 +       n3 = G.addNode(), n4 = G.addNode();
 161.186 +  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
 161.187 +      a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1),
 161.188 +      a5 = G.addArc(n2, n4);
 161.189 +
 161.190 +  // Check arc deletion
 161.191 +  G.erase(a1);
 161.192 +
 161.193 +  checkGraphNodeList(G, 4);
 161.194 +  checkGraphArcList(G, 4);
 161.195 +
 161.196 +  checkGraphOutArcList(G, n1, 0);
 161.197 +  checkGraphOutArcList(G, n2, 1);
 161.198 +  checkGraphOutArcList(G, n3, 1);
 161.199 +  checkGraphOutArcList(G, n4, 2);
 161.200 +
 161.201 +  checkGraphInArcList(G, n1, 2);
 161.202 +  checkGraphInArcList(G, n2, 0);
 161.203 +  checkGraphInArcList(G, n3, 1);
 161.204 +  checkGraphInArcList(G, n4, 1);
 161.205 +
 161.206 +  checkGraphConArcList(G, 4);
 161.207 +
 161.208 +  // Check node deletion
 161.209 +  G.erase(n4);
 161.210 +
 161.211 +  checkGraphNodeList(G, 3);
 161.212 +  checkGraphArcList(G, 1);
 161.213 +
 161.214 +  checkGraphOutArcList(G, n1, 0);
 161.215 +  checkGraphOutArcList(G, n2, 0);
 161.216 +  checkGraphOutArcList(G, n3, 1);
 161.217 +  checkGraphOutArcList(G, n4, 0);
 161.218 +
 161.219 +  checkGraphInArcList(G, n1, 1);
 161.220 +  checkGraphInArcList(G, n2, 0);
 161.221 +  checkGraphInArcList(G, n3, 0);
 161.222 +  checkGraphInArcList(G, n4, 0);
 161.223 +
 161.224 +  checkGraphConArcList(G, 1);
 161.225 +}
 161.226 +
 161.227 +
 161.228 +template <class Digraph>
 161.229 +void checkDigraphSnapshot() {
 161.230 +  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 161.231 +
 161.232 +  Digraph G;
 161.233 +  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
 161.234 +  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
 161.235 +      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
 161.236 +
 161.237 +  typename Digraph::Snapshot snapshot(G);
 161.238 +
 161.239 +  Node n = G.addNode();
 161.240 +  G.addArc(n3, n);
 161.241 +  G.addArc(n, n3);
 161.242 +
 161.243 +  checkGraphNodeList(G, 4);
 161.244 +  checkGraphArcList(G, 6);
 161.245 +
 161.246 +  snapshot.restore();
 161.247 +
 161.248    checkGraphNodeList(G, 3);
 161.249    checkGraphArcList(G, 4);
 161.250  
 161.251 @@ -77,9 +281,25 @@
 161.252    checkGraphNodeMap(G);
 161.253    checkGraphArcMap(G);
 161.254  
 161.255 +  G.addNode();
 161.256 +  snapshot.save(G);
 161.257 +
 161.258 +  G.addArc(G.addNode(), G.addNode());
 161.259 +
 161.260 +  snapshot.restore();
 161.261 +  snapshot.save(G);
 161.262 +
 161.263 +  checkGraphNodeList(G, 4);
 161.264 +  checkGraphArcList(G, 4);
 161.265 +
 161.266 +  G.addArc(G.addNode(), G.addNode());
 161.267 +
 161.268 +  snapshot.restore();
 161.269 +
 161.270 +  checkGraphNodeList(G, 4);
 161.271 +  checkGraphArcList(G, 4);
 161.272  }
 161.273  
 161.274 -
 161.275  void checkConcepts() {
 161.276    { // Checking digraph components
 161.277      checkConcept<BaseDigraphComponent, BaseDigraphComponent >();
 161.278 @@ -109,12 +329,13 @@
 161.279      checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
 161.280      checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
 161.281    }
 161.282 -//  { // Checking FullDigraph
 161.283 -//    checkConcept<Digraph, FullDigraph>();
 161.284 -//  }
 161.285 -//  { // Checking HyperCubeDigraph
 161.286 -//    checkConcept<Digraph, HyperCubeDigraph>();
 161.287 -//  }
 161.288 +  { // Checking StaticDigraph
 161.289 +    checkConcept<Digraph, StaticDigraph>();
 161.290 +    checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
 161.291 +  }
 161.292 +  { // Checking FullDigraph
 161.293 +    checkConcept<Digraph, FullDigraph>();
 161.294 +  }
 161.295  }
 161.296  
 161.297  template <typename Digraph>
 161.298 @@ -167,15 +388,171 @@
 161.299    check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
 161.300  }
 161.301  
 161.302 +void checkStaticDigraph() {
 161.303 +  SmartDigraph g;
 161.304 +  SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
 161.305 +  SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
 161.306 +  
 161.307 +  StaticDigraph G;
 161.308 +  
 161.309 +  checkGraphNodeList(G, 0);
 161.310 +  checkGraphArcList(G, 0);
 161.311 +
 161.312 +  G.build(g, nref, aref);
 161.313 +
 161.314 +  checkGraphNodeList(G, 0);
 161.315 +  checkGraphArcList(G, 0);
 161.316 +
 161.317 +  SmartDigraph::Node
 161.318 +    n1 = g.addNode(),
 161.319 +    n2 = g.addNode(),
 161.320 +    n3 = g.addNode();
 161.321 +
 161.322 +  G.build(g, nref, aref);
 161.323 +
 161.324 +  checkGraphNodeList(G, 3);
 161.325 +  checkGraphArcList(G, 0);
 161.326 +
 161.327 +  SmartDigraph::Arc a1 = g.addArc(n1, n2);
 161.328 +
 161.329 +  G.build(g, nref, aref);
 161.330 +
 161.331 +  check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2],
 161.332 +        "Wrong arc or wrong references");
 161.333 +  checkGraphNodeList(G, 3);
 161.334 +  checkGraphArcList(G, 1);
 161.335 +
 161.336 +  checkGraphOutArcList(G, nref[n1], 1);
 161.337 +  checkGraphOutArcList(G, nref[n2], 0);
 161.338 +  checkGraphOutArcList(G, nref[n3], 0);
 161.339 +
 161.340 +  checkGraphInArcList(G, nref[n1], 0);
 161.341 +  checkGraphInArcList(G, nref[n2], 1);
 161.342 +  checkGraphInArcList(G, nref[n3], 0);
 161.343 +
 161.344 +  checkGraphConArcList(G, 1);
 161.345 +
 161.346 +  SmartDigraph::Arc
 161.347 +    a2 = g.addArc(n2, n1),
 161.348 +    a3 = g.addArc(n2, n3),
 161.349 +    a4 = g.addArc(n2, n3);
 161.350 +
 161.351 +  digraphCopy(g, G).nodeRef(nref).run();
 161.352 +
 161.353 +  checkGraphNodeList(G, 3);
 161.354 +  checkGraphArcList(G, 4);
 161.355 +
 161.356 +  checkGraphOutArcList(G, nref[n1], 1);
 161.357 +  checkGraphOutArcList(G, nref[n2], 3);
 161.358 +  checkGraphOutArcList(G, nref[n3], 0);
 161.359 +
 161.360 +  checkGraphInArcList(G, nref[n1], 1);
 161.361 +  checkGraphInArcList(G, nref[n2], 1);
 161.362 +  checkGraphInArcList(G, nref[n3], 2);
 161.363 +
 161.364 +  checkGraphConArcList(G, 4);
 161.365 +
 161.366 +  std::vector<std::pair<int,int> > arcs;
 161.367 +  arcs.push_back(std::make_pair(0,1));
 161.368 +  arcs.push_back(std::make_pair(0,2));
 161.369 +  arcs.push_back(std::make_pair(1,3));
 161.370 +  arcs.push_back(std::make_pair(1,2));
 161.371 +  arcs.push_back(std::make_pair(3,0));
 161.372 +  arcs.push_back(std::make_pair(3,3));
 161.373 +  arcs.push_back(std::make_pair(4,2));
 161.374 +  arcs.push_back(std::make_pair(4,3));
 161.375 +  arcs.push_back(std::make_pair(4,1));
 161.376 +
 161.377 +  G.build(6, arcs.begin(), arcs.end());
 161.378 +  
 161.379 +  checkGraphNodeList(G, 6);
 161.380 +  checkGraphArcList(G, 9);
 161.381 +
 161.382 +  checkGraphOutArcList(G, G.node(0), 2);
 161.383 +  checkGraphOutArcList(G, G.node(1), 2);
 161.384 +  checkGraphOutArcList(G, G.node(2), 0);
 161.385 +  checkGraphOutArcList(G, G.node(3), 2);
 161.386 +  checkGraphOutArcList(G, G.node(4), 3);
 161.387 +  checkGraphOutArcList(G, G.node(5), 0);
 161.388 +
 161.389 +  checkGraphInArcList(G, G.node(0), 1);
 161.390 +  checkGraphInArcList(G, G.node(1), 2);
 161.391 +  checkGraphInArcList(G, G.node(2), 3);
 161.392 +  checkGraphInArcList(G, G.node(3), 3);
 161.393 +  checkGraphInArcList(G, G.node(4), 0);
 161.394 +  checkGraphInArcList(G, G.node(5), 0);
 161.395 +
 161.396 +  checkGraphConArcList(G, 9);
 161.397 +
 161.398 +  checkNodeIds(G);
 161.399 +  checkArcIds(G);
 161.400 +  checkGraphNodeMap(G);
 161.401 +  checkGraphArcMap(G);
 161.402 +  
 161.403 +  int n = G.nodeNum();
 161.404 +  int m = G.arcNum();
 161.405 +  check(G.index(G.node(n-1)) == n-1, "Wrong index.");
 161.406 +  check(G.index(G.arc(m-1)) == m-1, "Wrong index.");
 161.407 +}
 161.408 +
 161.409 +void checkFullDigraph(int num) {
 161.410 +  typedef FullDigraph Digraph;
 161.411 +  DIGRAPH_TYPEDEFS(Digraph);
 161.412 +
 161.413 +  Digraph G(num);
 161.414 +  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
 161.415 +
 161.416 +  G.resize(num);
 161.417 +  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
 161.418 +
 161.419 +  checkGraphNodeList(G, num);
 161.420 +  checkGraphArcList(G, num * num);
 161.421 +
 161.422 +  for (NodeIt n(G); n != INVALID; ++n) {
 161.423 +    checkGraphOutArcList(G, n, num);
 161.424 +    checkGraphInArcList(G, n, num);
 161.425 +  }
 161.426 +
 161.427 +  checkGraphConArcList(G, num * num);
 161.428 +
 161.429 +  checkNodeIds(G);
 161.430 +  checkArcIds(G);
 161.431 +  checkGraphNodeMap(G);
 161.432 +  checkGraphArcMap(G);
 161.433 +
 161.434 +  for (int i = 0; i < G.nodeNum(); ++i) {
 161.435 +    check(G.index(G(i)) == i, "Wrong index");
 161.436 +  }
 161.437 +
 161.438 +  for (NodeIt s(G); s != INVALID; ++s) {
 161.439 +    for (NodeIt t(G); t != INVALID; ++t) {
 161.440 +      Arc a = G.arc(s, t);
 161.441 +      check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
 161.442 +    }
 161.443 +  }
 161.444 +}
 161.445 +
 161.446  void checkDigraphs() {
 161.447    { // Checking ListDigraph
 161.448 -    checkDigraph<ListDigraph>();
 161.449 +    checkDigraphBuild<ListDigraph>();
 161.450 +    checkDigraphSplit<ListDigraph>();
 161.451 +    checkDigraphAlter<ListDigraph>();
 161.452 +    checkDigraphErase<ListDigraph>();
 161.453 +    checkDigraphSnapshot<ListDigraph>();
 161.454      checkDigraphValidityErase<ListDigraph>();
 161.455    }
 161.456    { // Checking SmartDigraph
 161.457 -    checkDigraph<SmartDigraph>();
 161.458 +    checkDigraphBuild<SmartDigraph>();
 161.459 +    checkDigraphSplit<SmartDigraph>();
 161.460 +    checkDigraphSnapshot<SmartDigraph>();
 161.461      checkDigraphValidity<SmartDigraph>();
 161.462    }
 161.463 +  { // Checking StaticDigraph
 161.464 +    checkStaticDigraph();
 161.465 +  }
 161.466 +  { // Checking FullDigraph
 161.467 +    checkFullDigraph(8);
 161.468 +  }
 161.469  }
 161.470  
 161.471  int main() {
   162.1 --- a/test/dijkstra_test.cc	Fri Oct 16 10:21:37 2009 +0200
   162.2 +++ b/test/dijkstra_test.cc	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   162.8 + * Copyright (C) 2003-2009
   162.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  162.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  162.11   *
  162.12 @@ -60,48 +60,94 @@
  162.13    typedef Digraph::Arc Arc;
  162.14  
  162.15    Digraph G;
  162.16 -  Node s, t;
  162.17 +  Node s, t, n;
  162.18    Arc e;
  162.19    VType l;
  162.20 +  int i;
  162.21    bool b;
  162.22    DType::DistMap d(G);
  162.23    DType::PredMap p(G);
  162.24    LengthMap length;
  162.25    Path<Digraph> pp;
  162.26 +  concepts::ReadMap<Node,bool> nm;
  162.27  
  162.28    {
  162.29      DType dijkstra_test(G,length);
  162.30 +    const DType& const_dijkstra_test = dijkstra_test;
  162.31  
  162.32      dijkstra_test.run(s);
  162.33      dijkstra_test.run(s,t);
  162.34  
  162.35 +    dijkstra_test.init();
  162.36 +    dijkstra_test.addSource(s);
  162.37 +    dijkstra_test.addSource(s, 1);
  162.38 +    n = dijkstra_test.processNextNode();
  162.39 +    n = const_dijkstra_test.nextNode();
  162.40 +    b = const_dijkstra_test.emptyQueue();
  162.41 +    i = const_dijkstra_test.queueSize();
  162.42 +    
  162.43 +    dijkstra_test.start();
  162.44 +    dijkstra_test.start(t);
  162.45 +    dijkstra_test.start(nm);
  162.46 +
  162.47 +    l  = const_dijkstra_test.dist(t);
  162.48 +    e  = const_dijkstra_test.predArc(t);
  162.49 +    s  = const_dijkstra_test.predNode(t);
  162.50 +    b  = const_dijkstra_test.reached(t);
  162.51 +    b  = const_dijkstra_test.processed(t);
  162.52 +    d  = const_dijkstra_test.distMap();
  162.53 +    p  = const_dijkstra_test.predMap();
  162.54 +    pp = const_dijkstra_test.path(t);
  162.55 +    l  = const_dijkstra_test.currentDist(t);
  162.56 +  }
  162.57 +  {
  162.58 +    DType
  162.59 +      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
  162.60 +      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
  162.61 +      ::SetStandardProcessedMap
  162.62 +      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
  162.63 +      ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
  162.64 +      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
  162.65 +      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
  162.66 +      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >, 
  162.67 +                concepts::ReadWriteMap<Node,int> >
  162.68 +      ::Create dijkstra_test(G,length);
  162.69 +
  162.70 +    LengthMap length_map;
  162.71 +    concepts::ReadWriteMap<Node,Arc> pred_map;
  162.72 +    concepts::ReadWriteMap<Node,VType> dist_map;
  162.73 +    concepts::WriteMap<Node,bool> processed_map;
  162.74 +    concepts::ReadWriteMap<Node,int> heap_cross_ref;
  162.75 +    BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
  162.76 +    
  162.77 +    dijkstra_test
  162.78 +      .lengthMap(length_map)
  162.79 +      .predMap(pred_map)
  162.80 +      .distMap(dist_map)
  162.81 +      .processedMap(processed_map)
  162.82 +      .heap(heap, heap_cross_ref);
  162.83 +
  162.84 +    dijkstra_test.run(s);
  162.85 +    dijkstra_test.run(s,t);
  162.86 +
  162.87 +    dijkstra_test.addSource(s);
  162.88 +    dijkstra_test.addSource(s, 1);
  162.89 +    n = dijkstra_test.processNextNode();
  162.90 +    n = dijkstra_test.nextNode();
  162.91 +    b = dijkstra_test.emptyQueue();
  162.92 +    i = dijkstra_test.queueSize();
  162.93 +    
  162.94 +    dijkstra_test.start();
  162.95 +    dijkstra_test.start(t);
  162.96 +    dijkstra_test.start(nm);
  162.97 +
  162.98      l  = dijkstra_test.dist(t);
  162.99      e  = dijkstra_test.predArc(t);
 162.100      s  = dijkstra_test.predNode(t);
 162.101      b  = dijkstra_test.reached(t);
 162.102 -    d  = dijkstra_test.distMap();
 162.103 -    p  = dijkstra_test.predMap();
 162.104 +    b  = dijkstra_test.processed(t);
 162.105      pp = dijkstra_test.path(t);
 162.106 -  }
 162.107 -  {
 162.108 -    DType
 162.109 -      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
 162.110 -      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
 162.111 -      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
 162.112 -      ::SetStandardProcessedMap
 162.113 -      ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
 162.114 -      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
 162.115 -      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
 162.116 -      ::Create dijkstra_test(G,length);
 162.117 -
 162.118 -    dijkstra_test.run(s);
 162.119 -    dijkstra_test.run(s,t);
 162.120 -
 162.121 -    l  = dijkstra_test.dist(t);
 162.122 -    e  = dijkstra_test.predArc(t);
 162.123 -    s  = dijkstra_test.predNode(t);
 162.124 -    b  = dijkstra_test.reached(t);
 162.125 -    pp = dijkstra_test.path(t);
 162.126 +    l  = dijkstra_test.currentDist(t);
 162.127    }
 162.128  
 162.129  }
   163.1 --- a/test/dim_test.cc	Fri Oct 16 10:21:37 2009 +0200
   163.2 +++ b/test/dim_test.cc	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   163.8 + * Copyright (C) 2003-2009
   163.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  163.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  163.11   *
   164.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   164.2 +++ b/test/edge_set_test.cc	Thu Nov 05 15:50:01 2009 +0100
   164.3 @@ -0,0 +1,380 @@
   164.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   164.5 + *
   164.6 + * This file is a part of LEMON, a generic C++ optimization library.
   164.7 + *
   164.8 + * Copyright (C) 2003-2008
   164.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  164.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  164.11 + *
  164.12 + * Permission to use, modify and distribute this software is granted
  164.13 + * provided that this copyright notice appears in all copies. For
  164.14 + * precise terms see the accompanying LICENSE file.
  164.15 + *
  164.16 + * This software is provided "AS IS" with no warranty of any kind,
  164.17 + * express or implied, and with no claim as to its suitability for any
  164.18 + * purpose.
  164.19 + *
  164.20 + */
  164.21 +
  164.22 +#include <iostream>
  164.23 +#include <vector>
  164.24 +
  164.25 +#include <lemon/concepts/digraph.h>
  164.26 +#include <lemon/concepts/graph.h>
  164.27 +#include <lemon/concept_check.h>
  164.28 +
  164.29 +#include <lemon/list_graph.h>
  164.30 +
  164.31 +#include <lemon/edge_set.h>
  164.32 +
  164.33 +#include "graph_test.h"
  164.34 +#include "test_tools.h"
  164.35 +
  164.36 +using namespace lemon;
  164.37 +
  164.38 +void checkSmartArcSet() {
  164.39 +  checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
  164.40 +
  164.41 +  typedef ListDigraph Digraph;
  164.42 +  typedef SmartArcSet<Digraph> ArcSet;
  164.43 +
  164.44 +  Digraph digraph;
  164.45 +  Digraph::Node
  164.46 +    n1 = digraph.addNode(),
  164.47 +    n2 = digraph.addNode();
  164.48 +
  164.49 +  Digraph::Arc ga1 = digraph.addArc(n1, n2);
  164.50 +
  164.51 +  ArcSet arc_set(digraph);
  164.52 +
  164.53 +  Digraph::Arc ga2 = digraph.addArc(n2, n1);
  164.54 +
  164.55 +  checkGraphNodeList(arc_set, 2);
  164.56 +  checkGraphArcList(arc_set, 0);
  164.57 +
  164.58 +  Digraph::Node
  164.59 +    n3 = digraph.addNode();
  164.60 +  checkGraphNodeList(arc_set, 3);
  164.61 +  checkGraphArcList(arc_set, 0);
  164.62 +
  164.63 +  ArcSet::Arc a1 = arc_set.addArc(n1, n2);
  164.64 +  check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
  164.65 +  checkGraphNodeList(arc_set, 3);
  164.66 +  checkGraphArcList(arc_set, 1);
  164.67 +
  164.68 +  checkGraphOutArcList(arc_set, n1, 1);
  164.69 +  checkGraphOutArcList(arc_set, n2, 0);
  164.70 +  checkGraphOutArcList(arc_set, n3, 0);
  164.71 +
  164.72 +  checkGraphInArcList(arc_set, n1, 0);
  164.73 +  checkGraphInArcList(arc_set, n2, 1);
  164.74 +  checkGraphInArcList(arc_set, n3, 0);
  164.75 +
  164.76 +  checkGraphConArcList(arc_set, 1);
  164.77 +
  164.78 +  ArcSet::Arc a2 = arc_set.addArc(n2, n1),
  164.79 +    a3 = arc_set.addArc(n2, n3),
  164.80 +    a4 = arc_set.addArc(n2, n3);
  164.81 +  checkGraphNodeList(arc_set, 3);
  164.82 +  checkGraphArcList(arc_set, 4);
  164.83 +
  164.84 +  checkGraphOutArcList(arc_set, n1, 1);
  164.85 +  checkGraphOutArcList(arc_set, n2, 3);
  164.86 +  checkGraphOutArcList(arc_set, n3, 0);
  164.87 +
  164.88 +  checkGraphInArcList(arc_set, n1, 1);
  164.89 +  checkGraphInArcList(arc_set, n2, 1);
  164.90 +  checkGraphInArcList(arc_set, n3, 2);
  164.91 +
  164.92 +  checkGraphConArcList(arc_set, 4);
  164.93 +
  164.94 +  checkNodeIds(arc_set);
  164.95 +  checkArcIds(arc_set);
  164.96 +  checkGraphNodeMap(arc_set);
  164.97 +  checkGraphArcMap(arc_set);
  164.98 +
  164.99 +  check(arc_set.valid(), "Wrong validity");
 164.100 +  digraph.erase(n1);
 164.101 +  check(!arc_set.valid(), "Wrong validity");
 164.102 +}
 164.103 +
 164.104 +void checkListArcSet() {
 164.105 +  checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
 164.106 +
 164.107 +  typedef ListDigraph Digraph;
 164.108 +  typedef ListArcSet<Digraph> ArcSet;
 164.109 +
 164.110 +  Digraph digraph;
 164.111 +  Digraph::Node
 164.112 +    n1 = digraph.addNode(),
 164.113 +    n2 = digraph.addNode();
 164.114 +
 164.115 +  Digraph::Arc ga1 = digraph.addArc(n1, n2);
 164.116 +
 164.117 +  ArcSet arc_set(digraph);
 164.118 +
 164.119 +  Digraph::Arc ga2 = digraph.addArc(n2, n1);
 164.120 +
 164.121 +  checkGraphNodeList(arc_set, 2);
 164.122 +  checkGraphArcList(arc_set, 0);
 164.123 +
 164.124 +  Digraph::Node
 164.125 +    n3 = digraph.addNode();
 164.126 +  checkGraphNodeList(arc_set, 3);
 164.127 +  checkGraphArcList(arc_set, 0);
 164.128 +
 164.129 +  ArcSet::Arc a1 = arc_set.addArc(n1, n2);
 164.130 +  check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
 164.131 +  checkGraphNodeList(arc_set, 3);
 164.132 +  checkGraphArcList(arc_set, 1);
 164.133 +
 164.134 +  checkGraphOutArcList(arc_set, n1, 1);
 164.135 +  checkGraphOutArcList(arc_set, n2, 0);
 164.136 +  checkGraphOutArcList(arc_set, n3, 0);
 164.137 +
 164.138 +  checkGraphInArcList(arc_set, n1, 0);
 164.139 +  checkGraphInArcList(arc_set, n2, 1);
 164.140 +  checkGraphInArcList(arc_set, n3, 0);
 164.141 +
 164.142 +  checkGraphConArcList(arc_set, 1);
 164.143 +
 164.144 +  ArcSet::Arc a2 = arc_set.addArc(n2, n1),
 164.145 +    a3 = arc_set.addArc(n2, n3),
 164.146 +    a4 = arc_set.addArc(n2, n3);
 164.147 +  checkGraphNodeList(arc_set, 3);
 164.148 +  checkGraphArcList(arc_set, 4);
 164.149 +
 164.150 +  checkGraphOutArcList(arc_set, n1, 1);
 164.151 +  checkGraphOutArcList(arc_set, n2, 3);
 164.152 +  checkGraphOutArcList(arc_set, n3, 0);
 164.153 +
 164.154 +  checkGraphInArcList(arc_set, n1, 1);
 164.155 +  checkGraphInArcList(arc_set, n2, 1);
 164.156 +  checkGraphInArcList(arc_set, n3, 2);
 164.157 +
 164.158 +  checkGraphConArcList(arc_set, 4);
 164.159 +
 164.160 +  checkNodeIds(arc_set);
 164.161 +  checkArcIds(arc_set);
 164.162 +  checkGraphNodeMap(arc_set);
 164.163 +  checkGraphArcMap(arc_set);
 164.164 +
 164.165 +  digraph.erase(n1);
 164.166 +
 164.167 +  checkGraphNodeList(arc_set, 2);
 164.168 +  checkGraphArcList(arc_set, 2);
 164.169 +
 164.170 +  checkGraphOutArcList(arc_set, n2, 2);
 164.171 +  checkGraphOutArcList(arc_set, n3, 0);
 164.172 +
 164.173 +  checkGraphInArcList(arc_set, n2, 0);
 164.174 +  checkGraphInArcList(arc_set, n3, 2);
 164.175 +
 164.176 +  checkNodeIds(arc_set);
 164.177 +  checkArcIds(arc_set);
 164.178 +  checkGraphNodeMap(arc_set);
 164.179 +  checkGraphArcMap(arc_set);
 164.180 +
 164.181 +  checkGraphConArcList(arc_set, 2);
 164.182 +}
 164.183 +
 164.184 +void checkSmartEdgeSet() {
 164.185 +  checkConcept<concepts::Digraph, SmartEdgeSet<ListDigraph> >();
 164.186 +
 164.187 +  typedef ListDigraph Digraph;
 164.188 +  typedef SmartEdgeSet<Digraph> EdgeSet;
 164.189 +
 164.190 +  Digraph digraph;
 164.191 +  Digraph::Node
 164.192 +    n1 = digraph.addNode(),
 164.193 +    n2 = digraph.addNode();
 164.194 +
 164.195 +  Digraph::Arc ga1 = digraph.addArc(n1, n2);
 164.196 +
 164.197 +  EdgeSet edge_set(digraph);
 164.198 +
 164.199 +  Digraph::Arc ga2 = digraph.addArc(n2, n1);
 164.200 +
 164.201 +  checkGraphNodeList(edge_set, 2);
 164.202 +  checkGraphArcList(edge_set, 0);
 164.203 +  checkGraphEdgeList(edge_set, 0);
 164.204 +
 164.205 +  Digraph::Node
 164.206 +    n3 = digraph.addNode();
 164.207 +  checkGraphNodeList(edge_set, 3);
 164.208 +  checkGraphArcList(edge_set, 0);
 164.209 +  checkGraphEdgeList(edge_set, 0);
 164.210 +
 164.211 +  EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
 164.212 +  check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
 164.213 +        (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
 164.214 +  checkGraphNodeList(edge_set, 3);
 164.215 +  checkGraphArcList(edge_set, 2);
 164.216 +  checkGraphEdgeList(edge_set, 1);
 164.217 +
 164.218 +  checkGraphOutArcList(edge_set, n1, 1);
 164.219 +  checkGraphOutArcList(edge_set, n2, 1);
 164.220 +  checkGraphOutArcList(edge_set, n3, 0);
 164.221 +
 164.222 +  checkGraphInArcList(edge_set, n1, 1);
 164.223 +  checkGraphInArcList(edge_set, n2, 1);
 164.224 +  checkGraphInArcList(edge_set, n3, 0);
 164.225 +
 164.226 +  checkGraphIncEdgeList(edge_set, n1, 1);
 164.227 +  checkGraphIncEdgeList(edge_set, n2, 1);
 164.228 +  checkGraphIncEdgeList(edge_set, n3, 0);
 164.229 +
 164.230 +  checkGraphConEdgeList(edge_set, 1);
 164.231 +  checkGraphConArcList(edge_set, 2);
 164.232 +
 164.233 +  EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
 164.234 +    e3 = edge_set.addEdge(n2, n3),
 164.235 +    e4 = edge_set.addEdge(n2, n3);
 164.236 +  checkGraphNodeList(edge_set, 3);
 164.237 +  checkGraphEdgeList(edge_set, 4);
 164.238 +
 164.239 +  checkGraphOutArcList(edge_set, n1, 2);
 164.240 +  checkGraphOutArcList(edge_set, n2, 4);
 164.241 +  checkGraphOutArcList(edge_set, n3, 2);
 164.242 +
 164.243 +  checkGraphInArcList(edge_set, n1, 2);
 164.244 +  checkGraphInArcList(edge_set, n2, 4);
 164.245 +  checkGraphInArcList(edge_set, n3, 2);
 164.246 +
 164.247 +  checkGraphIncEdgeList(edge_set, n1, 2);
 164.248 +  checkGraphIncEdgeList(edge_set, n2, 4);
 164.249 +  checkGraphIncEdgeList(edge_set, n3, 2);
 164.250 +
 164.251 +  checkGraphConEdgeList(edge_set, 4);
 164.252 +  checkGraphConArcList(edge_set, 8);
 164.253 +
 164.254 +  checkArcDirections(edge_set);
 164.255 +
 164.256 +  checkNodeIds(edge_set);
 164.257 +  checkArcIds(edge_set);
 164.258 +  checkEdgeIds(edge_set);
 164.259 +  checkGraphNodeMap(edge_set);
 164.260 +  checkGraphArcMap(edge_set);
 164.261 +  checkGraphEdgeMap(edge_set);
 164.262 +
 164.263 +  check(edge_set.valid(), "Wrong validity");
 164.264 +  digraph.erase(n1);
 164.265 +  check(!edge_set.valid(), "Wrong validity");
 164.266 +}
 164.267 +
 164.268 +void checkListEdgeSet() {
 164.269 +  checkConcept<concepts::Digraph, ListEdgeSet<ListDigraph> >();
 164.270 +
 164.271 +  typedef ListDigraph Digraph;
 164.272 +  typedef ListEdgeSet<Digraph> EdgeSet;
 164.273 +
 164.274 +  Digraph digraph;
 164.275 +  Digraph::Node
 164.276 +    n1 = digraph.addNode(),
 164.277 +    n2 = digraph.addNode();
 164.278 +
 164.279 +  Digraph::Arc ga1 = digraph.addArc(n1, n2);
 164.280 +
 164.281 +  EdgeSet edge_set(digraph);
 164.282 +
 164.283 +  Digraph::Arc ga2 = digraph.addArc(n2, n1);
 164.284 +
 164.285 +  checkGraphNodeList(edge_set, 2);
 164.286 +  checkGraphArcList(edge_set, 0);
 164.287 +  checkGraphEdgeList(edge_set, 0);
 164.288 +
 164.289 +  Digraph::Node
 164.290 +    n3 = digraph.addNode();
 164.291 +  checkGraphNodeList(edge_set, 3);
 164.292 +  checkGraphArcList(edge_set, 0);
 164.293 +  checkGraphEdgeList(edge_set, 0);
 164.294 +
 164.295 +  EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
 164.296 +  check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
 164.297 +        (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
 164.298 +  checkGraphNodeList(edge_set, 3);
 164.299 +  checkGraphArcList(edge_set, 2);
 164.300 +  checkGraphEdgeList(edge_set, 1);
 164.301 +
 164.302 +  checkGraphOutArcList(edge_set, n1, 1);
 164.303 +  checkGraphOutArcList(edge_set, n2, 1);
 164.304 +  checkGraphOutArcList(edge_set, n3, 0);
 164.305 +
 164.306 +  checkGraphInArcList(edge_set, n1, 1);
 164.307 +  checkGraphInArcList(edge_set, n2, 1);
 164.308 +  checkGraphInArcList(edge_set, n3, 0);
 164.309 +
 164.310 +  checkGraphIncEdgeList(edge_set, n1, 1);
 164.311 +  checkGraphIncEdgeList(edge_set, n2, 1);
 164.312 +  checkGraphIncEdgeList(edge_set, n3, 0);
 164.313 +
 164.314 +  checkGraphConEdgeList(edge_set, 1);
 164.315 +  checkGraphConArcList(edge_set, 2);
 164.316 +
 164.317 +  EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
 164.318 +    e3 = edge_set.addEdge(n2, n3),
 164.319 +    e4 = edge_set.addEdge(n2, n3);
 164.320 +  checkGraphNodeList(edge_set, 3);
 164.321 +  checkGraphEdgeList(edge_set, 4);
 164.322 +
 164.323 +  checkGraphOutArcList(edge_set, n1, 2);
 164.324 +  checkGraphOutArcList(edge_set, n2, 4);
 164.325 +  checkGraphOutArcList(edge_set, n3, 2);
 164.326 +
 164.327 +  checkGraphInArcList(edge_set, n1, 2);
 164.328 +  checkGraphInArcList(edge_set, n2, 4);
 164.329 +  checkGraphInArcList(edge_set, n3, 2);
 164.330 +
 164.331 +  checkGraphIncEdgeList(edge_set, n1, 2);
 164.332 +  checkGraphIncEdgeList(edge_set, n2, 4);
 164.333 +  checkGraphIncEdgeList(edge_set, n3, 2);
 164.334 +
 164.335 +  checkGraphConEdgeList(edge_set, 4);
 164.336 +  checkGraphConArcList(edge_set, 8);
 164.337 +
 164.338 +  checkArcDirections(edge_set);
 164.339 +
 164.340 +  checkNodeIds(edge_set);
 164.341 +  checkArcIds(edge_set);
 164.342 +  checkEdgeIds(edge_set);
 164.343 +  checkGraphNodeMap(edge_set);
 164.344 +  checkGraphArcMap(edge_set);
 164.345 +  checkGraphEdgeMap(edge_set);
 164.346 +
 164.347 +  digraph.erase(n1);
 164.348 +
 164.349 +  checkGraphNodeList(edge_set, 2);
 164.350 +  checkGraphArcList(edge_set, 4);
 164.351 +  checkGraphEdgeList(edge_set, 2);
 164.352 +
 164.353 +  checkGraphOutArcList(edge_set, n2, 2);
 164.354 +  checkGraphOutArcList(edge_set, n3, 2);
 164.355 +
 164.356 +  checkGraphInArcList(edge_set, n2, 2);
 164.357 +  checkGraphInArcList(edge_set, n3, 2);
 164.358 +
 164.359 +  checkGraphIncEdgeList(edge_set, n2, 2);
 164.360 +  checkGraphIncEdgeList(edge_set, n3, 2);
 164.361 +
 164.362 +  checkNodeIds(edge_set);
 164.363 +  checkArcIds(edge_set);
 164.364 +  checkEdgeIds(edge_set);
 164.365 +  checkGraphNodeMap(edge_set);
 164.366 +  checkGraphArcMap(edge_set);
 164.367 +  checkGraphEdgeMap(edge_set);
 164.368 +
 164.369 +  checkGraphConEdgeList(edge_set, 2);
 164.370 +  checkGraphConArcList(edge_set, 4);
 164.371 +
 164.372 +}
 164.373 +
 164.374 +
 164.375 +int main() {
 164.376 +
 164.377 +  checkSmartArcSet();
 164.378 +  checkListArcSet();
 164.379 +  checkSmartEdgeSet();
 164.380 +  checkListEdgeSet();
 164.381 +
 164.382 +  return 0;
 164.383 +}
   165.1 --- a/test/error_test.cc	Fri Oct 16 10:21:37 2009 +0200
   165.2 +++ b/test/error_test.cc	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   165.8 + * Copyright (C) 2003-2009
   165.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  165.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  165.11   *
   166.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   166.2 +++ b/test/euler_test.cc	Thu Nov 05 15:50:01 2009 +0100
   166.3 @@ -0,0 +1,223 @@
   166.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   166.5 + *
   166.6 + * This file is a part of LEMON, a generic C++ optimization library.
   166.7 + *
   166.8 + * Copyright (C) 2003-2009
   166.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  166.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  166.11 + *
  166.12 + * Permission to use, modify and distribute this software is granted
  166.13 + * provided that this copyright notice appears in all copies. For
  166.14 + * precise terms see the accompanying LICENSE file.
  166.15 + *
  166.16 + * This software is provided "AS IS" with no warranty of any kind,
  166.17 + * express or implied, and with no claim as to its suitability for any
  166.18 + * purpose.
  166.19 + *
  166.20 + */
  166.21 +
  166.22 +#include <lemon/euler.h>
  166.23 +#include <lemon/list_graph.h>
  166.24 +#include <lemon/adaptors.h>
  166.25 +#include "test_tools.h"
  166.26 +
  166.27 +using namespace lemon;
  166.28 +
  166.29 +template <typename Digraph>
  166.30 +void checkDiEulerIt(const Digraph& g,
  166.31 +                    const typename Digraph::Node& start = INVALID)
  166.32 +{
  166.33 +  typename Digraph::template ArcMap<int> visitationNumber(g, 0);
  166.34 +
  166.35 +  DiEulerIt<Digraph> e(g, start);
  166.36 +  if (e == INVALID) return;
  166.37 +  typename Digraph::Node firstNode = g.source(e);
  166.38 +  typename Digraph::Node lastNode = g.target(e);
  166.39 +  if (start != INVALID) {
  166.40 +    check(firstNode == start, "checkDiEulerIt: Wrong first node");
  166.41 +  }
  166.42 +
  166.43 +  for (; e != INVALID; ++e) {
  166.44 +    if (e != INVALID) lastNode = g.target(e);
  166.45 +    ++visitationNumber[e];
  166.46 +  }
  166.47 +
  166.48 +  check(firstNode == lastNode,
  166.49 +      "checkDiEulerIt: First and last nodes are not the same");
  166.50 +
  166.51 +  for (typename Digraph::ArcIt a(g); a != INVALID; ++a)
  166.52 +  {
  166.53 +    check(visitationNumber[a] == 1,
  166.54 +        "checkDiEulerIt: Not visited or multiple times visited arc found");
  166.55 +  }
  166.56 +}
  166.57 +
  166.58 +template <typename Graph>
  166.59 +void checkEulerIt(const Graph& g,
  166.60 +                  const typename Graph::Node& start = INVALID)
  166.61 +{
  166.62 +  typename Graph::template EdgeMap<int> visitationNumber(g, 0);
  166.63 +
  166.64 +  EulerIt<Graph> e(g, start);
  166.65 +  if (e == INVALID) return;
  166.66 +  typename Graph::Node firstNode = g.source(typename Graph::Arc(e));
  166.67 +  typename Graph::Node lastNode = g.target(typename Graph::Arc(e));
  166.68 +  if (start != INVALID) {
  166.69 +    check(firstNode == start, "checkEulerIt: Wrong first node");
  166.70 +  }
  166.71 +
  166.72 +  for (; e != INVALID; ++e) {
  166.73 +    if (e != INVALID) lastNode = g.target(typename Graph::Arc(e));
  166.74 +    ++visitationNumber[e];
  166.75 +  }
  166.76 +
  166.77 +  check(firstNode == lastNode,
  166.78 +      "checkEulerIt: First and last nodes are not the same");
  166.79 +
  166.80 +  for (typename Graph::EdgeIt e(g); e != INVALID; ++e)
  166.81 +  {
  166.82 +    check(visitationNumber[e] == 1,
  166.83 +        "checkEulerIt: Not visited or multiple times visited edge found");
  166.84 +  }
  166.85 +}
  166.86 +
  166.87 +int main()
  166.88 +{
  166.89 +  typedef ListDigraph Digraph;
  166.90 +  typedef Undirector<Digraph> Graph;
  166.91 +  
  166.92 +  {
  166.93 +    Digraph d;
  166.94 +    Graph g(d);
  166.95 +    
  166.96 +    checkDiEulerIt(d);
  166.97 +    checkDiEulerIt(g);
  166.98 +    checkEulerIt(g);
  166.99 +
 166.100 +    check(eulerian(d), "This graph is Eulerian");
 166.101 +    check(eulerian(g), "This graph is Eulerian");
 166.102 +  }
 166.103 +  {
 166.104 +    Digraph d;
 166.105 +    Graph g(d);
 166.106 +    Digraph::Node n = d.addNode();
 166.107 +
 166.108 +    checkDiEulerIt(d);
 166.109 +    checkDiEulerIt(g);
 166.110 +    checkEulerIt(g);
 166.111 +
 166.112 +    check(eulerian(d), "This graph is Eulerian");
 166.113 +    check(eulerian(g), "This graph is Eulerian");
 166.114 +  }
 166.115 +  {
 166.116 +    Digraph d;
 166.117 +    Graph g(d);
 166.118 +    Digraph::Node n = d.addNode();
 166.119 +    d.addArc(n, n);
 166.120 +
 166.121 +    checkDiEulerIt(d);
 166.122 +    checkDiEulerIt(g);
 166.123 +    checkEulerIt(g);
 166.124 +
 166.125 +    check(eulerian(d), "This graph is Eulerian");
 166.126 +    check(eulerian(g), "This graph is Eulerian");
 166.127 +  }
 166.128 +  {
 166.129 +    Digraph d;
 166.130 +    Graph g(d);
 166.131 +    Digraph::Node n1 = d.addNode();
 166.132 +    Digraph::Node n2 = d.addNode();
 166.133 +    Digraph::Node n3 = d.addNode();
 166.134 +    
 166.135 +    d.addArc(n1, n2);
 166.136 +    d.addArc(n2, n1);
 166.137 +    d.addArc(n2, n3);
 166.138 +    d.addArc(n3, n2);
 166.139 +
 166.140 +    checkDiEulerIt(d);
 166.141 +    checkDiEulerIt(d, n2);
 166.142 +    checkDiEulerIt(g);
 166.143 +    checkDiEulerIt(g, n2);
 166.144 +    checkEulerIt(g);
 166.145 +    checkEulerIt(g, n2);
 166.146 +
 166.147 +    check(eulerian(d), "This graph is Eulerian");
 166.148 +    check(eulerian(g), "This graph is Eulerian");
 166.149 +  }
 166.150 +  {
 166.151 +    Digraph d;
 166.152 +    Graph g(d);
 166.153 +    Digraph::Node n1 = d.addNode();
 166.154 +    Digraph::Node n2 = d.addNode();
 166.155 +    Digraph::Node n3 = d.addNode();
 166.156 +    Digraph::Node n4 = d.addNode();
 166.157 +    Digraph::Node n5 = d.addNode();
 166.158 +    Digraph::Node n6 = d.addNode();
 166.159 +    
 166.160 +    d.addArc(n1, n2);
 166.161 +    d.addArc(n2, n4);
 166.162 +    d.addArc(n1, n3);
 166.163 +    d.addArc(n3, n4);
 166.164 +    d.addArc(n4, n1);
 166.165 +    d.addArc(n3, n5);
 166.166 +    d.addArc(n5, n2);
 166.167 +    d.addArc(n4, n6);
 166.168 +    d.addArc(n2, n6);
 166.169 +    d.addArc(n6, n1);
 166.170 +    d.addArc(n6, n3);
 166.171 +
 166.172 +    checkDiEulerIt(d);
 166.173 +    checkDiEulerIt(d, n1);
 166.174 +    checkDiEulerIt(d, n5);
 166.175 +
 166.176 +    checkDiEulerIt(g);
 166.177 +    checkDiEulerIt(g, n1);
 166.178 +    checkDiEulerIt(g, n5);
 166.179 +    checkEulerIt(g);
 166.180 +    checkEulerIt(g, n1);
 166.181 +    checkEulerIt(g, n5);
 166.182 +
 166.183 +    check(eulerian(d), "This graph is Eulerian");
 166.184 +    check(eulerian(g), "This graph is Eulerian");
 166.185 +  }
 166.186 +  {
 166.187 +    Digraph d;
 166.188 +    Graph g(d);
 166.189 +    Digraph::Node n0 = d.addNode();
 166.190 +    Digraph::Node n1 = d.addNode();
 166.191 +    Digraph::Node n2 = d.addNode();
 166.192 +    Digraph::Node n3 = d.addNode();
 166.193 +    Digraph::Node n4 = d.addNode();
 166.194 +    Digraph::Node n5 = d.addNode();
 166.195 +    
 166.196 +    d.addArc(n1, n2);
 166.197 +    d.addArc(n2, n3);
 166.198 +    d.addArc(n3, n1);
 166.199 +
 166.200 +    checkDiEulerIt(d);
 166.201 +    checkDiEulerIt(d, n2);
 166.202 +
 166.203 +    checkDiEulerIt(g);
 166.204 +    checkDiEulerIt(g, n2);
 166.205 +    checkEulerIt(g);
 166.206 +    checkEulerIt(g, n2);
 166.207 +
 166.208 +    check(!eulerian(d), "This graph is not Eulerian");
 166.209 +    check(!eulerian(g), "This graph is not Eulerian");
 166.210 +  }
 166.211 +  {
 166.212 +    Digraph d;
 166.213 +    Graph g(d);
 166.214 +    Digraph::Node n1 = d.addNode();
 166.215 +    Digraph::Node n2 = d.addNode();
 166.216 +    Digraph::Node n3 = d.addNode();
 166.217 +    
 166.218 +    d.addArc(n1, n2);
 166.219 +    d.addArc(n2, n3);
 166.220 +
 166.221 +    check(!eulerian(d), "This graph is not Eulerian");
 166.222 +    check(!eulerian(g), "This graph is not Eulerian");
 166.223 +  }
 166.224 +
 166.225 +  return 0;
 166.226 +}
   167.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   167.2 +++ b/test/gomory_hu_test.cc	Thu Nov 05 15:50:01 2009 +0100
   167.3 @@ -0,0 +1,123 @@
   167.4 +#include <iostream>
   167.5 +
   167.6 +#include "test_tools.h"
   167.7 +#include <lemon/smart_graph.h>
   167.8 +#include <lemon/concepts/graph.h>
   167.9 +#include <lemon/concepts/maps.h>
  167.10 +#include <lemon/lgf_reader.h>
  167.11 +#include <lemon/gomory_hu.h>
  167.12 +#include <cstdlib>
  167.13 +
  167.14 +using namespace std;
  167.15 +using namespace lemon;
  167.16 +
  167.17 +typedef SmartGraph Graph;
  167.18 +
  167.19 +char test_lgf[] =
  167.20 +  "@nodes\n"
  167.21 +  "label\n"
  167.22 +  "0\n"
  167.23 +  "1\n"
  167.24 +  "2\n"
  167.25 +  "3\n"
  167.26 +  "4\n"
  167.27 +  "@arcs\n"
  167.28 +  "     label capacity\n"
  167.29 +  "0 1  0     1\n"
  167.30 +  "1 2  1     1\n"
  167.31 +  "2 3  2     1\n"
  167.32 +  "0 3  4     5\n"
  167.33 +  "0 3  5     10\n"
  167.34 +  "0 3  6     7\n"
  167.35 +  "4 2  7     1\n"
  167.36 +  "@attributes\n"
  167.37 +  "source 0\n"
  167.38 +  "target 3\n";
  167.39 +  
  167.40 +void checkGomoryHuCompile()
  167.41 +{
  167.42 +  typedef int Value;
  167.43 +  typedef concepts::Graph Graph;
  167.44 +
  167.45 +  typedef Graph::Node Node;
  167.46 +  typedef Graph::Edge Edge;
  167.47 +  typedef concepts::ReadMap<Edge, Value> CapMap;
  167.48 +  typedef concepts::ReadWriteMap<Node, bool> CutMap;
  167.49 +
  167.50 +  Graph g;
  167.51 +  Node n;
  167.52 +  CapMap cap;
  167.53 +  CutMap cut;
  167.54 +  Value v;
  167.55 +  int d;
  167.56 +
  167.57 +  GomoryHu<Graph, CapMap> gh_test(g, cap);
  167.58 +  const GomoryHu<Graph, CapMap>&
  167.59 +    const_gh_test = gh_test;
  167.60 +
  167.61 +  gh_test.run();
  167.62 +
  167.63 +  n = const_gh_test.predNode(n);
  167.64 +  v = const_gh_test.predValue(n);
  167.65 +  d = const_gh_test.rootDist(n);
  167.66 +  v = const_gh_test.minCutValue(n, n);
  167.67 +  v = const_gh_test.minCutMap(n, n, cut);
  167.68 +}
  167.69 +
  167.70 +GRAPH_TYPEDEFS(Graph);
  167.71 +typedef Graph::EdgeMap<int> IntEdgeMap;
  167.72 +typedef Graph::NodeMap<bool> BoolNodeMap;
  167.73 +
  167.74 +int cutValue(const Graph& graph, const BoolNodeMap& cut,
  167.75 +	     const IntEdgeMap& capacity) {
  167.76 +
  167.77 +  int sum = 0;
  167.78 +  for (EdgeIt e(graph); e != INVALID; ++e) {
  167.79 +    Node s = graph.u(e);
  167.80 +    Node t = graph.v(e);
  167.81 +
  167.82 +    if (cut[s] != cut[t]) {
  167.83 +      sum += capacity[e];
  167.84 +    }
  167.85 +  }
  167.86 +  return sum;
  167.87 +}
  167.88 +
  167.89 +
  167.90 +int main() {
  167.91 +  Graph graph;
  167.92 +  IntEdgeMap capacity(graph);
  167.93 +
  167.94 +  std::istringstream input(test_lgf);
  167.95 +  GraphReader<Graph>(graph, input).
  167.96 +    edgeMap("capacity", capacity).run();
  167.97 +
  167.98 +  GomoryHu<Graph> ght(graph, capacity);
  167.99 +  ght.run();
 167.100 +
 167.101 +  for (NodeIt u(graph); u != INVALID; ++u) {
 167.102 +    for (NodeIt v(graph); v != u; ++v) {
 167.103 +      Preflow<Graph, IntEdgeMap> pf(graph, capacity, u, v);
 167.104 +      pf.runMinCut();
 167.105 +      BoolNodeMap cm(graph);
 167.106 +      ght.minCutMap(u, v, cm);
 167.107 +      check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1");
 167.108 +      check(cm[u] != cm[v], "Wrong cut 2");
 167.109 +      check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 3");
 167.110 +
 167.111 +      int sum=0;
 167.112 +      for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
 167.113 +        sum+=capacity[a]; 
 167.114 +      check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
 167.115 +
 167.116 +      sum=0;
 167.117 +      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,true);n!=INVALID;++n)
 167.118 +        sum++;
 167.119 +      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,false);n!=INVALID;++n)
 167.120 +        sum++;
 167.121 +      check(sum == countNodes(graph), "Problem with MinCutNodeIt");
 167.122 +    }
 167.123 +  }
 167.124 +  
 167.125 +  return 0;
 167.126 +}
   168.1 --- a/test/graph_copy_test.cc	Fri Oct 16 10:21:37 2009 +0200
   168.2 +++ b/test/graph_copy_test.cc	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   168.8 + * Copyright (C) 2003-2009
   168.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  168.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  168.11   *
   169.1 --- a/test/graph_test.cc	Fri Oct 16 10:21:37 2009 +0200
   169.2 +++ b/test/graph_test.cc	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   169.8 + * Copyright (C) 2003-2009
   169.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  169.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  169.11   *
  169.12 @@ -19,8 +19,9 @@
  169.13  #include <lemon/concepts/graph.h>
  169.14  #include <lemon/list_graph.h>
  169.15  #include <lemon/smart_graph.h>
  169.16 -// #include <lemon/full_graph.h>
  169.17 -// #include <lemon/grid_graph.h>
  169.18 +#include <lemon/full_graph.h>
  169.19 +#include <lemon/grid_graph.h>
  169.20 +#include <lemon/hypercube_graph.h>
  169.21  
  169.22  #include "test_tools.h"
  169.23  #include "graph_test.h"
  169.24 @@ -29,12 +30,16 @@
  169.25  using namespace lemon::concepts;
  169.26  
  169.27  template <class Graph>
  169.28 -void checkGraph() {
  169.29 +void checkGraphBuild() {
  169.30    TEMPLATE_GRAPH_TYPEDEFS(Graph);
  169.31  
  169.32    Graph G;
  169.33    checkGraphNodeList(G, 0);
  169.34    checkGraphEdgeList(G, 0);
  169.35 +  checkGraphArcList(G, 0);
  169.36 +
  169.37 +  G.reserveNode(3);
  169.38 +  G.reserveEdge(3);
  169.39  
  169.40    Node
  169.41      n1 = G.addNode(),
  169.42 @@ -42,48 +47,36 @@
  169.43      n3 = G.addNode();
  169.44    checkGraphNodeList(G, 3);
  169.45    checkGraphEdgeList(G, 0);
  169.46 +  checkGraphArcList(G, 0);
  169.47  
  169.48    Edge e1 = G.addEdge(n1, n2);
  169.49    check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
  169.50          "Wrong edge");
  169.51 +
  169.52    checkGraphNodeList(G, 3);
  169.53 +  checkGraphEdgeList(G, 1);
  169.54    checkGraphArcList(G, 2);
  169.55 -  checkGraphEdgeList(G, 1);
  169.56  
  169.57 -  checkGraphOutArcList(G, n1, 1);
  169.58 -  checkGraphOutArcList(G, n2, 1);
  169.59 -  checkGraphOutArcList(G, n3, 0);
  169.60 +  checkGraphIncEdgeArcLists(G, n1, 1);
  169.61 +  checkGraphIncEdgeArcLists(G, n2, 1);
  169.62 +  checkGraphIncEdgeArcLists(G, n3, 0);
  169.63  
  169.64 -  checkGraphInArcList(G, n1, 1);
  169.65 -  checkGraphInArcList(G, n2, 1);
  169.66 -  checkGraphInArcList(G, n3, 0);
  169.67 +  checkGraphConEdgeList(G, 1);
  169.68 +  checkGraphConArcList(G, 2);
  169.69  
  169.70 -  checkGraphIncEdgeList(G, n1, 1);
  169.71 -  checkGraphIncEdgeList(G, n2, 1);
  169.72 -  checkGraphIncEdgeList(G, n3, 0);
  169.73 +  Edge e2 = G.addEdge(n2, n1),
  169.74 +       e3 = G.addEdge(n2, n3);
  169.75  
  169.76 -  checkGraphConArcList(G, 2);
  169.77 -  checkGraphConEdgeList(G, 1);
  169.78 +  checkGraphNodeList(G, 3);
  169.79 +  checkGraphEdgeList(G, 3);
  169.80 +  checkGraphArcList(G, 6);
  169.81  
  169.82 -  Edge e2 = G.addEdge(n2, n1), e3 = G.addEdge(n2, n3);
  169.83 -  checkGraphNodeList(G, 3);
  169.84 -  checkGraphArcList(G, 6);
  169.85 -  checkGraphEdgeList(G, 3);
  169.86 +  checkGraphIncEdgeArcLists(G, n1, 2);
  169.87 +  checkGraphIncEdgeArcLists(G, n2, 3);
  169.88 +  checkGraphIncEdgeArcLists(G, n3, 1);
  169.89  
  169.90 -  checkGraphOutArcList(G, n1, 2);
  169.91 -  checkGraphOutArcList(G, n2, 3);
  169.92 -  checkGraphOutArcList(G, n3, 1);
  169.93 -
  169.94 -  checkGraphInArcList(G, n1, 2);
  169.95 -  checkGraphInArcList(G, n2, 3);
  169.96 -  checkGraphInArcList(G, n3, 1);
  169.97 -
  169.98 -  checkGraphIncEdgeList(G, n1, 2);
  169.99 -  checkGraphIncEdgeList(G, n2, 3);
 169.100 -  checkGraphIncEdgeList(G, n3, 1);
 169.101 -
 169.102 +  checkGraphConEdgeList(G, 3);
 169.103    checkGraphConArcList(G, 6);
 169.104 -  checkGraphConEdgeList(G, 3);
 169.105  
 169.106    checkArcDirections(G);
 169.107  
 169.108 @@ -95,6 +88,246 @@
 169.109    checkGraphEdgeMap(G);
 169.110  }
 169.111  
 169.112 +template <class Graph>
 169.113 +void checkGraphAlter() {
 169.114 +  TEMPLATE_GRAPH_TYPEDEFS(Graph);
 169.115 +
 169.116 +  Graph G;
 169.117 +  Node n1 = G.addNode(), n2 = G.addNode(),
 169.118 +       n3 = G.addNode(), n4 = G.addNode();
 169.119 +  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
 169.120 +       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
 169.121 +       e5 = G.addEdge(n4, n3);
 169.122 +
 169.123 +  checkGraphNodeList(G, 4);
 169.124 +  checkGraphEdgeList(G, 5);
 169.125 +  checkGraphArcList(G, 10);
 169.126 +
 169.127 +  // Check changeU() and changeV()
 169.128 +  if (G.u(e2) == n2) {
 169.129 +    G.changeU(e2, n3);
 169.130 +  } else {
 169.131 +    G.changeV(e2, n3);
 169.132 +  }
 169.133 +
 169.134 +  checkGraphNodeList(G, 4);
 169.135 +  checkGraphEdgeList(G, 5);
 169.136 +  checkGraphArcList(G, 10);
 169.137 +
 169.138 +  checkGraphIncEdgeArcLists(G, n1, 3);
 169.139 +  checkGraphIncEdgeArcLists(G, n2, 2);
 169.140 +  checkGraphIncEdgeArcLists(G, n3, 3);
 169.141 +  checkGraphIncEdgeArcLists(G, n4, 2);
 169.142 +
 169.143 +  checkGraphConEdgeList(G, 5);
 169.144 +  checkGraphConArcList(G, 10);
 169.145 +
 169.146 +  if (G.u(e2) == n1) {
 169.147 +    G.changeU(e2, n2);
 169.148 +  } else {
 169.149 +    G.changeV(e2, n2);
 169.150 +  }
 169.151 +
 169.152 +  checkGraphNodeList(G, 4);
 169.153 +  checkGraphEdgeList(G, 5);
 169.154 +  checkGraphArcList(G, 10);
 169.155 +
 169.156 +  checkGraphIncEdgeArcLists(G, n1, 2);
 169.157 +  checkGraphIncEdgeArcLists(G, n2, 3);
 169.158 +  checkGraphIncEdgeArcLists(G, n3, 3);
 169.159 +  checkGraphIncEdgeArcLists(G, n4, 2);
 169.160 +
 169.161 +  checkGraphConEdgeList(G, 5);
 169.162 +  checkGraphConArcList(G, 10);
 169.163 +
 169.164 +  // Check contract()
 169.165 +  G.contract(n1, n4, false);
 169.166 +
 169.167 +  checkGraphNodeList(G, 3);
 169.168 +  checkGraphEdgeList(G, 5);
 169.169 +  checkGraphArcList(G, 10);
 169.170 +
 169.171 +  checkGraphIncEdgeArcLists(G, n1, 4);
 169.172 +  checkGraphIncEdgeArcLists(G, n2, 3);
 169.173 +  checkGraphIncEdgeArcLists(G, n3, 3);
 169.174 +
 169.175 +  checkGraphConEdgeList(G, 5);
 169.176 +  checkGraphConArcList(G, 10);
 169.177 +
 169.178 +  G.contract(n2, n3);
 169.179 +
 169.180 +  checkGraphNodeList(G, 2);
 169.181 +  checkGraphEdgeList(G, 3);
 169.182 +  checkGraphArcList(G, 6);
 169.183 +
 169.184 +  checkGraphIncEdgeArcLists(G, n1, 4);
 169.185 +  checkGraphIncEdgeArcLists(G, n2, 2);
 169.186 +
 169.187 +  checkGraphConEdgeList(G, 3);
 169.188 +  checkGraphConArcList(G, 6);
 169.189 +}
 169.190 +
 169.191 +template <class Graph>
 169.192 +void checkGraphErase() {
 169.193 +  TEMPLATE_GRAPH_TYPEDEFS(Graph);
 169.194 +
 169.195 +  Graph G;
 169.196 +  Node n1 = G.addNode(), n2 = G.addNode(),
 169.197 +       n3 = G.addNode(), n4 = G.addNode();
 169.198 +  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
 169.199 +       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
 169.200 +       e5 = G.addEdge(n4, n3);
 169.201 +
 169.202 +  // Check edge deletion
 169.203 +  G.erase(e2);
 169.204 +
 169.205 +  checkGraphNodeList(G, 4);
 169.206 +  checkGraphEdgeList(G, 4);
 169.207 +  checkGraphArcList(G, 8);
 169.208 +
 169.209 +  checkGraphIncEdgeArcLists(G, n1, 2);
 169.210 +  checkGraphIncEdgeArcLists(G, n2, 2);
 169.211 +  checkGraphIncEdgeArcLists(G, n3, 2);
 169.212 +  checkGraphIncEdgeArcLists(G, n4, 2);
 169.213 +
 169.214 +  checkGraphConEdgeList(G, 4);
 169.215 +  checkGraphConArcList(G, 8);
 169.216 +
 169.217 +  // Check node deletion
 169.218 +  G.erase(n3);
 169.219 +
 169.220 +  checkGraphNodeList(G, 3);
 169.221 +  checkGraphEdgeList(G, 2);
 169.222 +  checkGraphArcList(G, 4);
 169.223 +
 169.224 +  checkGraphIncEdgeArcLists(G, n1, 2);
 169.225 +  checkGraphIncEdgeArcLists(G, n2, 1);
 169.226 +  checkGraphIncEdgeArcLists(G, n4, 1);
 169.227 +
 169.228 +  checkGraphConEdgeList(G, 2);
 169.229 +  checkGraphConArcList(G, 4);
 169.230 +}
 169.231 +
 169.232 +
 169.233 +template <class Graph>
 169.234 +void checkGraphSnapshot() {
 169.235 +  TEMPLATE_GRAPH_TYPEDEFS(Graph);
 169.236 +
 169.237 +  Graph G;
 169.238 +  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
 169.239 +  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
 169.240 +       e3 = G.addEdge(n2, n3);
 169.241 +
 169.242 +  checkGraphNodeList(G, 3);
 169.243 +  checkGraphEdgeList(G, 3);
 169.244 +  checkGraphArcList(G, 6);
 169.245 +
 169.246 +  typename Graph::Snapshot snapshot(G);
 169.247 +
 169.248 +  Node n = G.addNode();
 169.249 +  G.addEdge(n3, n);
 169.250 +  G.addEdge(n, n3);
 169.251 +  G.addEdge(n3, n2);
 169.252 +
 169.253 +  checkGraphNodeList(G, 4);
 169.254 +  checkGraphEdgeList(G, 6);
 169.255 +  checkGraphArcList(G, 12);
 169.256 +
 169.257 +  snapshot.restore();
 169.258 +
 169.259 +  checkGraphNodeList(G, 3);
 169.260 +  checkGraphEdgeList(G, 3);
 169.261 +  checkGraphArcList(G, 6);
 169.262 +
 169.263 +  checkGraphIncEdgeArcLists(G, n1, 2);
 169.264 +  checkGraphIncEdgeArcLists(G, n2, 3);
 169.265 +  checkGraphIncEdgeArcLists(G, n3, 1);
 169.266 +
 169.267 +  checkGraphConEdgeList(G, 3);
 169.268 +  checkGraphConArcList(G, 6);
 169.269 +
 169.270 +  checkNodeIds(G);
 169.271 +  checkEdgeIds(G);
 169.272 +  checkArcIds(G);
 169.273 +  checkGraphNodeMap(G);
 169.274 +  checkGraphEdgeMap(G);
 169.275 +  checkGraphArcMap(G);
 169.276 +
 169.277 +  G.addNode();
 169.278 +  snapshot.save(G);
 169.279 +
 169.280 +  G.addEdge(G.addNode(), G.addNode());
 169.281 +
 169.282 +  snapshot.restore();
 169.283 +  snapshot.save(G);
 169.284 +
 169.285 +  checkGraphNodeList(G, 4);
 169.286 +  checkGraphEdgeList(G, 3);
 169.287 +  checkGraphArcList(G, 6);
 169.288 +  
 169.289 +  G.addEdge(G.addNode(), G.addNode());
 169.290 +
 169.291 +  snapshot.restore();
 169.292 +
 169.293 +  checkGraphNodeList(G, 4);
 169.294 +  checkGraphEdgeList(G, 3);
 169.295 +  checkGraphArcList(G, 6);
 169.296 +}
 169.297 +
 169.298 +void checkFullGraph(int num) {
 169.299 +  typedef FullGraph Graph;
 169.300 +  GRAPH_TYPEDEFS(Graph);
 169.301 +
 169.302 +  Graph G(num);
 169.303 +  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
 169.304 +        "Wrong size");
 169.305 +
 169.306 +  G.resize(num);
 169.307 +  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
 169.308 +        "Wrong size");
 169.309 +
 169.310 +  checkGraphNodeList(G, num);
 169.311 +  checkGraphEdgeList(G, num * (num - 1) / 2);
 169.312 +
 169.313 +  for (NodeIt n(G); n != INVALID; ++n) {
 169.314 +    checkGraphOutArcList(G, n, num - 1);
 169.315 +    checkGraphInArcList(G, n, num - 1);
 169.316 +    checkGraphIncEdgeList(G, n, num - 1);
 169.317 +  }
 169.318 +
 169.319 +  checkGraphConArcList(G, num * (num - 1));
 169.320 +  checkGraphConEdgeList(G, num * (num - 1) / 2);
 169.321 +
 169.322 +  checkArcDirections(G);
 169.323 +
 169.324 +  checkNodeIds(G);
 169.325 +  checkArcIds(G);
 169.326 +  checkEdgeIds(G);
 169.327 +  checkGraphNodeMap(G);
 169.328 +  checkGraphArcMap(G);
 169.329 +  checkGraphEdgeMap(G);
 169.330 +
 169.331 +
 169.332 +  for (int i = 0; i < G.nodeNum(); ++i) {
 169.333 +    check(G.index(G(i)) == i, "Wrong index");
 169.334 +  }
 169.335 +
 169.336 +  for (NodeIt u(G); u != INVALID; ++u) {
 169.337 +    for (NodeIt v(G); v != INVALID; ++v) {
 169.338 +      Edge e = G.edge(u, v);
 169.339 +      Arc a = G.arc(u, v);
 169.340 +      if (u == v) {
 169.341 +        check(e == INVALID, "Wrong edge lookup");
 169.342 +        check(a == INVALID, "Wrong arc lookup");
 169.343 +      } else {
 169.344 +        check((G.u(e) == u && G.v(e) == v) ||
 169.345 +              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
 169.346 +        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
 169.347 +      }
 169.348 +    }
 169.349 +  }
 169.350 +}
 169.351 +
 169.352  void checkConcepts() {
 169.353    { // Checking graph components
 169.354      checkConcept<BaseGraphComponent, BaseGraphComponent >();
 169.355 @@ -124,14 +357,15 @@
 169.356      checkConcept<ExtendableGraphComponent<>, SmartGraph>();
 169.357      checkConcept<ClearableGraphComponent<>, SmartGraph>();
 169.358    }
 169.359 -//  { // Checking FullGraph
 169.360 -//    checkConcept<Graph, FullGraph>();
 169.361 -//    checkGraphIterators<FullGraph>();
 169.362 -//  }
 169.363 -//  { // Checking GridGraph
 169.364 -//    checkConcept<Graph, GridGraph>();
 169.365 -//    checkGraphIterators<GridGraph>();
 169.366 -//  }
 169.367 +  { // Checking FullGraph
 169.368 +    checkConcept<Graph, FullGraph>();
 169.369 +  }
 169.370 +  { // Checking GridGraph
 169.371 +    checkConcept<Graph, GridGraph>();
 169.372 +  }
 169.373 +  { // Checking HypercubeGraph
 169.374 +    checkConcept<Graph, HypercubeGraph>();
 169.375 +  }
 169.376  }
 169.377  
 169.378  template <typename Graph>
 169.379 @@ -188,70 +422,172 @@
 169.380    check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
 169.381  }
 169.382  
 169.383 -// void checkGridGraph(const GridGraph& g, int w, int h) {
 169.384 -//   check(g.width() == w, "Wrong width");
 169.385 -//   check(g.height() == h, "Wrong height");
 169.386 +void checkGridGraph(int width, int height) {
 169.387 +  typedef GridGraph Graph;
 169.388 +  GRAPH_TYPEDEFS(Graph);
 169.389 +  Graph G(width, height);
 169.390  
 169.391 -//   for (int i = 0; i < w; ++i) {
 169.392 -//     for (int j = 0; j < h; ++j) {
 169.393 -//       check(g.col(g(i, j)) == i, "Wrong col");
 169.394 -//       check(g.row(g(i, j)) == j, "Wrong row");
 169.395 -//     }
 169.396 -//   }
 169.397 +  check(G.width() == width, "Wrong column number");
 169.398 +  check(G.height() == height, "Wrong row number");
 169.399  
 169.400 -//   for (int i = 0; i < w; ++i) {
 169.401 -//     for (int j = 0; j < h - 1; ++j) {
 169.402 -//       check(g.source(g.down(g(i, j))) == g(i, j), "Wrong down");
 169.403 -//       check(g.target(g.down(g(i, j))) == g(i, j + 1), "Wrong down");
 169.404 -//     }
 169.405 -//     check(g.down(g(i, h - 1)) == INVALID, "Wrong down");
 169.406 -//   }
 169.407 +  G.resize(width, height);
 169.408 +  check(G.width() == width, "Wrong column number");
 169.409 +  check(G.height() == height, "Wrong row number");
 169.410  
 169.411 -//   for (int i = 0; i < w; ++i) {
 169.412 -//     for (int j = 1; j < h; ++j) {
 169.413 -//       check(g.source(g.up(g(i, j))) == g(i, j), "Wrong up");
 169.414 -//       check(g.target(g.up(g(i, j))) == g(i, j - 1), "Wrong up");
 169.415 -//     }
 169.416 -//     check(g.up(g(i, 0)) == INVALID, "Wrong up");
 169.417 -//   }
 169.418 +  for (int i = 0; i < width; ++i) {
 169.419 +    for (int j = 0; j < height; ++j) {
 169.420 +      check(G.col(G(i, j)) == i, "Wrong column");
 169.421 +      check(G.row(G(i, j)) == j, "Wrong row");
 169.422 +      check(G.pos(G(i, j)).x == i, "Wrong column");
 169.423 +      check(G.pos(G(i, j)).y == j, "Wrong row");
 169.424 +    }
 169.425 +  }
 169.426  
 169.427 -//   for (int j = 0; j < h; ++j) {
 169.428 -//     for (int i = 0; i < w - 1; ++i) {
 169.429 -//       check(g.source(g.right(g(i, j))) == g(i, j), "Wrong right");
 169.430 -//       check(g.target(g.right(g(i, j))) == g(i + 1, j), "Wrong right");
 169.431 -//     }
 169.432 -//     check(g.right(g(w - 1, j)) == INVALID, "Wrong right");
 169.433 -//   }
 169.434 +  for (int j = 0; j < height; ++j) {
 169.435 +    for (int i = 0; i < width - 1; ++i) {
 169.436 +      check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
 169.437 +      check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
 169.438 +    }
 169.439 +    check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
 169.440 +  }
 169.441  
 169.442 -//   for (int j = 0; j < h; ++j) {
 169.443 -//     for (int i = 1; i < w; ++i) {
 169.444 -//       check(g.source(g.left(g(i, j))) == g(i, j), "Wrong left");
 169.445 -//       check(g.target(g.left(g(i, j))) == g(i - 1, j), "Wrong left");
 169.446 -//     }
 169.447 -//     check(g.left(g(0, j)) == INVALID, "Wrong left");
 169.448 -//   }
 169.449 -// }
 169.450 +  for (int j = 0; j < height; ++j) {
 169.451 +    for (int i = 1; i < width; ++i) {
 169.452 +      check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
 169.453 +      check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
 169.454 +    }
 169.455 +    check(G.left(G(0, j)) == INVALID, "Wrong left");
 169.456 +  }
 169.457 +
 169.458 +  for (int i = 0; i < width; ++i) {
 169.459 +    for (int j = 0; j < height - 1; ++j) {
 169.460 +      check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
 169.461 +      check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
 169.462 +    }
 169.463 +    check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
 169.464 +  }
 169.465 +
 169.466 +  for (int i = 0; i < width; ++i) {
 169.467 +    for (int j = 1; j < height; ++j) {
 169.468 +      check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
 169.469 +      check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
 169.470 +    }
 169.471 +    check(G.down(G(i, 0)) == INVALID, "Wrong down");
 169.472 +  }
 169.473 +
 169.474 +  checkGraphNodeList(G, width * height);
 169.475 +  checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
 169.476 +  checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
 169.477 +
 169.478 +  for (NodeIt n(G); n != INVALID; ++n) {
 169.479 +    int nb = 4;
 169.480 +    if (G.col(n) == 0) --nb;
 169.481 +    if (G.col(n) == width - 1) --nb;
 169.482 +    if (G.row(n) == 0) --nb;
 169.483 +    if (G.row(n) == height - 1) --nb;
 169.484 +
 169.485 +    checkGraphOutArcList(G, n, nb);
 169.486 +    checkGraphInArcList(G, n, nb);
 169.487 +    checkGraphIncEdgeList(G, n, nb);
 169.488 +  }
 169.489 +
 169.490 +  checkArcDirections(G);
 169.491 +
 169.492 +  checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
 169.493 +  checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
 169.494 +
 169.495 +  checkNodeIds(G);
 169.496 +  checkArcIds(G);
 169.497 +  checkEdgeIds(G);
 169.498 +  checkGraphNodeMap(G);
 169.499 +  checkGraphArcMap(G);
 169.500 +  checkGraphEdgeMap(G);
 169.501 +
 169.502 +}
 169.503 +
 169.504 +void checkHypercubeGraph(int dim) {
 169.505 +  GRAPH_TYPEDEFS(HypercubeGraph);
 169.506 +
 169.507 +  HypercubeGraph G(dim);
 169.508 +  check(G.dimension() == dim, "Wrong dimension");
 169.509 +
 169.510 +  G.resize(dim);
 169.511 +  check(G.dimension() == dim, "Wrong dimension");
 169.512 +  
 169.513 +  checkGraphNodeList(G, 1 << dim);
 169.514 +  checkGraphEdgeList(G, dim * (1 << (dim-1)));
 169.515 +  checkGraphArcList(G, dim * (1 << dim));
 169.516 +
 169.517 +  Node n = G.nodeFromId(dim);
 169.518 +
 169.519 +  for (NodeIt n(G); n != INVALID; ++n) {
 169.520 +    checkGraphIncEdgeList(G, n, dim);
 169.521 +    for (IncEdgeIt e(G, n); e != INVALID; ++e) {
 169.522 +      check( (G.u(e) == n &&
 169.523 +              G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
 169.524 +             (G.v(e) == n &&
 169.525 +              G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
 169.526 +             "Wrong edge or wrong dimension");
 169.527 +    }
 169.528 +
 169.529 +    checkGraphOutArcList(G, n, dim);
 169.530 +    for (OutArcIt a(G, n); a != INVALID; ++a) {
 169.531 +      check(G.source(a) == n &&
 169.532 +            G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
 169.533 +            "Wrong arc or wrong dimension");
 169.534 +    }
 169.535 +
 169.536 +    checkGraphInArcList(G, n, dim);
 169.537 +    for (InArcIt a(G, n); a != INVALID; ++a) {
 169.538 +      check(G.target(a) == n &&
 169.539 +            G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
 169.540 +            "Wrong arc or wrong dimension");
 169.541 +    }
 169.542 +  }
 169.543 +
 169.544 +  checkGraphConArcList(G, (1 << dim) * dim);
 169.545 +  checkGraphConEdgeList(G, dim * (1 << (dim-1)));
 169.546 +
 169.547 +  checkArcDirections(G);
 169.548 +
 169.549 +  checkNodeIds(G);
 169.550 +  checkArcIds(G);
 169.551 +  checkEdgeIds(G);
 169.552 +  checkGraphNodeMap(G);
 169.553 +  checkGraphArcMap(G);
 169.554 +  checkGraphEdgeMap(G);
 169.555 +}
 169.556  
 169.557  void checkGraphs() {
 169.558    { // Checking ListGraph
 169.559 -    checkGraph<ListGraph>();
 169.560 +    checkGraphBuild<ListGraph>();
 169.561 +    checkGraphAlter<ListGraph>();
 169.562 +    checkGraphErase<ListGraph>();
 169.563 +    checkGraphSnapshot<ListGraph>();
 169.564      checkGraphValidityErase<ListGraph>();
 169.565    }
 169.566    { // Checking SmartGraph
 169.567 -    checkGraph<SmartGraph>();
 169.568 +    checkGraphBuild<SmartGraph>();
 169.569 +    checkGraphSnapshot<SmartGraph>();
 169.570      checkGraphValidity<SmartGraph>();
 169.571    }
 169.572 -//   { // Checking FullGraph
 169.573 -//     FullGraph g(5);
 169.574 -//     checkGraphNodeList(g, 5);
 169.575 -//     checkGraphEdgeList(g, 10);
 169.576 -//   }
 169.577 -//   { // Checking GridGraph
 169.578 -//     GridGraph g(5, 6);
 169.579 -//     checkGraphNodeList(g, 30);
 169.580 -//     checkGraphEdgeList(g, 49);
 169.581 -//     checkGridGraph(g, 5, 6);
 169.582 -//   }
 169.583 +  { // Checking FullGraph
 169.584 +    checkFullGraph(7);
 169.585 +    checkFullGraph(8);
 169.586 +  }
 169.587 +  { // Checking GridGraph
 169.588 +    checkGridGraph(5, 8);
 169.589 +    checkGridGraph(8, 5);
 169.590 +    checkGridGraph(5, 5);
 169.591 +    checkGridGraph(0, 0);
 169.592 +    checkGridGraph(1, 1);
 169.593 +  }
 169.594 +  { // Checking HypercubeGraph
 169.595 +    checkHypercubeGraph(1);
 169.596 +    checkHypercubeGraph(2);
 169.597 +    checkHypercubeGraph(3);
 169.598 +    checkHypercubeGraph(4);
 169.599 +  }
 169.600  }
 169.601  
 169.602  int main() {
   170.1 --- a/test/graph_test.h	Fri Oct 16 10:21:37 2009 +0200
   170.2 +++ b/test/graph_test.h	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   170.8 + * Copyright (C) 2003-2009
   170.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  170.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  170.11   *
  170.12 @@ -117,6 +117,15 @@
  170.13    }
  170.14  
  170.15    template <class Graph>
  170.16 +  void checkGraphIncEdgeArcLists(const Graph &G, typename Graph::Node n,
  170.17 +                                 int cnt)
  170.18 +  {
  170.19 +    checkGraphIncEdgeList(G, n, cnt);
  170.20 +    checkGraphOutArcList(G, n, cnt);
  170.21 +    checkGraphInArcList(G, n, cnt);
  170.22 +  }
  170.23 +
  170.24 +  template <class Graph>
  170.25    void checkGraphConArcList(const Graph &G, int cnt) {
  170.26      int i = 0;
  170.27      for (typename Graph::NodeIt u(G); u != INVALID; ++u) {
   171.1 --- a/test/graph_utils_test.cc	Fri Oct 16 10:21:37 2009 +0200
   171.2 +++ b/test/graph_utils_test.cc	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   171.8 + * Copyright (C) 2003-2009
   171.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  171.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  171.11   *
  171.12 @@ -38,15 +38,15 @@
  171.13      for (int i = 0; i < 10; ++i) {
  171.14        digraph.addNode();
  171.15      }
  171.16 -    DescriptorMap<Digraph, Node> nodes(digraph);
  171.17 -    typename DescriptorMap<Digraph, Node>::InverseMap invNodes(nodes);
  171.18 +    RangeIdMap<Digraph, Node> nodes(digraph);
  171.19 +    typename RangeIdMap<Digraph, Node>::InverseMap invNodes(nodes);
  171.20      for (int i = 0; i < 100; ++i) {
  171.21        int src = rnd[invNodes.size()];
  171.22        int trg = rnd[invNodes.size()];
  171.23        digraph.addArc(invNodes[src], invNodes[trg]);
  171.24      }
  171.25      typename Digraph::template ArcMap<bool> found(digraph, false);
  171.26 -    DescriptorMap<Digraph, Arc> arcs(digraph);
  171.27 +    RangeIdMap<Digraph, Arc> arcs(digraph);
  171.28      for (NodeIt src(digraph); src != INVALID; ++src) {
  171.29        for (NodeIt trg(digraph); trg != INVALID; ++trg) {
  171.30          for (ConArcIt<Digraph> con(digraph, src, trg); con != INVALID; ++con) {
  171.31 @@ -113,15 +113,15 @@
  171.32    for (int i = 0; i < 10; ++i) {
  171.33      graph.addNode();
  171.34    }
  171.35 -  DescriptorMap<Graph, Node> nodes(graph);
  171.36 -  typename DescriptorMap<Graph, Node>::InverseMap invNodes(nodes);
  171.37 +  RangeIdMap<Graph, Node> nodes(graph);
  171.38 +  typename RangeIdMap<Graph, Node>::InverseMap invNodes(nodes);
  171.39    for (int i = 0; i < 100; ++i) {
  171.40      int src = rnd[invNodes.size()];
  171.41      int trg = rnd[invNodes.size()];
  171.42      graph.addEdge(invNodes[src], invNodes[trg]);
  171.43    }
  171.44    typename Graph::template EdgeMap<int> found(graph, 0);
  171.45 -  DescriptorMap<Graph, Edge> edges(graph);
  171.46 +  RangeIdMap<Graph, Edge> edges(graph);
  171.47    for (NodeIt src(graph); src != INVALID; ++src) {
  171.48      for (NodeIt trg(graph); trg != INVALID; ++trg) {
  171.49        for (ConEdgeIt<Graph> con(graph, src, trg); con != INVALID; ++con) {
   172.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   172.2 +++ b/test/hao_orlin_test.cc	Thu Nov 05 15:50:01 2009 +0100
   172.3 @@ -0,0 +1,163 @@
   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-2009
   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 <sstream>
  172.23 +
  172.24 +#include <lemon/smart_graph.h>
  172.25 +#include <lemon/adaptors.h>
  172.26 +#include <lemon/concepts/digraph.h>
  172.27 +#include <lemon/concepts/maps.h>
  172.28 +#include <lemon/lgf_reader.h>
  172.29 +#include <lemon/hao_orlin.h>
  172.30 +
  172.31 +#include "test_tools.h"
  172.32 +
  172.33 +using namespace lemon;
  172.34 +using namespace std;
  172.35 +
  172.36 +const std::string lgf =
  172.37 +  "@nodes\n"
  172.38 +  "label\n"
  172.39 +  "0\n"
  172.40 +  "1\n"
  172.41 +  "2\n"
  172.42 +  "3\n"
  172.43 +  "4\n"
  172.44 +  "5\n"
  172.45 +  "@edges\n"
  172.46 +  "     cap1 cap2 cap3\n"
  172.47 +  "0 1  1    1    1   \n"
  172.48 +  "0 2  2    2    4   \n"
  172.49 +  "1 2  4    4    4   \n"
  172.50 +  "3 4  1    1    1   \n"
  172.51 +  "3 5  2    2    4   \n"
  172.52 +  "4 5  4    4    4   \n"
  172.53 +  "5 4  4    4    4   \n"
  172.54 +  "2 3  1    6    6   \n"
  172.55 +  "4 0  1    6    6   \n";
  172.56 +
  172.57 +void checkHaoOrlinCompile()
  172.58 +{
  172.59 +  typedef int Value;
  172.60 +  typedef concepts::Digraph Digraph;
  172.61 +
  172.62 +  typedef Digraph::Node Node;
  172.63 +  typedef Digraph::Arc Arc;
  172.64 +  typedef concepts::ReadMap<Arc, Value> CapMap;
  172.65 +  typedef concepts::WriteMap<Node, bool> CutMap;
  172.66 +
  172.67 +  Digraph g;
  172.68 +  Node n;
  172.69 +  CapMap cap;
  172.70 +  CutMap cut;
  172.71 +  Value v;
  172.72 +
  172.73 +  HaoOrlin<Digraph, CapMap> ho_test(g, cap);
  172.74 +  const HaoOrlin<Digraph, CapMap>&
  172.75 +    const_ho_test = ho_test;
  172.76 +
  172.77 +  ho_test.init();
  172.78 +  ho_test.init(n);
  172.79 +  ho_test.calculateOut();
  172.80 +  ho_test.calculateIn();
  172.81 +  ho_test.run();
  172.82 +  ho_test.run(n);
  172.83 +
  172.84 +  v = const_ho_test.minCutValue();
  172.85 +  v = const_ho_test.minCutMap(cut);
  172.86 +}
  172.87 +
  172.88 +template <typename Graph, typename CapMap, typename CutMap>
  172.89 +typename CapMap::Value 
  172.90 +  cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
  172.91 +{
  172.92 +  typename CapMap::Value sum = 0;
  172.93 +  for (typename Graph::ArcIt a(graph); a != INVALID; ++a) {
  172.94 +    if (cut[graph.source(a)] && !cut[graph.target(a)])
  172.95 +      sum += cap[a];
  172.96 +  }
  172.97 +  return sum;
  172.98 +}
  172.99 +
 172.100 +int main() {
 172.101 +  SmartDigraph graph;
 172.102 +  SmartDigraph::ArcMap<int> cap1(graph), cap2(graph), cap3(graph);
 172.103 +  SmartDigraph::NodeMap<bool> cut(graph);
 172.104 +
 172.105 +  istringstream input(lgf);
 172.106 +  digraphReader(graph, input)
 172.107 +    .arcMap("cap1", cap1)
 172.108 +    .arcMap("cap2", cap2)
 172.109 +    .arcMap("cap3", cap3)
 172.110 +    .run();
 172.111 +
 172.112 +  {
 172.113 +    HaoOrlin<SmartDigraph> ho(graph, cap1);
 172.114 +    ho.run();
 172.115 +    ho.minCutMap(cut);
 172.116 +    
 172.117 +    check(ho.minCutValue() == 1, "Wrong cut value");
 172.118 +    check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
 172.119 +  }
 172.120 +  {
 172.121 +    HaoOrlin<SmartDigraph> ho(graph, cap2);
 172.122 +    ho.run();
 172.123 +    ho.minCutMap(cut);
 172.124 +
 172.125 +    check(ho.minCutValue() == 1, "Wrong cut value");
 172.126 +    check(ho.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
 172.127 +  }
 172.128 +  {
 172.129 +    HaoOrlin<SmartDigraph> ho(graph, cap3);
 172.130 +    ho.run();
 172.131 +    ho.minCutMap(cut);
 172.132 +    
 172.133 +    check(ho.minCutValue() == 1, "Wrong cut value");
 172.134 +    check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
 172.135 +  }
 172.136 +  
 172.137 +  typedef Undirector<SmartDigraph> UGraph;
 172.138 +  UGraph ugraph(graph);
 172.139 +  
 172.140 +  {
 172.141 +    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1);
 172.142 +    ho.run();
 172.143 +    ho.minCutMap(cut);
 172.144 +    
 172.145 +    check(ho.minCutValue() == 2, "Wrong cut value");
 172.146 +    check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value");
 172.147 +  }
 172.148 +  {
 172.149 +    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap2);
 172.150 +    ho.run();
 172.151 +    ho.minCutMap(cut);
 172.152 +    
 172.153 +    check(ho.minCutValue() == 5, "Wrong cut value");
 172.154 +    check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value");
 172.155 +  }
 172.156 +  {
 172.157 +    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap3);
 172.158 +    ho.run();
 172.159 +    ho.minCutMap(cut);
 172.160 +    
 172.161 +    check(ho.minCutValue() == 5, "Wrong cut value");
 172.162 +    check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value");
 172.163 +  }
 172.164 +
 172.165 +  return 0;
 172.166 +}
   173.1 --- a/test/heap_test.cc	Fri Oct 16 10:21:37 2009 +0200
   173.2 +++ b/test/heap_test.cc	Thu Nov 05 15:50:01 2009 +0100
   173.3 @@ -2,7 +2,7 @@
   173.4   *
   173.5   * This file is a part of LEMON, a generic C++ optimization library.
   173.6   *
   173.7 - * Copyright (C) 2003-2008
   173.8 + * Copyright (C) 2003-2009
   173.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  173.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  173.11   *
  173.12 @@ -25,12 +25,18 @@
  173.13  #include <lemon/concepts/heap.h>
  173.14  
  173.15  #include <lemon/smart_graph.h>
  173.16 -
  173.17  #include <lemon/lgf_reader.h>
  173.18  #include <lemon/dijkstra.h>
  173.19  #include <lemon/maps.h>
  173.20  
  173.21  #include <lemon/bin_heap.h>
  173.22 +#include <lemon/fourary_heap.h>
  173.23 +#include <lemon/kary_heap.h>
  173.24 +#include <lemon/fib_heap.h>
  173.25 +#include <lemon/pairing_heap.h>
  173.26 +#include <lemon/radix_heap.h>
  173.27 +#include <lemon/binom_heap.h>
  173.28 +#include <lemon/bucket_heap.h>
  173.29  
  173.30  #include "test_tools.h"
  173.31  
  173.32 @@ -86,18 +92,16 @@
  173.33  template <typename Heap>
  173.34  void heapSortTest() {
  173.35    RangeMap<int> map(test_len, -1);
  173.36 -
  173.37    Heap heap(map);
  173.38  
  173.39    std::vector<int> v(test_len);
  173.40 -
  173.41    for (int i = 0; i < test_len; ++i) {
  173.42      v[i] = test_seq[i];
  173.43      heap.push(i, v[i]);
  173.44    }
  173.45    std::sort(v.begin(), v.end());
  173.46    for (int i = 0; i < test_len; ++i) {
  173.47 -    check(v[i] == heap.prio() ,"Wrong order in heap sort.");
  173.48 +    check(v[i] == heap.prio(), "Wrong order in heap sort.");
  173.49      heap.pop();
  173.50    }
  173.51  }
  173.52 @@ -109,7 +113,6 @@
  173.53    Heap heap(map);
  173.54  
  173.55    std::vector<int> v(test_len);
  173.56 -
  173.57    for (int i = 0; i < test_len; ++i) {
  173.58      v[i] = test_seq[i];
  173.59      heap.push(i, v[i]);
  173.60 @@ -120,13 +123,11 @@
  173.61    }
  173.62    std::sort(v.begin(), v.end());
  173.63    for (int i = 0; i < test_len; ++i) {
  173.64 -    check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
  173.65 +    check(v[i] == heap.prio(), "Wrong order in heap increase test.");
  173.66      heap.pop();
  173.67    }
  173.68  }
  173.69  
  173.70 -
  173.71 -
  173.72  template <typename Heap>
  173.73  void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
  173.74                        Node source) {
  173.75 @@ -141,7 +142,7 @@
  173.76      Node t = digraph.target(a);
  173.77      if (dijkstra.reached(s)) {
  173.78        check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
  173.79 -             "Error in a shortest path tree!");
  173.80 +             "Error in shortest path tree.");
  173.81      }
  173.82    }
  173.83  
  173.84 @@ -150,7 +151,7 @@
  173.85        Arc a = dijkstra.predArc(n);
  173.86        Node s = digraph.source(a);
  173.87        check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
  173.88 -             "Error in a shortest path tree!");
  173.89 +             "Error in shortest path tree.");
  173.90      }
  173.91    }
  173.92  
  173.93 @@ -172,6 +173,7 @@
  173.94      node("source", source).
  173.95      run();
  173.96  
  173.97 +  // BinHeap
  173.98    {
  173.99      typedef BinHeap<Prio, ItemIntMap> IntHeap;
 173.100      checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 173.101 @@ -183,5 +185,92 @@
 173.102      dijkstraHeapTest<NodeHeap>(digraph, length, source);
 173.103    }
 173.104  
 173.105 +  // FouraryHeap
 173.106 +  {
 173.107 +    typedef FouraryHeap<Prio, ItemIntMap> IntHeap;
 173.108 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 173.109 +    heapSortTest<IntHeap>();
 173.110 +    heapIncreaseTest<IntHeap>();
 173.111 +
 173.112 +    typedef FouraryHeap<Prio, IntNodeMap > NodeHeap;
 173.113 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 173.114 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 173.115 +  }
 173.116 +
 173.117 +  // KaryHeap
 173.118 +  {
 173.119 +    typedef KaryHeap<Prio, ItemIntMap> IntHeap;
 173.120 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 173.121 +    heapSortTest<IntHeap>();
 173.122 +    heapIncreaseTest<IntHeap>();
 173.123 +
 173.124 +    typedef KaryHeap<Prio, IntNodeMap > NodeHeap;
 173.125 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 173.126 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 173.127 +  }
 173.128 +
 173.129 +  // FibHeap
 173.130 +  {
 173.131 +    typedef FibHeap<Prio, ItemIntMap> IntHeap;
 173.132 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 173.133 +    heapSortTest<IntHeap>();
 173.134 +    heapIncreaseTest<IntHeap>();
 173.135 +
 173.136 +    typedef FibHeap<Prio, IntNodeMap > NodeHeap;
 173.137 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 173.138 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 173.139 +  }
 173.140 +
 173.141 +  // PairingHeap
 173.142 +  {
 173.143 +    typedef PairingHeap<Prio, ItemIntMap> IntHeap;
 173.144 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 173.145 +    heapSortTest<IntHeap>();
 173.146 +    heapIncreaseTest<IntHeap>();
 173.147 +
 173.148 +    typedef PairingHeap<Prio, IntNodeMap > NodeHeap;
 173.149 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 173.150 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 173.151 +  }
 173.152 +
 173.153 +  // RadixHeap
 173.154 +  {
 173.155 +    typedef RadixHeap<ItemIntMap> IntHeap;
 173.156 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 173.157 +    heapSortTest<IntHeap>();
 173.158 +    heapIncreaseTest<IntHeap>();
 173.159 +
 173.160 +    typedef RadixHeap<IntNodeMap > NodeHeap;
 173.161 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 173.162 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 173.163 +  }
 173.164 +
 173.165 +  // BinomHeap
 173.166 +  {
 173.167 +    typedef BinomHeap<Prio, ItemIntMap> IntHeap;
 173.168 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 173.169 +    heapSortTest<IntHeap>();
 173.170 +    heapIncreaseTest<IntHeap>();
 173.171 +
 173.172 +    typedef BinomHeap<Prio, IntNodeMap > NodeHeap;
 173.173 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 173.174 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 173.175 +  }
 173.176 +
 173.177 +  // BucketHeap, SimpleBucketHeap
 173.178 +  {
 173.179 +    typedef BucketHeap<ItemIntMap> IntHeap;
 173.180 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 173.181 +    heapSortTest<IntHeap>();
 173.182 +    heapIncreaseTest<IntHeap>();
 173.183 +
 173.184 +    typedef BucketHeap<IntNodeMap > NodeHeap;
 173.185 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 173.186 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 173.187 +
 173.188 +    typedef SimpleBucketHeap<ItemIntMap> SimpleIntHeap;
 173.189 +    heapSortTest<SimpleIntHeap>();
 173.190 +  }
 173.191 +
 173.192    return 0;
 173.193  }
   174.1 --- a/test/kruskal_test.cc	Fri Oct 16 10:21:37 2009 +0200
   174.2 +++ b/test/kruskal_test.cc	Thu Nov 05 15:50:01 2009 +0100
   174.3 @@ -2,7 +2,7 @@
   174.4   *
   174.5   * This file is a part of LEMON, a generic C++ optimization library.
   174.6   *
   174.7 - * Copyright (C) 2003-2008
   174.8 + * Copyright (C) 2003-2009
   174.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  174.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  174.11   *
  174.12 @@ -99,16 +99,16 @@
  174.13    check(kruskal(G, edge_cost_map, tree_map)==10,
  174.14          "Total cost should be 10");
  174.15  
  174.16 -  edge_cost_map.set(e1, -10);
  174.17 -  edge_cost_map.set(e2, -9);
  174.18 -  edge_cost_map.set(e3, -8);
  174.19 -  edge_cost_map.set(e4, -7);
  174.20 -  edge_cost_map.set(e5, -6);
  174.21 -  edge_cost_map.set(e6, -5);
  174.22 -  edge_cost_map.set(e7, -4);
  174.23 -  edge_cost_map.set(e8, -3);
  174.24 -  edge_cost_map.set(e9, -2);
  174.25 -  edge_cost_map.set(e10, -1);
  174.26 +  edge_cost_map[e1] = -10;
  174.27 +  edge_cost_map[e2] = -9;
  174.28 +  edge_cost_map[e3] = -8;
  174.29 +  edge_cost_map[e4] = -7;
  174.30 +  edge_cost_map[e5] = -6;
  174.31 +  edge_cost_map[e6] = -5;
  174.32 +  edge_cost_map[e7] = -4;
  174.33 +  edge_cost_map[e8] = -3;
  174.34 +  edge_cost_map[e9] = -2;
  174.35 +  edge_cost_map[e10] = -1;
  174.36  
  174.37    vector<Edge> tree_edge_vec(5);
  174.38  
   175.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   175.2 +++ b/test/lp_test.cc	Thu Nov 05 15:50:01 2009 +0100
   175.3 @@ -0,0 +1,419 @@
   175.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   175.5 + *
   175.6 + * This file is a part of LEMON, a generic C++ optimization library.
   175.7 + *
   175.8 + * Copyright (C) 2003-2009
   175.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  175.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  175.11 + *
  175.12 + * Permission to use, modify and distribute this software is granted
  175.13 + * provided that this copyright notice appears in all copies. For
  175.14 + * precise terms see the accompanying LICENSE file.
  175.15 + *
  175.16 + * This software is provided "AS IS" with no warranty of any kind,
  175.17 + * express or implied, and with no claim as to its suitability for any
  175.18 + * purpose.
  175.19 + *
  175.20 + */
  175.21 +
  175.22 +#include <sstream>
  175.23 +#include <lemon/lp_skeleton.h>
  175.24 +#include "test_tools.h"
  175.25 +#include <lemon/tolerance.h>
  175.26 +
  175.27 +#include <lemon/config.h>
  175.28 +
  175.29 +#ifdef LEMON_HAVE_GLPK
  175.30 +#include <lemon/glpk.h>
  175.31 +#endif
  175.32 +
  175.33 +#ifdef LEMON_HAVE_CPLEX
  175.34 +#include <lemon/cplex.h>
  175.35 +#endif
  175.36 +
  175.37 +#ifdef LEMON_HAVE_SOPLEX
  175.38 +#include <lemon/soplex.h>
  175.39 +#endif
  175.40 +
  175.41 +#ifdef LEMON_HAVE_CLP
  175.42 +#include <lemon/clp.h>
  175.43 +#endif
  175.44 +
  175.45 +using namespace lemon;
  175.46 +
  175.47 +void lpTest(LpSolver& lp)
  175.48 +{
  175.49 +
  175.50 +  typedef LpSolver LP;
  175.51 +
  175.52 +  std::vector<LP::Col> x(10);
  175.53 +  //  for(int i=0;i<10;i++) x.push_back(lp.addCol());
  175.54 +  lp.addColSet(x);
  175.55 +  lp.colLowerBound(x,1);
  175.56 +  lp.colUpperBound(x,1);
  175.57 +  lp.colBounds(x,1,2);
  175.58 +
  175.59 +  std::vector<LP::Col> y(10);
  175.60 +  lp.addColSet(y);
  175.61 +
  175.62 +  lp.colLowerBound(y,1);
  175.63 +  lp.colUpperBound(y,1);
  175.64 +  lp.colBounds(y,1,2);
  175.65 +
  175.66 +  std::map<int,LP::Col> z;
  175.67 +
  175.68 +  z.insert(std::make_pair(12,INVALID));
  175.69 +  z.insert(std::make_pair(2,INVALID));
  175.70 +  z.insert(std::make_pair(7,INVALID));
  175.71 +  z.insert(std::make_pair(5,INVALID));
  175.72 +
  175.73 +  lp.addColSet(z);
  175.74 +
  175.75 +  lp.colLowerBound(z,1);
  175.76 +  lp.colUpperBound(z,1);
  175.77 +  lp.colBounds(z,1,2);
  175.78 +
  175.79 +  {
  175.80 +    LP::Expr e,f,g;
  175.81 +    LP::Col p1,p2,p3,p4,p5;
  175.82 +    LP::Constr c;
  175.83 +
  175.84 +    p1=lp.addCol();
  175.85 +    p2=lp.addCol();
  175.86 +    p3=lp.addCol();
  175.87 +    p4=lp.addCol();
  175.88 +    p5=lp.addCol();
  175.89 +
  175.90 +    e[p1]=2;
  175.91 +    *e=12;
  175.92 +    e[p1]+=2;
  175.93 +    *e+=12;
  175.94 +    e[p1]-=2;
  175.95 +    *e-=12;
  175.96 +
  175.97 +    e=2;
  175.98 +    e=2.2;
  175.99 +    e=p1;
 175.100 +    e=f;
 175.101 +
 175.102 +    e+=2;
 175.103 +    e+=2.2;
 175.104 +    e+=p1;
 175.105 +    e+=f;
 175.106 +
 175.107 +    e-=2;
 175.108 +    e-=2.2;
 175.109 +    e-=p1;
 175.110 +    e-=f;
 175.111 +
 175.112 +    e*=2;
 175.113 +    e*=2.2;
 175.114 +    e/=2;
 175.115 +    e/=2.2;
 175.116 +
 175.117 +    e=((p1+p2)+(p1-p2)+(p1+12)+(12+p1)+(p1-12)+(12-p1)+
 175.118 +       (f+12)+(12+f)+(p1+f)+(f+p1)+(f+g)+
 175.119 +       (f-12)+(12-f)+(p1-f)+(f-p1)+(f-g)+
 175.120 +       2.2*f+f*2.2+f/2.2+
 175.121 +       2*f+f*2+f/2+
 175.122 +       2.2*p1+p1*2.2+p1/2.2+
 175.123 +       2*p1+p1*2+p1/2
 175.124 +       );
 175.125 +
 175.126 +
 175.127 +    c = (e  <= f  );
 175.128 +    c = (e  <= 2.2);
 175.129 +    c = (e  <= 2  );
 175.130 +    c = (e  <= p1 );
 175.131 +    c = (2.2<= f  );
 175.132 +    c = (2  <= f  );
 175.133 +    c = (p1 <= f  );
 175.134 +    c = (p1 <= p2 );
 175.135 +    c = (p1 <= 2.2);
 175.136 +    c = (p1 <= 2  );
 175.137 +    c = (2.2<= p2 );
 175.138 +    c = (2  <= p2 );
 175.139 +
 175.140 +    c = (e  >= f  );
 175.141 +    c = (e  >= 2.2);
 175.142 +    c = (e  >= 2  );
 175.143 +    c = (e  >= p1 );
 175.144 +    c = (2.2>= f  );
 175.145 +    c = (2  >= f  );
 175.146 +    c = (p1 >= f  );
 175.147 +    c = (p1 >= p2 );
 175.148 +    c = (p1 >= 2.2);
 175.149 +    c = (p1 >= 2  );
 175.150 +    c = (2.2>= p2 );
 175.151 +    c = (2  >= p2 );
 175.152 +
 175.153 +    c = (e  == f  );
 175.154 +    c = (e  == 2.2);
 175.155 +    c = (e  == 2  );
 175.156 +    c = (e  == p1 );
 175.157 +    c = (2.2== f  );
 175.158 +    c = (2  == f  );
 175.159 +    c = (p1 == f  );
 175.160 +    //c = (p1 == p2 );
 175.161 +    c = (p1 == 2.2);
 175.162 +    c = (p1 == 2  );
 175.163 +    c = (2.2== p2 );
 175.164 +    c = (2  == p2 );
 175.165 +
 175.166 +    c = ((2 <= e) <= 3);
 175.167 +    c = ((2 <= p1) <= 3);
 175.168 +
 175.169 +    c = ((2 >= e) >= 3);
 175.170 +    c = ((2 >= p1) >= 3);
 175.171 +
 175.172 +    e[x[3]]=2;
 175.173 +    e[x[3]]=4;
 175.174 +    e[x[3]]=1;
 175.175 +    *e=12;
 175.176 +
 175.177 +    lp.addRow(-LP::INF,e,23);
 175.178 +    lp.addRow(-LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
 175.179 +    lp.addRow(-LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
 175.180 +
 175.181 +    lp.addRow(x[1]+x[3]<=x[5]-3);
 175.182 +    lp.addRow((-7<=x[1]+x[3]-12)<=3);
 175.183 +    lp.addRow(x[1]<=x[5]);
 175.184 +
 175.185 +    std::ostringstream buf;
 175.186 +
 175.187 +
 175.188 +    e=((p1+p2)+(p1-0.99*p2));
 175.189 +    //e.prettyPrint(std::cout);
 175.190 +    //(e<=2).prettyPrint(std::cout);
 175.191 +    double tolerance=0.001;
 175.192 +    e.simplify(tolerance);
 175.193 +    buf << "Coeff. of p2 should be 0.01";
 175.194 +    check(e[p2]>0, buf.str());
 175.195 +
 175.196 +    tolerance=0.02;
 175.197 +    e.simplify(tolerance);
 175.198 +    buf << "Coeff. of p2 should be 0";
 175.199 +    check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
 175.200 +
 175.201 +    //Test for clone/new
 175.202 +    LP* lpnew = lp.newSolver();
 175.203 +    LP* lpclone = lp.cloneSolver();
 175.204 +    delete lpnew;
 175.205 +    delete lpclone;
 175.206 +
 175.207 +  }
 175.208 +
 175.209 +  {
 175.210 +    LP::DualExpr e,f,g;
 175.211 +    LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID,
 175.212 +      p4 = INVALID, p5 = INVALID;
 175.213 +
 175.214 +    e[p1]=2;
 175.215 +    e[p1]+=2;
 175.216 +    e[p1]-=2;
 175.217 +
 175.218 +    e=p1;
 175.219 +    e=f;
 175.220 +
 175.221 +    e+=p1;
 175.222 +    e+=f;
 175.223 +
 175.224 +    e-=p1;
 175.225 +    e-=f;
 175.226 +
 175.227 +    e*=2;
 175.228 +    e*=2.2;
 175.229 +    e/=2;
 175.230 +    e/=2.2;
 175.231 +
 175.232 +    e=((p1+p2)+(p1-p2)+
 175.233 +       (p1+f)+(f+p1)+(f+g)+
 175.234 +       (p1-f)+(f-p1)+(f-g)+
 175.235 +       2.2*f+f*2.2+f/2.2+
 175.236 +       2*f+f*2+f/2+
 175.237 +       2.2*p1+p1*2.2+p1/2.2+
 175.238 +       2*p1+p1*2+p1/2
 175.239 +       );
 175.240 +  }
 175.241 +
 175.242 +}
 175.243 +
 175.244 +void solveAndCheck(LpSolver& lp, LpSolver::ProblemType stat,
 175.245 +                   double exp_opt) {
 175.246 +  using std::string;
 175.247 +  lp.solve();
 175.248 +
 175.249 +  std::ostringstream buf;
 175.250 +  buf << "PrimalType should be: " << int(stat) << int(lp.primalType());
 175.251 +
 175.252 +  check(lp.primalType()==stat, buf.str());
 175.253 +
 175.254 +  if (stat ==  LpSolver::OPTIMAL) {
 175.255 +    std::ostringstream sbuf;
 175.256 +    sbuf << "Wrong optimal value (" << lp.primal() <<") with "
 175.257 +         << lp.solverName() <<"\n     the right optimum is " << exp_opt;
 175.258 +    check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
 175.259 +  }
 175.260 +}
 175.261 +
 175.262 +void aTest(LpSolver & lp)
 175.263 +{
 175.264 +  typedef LpSolver LP;
 175.265 +
 175.266 + //The following example is very simple
 175.267 +
 175.268 +  typedef LpSolver::Row Row;
 175.269 +  typedef LpSolver::Col Col;
 175.270 +
 175.271 +
 175.272 +  Col x1 = lp.addCol();
 175.273 +  Col x2 = lp.addCol();
 175.274 +
 175.275 +
 175.276 +  //Constraints
 175.277 +  Row upright=lp.addRow(x1+2*x2 <=1);
 175.278 +  lp.addRow(x1+x2 >=-1);
 175.279 +  lp.addRow(x1-x2 <=1);
 175.280 +  lp.addRow(x1-x2 >=-1);
 175.281 +  //Nonnegativity of the variables
 175.282 +  lp.colLowerBound(x1, 0);
 175.283 +  lp.colLowerBound(x2, 0);
 175.284 +  //Objective function
 175.285 +  lp.obj(x1+x2);
 175.286 +
 175.287 +  lp.sense(lp.MAX);
 175.288 +
 175.289 +  //Testing the problem retrieving routines
 175.290 +  check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
 175.291 +  check(lp.sense() == lp.MAX,"This is a maximization!");
 175.292 +  check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
 175.293 +  check(lp.colLowerBound(x1)==0,
 175.294 +        "The lower bound for variable x1 should be 0.");
 175.295 +  check(lp.colUpperBound(x1)==LpSolver::INF,
 175.296 +        "The upper bound for variable x1 should be infty.");
 175.297 +  check(lp.rowLowerBound(upright) == -LpSolver::INF,
 175.298 +        "The lower bound for the first row should be -infty.");
 175.299 +  check(lp.rowUpperBound(upright)==1,
 175.300 +        "The upper bound for the first row should be 1.");
 175.301 +  LpSolver::Expr e = lp.row(upright);
 175.302 +  check(e[x1] == 1, "The first coefficient should 1.");
 175.303 +  check(e[x2] == 2, "The second coefficient should 1.");
 175.304 +
 175.305 +  lp.row(upright, x1+x2 <=1);
 175.306 +  e = lp.row(upright);
 175.307 +  check(e[x1] == 1, "The first coefficient should 1.");
 175.308 +  check(e[x2] == 1, "The second coefficient should 1.");
 175.309 +
 175.310 +  LpSolver::DualExpr de = lp.col(x1);
 175.311 +  check(  de[upright] == 1, "The first coefficient should 1.");
 175.312 +
 175.313 +  LpSolver* clp = lp.cloneSolver();
 175.314 +
 175.315 +  //Testing the problem retrieving routines
 175.316 +  check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!");
 175.317 +  check(clp->sense() == clp->MAX,"This is a maximization!");
 175.318 +  check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!");
 175.319 +  //  std::cout<<lp.colLowerBound(x1)<<std::endl;
 175.320 +  check(clp->colLowerBound(x1)==0,
 175.321 +        "The lower bound for variable x1 should be 0.");
 175.322 +  check(clp->colUpperBound(x1)==LpSolver::INF,
 175.323 +        "The upper bound for variable x1 should be infty.");
 175.324 +
 175.325 +  check(lp.rowLowerBound(upright)==-LpSolver::INF,
 175.326 +        "The lower bound for the first row should be -infty.");
 175.327 +  check(lp.rowUpperBound(upright)==1,
 175.328 +        "The upper bound for the first row should be 1.");
 175.329 +  e = clp->row(upright);
 175.330 +  check(e[x1] == 1, "The first coefficient should 1.");
 175.331 +  check(e[x2] == 1, "The second coefficient should 1.");
 175.332 +
 175.333 +  de = clp->col(x1);
 175.334 +  check(de[upright] == 1, "The first coefficient should 1.");
 175.335 +
 175.336 +  delete clp;
 175.337 +
 175.338 +  //Maximization of x1+x2
 175.339 +  //over the triangle with vertices (0,0) (0,1) (1,0)
 175.340 +  double expected_opt=1;
 175.341 +  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
 175.342 +
 175.343 +  //Minimization
 175.344 +  lp.sense(lp.MIN);
 175.345 +  expected_opt=0;
 175.346 +  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
 175.347 +
 175.348 +  //Vertex (-1,0) instead of (0,0)
 175.349 +  lp.colLowerBound(x1, -LpSolver::INF);
 175.350 +  expected_opt=-1;
 175.351 +  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
 175.352 +
 175.353 +  //Erase one constraint and return to maximization
 175.354 +  lp.erase(upright);
 175.355 +  lp.sense(lp.MAX);
 175.356 +  expected_opt=LpSolver::INF;
 175.357 +  solveAndCheck(lp, LpSolver::UNBOUNDED, expected_opt);
 175.358 +
 175.359 +  //Infeasibilty
 175.360 +  lp.addRow(x1+x2 <=-2);
 175.361 +  solveAndCheck(lp, LpSolver::INFEASIBLE, expected_opt);
 175.362 +
 175.363 +}
 175.364 +
 175.365 +template<class LP>
 175.366 +void cloneTest()
 175.367 +{
 175.368 +  //Test for clone/new
 175.369 +
 175.370 +  LP* lp = new LP();
 175.371 +  LP* lpnew = lp->newSolver();
 175.372 +  LP* lpclone = lp->cloneSolver();
 175.373 +  delete lp;
 175.374 +  delete lpnew;
 175.375 +  delete lpclone;
 175.376 +}
 175.377 +
 175.378 +int main()
 175.379 +{
 175.380 +  LpSkeleton lp_skel;
 175.381 +  lpTest(lp_skel);
 175.382 +
 175.383 +#ifdef LEMON_HAVE_GLPK
 175.384 +  {
 175.385 +    GlpkLp lp_glpk1,lp_glpk2;
 175.386 +    lpTest(lp_glpk1);
 175.387 +    aTest(lp_glpk2);
 175.388 +    cloneTest<GlpkLp>();
 175.389 +  }
 175.390 +#endif
 175.391 +
 175.392 +#ifdef LEMON_HAVE_CPLEX
 175.393 +  try {
 175.394 +    CplexLp lp_cplex1,lp_cplex2;
 175.395 +    lpTest(lp_cplex1);
 175.396 +    aTest(lp_cplex2);
 175.397 +    cloneTest<CplexLp>();
 175.398 +  } catch (CplexEnv::LicenseError& error) {
 175.399 +    check(false, error.what());
 175.400 +  }
 175.401 +#endif
 175.402 +
 175.403 +#ifdef LEMON_HAVE_SOPLEX
 175.404 +  {
 175.405 +    SoplexLp lp_soplex1,lp_soplex2;
 175.406 +    lpTest(lp_soplex1);
 175.407 +    aTest(lp_soplex2);
 175.408 +    cloneTest<SoplexLp>();
 175.409 +  }
 175.410 +#endif
 175.411 +
 175.412 +#ifdef LEMON_HAVE_CLP
 175.413 +  {
 175.414 +    ClpLp lp_clp1,lp_clp2;
 175.415 +    lpTest(lp_clp1);
 175.416 +    aTest(lp_clp2);
 175.417 +    cloneTest<ClpLp>();
 175.418 +  }
 175.419 +#endif
 175.420 +
 175.421 +  return 0;
 175.422 +}
   176.1 --- a/test/maps_test.cc	Fri Oct 16 10:21:37 2009 +0200
   176.2 +++ b/test/maps_test.cc	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   176.8 + * Copyright (C) 2003-2009
   176.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  176.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  176.11   *
  176.12 @@ -22,6 +22,10 @@
  176.13  #include <lemon/concept_check.h>
  176.14  #include <lemon/concepts/maps.h>
  176.15  #include <lemon/maps.h>
  176.16 +#include <lemon/list_graph.h>
  176.17 +#include <lemon/smart_graph.h>
  176.18 +#include <lemon/adaptors.h>
  176.19 +#include <lemon/dfs.h>
  176.20  
  176.21  #include "test_tools.h"
  176.22  
  176.23 @@ -60,6 +64,12 @@
  176.24  typedef ReadWriteMap<A, bool> BoolWriteMap;
  176.25  typedef ReferenceMap<A, bool, bool&, const bool&> BoolRefMap;
  176.26  
  176.27 +template<typename Map1, typename Map2, typename ItemIt>
  176.28 +void compareMap(const Map1& map1, const Map2& map2, ItemIt it) {
  176.29 +  for (; it != INVALID; ++it)
  176.30 +    check(map1[it] == map2[it], "The maps are not equal");
  176.31 +}
  176.32 +
  176.33  int main()
  176.34  {
  176.35    // Map concepts
  176.36 @@ -170,7 +180,7 @@
  176.37    {
  176.38      typedef ComposeMap<DoubleMap, ReadMap<B,A> > CompMap;
  176.39      checkConcept<ReadMap<B,double>, CompMap>();
  176.40 -    CompMap map1(DoubleMap(),ReadMap<B,A>());
  176.41 +    CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
  176.42      CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
  176.43  
  176.44      SparseMap<double, bool> m1(false); m1[3.14] = true;
  176.45 @@ -183,7 +193,7 @@
  176.46    {
  176.47      typedef CombineMap<DoubleMap, DoubleMap, std::plus<double> > CombMap;
  176.48      checkConcept<ReadMap<A,double>, CombMap>();
  176.49 -    CombMap map1(DoubleMap(), DoubleMap());
  176.50 +    CombMap map1 = CombMap(DoubleMap(), DoubleMap());
  176.51      CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
  176.52  
  176.53      check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3,
  176.54 @@ -195,11 +205,11 @@
  176.55      checkConcept<ReadMap<A,B>, FunctorToMap<F,A,B> >();
  176.56      checkConcept<ReadMap<A,B>, FunctorToMap<F> >();
  176.57      FunctorToMap<F> map1;
  176.58 -    FunctorToMap<F> map2(F());
  176.59 +    FunctorToMap<F> map2 = FunctorToMap<F>(F());
  176.60      B b = functorToMap(F())[A()];
  176.61  
  176.62      checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
  176.63 -    MapToFunctor<ReadMap<A,B> > map(ReadMap<A,B>());
  176.64 +    MapToFunctor<ReadMap<A,B> > map = MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
  176.65  
  176.66      check(functorToMap(&func)[A()] == 3,
  176.67            "Something is wrong with FunctorToMap");
  176.68 @@ -328,6 +338,10 @@
  176.69    // LoggerBoolMap
  176.70    {
  176.71      typedef std::vector<int> vec;
  176.72 +    checkConcept<WriteMap<int, bool>, LoggerBoolMap<vec::iterator> >();
  176.73 +    checkConcept<WriteMap<int, bool>,
  176.74 +                 LoggerBoolMap<std::back_insert_iterator<vec> > >();
  176.75 +
  176.76      vec v1;
  176.77      vec v2(10);
  176.78      LoggerBoolMap<std::back_insert_iterator<vec> >
  176.79 @@ -347,7 +361,444 @@
  176.80      for ( LoggerBoolMap<vec::iterator>::Iterator it = map2.begin();
  176.81            it != map2.end(); ++it )
  176.82        check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
  176.83 +    
  176.84 +    typedef ListDigraph Graph;
  176.85 +    DIGRAPH_TYPEDEFS(Graph);
  176.86 +    Graph gr;
  176.87 +
  176.88 +    Node n0 = gr.addNode();
  176.89 +    Node n1 = gr.addNode();
  176.90 +    Node n2 = gr.addNode();
  176.91 +    Node n3 = gr.addNode();
  176.92 +    
  176.93 +    gr.addArc(n3, n0);
  176.94 +    gr.addArc(n3, n2);
  176.95 +    gr.addArc(n0, n2);
  176.96 +    gr.addArc(n2, n1);
  176.97 +    gr.addArc(n0, n1);
  176.98 +    
  176.99 +    {
 176.100 +      std::vector<Node> v;
 176.101 +      dfs(gr).processedMap(loggerBoolMap(std::back_inserter(v))).run();
 176.102 +
 176.103 +      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
 176.104 +            "Something is wrong with LoggerBoolMap");
 176.105 +    }
 176.106 +    {
 176.107 +      std::vector<Node> v(countNodes(gr));
 176.108 +      dfs(gr).processedMap(loggerBoolMap(v.begin())).run();
 176.109 +      
 176.110 +      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
 176.111 +            "Something is wrong with LoggerBoolMap");
 176.112 +    }
 176.113 +  }
 176.114 +  
 176.115 +  // IdMap, RangeIdMap
 176.116 +  {
 176.117 +    typedef ListDigraph Graph;
 176.118 +    DIGRAPH_TYPEDEFS(Graph);
 176.119 +
 176.120 +    checkConcept<ReadMap<Node, int>, IdMap<Graph, Node> >();
 176.121 +    checkConcept<ReadMap<Arc, int>, IdMap<Graph, Arc> >();
 176.122 +    checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >();
 176.123 +    checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >();
 176.124 +    
 176.125 +    Graph gr;
 176.126 +    IdMap<Graph, Node> nmap(gr);
 176.127 +    IdMap<Graph, Arc> amap(gr);
 176.128 +    RangeIdMap<Graph, Node> nrmap(gr);
 176.129 +    RangeIdMap<Graph, Arc> armap(gr);
 176.130 +    
 176.131 +    Node n0 = gr.addNode();
 176.132 +    Node n1 = gr.addNode();
 176.133 +    Node n2 = gr.addNode();
 176.134 +    
 176.135 +    Arc a0 = gr.addArc(n0, n1);
 176.136 +    Arc a1 = gr.addArc(n0, n2);
 176.137 +    Arc a2 = gr.addArc(n2, n1);
 176.138 +    Arc a3 = gr.addArc(n2, n0);
 176.139 +    
 176.140 +    check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap");
 176.141 +    check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap");
 176.142 +    check(nmap[n2] == gr.id(n2) && nmap(gr.id(n2)) == n2, "Wrong IdMap");
 176.143 +
 176.144 +    check(amap[a0] == gr.id(a0) && amap(gr.id(a0)) == a0, "Wrong IdMap");
 176.145 +    check(amap[a1] == gr.id(a1) && amap(gr.id(a1)) == a1, "Wrong IdMap");
 176.146 +    check(amap[a2] == gr.id(a2) && amap(gr.id(a2)) == a2, "Wrong IdMap");
 176.147 +    check(amap[a3] == gr.id(a3) && amap(gr.id(a3)) == a3, "Wrong IdMap");
 176.148 +
 176.149 +    check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap");
 176.150 +    check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap");
 176.151 +    
 176.152 +    check(nrmap.size() == 3 && armap.size() == 4,
 176.153 +          "Wrong RangeIdMap::size()");
 176.154 +
 176.155 +    check(nrmap[n0] == 0 && nrmap(0) == n0, "Wrong RangeIdMap");
 176.156 +    check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap");
 176.157 +    check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap");
 176.158 +    
 176.159 +    check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap");
 176.160 +    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
 176.161 +    check(armap[a2] == 2 && armap(2) == a2, "Wrong RangeIdMap");
 176.162 +    check(armap[a3] == 3 && armap(3) == a3, "Wrong RangeIdMap");
 176.163 +
 176.164 +    check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap");
 176.165 +    check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap");
 176.166 +    
 176.167 +    gr.erase(n1);
 176.168 +    
 176.169 +    if (nrmap[n0] == 1) nrmap.swap(n0, n2);
 176.170 +    nrmap.swap(n2, n0);
 176.171 +    if (armap[a1] == 1) armap.swap(a1, a3);
 176.172 +    armap.swap(a3, a1);
 176.173 +    
 176.174 +    check(nrmap.size() == 2 && armap.size() == 2,
 176.175 +          "Wrong RangeIdMap::size()");
 176.176 +
 176.177 +    check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap");
 176.178 +    check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap");
 176.179 +    
 176.180 +    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
 176.181 +    check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap");
 176.182 +
 176.183 +    check(nrmap.inverse()[0] == n2, "Wrong RangeIdMap::InverseMap");
 176.184 +    check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap");
 176.185 +  }
 176.186 +  
 176.187 +  // SourceMap, TargetMap, ForwardMap, BackwardMap, InDegMap, OutDegMap
 176.188 +  {
 176.189 +    typedef ListGraph Graph;
 176.190 +    GRAPH_TYPEDEFS(Graph);
 176.191 +    
 176.192 +    checkConcept<ReadMap<Arc, Node>, SourceMap<Graph> >();
 176.193 +    checkConcept<ReadMap<Arc, Node>, TargetMap<Graph> >();
 176.194 +    checkConcept<ReadMap<Edge, Arc>, ForwardMap<Graph> >();
 176.195 +    checkConcept<ReadMap<Edge, Arc>, BackwardMap<Graph> >();
 176.196 +    checkConcept<ReadMap<Node, int>, InDegMap<Graph> >();
 176.197 +    checkConcept<ReadMap<Node, int>, OutDegMap<Graph> >();
 176.198 +
 176.199 +    Graph gr;
 176.200 +    Node n0 = gr.addNode();
 176.201 +    Node n1 = gr.addNode();
 176.202 +    Node n2 = gr.addNode();
 176.203 +    
 176.204 +    gr.addEdge(n0,n1);
 176.205 +    gr.addEdge(n1,n2);
 176.206 +    gr.addEdge(n0,n2);
 176.207 +    gr.addEdge(n2,n1);
 176.208 +    gr.addEdge(n1,n2);
 176.209 +    gr.addEdge(n0,n1);
 176.210 +    
 176.211 +    for (EdgeIt e(gr); e != INVALID; ++e) {
 176.212 +      check(forwardMap(gr)[e] == gr.direct(e, true), "Wrong ForwardMap");
 176.213 +      check(backwardMap(gr)[e] == gr.direct(e, false), "Wrong BackwardMap");
 176.214 +    }
 176.215 +    
 176.216 +    compareMap(sourceMap(orienter(gr, constMap<Edge, bool>(true))),
 176.217 +               targetMap(orienter(gr, constMap<Edge, bool>(false))),
 176.218 +               EdgeIt(gr));
 176.219 +
 176.220 +    typedef Orienter<Graph, const ConstMap<Edge, bool> > Digraph;
 176.221 +    Digraph dgr(gr, constMap<Edge, bool>(true));
 176.222 +    OutDegMap<Digraph> odm(dgr);
 176.223 +    InDegMap<Digraph> idm(dgr);
 176.224 +    
 176.225 +    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 1, "Wrong OutDegMap");
 176.226 +    check(idm[n0] == 0 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
 176.227 +   
 176.228 +    gr.addEdge(n2, n0);
 176.229 +
 176.230 +    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 2, "Wrong OutDegMap");
 176.231 +    check(idm[n0] == 1 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
 176.232 +  }
 176.233 +  
 176.234 +  // CrossRefMap
 176.235 +  {
 176.236 +    typedef ListDigraph Graph;
 176.237 +    DIGRAPH_TYPEDEFS(Graph);
 176.238 +
 176.239 +    checkConcept<ReadWriteMap<Node, int>,
 176.240 +                 CrossRefMap<Graph, Node, int> >();
 176.241 +    checkConcept<ReadWriteMap<Node, bool>,
 176.242 +                 CrossRefMap<Graph, Node, bool> >();
 176.243 +    checkConcept<ReadWriteMap<Node, double>,
 176.244 +                 CrossRefMap<Graph, Node, double> >();
 176.245 +    
 176.246 +    Graph gr;
 176.247 +    typedef CrossRefMap<Graph, Node, char> CRMap;
 176.248 +    CRMap map(gr);
 176.249 +    
 176.250 +    Node n0 = gr.addNode();
 176.251 +    Node n1 = gr.addNode();
 176.252 +    Node n2 = gr.addNode();
 176.253 +    
 176.254 +    map.set(n0, 'A');
 176.255 +    map.set(n1, 'B');
 176.256 +    map.set(n2, 'C');
 176.257 +    
 176.258 +    check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0,
 176.259 +          "Wrong CrossRefMap");
 176.260 +    check(map[n1] == 'B' && map('B') == n1 && map.inverse()['B'] == n1,
 176.261 +          "Wrong CrossRefMap");
 176.262 +    check(map[n2] == 'C' && map('C') == n2 && map.inverse()['C'] == n2,
 176.263 +          "Wrong CrossRefMap");
 176.264 +    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
 176.265 +          "Wrong CrossRefMap::count()");
 176.266 +    
 176.267 +    CRMap::ValueIt it = map.beginValue();
 176.268 +    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
 176.269 +          it == map.endValue(), "Wrong value iterator");
 176.270 +    
 176.271 +    map.set(n2, 'A');
 176.272 +
 176.273 +    check(map[n0] == 'A' && map[n1] == 'B' && map[n2] == 'A',
 176.274 +          "Wrong CrossRefMap");
 176.275 +    check(map('A') == n0 && map.inverse()['A'] == n0, "Wrong CrossRefMap");
 176.276 +    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
 176.277 +    check(map('C') == INVALID && map.inverse()['C'] == INVALID,
 176.278 +          "Wrong CrossRefMap");
 176.279 +    check(map.count('A') == 2 && map.count('B') == 1 && map.count('C') == 0,
 176.280 +          "Wrong CrossRefMap::count()");
 176.281 +
 176.282 +    it = map.beginValue();
 176.283 +    check(*it++ == 'A' && *it++ == 'A' && *it++ == 'B' &&
 176.284 +          it == map.endValue(), "Wrong value iterator");
 176.285 +
 176.286 +    map.set(n0, 'C');
 176.287 +
 176.288 +    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
 176.289 +          "Wrong CrossRefMap");
 176.290 +    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
 176.291 +    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
 176.292 +    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
 176.293 +    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
 176.294 +          "Wrong CrossRefMap::count()");
 176.295 +
 176.296 +    it = map.beginValue();
 176.297 +    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
 176.298 +          it == map.endValue(), "Wrong value iterator");
 176.299    }
 176.300  
 176.301 +  // CrossRefMap
 176.302 +  {
 176.303 +    typedef SmartDigraph Graph;
 176.304 +    DIGRAPH_TYPEDEFS(Graph);
 176.305 +
 176.306 +    checkConcept<ReadWriteMap<Node, int>,
 176.307 +                 CrossRefMap<Graph, Node, int> >();
 176.308 +    
 176.309 +    Graph gr;
 176.310 +    typedef CrossRefMap<Graph, Node, char> CRMap;
 176.311 +    typedef CRMap::ValueIterator ValueIt;
 176.312 +    CRMap map(gr);
 176.313 +    
 176.314 +    Node n0 = gr.addNode();
 176.315 +    Node n1 = gr.addNode();
 176.316 +    Node n2 = gr.addNode();
 176.317 +    
 176.318 +    map.set(n0, 'A');
 176.319 +    map.set(n1, 'B');
 176.320 +    map.set(n2, 'C');
 176.321 +    map.set(n2, 'A');
 176.322 +    map.set(n0, 'C');
 176.323 +
 176.324 +    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
 176.325 +          "Wrong CrossRefMap");
 176.326 +    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
 176.327 +    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
 176.328 +    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
 176.329 +
 176.330 +    ValueIt it = map.beginValue();
 176.331 +    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
 176.332 +          it == map.endValue(), "Wrong value iterator");
 176.333 +  }
 176.334 +  
 176.335 +  // Iterable bool map
 176.336 +  {
 176.337 +    typedef SmartGraph Graph;
 176.338 +    typedef SmartGraph::Node Item;
 176.339 +
 176.340 +    typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;
 176.341 +    checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();
 176.342 +
 176.343 +    const int num = 10;
 176.344 +    Graph g;
 176.345 +    std::vector<Item> items;
 176.346 +    for (int i = 0; i < num; ++i) {
 176.347 +      items.push_back(g.addNode());
 176.348 +    }
 176.349 +
 176.350 +    Ibm map1(g, true);
 176.351 +    int n = 0;
 176.352 +    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
 176.353 +      check(map1[static_cast<Item>(it)], "Wrong TrueIt");
 176.354 +      ++n;
 176.355 +    }
 176.356 +    check(n == num, "Wrong number");
 176.357 +
 176.358 +    n = 0;
 176.359 +    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
 176.360 +        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
 176.361 +        ++n;
 176.362 +    }
 176.363 +    check(n == num, "Wrong number");
 176.364 +    check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");
 176.365 +    check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");
 176.366 +
 176.367 +    map1[items[5]] = true;
 176.368 +
 176.369 +    n = 0;
 176.370 +    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
 176.371 +        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
 176.372 +        ++n;
 176.373 +    }
 176.374 +    check(n == num, "Wrong number");
 176.375 +
 176.376 +    map1[items[num / 2]] = false;
 176.377 +    check(map1[items[num / 2]] == false, "Wrong map value");
 176.378 +
 176.379 +    n = 0;
 176.380 +    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
 176.381 +        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
 176.382 +        ++n;
 176.383 +    }
 176.384 +    check(n == num - 1, "Wrong number");
 176.385 +
 176.386 +    n = 0;
 176.387 +    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
 176.388 +        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
 176.389 +        ++n;
 176.390 +    }
 176.391 +    check(n == 1, "Wrong number");
 176.392 +
 176.393 +    map1[items[0]] = false;
 176.394 +    check(map1[items[0]] == false, "Wrong map value");
 176.395 +
 176.396 +    map1[items[num - 1]] = false;
 176.397 +    check(map1[items[num - 1]] == false, "Wrong map value");
 176.398 +
 176.399 +    n = 0;
 176.400 +    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
 176.401 +        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
 176.402 +        ++n;
 176.403 +    }
 176.404 +    check(n == num - 3, "Wrong number");
 176.405 +    check(map1.trueNum() == num - 3, "Wrong number");
 176.406 +
 176.407 +    n = 0;
 176.408 +    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
 176.409 +        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
 176.410 +        ++n;
 176.411 +    }
 176.412 +    check(n == 3, "Wrong number");
 176.413 +    check(map1.falseNum() == 3, "Wrong number");
 176.414 +  }
 176.415 +
 176.416 +  // Iterable int map
 176.417 +  {
 176.418 +    typedef SmartGraph Graph;
 176.419 +    typedef SmartGraph::Node Item;
 176.420 +    typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;
 176.421 +
 176.422 +    checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();
 176.423 +
 176.424 +    const int num = 10;
 176.425 +    Graph g;
 176.426 +    std::vector<Item> items;
 176.427 +    for (int i = 0; i < num; ++i) {
 176.428 +      items.push_back(g.addNode());
 176.429 +    }
 176.430 +
 176.431 +    Iim map1(g);
 176.432 +    check(map1.size() == 0, "Wrong size");
 176.433 +
 176.434 +    for (int i = 0; i < num; ++i) {
 176.435 +      map1[items[i]] = i;
 176.436 +    }
 176.437 +    check(map1.size() == num, "Wrong size");
 176.438 +
 176.439 +    for (int i = 0; i < num; ++i) {
 176.440 +      Iim::ItemIt it(map1, i);
 176.441 +      check(static_cast<Item>(it) == items[i], "Wrong value");
 176.442 +      ++it;
 176.443 +      check(static_cast<Item>(it) == INVALID, "Wrong value");
 176.444 +    }
 176.445 +
 176.446 +    for (int i = 0; i < num; ++i) {
 176.447 +      map1[items[i]] = i % 2;
 176.448 +    }
 176.449 +    check(map1.size() == 2, "Wrong size");
 176.450 +
 176.451 +    int n = 0;
 176.452 +    for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
 176.453 +      check(map1[static_cast<Item>(it)] == 0, "Wrong value");
 176.454 +      ++n;
 176.455 +    }
 176.456 +    check(n == (num + 1) / 2, "Wrong number");
 176.457 +
 176.458 +    for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
 176.459 +      check(map1[static_cast<Item>(it)] == 1, "Wrong value");
 176.460 +      ++n;
 176.461 +    }
 176.462 +    check(n == num, "Wrong number");
 176.463 +
 176.464 +  }
 176.465 +
 176.466 +  // Iterable value map
 176.467 +  {
 176.468 +    typedef SmartGraph Graph;
 176.469 +    typedef SmartGraph::Node Item;
 176.470 +    typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;
 176.471 +
 176.472 +    checkConcept<ReadWriteMap<Item, double>, Ivm>();
 176.473 +
 176.474 +    const int num = 10;
 176.475 +    Graph g;
 176.476 +    std::vector<Item> items;
 176.477 +    for (int i = 0; i < num; ++i) {
 176.478 +      items.push_back(g.addNode());
 176.479 +    }
 176.480 +
 176.481 +    Ivm map1(g, 0.0);
 176.482 +    check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");
 176.483 +    check(*map1.beginValue() == 0.0, "Wrong value");
 176.484 +
 176.485 +    for (int i = 0; i < num; ++i) {
 176.486 +      map1.set(items[i], static_cast<double>(i));
 176.487 +    }
 176.488 +    check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");
 176.489 +
 176.490 +    for (int i = 0; i < num; ++i) {
 176.491 +      Ivm::ItemIt it(map1, static_cast<double>(i));
 176.492 +      check(static_cast<Item>(it) == items[i], "Wrong value");
 176.493 +      ++it;
 176.494 +      check(static_cast<Item>(it) == INVALID, "Wrong value");
 176.495 +    }
 176.496 +
 176.497 +    for (Ivm::ValueIt vit = map1.beginValue();
 176.498 +         vit != map1.endValue(); ++vit) {
 176.499 +      check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,
 176.500 +            "Wrong ValueIt");
 176.501 +    }
 176.502 +
 176.503 +    for (int i = 0; i < num; ++i) {
 176.504 +      map1.set(items[i], static_cast<double>(i % 2));
 176.505 +    }
 176.506 +    check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");
 176.507 +
 176.508 +    int n = 0;
 176.509 +    for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
 176.510 +      check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");
 176.511 +      ++n;
 176.512 +    }
 176.513 +    check(n == (num + 1) / 2, "Wrong number");
 176.514 +
 176.515 +    for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
 176.516 +      check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");
 176.517 +      ++n;
 176.518 +    }
 176.519 +    check(n == num, "Wrong number");
 176.520 +
 176.521 +  }
 176.522    return 0;
 176.523  }
   177.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   177.2 +++ b/test/matching_test.cc	Thu Nov 05 15:50:01 2009 +0100
   177.3 @@ -0,0 +1,424 @@
   177.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   177.5 + *
   177.6 + * This file is a part of LEMON, a generic C++ optimization library.
   177.7 + *
   177.8 + * Copyright (C) 2003-2009
   177.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  177.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  177.11 + *
  177.12 + * Permission to use, modify and distribute this software is granted
  177.13 + * provided that this copyright notice appears in all copies. For
  177.14 + * precise terms see the accompanying LICENSE file.
  177.15 + *
  177.16 + * This software is provided "AS IS" with no warranty of any kind,
  177.17 + * express or implied, and with no claim as to its suitability for any
  177.18 + * purpose.
  177.19 + *
  177.20 + */
  177.21 +
  177.22 +#include <iostream>
  177.23 +#include <sstream>
  177.24 +#include <vector>
  177.25 +#include <queue>
  177.26 +#include <cstdlib>
  177.27 +
  177.28 +#include <lemon/matching.h>
  177.29 +#include <lemon/smart_graph.h>
  177.30 +#include <lemon/concepts/graph.h>
  177.31 +#include <lemon/concepts/maps.h>
  177.32 +#include <lemon/lgf_reader.h>
  177.33 +#include <lemon/math.h>
  177.34 +
  177.35 +#include "test_tools.h"
  177.36 +
  177.37 +using namespace std;
  177.38 +using namespace lemon;
  177.39 +
  177.40 +GRAPH_TYPEDEFS(SmartGraph);
  177.41 +
  177.42 +
  177.43 +const int lgfn = 3;
  177.44 +const std::string lgf[lgfn] = {
  177.45 +  "@nodes\n"
  177.46 +  "label\n"
  177.47 +  "0\n"
  177.48 +  "1\n"
  177.49 +  "2\n"
  177.50 +  "3\n"
  177.51 +  "4\n"
  177.52 +  "5\n"
  177.53 +  "6\n"
  177.54 +  "7\n"
  177.55 +  "@edges\n"
  177.56 +  "     label  weight\n"
  177.57 +  "7 4  0      984\n"
  177.58 +  "0 7  1      73\n"
  177.59 +  "7 1  2      204\n"
  177.60 +  "2 3  3      583\n"
  177.61 +  "2 7  4      565\n"
  177.62 +  "2 1  5      582\n"
  177.63 +  "0 4  6      551\n"
  177.64 +  "2 5  7      385\n"
  177.65 +  "1 5  8      561\n"
  177.66 +  "5 3  9      484\n"
  177.67 +  "7 5  10     904\n"
  177.68 +  "3 6  11     47\n"
  177.69 +  "7 6  12     888\n"
  177.70 +  "3 0  13     747\n"
  177.71 +  "6 1  14     310\n",
  177.72 +
  177.73 +  "@nodes\n"
  177.74 +  "label\n"
  177.75 +  "0\n"
  177.76 +  "1\n"
  177.77 +  "2\n"
  177.78 +  "3\n"
  177.79 +  "4\n"
  177.80 +  "5\n"
  177.81 +  "6\n"
  177.82 +  "7\n"
  177.83 +  "@edges\n"
  177.84 +  "     label  weight\n"
  177.85 +  "2 5  0      710\n"
  177.86 +  "0 5  1      241\n"
  177.87 +  "2 4  2      856\n"
  177.88 +  "2 6  3      762\n"
  177.89 +  "4 1  4      747\n"
  177.90 +  "6 1  5      962\n"
  177.91 +  "4 7  6      723\n"
  177.92 +  "1 7  7      661\n"
  177.93 +  "2 3  8      376\n"
  177.94 +  "1 0  9      416\n"
  177.95 +  "6 7  10     391\n",
  177.96 +
  177.97 +  "@nodes\n"
  177.98 +  "label\n"
  177.99 +  "0\n"
 177.100 +  "1\n"
 177.101 +  "2\n"
 177.102 +  "3\n"
 177.103 +  "4\n"
 177.104 +  "5\n"
 177.105 +  "6\n"
 177.106 +  "7\n"
 177.107 +  "@edges\n"
 177.108 +  "     label  weight\n"
 177.109 +  "6 2  0      553\n"
 177.110 +  "0 7  1      653\n"
 177.111 +  "6 3  2      22\n"
 177.112 +  "4 7  3      846\n"
 177.113 +  "7 2  4      981\n"
 177.114 +  "7 6  5      250\n"
 177.115 +  "5 2  6      539\n",
 177.116 +};
 177.117 +
 177.118 +void checkMaxMatchingCompile()
 177.119 +{
 177.120 +  typedef concepts::Graph Graph;
 177.121 +  typedef Graph::Node Node;
 177.122 +  typedef Graph::Edge Edge;
 177.123 +  typedef Graph::EdgeMap<bool> MatMap;
 177.124 +
 177.125 +  Graph g;
 177.126 +  Node n;
 177.127 +  Edge e;
 177.128 +  MatMap mat(g);
 177.129 +
 177.130 +  MaxMatching<Graph> mat_test(g);
 177.131 +  const MaxMatching<Graph>&
 177.132 +    const_mat_test = mat_test;
 177.133 +
 177.134 +  mat_test.init();
 177.135 +  mat_test.greedyInit();
 177.136 +  mat_test.matchingInit(mat);
 177.137 +  mat_test.startSparse();
 177.138 +  mat_test.startDense();
 177.139 +  mat_test.run();
 177.140 +  
 177.141 +  const_mat_test.matchingSize();
 177.142 +  const_mat_test.matching(e);
 177.143 +  const_mat_test.matching(n);
 177.144 +  const MaxMatching<Graph>::MatchingMap& mmap =
 177.145 +    const_mat_test.matchingMap();
 177.146 +  e = mmap[n];
 177.147 +  const_mat_test.mate(n);
 177.148 +
 177.149 +  MaxMatching<Graph>::Status stat = 
 177.150 +    const_mat_test.status(n);
 177.151 +  const MaxMatching<Graph>::StatusMap& smap =
 177.152 +    const_mat_test.statusMap();
 177.153 +  stat = smap[n];
 177.154 +  const_mat_test.barrier(n);
 177.155 +}
 177.156 +
 177.157 +void checkMaxWeightedMatchingCompile()
 177.158 +{
 177.159 +  typedef concepts::Graph Graph;
 177.160 +  typedef Graph::Node Node;
 177.161 +  typedef Graph::Edge Edge;
 177.162 +  typedef Graph::EdgeMap<int> WeightMap;
 177.163 +
 177.164 +  Graph g;
 177.165 +  Node n;
 177.166 +  Edge e;
 177.167 +  WeightMap w(g);
 177.168 +
 177.169 +  MaxWeightedMatching<Graph> mat_test(g, w);
 177.170 +  const MaxWeightedMatching<Graph>&
 177.171 +    const_mat_test = mat_test;
 177.172 +
 177.173 +  mat_test.init();
 177.174 +  mat_test.start();
 177.175 +  mat_test.run();
 177.176 +  
 177.177 +  const_mat_test.matchingWeight();
 177.178 +  const_mat_test.matchingSize();
 177.179 +  const_mat_test.matching(e);
 177.180 +  const_mat_test.matching(n);
 177.181 +  const MaxWeightedMatching<Graph>::MatchingMap& mmap =
 177.182 +    const_mat_test.matchingMap();
 177.183 +  e = mmap[n];
 177.184 +  const_mat_test.mate(n);
 177.185 +  
 177.186 +  int k = 0;
 177.187 +  const_mat_test.dualValue();
 177.188 +  const_mat_test.nodeValue(n);
 177.189 +  const_mat_test.blossomNum();
 177.190 +  const_mat_test.blossomSize(k);
 177.191 +  const_mat_test.blossomValue(k);
 177.192 +}
 177.193 +
 177.194 +void checkMaxWeightedPerfectMatchingCompile()
 177.195 +{
 177.196 +  typedef concepts::Graph Graph;
 177.197 +  typedef Graph::Node Node;
 177.198 +  typedef Graph::Edge Edge;
 177.199 +  typedef Graph::EdgeMap<int> WeightMap;
 177.200 +
 177.201 +  Graph g;
 177.202 +  Node n;
 177.203 +  Edge e;
 177.204 +  WeightMap w(g);
 177.205 +
 177.206 +  MaxWeightedPerfectMatching<Graph> mat_test(g, w);
 177.207 +  const MaxWeightedPerfectMatching<Graph>&
 177.208 +    const_mat_test = mat_test;
 177.209 +
 177.210 +  mat_test.init();
 177.211 +  mat_test.start();
 177.212 +  mat_test.run();
 177.213 +  
 177.214 +  const_mat_test.matchingWeight();
 177.215 +  const_mat_test.matching(e);
 177.216 +  const_mat_test.matching(n);
 177.217 +  const MaxWeightedPerfectMatching<Graph>::MatchingMap& mmap =
 177.218 +    const_mat_test.matchingMap();
 177.219 +  e = mmap[n];
 177.220 +  const_mat_test.mate(n);
 177.221 +  
 177.222 +  int k = 0;
 177.223 +  const_mat_test.dualValue();
 177.224 +  const_mat_test.nodeValue(n);
 177.225 +  const_mat_test.blossomNum();
 177.226 +  const_mat_test.blossomSize(k);
 177.227 +  const_mat_test.blossomValue(k);
 177.228 +}
 177.229 +
 177.230 +void checkMatching(const SmartGraph& graph,
 177.231 +                   const MaxMatching<SmartGraph>& mm) {
 177.232 +  int num = 0;
 177.233 +
 177.234 +  IntNodeMap comp_index(graph);
 177.235 +  UnionFind<IntNodeMap> comp(comp_index);
 177.236 +
 177.237 +  int barrier_num = 0;
 177.238 +
 177.239 +  for (NodeIt n(graph); n != INVALID; ++n) {
 177.240 +    check(mm.status(n) == MaxMatching<SmartGraph>::EVEN ||
 177.241 +          mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
 177.242 +    if (mm.status(n) == MaxMatching<SmartGraph>::ODD) {
 177.243 +      ++barrier_num;
 177.244 +    } else {
 177.245 +      comp.insert(n);
 177.246 +    }
 177.247 +  }
 177.248 +
 177.249 +  for (EdgeIt e(graph); e != INVALID; ++e) {
 177.250 +    if (mm.matching(e)) {
 177.251 +      check(e == mm.matching(graph.u(e)), "Wrong matching");
 177.252 +      check(e == mm.matching(graph.v(e)), "Wrong matching");
 177.253 +      ++num;
 177.254 +    }
 177.255 +    check(mm.status(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
 177.256 +          mm.status(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
 177.257 +          "Wrong Gallai-Edmonds decomposition");
 177.258 +
 177.259 +    check(mm.status(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
 177.260 +          mm.status(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
 177.261 +          "Wrong Gallai-Edmonds decomposition");
 177.262 +
 177.263 +    if (mm.status(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
 177.264 +        mm.status(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
 177.265 +      comp.join(graph.u(e), graph.v(e));
 177.266 +    }
 177.267 +  }
 177.268 +
 177.269 +  std::set<int> comp_root;
 177.270 +  int odd_comp_num = 0;
 177.271 +  for (NodeIt n(graph); n != INVALID; ++n) {
 177.272 +    if (mm.status(n) != MaxMatching<SmartGraph>::ODD) {
 177.273 +      int root = comp.find(n);
 177.274 +      if (comp_root.find(root) == comp_root.end()) {
 177.275 +        comp_root.insert(root);
 177.276 +        if (comp.size(n) % 2 == 1) {
 177.277 +          ++odd_comp_num;
 177.278 +        }
 177.279 +      }
 177.280 +    }
 177.281 +  }
 177.282 +
 177.283 +  check(mm.matchingSize() == num, "Wrong matching");
 177.284 +  check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num),
 177.285 +         "Wrong matching");
 177.286 +  return;
 177.287 +}
 177.288 +
 177.289 +void checkWeightedMatching(const SmartGraph& graph,
 177.290 +                   const SmartGraph::EdgeMap<int>& weight,
 177.291 +                   const MaxWeightedMatching<SmartGraph>& mwm) {
 177.292 +  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
 177.293 +    if (graph.u(e) == graph.v(e)) continue;
 177.294 +    int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e));
 177.295 +
 177.296 +    for (int i = 0; i < mwm.blossomNum(); ++i) {
 177.297 +      bool s = false, t = false;
 177.298 +      for (MaxWeightedMatching<SmartGraph>::BlossomIt n(mwm, i);
 177.299 +           n != INVALID; ++n) {
 177.300 +        if (graph.u(e) == n) s = true;
 177.301 +        if (graph.v(e) == n) t = true;
 177.302 +      }
 177.303 +      if (s == true && t == true) {
 177.304 +        rw += mwm.blossomValue(i);
 177.305 +      }
 177.306 +    }
 177.307 +    rw -= weight[e] * mwm.dualScale;
 177.308 +
 177.309 +    check(rw >= 0, "Negative reduced weight");
 177.310 +    check(rw == 0 || !mwm.matching(e),
 177.311 +          "Non-zero reduced weight on matching edge");
 177.312 +  }
 177.313 +
 177.314 +  int pv = 0;
 177.315 +  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 177.316 +    if (mwm.matching(n) != INVALID) {
 177.317 +      check(mwm.nodeValue(n) >= 0, "Invalid node value");
 177.318 +      pv += weight[mwm.matching(n)];
 177.319 +      SmartGraph::Node o = graph.target(mwm.matching(n));
 177.320 +      check(mwm.mate(n) == o, "Invalid matching");
 177.321 +      check(mwm.matching(n) == graph.oppositeArc(mwm.matching(o)),
 177.322 +            "Invalid matching");
 177.323 +    } else {
 177.324 +      check(mwm.mate(n) == INVALID, "Invalid matching");
 177.325 +      check(mwm.nodeValue(n) == 0, "Invalid matching");
 177.326 +    }
 177.327 +  }
 177.328 +
 177.329 +  int dv = 0;
 177.330 +  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 177.331 +    dv += mwm.nodeValue(n);
 177.332 +  }
 177.333 +
 177.334 +  for (int i = 0; i < mwm.blossomNum(); ++i) {
 177.335 +    check(mwm.blossomValue(i) >= 0, "Invalid blossom value");
 177.336 +    check(mwm.blossomSize(i) % 2 == 1, "Even blossom size");
 177.337 +    dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2);
 177.338 +  }
 177.339 +
 177.340 +  check(pv * mwm.dualScale == dv * 2, "Wrong duality");
 177.341 +
 177.342 +  return;
 177.343 +}
 177.344 +
 177.345 +void checkWeightedPerfectMatching(const SmartGraph& graph,
 177.346 +                          const SmartGraph::EdgeMap<int>& weight,
 177.347 +                          const MaxWeightedPerfectMatching<SmartGraph>& mwpm) {
 177.348 +  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
 177.349 +    if (graph.u(e) == graph.v(e)) continue;
 177.350 +    int rw = mwpm.nodeValue(graph.u(e)) + mwpm.nodeValue(graph.v(e));
 177.351 +
 177.352 +    for (int i = 0; i < mwpm.blossomNum(); ++i) {
 177.353 +      bool s = false, t = false;
 177.354 +      for (MaxWeightedPerfectMatching<SmartGraph>::BlossomIt n(mwpm, i);
 177.355 +           n != INVALID; ++n) {
 177.356 +        if (graph.u(e) == n) s = true;
 177.357 +        if (graph.v(e) == n) t = true;
 177.358 +      }
 177.359 +      if (s == true && t == true) {
 177.360 +        rw += mwpm.blossomValue(i);
 177.361 +      }
 177.362 +    }
 177.363 +    rw -= weight[e] * mwpm.dualScale;
 177.364 +
 177.365 +    check(rw >= 0, "Negative reduced weight");
 177.366 +    check(rw == 0 || !mwpm.matching(e),
 177.367 +          "Non-zero reduced weight on matching edge");
 177.368 +  }
 177.369 +
 177.370 +  int pv = 0;
 177.371 +  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 177.372 +    check(mwpm.matching(n) != INVALID, "Non perfect");
 177.373 +    pv += weight[mwpm.matching(n)];
 177.374 +    SmartGraph::Node o = graph.target(mwpm.matching(n));
 177.375 +    check(mwpm.mate(n) == o, "Invalid matching");
 177.376 +    check(mwpm.matching(n) == graph.oppositeArc(mwpm.matching(o)),
 177.377 +          "Invalid matching");
 177.378 +  }
 177.379 +
 177.380 +  int dv = 0;
 177.381 +  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 177.382 +    dv += mwpm.nodeValue(n);
 177.383 +  }
 177.384 +
 177.385 +  for (int i = 0; i < mwpm.blossomNum(); ++i) {
 177.386 +    check(mwpm.blossomValue(i) >= 0, "Invalid blossom value");
 177.387 +    check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size");
 177.388 +    dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2);
 177.389 +  }
 177.390 +
 177.391 +  check(pv * mwpm.dualScale == dv * 2, "Wrong duality");
 177.392 +
 177.393 +  return;
 177.394 +}
 177.395 +
 177.396 +
 177.397 +int main() {
 177.398 +
 177.399 +  for (int i = 0; i < lgfn; ++i) {
 177.400 +    SmartGraph graph;
 177.401 +    SmartGraph::EdgeMap<int> weight(graph);
 177.402 +
 177.403 +    istringstream lgfs(lgf[i]);
 177.404 +    graphReader(graph, lgfs).
 177.405 +      edgeMap("weight", weight).run();
 177.406 +
 177.407 +    MaxMatching<SmartGraph> mm(graph);
 177.408 +    mm.run();
 177.409 +    checkMatching(graph, mm);
 177.410 +
 177.411 +    MaxWeightedMatching<SmartGraph> mwm(graph, weight);
 177.412 +    mwm.run();
 177.413 +    checkWeightedMatching(graph, weight, mwm);
 177.414 +
 177.415 +    MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
 177.416 +    bool perfect = mwpm.run();
 177.417 +
 177.418 +    check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
 177.419 +          "Perfect matching found");
 177.420 +
 177.421 +    if (perfect) {
 177.422 +      checkWeightedPerfectMatching(graph, weight, mwpm);
 177.423 +    }
 177.424 +  }
 177.425 +
 177.426 +  return 0;
 177.427 +}
   178.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   178.2 +++ b/test/min_cost_arborescence_test.cc	Thu Nov 05 15:50:01 2009 +0100
   178.3 @@ -0,0 +1,206 @@
   178.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   178.5 + *
   178.6 + * This file is a part of LEMON, a generic C++ optimization library.
   178.7 + *
   178.8 + * Copyright (C) 2003-2008
   178.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  178.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  178.11 + *
  178.12 + * Permission to use, modify and distribute this software is granted
  178.13 + * provided that this copyright notice appears in all copies. For
  178.14 + * precise terms see the accompanying LICENSE file.
  178.15 + *
  178.16 + * This software is provided "AS IS" with no warranty of any kind,
  178.17 + * express or implied, and with no claim as to its suitability for any
  178.18 + * purpose.
  178.19 + *
  178.20 + */
  178.21 +
  178.22 +#include <iostream>
  178.23 +#include <set>
  178.24 +#include <vector>
  178.25 +#include <iterator>
  178.26 +
  178.27 +#include <lemon/smart_graph.h>
  178.28 +#include <lemon/min_cost_arborescence.h>
  178.29 +#include <lemon/lgf_reader.h>
  178.30 +#include <lemon/concepts/digraph.h>
  178.31 +
  178.32 +#include "test_tools.h"
  178.33 +
  178.34 +using namespace lemon;
  178.35 +using namespace std;
  178.36 +
  178.37 +const char test_lgf[] =
  178.38 +  "@nodes\n"
  178.39 +  "label\n"
  178.40 +  "0\n"
  178.41 +  "1\n"
  178.42 +  "2\n"
  178.43 +  "3\n"
  178.44 +  "4\n"
  178.45 +  "5\n"
  178.46 +  "6\n"
  178.47 +  "7\n"
  178.48 +  "8\n"
  178.49 +  "9\n"
  178.50 +  "@arcs\n"
  178.51 +  "     label  cost\n"
  178.52 +  "1 8  0      107\n"
  178.53 +  "0 3  1      70\n"
  178.54 +  "2 1  2      46\n"
  178.55 +  "4 1  3      28\n"
  178.56 +  "4 4  4      91\n"
  178.57 +  "3 9  5      76\n"
  178.58 +  "9 8  6      61\n"
  178.59 +  "8 1  7      39\n"
  178.60 +  "9 8  8      74\n"
  178.61 +  "8 0  9      39\n"
  178.62 +  "4 3  10     45\n"
  178.63 +  "2 2  11     34\n"
  178.64 +  "0 1  12     100\n"
  178.65 +  "6 3  13     95\n"
  178.66 +  "4 1  14     22\n"
  178.67 +  "1 1  15     31\n"
  178.68 +  "7 2  16     51\n"
  178.69 +  "2 6  17     29\n"
  178.70 +  "8 3  18     115\n"
  178.71 +  "6 9  19     32\n"
  178.72 +  "1 1  20     60\n"
  178.73 +  "0 3  21     40\n"
  178.74 +  "@attributes\n"
  178.75 +  "source 0\n";
  178.76 +
  178.77 +
  178.78 +void checkMinCostArborescenceCompile()
  178.79 +{
  178.80 +  typedef double VType;
  178.81 +  typedef concepts::Digraph Digraph;
  178.82 +  typedef concepts::ReadMap<Digraph::Arc, VType> CostMap;
  178.83 +  typedef Digraph::Node Node;
  178.84 +  typedef Digraph::Arc Arc;
  178.85 +  typedef concepts::WriteMap<Digraph::Arc, bool> ArbMap;
  178.86 +  typedef concepts::ReadWriteMap<Digraph::Node, Digraph::Arc> PredMap;
  178.87 +
  178.88 +  typedef MinCostArborescence<Digraph, CostMap>::
  178.89 +            SetArborescenceMap<ArbMap>::
  178.90 +            SetPredMap<PredMap>::Create MinCostArbType;
  178.91 +
  178.92 +  Digraph g;
  178.93 +  Node s, n;
  178.94 +  Arc e;
  178.95 +  VType c;
  178.96 +  bool b;
  178.97 +  int i;
  178.98 +  CostMap cost;
  178.99 +  ArbMap arb;
 178.100 +  PredMap pred;
 178.101 +
 178.102 +  MinCostArbType mcarb_test(g, cost);
 178.103 +  const MinCostArbType& const_mcarb_test = mcarb_test;
 178.104 +
 178.105 +  mcarb_test
 178.106 +    .arborescenceMap(arb)
 178.107 +    .predMap(pred)
 178.108 +    .run(s);
 178.109 +
 178.110 +  mcarb_test.init();
 178.111 +  mcarb_test.addSource(s);
 178.112 +  mcarb_test.start();
 178.113 +  n = mcarb_test.processNextNode();
 178.114 +  b = const_mcarb_test.emptyQueue();
 178.115 +  i = const_mcarb_test.queueSize();
 178.116 +  
 178.117 +  c = const_mcarb_test.arborescenceCost();
 178.118 +  b = const_mcarb_test.arborescence(e);
 178.119 +  e = const_mcarb_test.pred(n);
 178.120 +  const MinCostArbType::ArborescenceMap &am =
 178.121 +    const_mcarb_test.arborescenceMap();
 178.122 +  const MinCostArbType::PredMap &pm =
 178.123 +    const_mcarb_test.predMap();
 178.124 +  b = const_mcarb_test.reached(n);
 178.125 +  b = const_mcarb_test.processed(n);
 178.126 +  
 178.127 +  i = const_mcarb_test.dualNum();
 178.128 +  c = const_mcarb_test.dualValue();
 178.129 +  i = const_mcarb_test.dualSize(i);
 178.130 +  c = const_mcarb_test.dualValue(i);
 178.131 +  
 178.132 +  ignore_unused_variable_warning(am);
 178.133 +  ignore_unused_variable_warning(pm);
 178.134 +}
 178.135 +
 178.136 +int main() {
 178.137 +  typedef SmartDigraph Digraph;
 178.138 +  DIGRAPH_TYPEDEFS(Digraph);
 178.139 +
 178.140 +  typedef Digraph::ArcMap<double> CostMap;
 178.141 +
 178.142 +  Digraph digraph;
 178.143 +  CostMap cost(digraph);
 178.144 +  Node source;
 178.145 +
 178.146 +  std::istringstream is(test_lgf);
 178.147 +  digraphReader(digraph, is).
 178.148 +    arcMap("cost", cost).
 178.149 +    node("source", source).run();
 178.150 +
 178.151 +  MinCostArborescence<Digraph, CostMap> mca(digraph, cost);
 178.152 +  mca.run(source);
 178.153 +
 178.154 +  vector<pair<double, set<Node> > > dualSolution(mca.dualNum());
 178.155 +
 178.156 +  for (int i = 0; i < mca.dualNum(); ++i) {
 178.157 +    dualSolution[i].first = mca.dualValue(i);
 178.158 +    for (MinCostArborescence<Digraph, CostMap>::DualIt it(mca, i);
 178.159 +         it != INVALID; ++it) {
 178.160 +      dualSolution[i].second.insert(it);
 178.161 +    }
 178.162 +  }
 178.163 +
 178.164 +  for (ArcIt it(digraph); it != INVALID; ++it) {
 178.165 +    if (mca.reached(digraph.source(it))) {
 178.166 +      double sum = 0.0;
 178.167 +      for (int i = 0; i < int(dualSolution.size()); ++i) {
 178.168 +        if (dualSolution[i].second.find(digraph.target(it))
 178.169 +            != dualSolution[i].second.end() &&
 178.170 +            dualSolution[i].second.find(digraph.source(it))
 178.171 +            == dualSolution[i].second.end()) {
 178.172 +          sum += dualSolution[i].first;
 178.173 +        }
 178.174 +      }
 178.175 +      if (mca.arborescence(it)) {
 178.176 +        check(sum == cost[it], "Invalid dual solution");
 178.177 +      }
 178.178 +      check(sum <= cost[it], "Invalid dual solution");
 178.179 +    }
 178.180 +  }
 178.181 +
 178.182 +
 178.183 +  check(mca.dualValue() == mca.arborescenceCost(), "Invalid dual solution");
 178.184 +
 178.185 +  check(mca.reached(source), "Invalid arborescence");
 178.186 +  for (ArcIt a(digraph); a != INVALID; ++a) {
 178.187 +    check(!mca.reached(digraph.source(a)) ||
 178.188 +          mca.reached(digraph.target(a)), "Invalid arborescence");
 178.189 +  }
 178.190 +
 178.191 +  for (NodeIt n(digraph); n != INVALID; ++n) {
 178.192 +    if (!mca.reached(n)) continue;
 178.193 +    int cnt = 0;
 178.194 +    for (InArcIt a(digraph, n); a != INVALID; ++a) {
 178.195 +      if (mca.arborescence(a)) {
 178.196 +        check(mca.pred(n) == a, "Invalid arborescence");
 178.197 +        ++cnt;
 178.198 +      }
 178.199 +    }
 178.200 +    check((n == source ? cnt == 0 : cnt == 1), "Invalid arborescence");
 178.201 +  }
 178.202 +
 178.203 +  Digraph::ArcMap<bool> arborescence(digraph);
 178.204 +  check(mca.arborescenceCost() ==
 178.205 +        minCostArborescence(digraph, cost, source, arborescence),
 178.206 +        "Wrong result of the function interface");
 178.207 +
 178.208 +  return 0;
 178.209 +}
   179.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   179.2 +++ b/test/min_cost_flow_test.cc	Thu Nov 05 15:50:01 2009 +0100
   179.3 @@ -0,0 +1,450 @@
   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-2009
   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 <iostream>
  179.23 +#include <fstream>
  179.24 +#include <limits>
  179.25 +
  179.26 +#include <lemon/list_graph.h>
  179.27 +#include <lemon/lgf_reader.h>
  179.28 +
  179.29 +#include <lemon/network_simplex.h>
  179.30 +
  179.31 +#include <lemon/concepts/digraph.h>
  179.32 +#include <lemon/concept_check.h>
  179.33 +
  179.34 +#include "test_tools.h"
  179.35 +
  179.36 +using namespace lemon;
  179.37 +
  179.38 +char test_lgf[] =
  179.39 +  "@nodes\n"
  179.40 +  "label  sup1 sup2 sup3 sup4 sup5 sup6\n"
  179.41 +  "    1    20   27    0   30   20   30\n"
  179.42 +  "    2    -4    0    0    0   -8   -3\n"
  179.43 +  "    3     0    0    0    0    0    0\n"
  179.44 +  "    4     0    0    0    0    0    0\n"
  179.45 +  "    5     9    0    0    0    6   11\n"
  179.46 +  "    6    -6    0    0    0   -5   -6\n"
  179.47 +  "    7     0    0    0    0    0    0\n"
  179.48 +  "    8     0    0    0    0    0    3\n"
  179.49 +  "    9     3    0    0    0    0    0\n"
  179.50 +  "   10    -2    0    0    0   -7   -2\n"
  179.51 +  "   11     0    0    0    0  -10    0\n"
  179.52 +  "   12   -20  -27    0  -30  -30  -20\n"
  179.53 +  "\n"                
  179.54 +  "@arcs\n"
  179.55 +  "       cost  cap low1 low2 low3\n"
  179.56 +  " 1  2    70   11    0    8    8\n"
  179.57 +  " 1  3   150    3    0    1    0\n"
  179.58 +  " 1  4    80   15    0    2    2\n"
  179.59 +  " 2  8    80   12    0    0    0\n"
  179.60 +  " 3  5   140    5    0    3    1\n"
  179.61 +  " 4  6    60   10    0    1    0\n"
  179.62 +  " 4  7    80    2    0    0    0\n"
  179.63 +  " 4  8   110    3    0    0    0\n"
  179.64 +  " 5  7    60   14    0    0    0\n"
  179.65 +  " 5 11   120   12    0    0    0\n"
  179.66 +  " 6  3     0    3    0    0    0\n"
  179.67 +  " 6  9   140    4    0    0    0\n"
  179.68 +  " 6 10    90    8    0    0    0\n"
  179.69 +  " 7  1    30    5    0    0   -5\n"
  179.70 +  " 8 12    60   16    0    4    3\n"
  179.71 +  " 9 12    50    6    0    0    0\n"
  179.72 +  "10 12    70   13    0    5    2\n"
  179.73 +  "10  2   100    7    0    0    0\n"
  179.74 +  "10  7    60   10    0    0   -3\n"
  179.75 +  "11 10    20   14    0    6  -20\n"
  179.76 +  "12 11    30   10    0    0  -10\n"
  179.77 +  "\n"
  179.78 +  "@attributes\n"
  179.79 +  "source 1\n"
  179.80 +  "target 12\n";
  179.81 +
  179.82 +
  179.83 +enum SupplyType {
  179.84 +  EQ,
  179.85 +  GEQ,
  179.86 +  LEQ
  179.87 +};
  179.88 +
  179.89 +// Check the interface of an MCF algorithm
  179.90 +template <typename GR, typename Value, typename Cost>
  179.91 +class McfClassConcept
  179.92 +{
  179.93 +public:
  179.94 +
  179.95 +  template <typename MCF>
  179.96 +  struct Constraints {
  179.97 +    void constraints() {
  179.98 +      checkConcept<concepts::Digraph, GR>();
  179.99 +      
 179.100 +      const Constraints& me = *this;
 179.101 +
 179.102 +      MCF mcf(me.g);
 179.103 +      const MCF& const_mcf = mcf;
 179.104 +
 179.105 +      b = mcf.reset()
 179.106 +             .lowerMap(me.lower)
 179.107 +             .upperMap(me.upper)
 179.108 +             .costMap(me.cost)
 179.109 +             .supplyMap(me.sup)
 179.110 +             .stSupply(me.n, me.n, me.k)
 179.111 +             .run();
 179.112 +
 179.113 +      c = const_mcf.totalCost();
 179.114 +      x = const_mcf.template totalCost<double>();
 179.115 +      v = const_mcf.flow(me.a);
 179.116 +      c = const_mcf.potential(me.n);
 179.117 +      const_mcf.flowMap(fm);
 179.118 +      const_mcf.potentialMap(pm);
 179.119 +    }
 179.120 +
 179.121 +    typedef typename GR::Node Node;
 179.122 +    typedef typename GR::Arc Arc;
 179.123 +    typedef concepts::ReadMap<Node, Value> NM;
 179.124 +    typedef concepts::ReadMap<Arc, Value> VAM;
 179.125 +    typedef concepts::ReadMap<Arc, Cost> CAM;
 179.126 +    typedef concepts::WriteMap<Arc, Value> FlowMap;
 179.127 +    typedef concepts::WriteMap<Node, Cost> PotMap;
 179.128 +  
 179.129 +    GR g;
 179.130 +    VAM lower;
 179.131 +    VAM upper;
 179.132 +    CAM cost;
 179.133 +    NM sup;
 179.134 +    Node n;
 179.135 +    Arc a;
 179.136 +    Value k;
 179.137 +
 179.138 +    FlowMap fm;
 179.139 +    PotMap pm;
 179.140 +    bool b;
 179.141 +    double x;
 179.142 +    typename MCF::Value v;
 179.143 +    typename MCF::Cost c;
 179.144 +  };
 179.145 +
 179.146 +};
 179.147 +
 179.148 +
 179.149 +// Check the feasibility of the given flow (primal soluiton)
 179.150 +template < typename GR, typename LM, typename UM,
 179.151 +           typename SM, typename FM >
 179.152 +bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
 179.153 +                const SM& supply, const FM& flow,
 179.154 +                SupplyType type = EQ )
 179.155 +{
 179.156 +  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
 179.157 +
 179.158 +  for (ArcIt e(gr); e != INVALID; ++e) {
 179.159 +    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
 179.160 +  }
 179.161 +
 179.162 +  for (NodeIt n(gr); n != INVALID; ++n) {
 179.163 +    typename SM::Value sum = 0;
 179.164 +    for (OutArcIt e(gr, n); e != INVALID; ++e)
 179.165 +      sum += flow[e];
 179.166 +    for (InArcIt e(gr, n); e != INVALID; ++e)
 179.167 +      sum -= flow[e];
 179.168 +    bool b = (type ==  EQ && sum == supply[n]) ||
 179.169 +             (type == GEQ && sum >= supply[n]) ||
 179.170 +             (type == LEQ && sum <= supply[n]);
 179.171 +    if (!b) return false;
 179.172 +  }
 179.173 +
 179.174 +  return true;
 179.175 +}
 179.176 +
 179.177 +// Check the feasibility of the given potentials (dual soluiton)
 179.178 +// using the "Complementary Slackness" optimality condition
 179.179 +template < typename GR, typename LM, typename UM,
 179.180 +           typename CM, typename SM, typename FM, typename PM >
 179.181 +bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
 179.182 +                     const CM& cost, const SM& supply, const FM& flow, 
 179.183 +                     const PM& pi, SupplyType type )
 179.184 +{
 179.185 +  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
 179.186 +
 179.187 +  bool opt = true;
 179.188 +  for (ArcIt e(gr); opt && e != INVALID; ++e) {
 179.189 +    typename CM::Value red_cost =
 179.190 +      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
 179.191 +    opt = red_cost == 0 ||
 179.192 +          (red_cost > 0 && flow[e] == lower[e]) ||
 179.193 +          (red_cost < 0 && flow[e] == upper[e]);
 179.194 +  }
 179.195 +  
 179.196 +  for (NodeIt n(gr); opt && n != INVALID; ++n) {
 179.197 +    typename SM::Value sum = 0;
 179.198 +    for (OutArcIt e(gr, n); e != INVALID; ++e)
 179.199 +      sum += flow[e];
 179.200 +    for (InArcIt e(gr, n); e != INVALID; ++e)
 179.201 +      sum -= flow[e];
 179.202 +    if (type != LEQ) {
 179.203 +      opt = (pi[n] <= 0) && (sum == supply[n] || pi[n] == 0);
 179.204 +    } else {
 179.205 +      opt = (pi[n] >= 0) && (sum == supply[n] || pi[n] == 0);
 179.206 +    }
 179.207 +  }
 179.208 +  
 179.209 +  return opt;
 179.210 +}
 179.211 +
 179.212 +// Check whether the dual cost is equal to the primal cost
 179.213 +template < typename GR, typename LM, typename UM,
 179.214 +           typename CM, typename SM, typename PM >
 179.215 +bool checkDualCost( const GR& gr, const LM& lower, const UM& upper,
 179.216 +                    const CM& cost, const SM& supply, const PM& pi,
 179.217 +                    typename CM::Value total )
 179.218 +{
 179.219 +  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
 179.220 +
 179.221 +  typename CM::Value dual_cost = 0;
 179.222 +  SM red_supply(gr);
 179.223 +  for (NodeIt n(gr); n != INVALID; ++n) {
 179.224 +    red_supply[n] = supply[n];
 179.225 +  }
 179.226 +  for (ArcIt a(gr); a != INVALID; ++a) {
 179.227 +    if (lower[a] != 0) {
 179.228 +      dual_cost += lower[a] * cost[a];
 179.229 +      red_supply[gr.source(a)] -= lower[a];
 179.230 +      red_supply[gr.target(a)] += lower[a];
 179.231 +    }
 179.232 +  }
 179.233 +  
 179.234 +  for (NodeIt n(gr); n != INVALID; ++n) {
 179.235 +    dual_cost -= red_supply[n] * pi[n];
 179.236 +  }
 179.237 +  for (ArcIt a(gr); a != INVALID; ++a) {
 179.238 +    typename CM::Value red_cost =
 179.239 +      cost[a] + pi[gr.source(a)] - pi[gr.target(a)];
 179.240 +    dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0);
 179.241 +  }
 179.242 +  
 179.243 +  return dual_cost == total;
 179.244 +}
 179.245 +
 179.246 +// Run a minimum cost flow algorithm and check the results
 179.247 +template < typename MCF, typename GR,
 179.248 +           typename LM, typename UM,
 179.249 +           typename CM, typename SM,
 179.250 +           typename PT >
 179.251 +void checkMcf( const MCF& mcf, PT mcf_result,
 179.252 +               const GR& gr, const LM& lower, const UM& upper,
 179.253 +               const CM& cost, const SM& supply,
 179.254 +               PT result, bool optimal, typename CM::Value total,
 179.255 +               const std::string &test_id = "",
 179.256 +               SupplyType type = EQ )
 179.257 +{
 179.258 +  check(mcf_result == result, "Wrong result " + test_id);
 179.259 +  if (optimal) {
 179.260 +    typename GR::template ArcMap<typename SM::Value> flow(gr);
 179.261 +    typename GR::template NodeMap<typename CM::Value> pi(gr);
 179.262 +    mcf.flowMap(flow);
 179.263 +    mcf.potentialMap(pi);
 179.264 +    check(checkFlow(gr, lower, upper, supply, flow, type),
 179.265 +          "The flow is not feasible " + test_id);
 179.266 +    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
 179.267 +    check(checkPotential(gr, lower, upper, cost, supply, flow, pi, type),
 179.268 +          "Wrong potentials " + test_id);
 179.269 +    check(checkDualCost(gr, lower, upper, cost, supply, pi, total),
 179.270 +          "Wrong dual cost " + test_id);
 179.271 +  }
 179.272 +}
 179.273 +
 179.274 +int main()
 179.275 +{
 179.276 +  // Check the interfaces
 179.277 +  {
 179.278 +    typedef concepts::Digraph GR;
 179.279 +    checkConcept< McfClassConcept<GR, int, int>,
 179.280 +                  NetworkSimplex<GR> >();
 179.281 +    checkConcept< McfClassConcept<GR, double, double>,
 179.282 +                  NetworkSimplex<GR, double> >();
 179.283 +    checkConcept< McfClassConcept<GR, int, double>,
 179.284 +                  NetworkSimplex<GR, int, double> >();
 179.285 +  }
 179.286 +
 179.287 +  // Run various MCF tests
 179.288 +  typedef ListDigraph Digraph;
 179.289 +  DIGRAPH_TYPEDEFS(ListDigraph);
 179.290 +
 179.291 +  // Read the test digraph
 179.292 +  Digraph gr;
 179.293 +  Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
 179.294 +  Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
 179.295 +  ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
 179.296 +  Node v, w;
 179.297 +
 179.298 +  std::istringstream input(test_lgf);
 179.299 +  DigraphReader<Digraph>(gr, input)
 179.300 +    .arcMap("cost", c)
 179.301 +    .arcMap("cap", u)
 179.302 +    .arcMap("low1", l1)
 179.303 +    .arcMap("low2", l2)
 179.304 +    .arcMap("low3", l3)
 179.305 +    .nodeMap("sup1", s1)
 179.306 +    .nodeMap("sup2", s2)
 179.307 +    .nodeMap("sup3", s3)
 179.308 +    .nodeMap("sup4", s4)
 179.309 +    .nodeMap("sup5", s5)
 179.310 +    .nodeMap("sup6", s6)
 179.311 +    .node("source", v)
 179.312 +    .node("target", w)
 179.313 +    .run();
 179.314 +  
 179.315 +  // Build test digraphs with negative costs
 179.316 +  Digraph neg_gr;
 179.317 +  Node n1 = neg_gr.addNode();
 179.318 +  Node n2 = neg_gr.addNode();
 179.319 +  Node n3 = neg_gr.addNode();
 179.320 +  Node n4 = neg_gr.addNode();
 179.321 +  Node n5 = neg_gr.addNode();
 179.322 +  Node n6 = neg_gr.addNode();
 179.323 +  Node n7 = neg_gr.addNode();
 179.324 +  
 179.325 +  Arc a1 = neg_gr.addArc(n1, n2);
 179.326 +  Arc a2 = neg_gr.addArc(n1, n3);
 179.327 +  Arc a3 = neg_gr.addArc(n2, n4);
 179.328 +  Arc a4 = neg_gr.addArc(n3, n4);
 179.329 +  Arc a5 = neg_gr.addArc(n3, n2);
 179.330 +  Arc a6 = neg_gr.addArc(n5, n3);
 179.331 +  Arc a7 = neg_gr.addArc(n5, n6);
 179.332 +  Arc a8 = neg_gr.addArc(n6, n7);
 179.333 +  Arc a9 = neg_gr.addArc(n7, n5);
 179.334 +  
 179.335 +  Digraph::ArcMap<int> neg_c(neg_gr), neg_l1(neg_gr, 0), neg_l2(neg_gr, 0);
 179.336 +  ConstMap<Arc, int> neg_u1(std::numeric_limits<int>::max()), neg_u2(5000);
 179.337 +  Digraph::NodeMap<int> neg_s(neg_gr, 0);
 179.338 +  
 179.339 +  neg_l2[a7] =  1000;
 179.340 +  neg_l2[a8] = -1000;
 179.341 +  
 179.342 +  neg_s[n1] =  100;
 179.343 +  neg_s[n4] = -100;
 179.344 +  
 179.345 +  neg_c[a1] =  100;
 179.346 +  neg_c[a2] =   30;
 179.347 +  neg_c[a3] =   20;
 179.348 +  neg_c[a4] =   80;
 179.349 +  neg_c[a5] =   50;
 179.350 +  neg_c[a6] =   10;
 179.351 +  neg_c[a7] =   80;
 179.352 +  neg_c[a8] =   30;
 179.353 +  neg_c[a9] = -120;
 179.354 +
 179.355 +  Digraph negs_gr;
 179.356 +  Digraph::NodeMap<int> negs_s(negs_gr);
 179.357 +  Digraph::ArcMap<int> negs_c(negs_gr);
 179.358 +  ConstMap<Arc, int> negs_l(0), negs_u(1000);
 179.359 +  n1 = negs_gr.addNode();
 179.360 +  n2 = negs_gr.addNode();
 179.361 +  negs_s[n1] = 100;
 179.362 +  negs_s[n2] = -300;
 179.363 +  negs_c[negs_gr.addArc(n1, n2)] = -1;
 179.364 +
 179.365 +
 179.366 +  // A. Test NetworkSimplex with the default pivot rule
 179.367 +  {
 179.368 +    NetworkSimplex<Digraph> mcf(gr);
 179.369 +
 179.370 +    // Check the equality form
 179.371 +    mcf.upperMap(u).costMap(c);
 179.372 +    checkMcf(mcf, mcf.supplyMap(s1).run(),
 179.373 +             gr, l1, u, c, s1, mcf.OPTIMAL, true,   5240, "#A1");
 179.374 +    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
 179.375 +             gr, l1, u, c, s2, mcf.OPTIMAL, true,   7620, "#A2");
 179.376 +    mcf.lowerMap(l2);
 179.377 +    checkMcf(mcf, mcf.supplyMap(s1).run(),
 179.378 +             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#A3");
 179.379 +    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
 179.380 +             gr, l2, u, c, s2, mcf.OPTIMAL, true,   8010, "#A4");
 179.381 +    mcf.reset();
 179.382 +    checkMcf(mcf, mcf.supplyMap(s1).run(),
 179.383 +             gr, l1, cu, cc, s1, mcf.OPTIMAL, true,   74, "#A5");
 179.384 +    checkMcf(mcf, mcf.lowerMap(l2).stSupply(v, w, 27).run(),
 179.385 +             gr, l2, cu, cc, s2, mcf.OPTIMAL, true,   94, "#A6");
 179.386 +    mcf.reset();
 179.387 +    checkMcf(mcf, mcf.run(),
 179.388 +             gr, l1, cu, cc, s3, mcf.OPTIMAL, true,    0, "#A7");
 179.389 +    checkMcf(mcf, mcf.lowerMap(l2).upperMap(u).run(),
 179.390 +             gr, l2, u, cc, s3, mcf.INFEASIBLE, false, 0, "#A8");
 179.391 +    mcf.reset().lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
 179.392 +    checkMcf(mcf, mcf.run(),
 179.393 +             gr, l3, u, c, s4, mcf.OPTIMAL, true,   6360, "#A9");
 179.394 +
 179.395 +    // Check the GEQ form
 179.396 +    mcf.reset().upperMap(u).costMap(c).supplyMap(s5);
 179.397 +    checkMcf(mcf, mcf.run(),
 179.398 +             gr, l1, u, c, s5, mcf.OPTIMAL, true,   3530, "#A10", GEQ);
 179.399 +    mcf.supplyType(mcf.GEQ);
 179.400 +    checkMcf(mcf, mcf.lowerMap(l2).run(),
 179.401 +             gr, l2, u, c, s5, mcf.OPTIMAL, true,   4540, "#A11", GEQ);
 179.402 +    mcf.supplyMap(s6);
 179.403 +    checkMcf(mcf, mcf.run(),
 179.404 +             gr, l2, u, c, s6, mcf.INFEASIBLE, false,  0, "#A12", GEQ);
 179.405 +
 179.406 +    // Check the LEQ form
 179.407 +    mcf.reset().supplyType(mcf.LEQ);
 179.408 +    mcf.upperMap(u).costMap(c).supplyMap(s6);
 179.409 +    checkMcf(mcf, mcf.run(),
 179.410 +             gr, l1, u, c, s6, mcf.OPTIMAL, true,   5080, "#A13", LEQ);
 179.411 +    checkMcf(mcf, mcf.lowerMap(l2).run(),
 179.412 +             gr, l2, u, c, s6, mcf.OPTIMAL, true,   5930, "#A14", LEQ);
 179.413 +    mcf.supplyMap(s5);
 179.414 +    checkMcf(mcf, mcf.run(),
 179.415 +             gr, l2, u, c, s5, mcf.INFEASIBLE, false,  0, "#A15", LEQ);
 179.416 +
 179.417 +    // Check negative costs
 179.418 +    NetworkSimplex<Digraph> neg_mcf(neg_gr);
 179.419 +    neg_mcf.lowerMap(neg_l1).costMap(neg_c).supplyMap(neg_s);
 179.420 +    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u1,
 179.421 +      neg_c, neg_s, neg_mcf.UNBOUNDED, false,    0, "#A16");
 179.422 +    neg_mcf.upperMap(neg_u2);
 179.423 +    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u2,
 179.424 +      neg_c, neg_s, neg_mcf.OPTIMAL, true,  -40000, "#A17");
 179.425 +    neg_mcf.reset().lowerMap(neg_l2).costMap(neg_c).supplyMap(neg_s);
 179.426 +    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l2, neg_u1,
 179.427 +      neg_c, neg_s, neg_mcf.UNBOUNDED, false,    0, "#A18");
 179.428 +      
 179.429 +    NetworkSimplex<Digraph> negs_mcf(negs_gr);
 179.430 +    negs_mcf.costMap(negs_c).supplyMap(negs_s);
 179.431 +    checkMcf(negs_mcf, negs_mcf.run(), negs_gr, negs_l, negs_u,
 179.432 +      negs_c, negs_s, negs_mcf.OPTIMAL, true, -300, "#A19", GEQ);
 179.433 +  }
 179.434 +
 179.435 +  // B. Test NetworkSimplex with each pivot rule
 179.436 +  {
 179.437 +    NetworkSimplex<Digraph> mcf(gr);
 179.438 +    mcf.supplyMap(s1).costMap(c).upperMap(u).lowerMap(l2);
 179.439 +
 179.440 +    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::FIRST_ELIGIBLE),
 179.441 +             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B1");
 179.442 +    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BEST_ELIGIBLE),
 179.443 +             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B2");
 179.444 +    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BLOCK_SEARCH),
 179.445 +             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B3");
 179.446 +    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::CANDIDATE_LIST),
 179.447 +             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B4");
 179.448 +    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::ALTERING_LIST),
 179.449 +             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B5");
 179.450 +  }
 179.451 +
 179.452 +  return 0;
 179.453 +}
   180.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   180.2 +++ b/test/min_mean_cycle_test.cc	Thu Nov 05 15:50:01 2009 +0100
   180.3 @@ -0,0 +1,216 @@
   180.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   180.5 + *
   180.6 + * This file is a part of LEMON, a generic C++ optimization library.
   180.7 + *
   180.8 + * Copyright (C) 2003-2009
   180.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  180.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  180.11 + *
  180.12 + * Permission to use, modify and distribute this software is granted
  180.13 + * provided that this copyright notice appears in all copies. For
  180.14 + * precise terms see the accompanying LICENSE file.
  180.15 + *
  180.16 + * This software is provided "AS IS" with no warranty of any kind,
  180.17 + * express or implied, and with no claim as to its suitability for any
  180.18 + * purpose.
  180.19 + *
  180.20 + */
  180.21 +
  180.22 +#include <iostream>
  180.23 +#include <sstream>
  180.24 +
  180.25 +#include <lemon/smart_graph.h>
  180.26 +#include <lemon/lgf_reader.h>
  180.27 +#include <lemon/path.h>
  180.28 +#include <lemon/concepts/digraph.h>
  180.29 +#include <lemon/concept_check.h>
  180.30 +
  180.31 +#include <lemon/karp.h>
  180.32 +#include <lemon/hartmann_orlin.h>
  180.33 +#include <lemon/howard.h>
  180.34 +
  180.35 +#include "test_tools.h"
  180.36 +
  180.37 +using namespace lemon;
  180.38 +
  180.39 +char test_lgf[] =
  180.40 +  "@nodes\n"
  180.41 +  "label\n"
  180.42 +  "1\n"
  180.43 +  "2\n"
  180.44 +  "3\n"
  180.45 +  "4\n"
  180.46 +  "5\n"
  180.47 +  "6\n"
  180.48 +  "7\n"
  180.49 +  "@arcs\n"
  180.50 +  "    len1 len2 len3 len4  c1 c2 c3 c4\n"
  180.51 +  "1 2    1    1    1    1   0  0  0  0\n"
  180.52 +  "2 4    5    5    5    5   1  0  0  0\n"
  180.53 +  "2 3    8    8    8    8   0  0  0  0\n"
  180.54 +  "3 2   -2    0    0    0   1  0  0  0\n"
  180.55 +  "3 4    4    4    4    4   0  0  0  0\n"
  180.56 +  "3 7   -4   -4   -4   -4   0  0  0  0\n"
  180.57 +  "4 1    2    2    2    2   0  0  0  0\n"
  180.58 +  "4 3    3    3    3    3   1  0  0  0\n"
  180.59 +  "4 4    3    3    0    0   0  0  1  0\n"
  180.60 +  "5 2    4    4    4    4   0  0  0  0\n"
  180.61 +  "5 6    3    3    3    3   0  1  0  0\n"
  180.62 +  "6 5    2    2    2    2   0  1  0  0\n"
  180.63 +  "6 4   -1   -1   -1   -1   0  0  0  0\n"
  180.64 +  "6 7    1    1    1    1   0  0  0  0\n"
  180.65 +  "7 7    4    4    4   -1   0  0  0  1\n";
  180.66 +
  180.67 +                        
  180.68 +// Check the interface of an MMC algorithm
  180.69 +template <typename GR, typename Value>
  180.70 +struct MmcClassConcept
  180.71 +{
  180.72 +  template <typename MMC>
  180.73 +  struct Constraints {
  180.74 +    void constraints() {
  180.75 +      const Constraints& me = *this;
  180.76 +
  180.77 +      typedef typename MMC
  180.78 +        ::template SetPath<ListPath<GR> >
  180.79 +        ::template SetLargeValue<Value>
  180.80 +        ::Create MmcAlg;
  180.81 +      MmcAlg mmc(me.g, me.length);
  180.82 +      const MmcAlg& const_mmc = mmc;
  180.83 +      
  180.84 +      typename MmcAlg::Tolerance tol = const_mmc.tolerance();
  180.85 +      mmc.tolerance(tol);
  180.86 +      
  180.87 +      b = mmc.cycle(p).run();
  180.88 +      b = mmc.findMinMean();
  180.89 +      b = mmc.findCycle();
  180.90 +
  180.91 +      v = const_mmc.cycleLength();
  180.92 +      i = const_mmc.cycleArcNum();
  180.93 +      d = const_mmc.cycleMean();
  180.94 +      p = const_mmc.cycle();
  180.95 +    }
  180.96 +
  180.97 +    typedef concepts::ReadMap<typename GR::Arc, Value> LM;
  180.98 +  
  180.99 +    GR g;
 180.100 +    LM length;
 180.101 +    ListPath<GR> p;
 180.102 +    Value v;
 180.103 +    int i;
 180.104 +    double d;
 180.105 +    bool b;
 180.106 +  };
 180.107 +};
 180.108 +
 180.109 +// Perform a test with the given parameters
 180.110 +template <typename MMC>
 180.111 +void checkMmcAlg(const SmartDigraph& gr,
 180.112 +                 const SmartDigraph::ArcMap<int>& lm,
 180.113 +                 const SmartDigraph::ArcMap<int>& cm,
 180.114 +                 int length, int size) {
 180.115 +  MMC alg(gr, lm);
 180.116 +  alg.findMinMean();
 180.117 +  check(alg.cycleMean() == static_cast<double>(length) / size,
 180.118 +        "Wrong cycle mean");
 180.119 +  alg.findCycle();
 180.120 +  check(alg.cycleLength() == length && alg.cycleArcNum() == size,
 180.121 +        "Wrong path");
 180.122 +  SmartDigraph::ArcMap<int> cycle(gr, 0);
 180.123 +  for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
 180.124 +    ++cycle[a];
 180.125 +  }
 180.126 +  for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
 180.127 +    check(cm[a] == cycle[a], "Wrong path");
 180.128 +  }
 180.129 +}
 180.130 +
 180.131 +// Class for comparing types
 180.132 +template <typename T1, typename T2>
 180.133 +struct IsSameType {
 180.134 +  static const int result = 0;
 180.135 +};
 180.136 +
 180.137 +template <typename T>
 180.138 +struct IsSameType<T,T> {
 180.139 +  static const int result = 1;
 180.140 +};
 180.141 +
 180.142 +
 180.143 +int main() {
 180.144 +  #ifdef LEMON_HAVE_LONG_LONG
 180.145 +    typedef long long long_int;
 180.146 +  #else
 180.147 +    typedef long long_int;
 180.148 +  #endif
 180.149 +
 180.150 +  // Check the interface
 180.151 +  {
 180.152 +    typedef concepts::Digraph GR;
 180.153 +
 180.154 +    // Karp
 180.155 +    checkConcept< MmcClassConcept<GR, int>,
 180.156 +                  Karp<GR, concepts::ReadMap<GR::Arc, int> > >();
 180.157 +    checkConcept< MmcClassConcept<GR, float>,
 180.158 +                  Karp<GR, concepts::ReadMap<GR::Arc, float> > >();
 180.159 +    
 180.160 +    // HartmannOrlin
 180.161 +    checkConcept< MmcClassConcept<GR, int>,
 180.162 +                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, int> > >();
 180.163 +    checkConcept< MmcClassConcept<GR, float>,
 180.164 +                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, float> > >();
 180.165 +    
 180.166 +    // Howard
 180.167 +    checkConcept< MmcClassConcept<GR, int>,
 180.168 +                  Howard<GR, concepts::ReadMap<GR::Arc, int> > >();
 180.169 +    checkConcept< MmcClassConcept<GR, float>,
 180.170 +                  Howard<GR, concepts::ReadMap<GR::Arc, float> > >();
 180.171 +
 180.172 +    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,
 180.173 +          long_int>::result == 0) check(false, "Wrong LargeValue type");
 180.174 +    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,
 180.175 +          double>::result == 0) check(false, "Wrong LargeValue type");
 180.176 +  }
 180.177 +
 180.178 +  // Run various tests
 180.179 +  {
 180.180 +    typedef SmartDigraph GR;
 180.181 +    DIGRAPH_TYPEDEFS(GR);
 180.182 +    
 180.183 +    GR gr;
 180.184 +    IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
 180.185 +    IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
 180.186 +    
 180.187 +    std::istringstream input(test_lgf);
 180.188 +    digraphReader(gr, input).
 180.189 +      arcMap("len1", l1).
 180.190 +      arcMap("len2", l2).
 180.191 +      arcMap("len3", l3).
 180.192 +      arcMap("len4", l4).
 180.193 +      arcMap("c1", c1).
 180.194 +      arcMap("c2", c2).
 180.195 +      arcMap("c3", c3).
 180.196 +      arcMap("c4", c4).
 180.197 +      run();
 180.198 +
 180.199 +    // Karp
 180.200 +    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l1, c1,  6, 3);
 180.201 +    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l2, c2,  5, 2);
 180.202 +    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l3, c3,  0, 1);
 180.203 +    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l4, c4, -1, 1);
 180.204 +
 180.205 +    // HartmannOrlin
 180.206 +    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l1, c1,  6, 3);
 180.207 +    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l2, c2,  5, 2);
 180.208 +    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l3, c3,  0, 1);
 180.209 +    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l4, c4, -1, 1);
 180.210 +
 180.211 +    // Howard
 180.212 +    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1,  6, 3);
 180.213 +    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2,  5, 2);
 180.214 +    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3,  0, 1);
 180.215 +    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1);
 180.216 +  }
 180.217 +
 180.218 +  return 0;
 180.219 +}
   181.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   181.2 +++ b/test/mip_test.cc	Thu Nov 05 15:50:01 2009 +0100
   181.3 @@ -0,0 +1,159 @@
   181.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   181.5 + *
   181.6 + * This file is a part of LEMON, a generic C++ optimization library.
   181.7 + *
   181.8 + * Copyright (C) 2003-2009
   181.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  181.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  181.11 + *
  181.12 + * Permission to use, modify and distribute this software is granted
  181.13 + * provided that this copyright notice appears in all copies. For
  181.14 + * precise terms see the accompanying LICENSE file.
  181.15 + *
  181.16 + * This software is provided "AS IS" with no warranty of any kind,
  181.17 + * express or implied, and with no claim as to its suitability for any
  181.18 + * purpose.
  181.19 + *
  181.20 + */
  181.21 +
  181.22 +#include "test_tools.h"
  181.23 +
  181.24 +#include <lemon/config.h>
  181.25 +
  181.26 +#ifdef LEMON_HAVE_CPLEX
  181.27 +#include <lemon/cplex.h>
  181.28 +#endif
  181.29 +
  181.30 +#ifdef LEMON_HAVE_GLPK
  181.31 +#include <lemon/glpk.h>
  181.32 +#endif
  181.33 +
  181.34 +#ifdef LEMON_HAVE_CBC
  181.35 +#include <lemon/cbc.h>
  181.36 +#endif
  181.37 +
  181.38 +
  181.39 +using namespace lemon;
  181.40 +
  181.41 +void solveAndCheck(MipSolver& mip, MipSolver::ProblemType stat,
  181.42 +                   double exp_opt) {
  181.43 +  using std::string;
  181.44 +
  181.45 +  mip.solve();
  181.46 +  //int decimal,sign;
  181.47 +  std::ostringstream buf;
  181.48 +  buf << "Type should be: " << int(stat)<<" and it is "<<int(mip.type());
  181.49 +
  181.50 +
  181.51 +  //  itoa(stat,buf1, 10);
  181.52 +  check(mip.type()==stat, buf.str());
  181.53 +
  181.54 +  if (stat ==  MipSolver::OPTIMAL) {
  181.55 +    std::ostringstream sbuf;
  181.56 +    sbuf << "Wrong optimal value ("<< mip.solValue()
  181.57 +         <<" instead of " << exp_opt << ")";
  181.58 +    check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
  181.59 +    //+ecvt(exp_opt,2)
  181.60 +  }
  181.61 +}
  181.62 +
  181.63 +void aTest(MipSolver& mip)
  181.64 +{
  181.65 +  //The following example is very simple
  181.66 +
  181.67 +
  181.68 +  typedef MipSolver::Row Row;
  181.69 +  typedef MipSolver::Col Col;
  181.70 +
  181.71 +
  181.72 +  Col x1 = mip.addCol();
  181.73 +  Col x2 = mip.addCol();
  181.74 +
  181.75 +
  181.76 +  //Objective function
  181.77 +  mip.obj(x1);
  181.78 +
  181.79 +  mip.max();
  181.80 +
  181.81 +  //Unconstrained optimization
  181.82 +  mip.solve();
  181.83 +  //Check it out!
  181.84 +
  181.85 +  //Constraints
  181.86 +  mip.addRow(2 * x1 + x2 <= 2);
  181.87 +  Row y2 = mip.addRow(x1 - 2 * x2 <= 0);
  181.88 +
  181.89 +  //Nonnegativity of the variable x1
  181.90 +  mip.colLowerBound(x1, 0);
  181.91 +
  181.92 +
  181.93 +  //Maximization of x1
  181.94 +  //over the triangle with vertices (0,0),(4/5,2/5),(0,2)
  181.95 +  double expected_opt=4.0/5.0;
  181.96 +  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
  181.97 +
  181.98 +
  181.99 +  //Restrict x2 to integer
 181.100 +  mip.colType(x2,MipSolver::INTEGER);
 181.101 +  expected_opt=1.0/2.0;
 181.102 +  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
 181.103 +
 181.104 +
 181.105 +  //Restrict both to integer
 181.106 +  mip.colType(x1,MipSolver::INTEGER);
 181.107 +  expected_opt=0;
 181.108 +  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
 181.109 +
 181.110 +  //Erase a variable
 181.111 +  mip.erase(x2);
 181.112 +  mip.rowUpperBound(y2, 8);
 181.113 +  expected_opt=1;
 181.114 +  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
 181.115 +
 181.116 +}
 181.117 +
 181.118 +
 181.119 +template<class MIP>
 181.120 +void cloneTest()
 181.121 +{
 181.122 +
 181.123 +  MIP* mip = new MIP();
 181.124 +  MIP* mipnew = mip->newSolver();
 181.125 +  MIP* mipclone = mip->cloneSolver();
 181.126 +  delete mip;
 181.127 +  delete mipnew;
 181.128 +  delete mipclone;
 181.129 +}
 181.130 +
 181.131 +int main()
 181.132 +{
 181.133 +
 181.134 +#ifdef LEMON_HAVE_GLPK
 181.135 +  {
 181.136 +    GlpkMip mip1;
 181.137 +    aTest(mip1);
 181.138 +    cloneTest<GlpkMip>();
 181.139 +  }
 181.140 +#endif
 181.141 +
 181.142 +#ifdef LEMON_HAVE_CPLEX
 181.143 +  try {
 181.144 +    CplexMip mip2;
 181.145 +    aTest(mip2);
 181.146 +    cloneTest<CplexMip>();
 181.147 +  } catch (CplexEnv::LicenseError& error) {
 181.148 +    check(false, error.what());
 181.149 +  }
 181.150 +#endif
 181.151 +
 181.152 +#ifdef LEMON_HAVE_CBC
 181.153 +  {
 181.154 +    CbcMip mip1;
 181.155 +    aTest(mip1);
 181.156 +    cloneTest<CbcMip>();
 181.157 +  }
 181.158 +#endif
 181.159 +
 181.160 +  return 0;
 181.161 +
 181.162 +}
   182.1 --- a/test/path_test.cc	Fri Oct 16 10:21:37 2009 +0200
   182.2 +++ b/test/path_test.cc	Thu Nov 05 15:50:01 2009 +0100
   182.3 @@ -2,7 +2,7 @@
   182.4   *
   182.5   * This file is a part of LEMON, a generic C++ optimization library.
   182.6   *
   182.7 - * Copyright (C) 2003-2008
   182.8 + * Copyright (C) 2003-2009
   182.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  182.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  182.11   *
   183.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   183.2 +++ b/test/preflow_test.cc	Thu Nov 05 15:50:01 2009 +0100
   183.3 @@ -0,0 +1,250 @@
   183.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   183.5 + *
   183.6 + * This file is a part of LEMON, a generic C++ optimization library.
   183.7 + *
   183.8 + * Copyright (C) 2003-2009
   183.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  183.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  183.11 + *
  183.12 + * Permission to use, modify and distribute this software is granted
  183.13 + * provided that this copyright notice appears in all copies. For
  183.14 + * precise terms see the accompanying LICENSE file.
  183.15 + *
  183.16 + * This software is provided "AS IS" with no warranty of any kind,
  183.17 + * express or implied, and with no claim as to its suitability for any
  183.18 + * purpose.
  183.19 + *
  183.20 + */
  183.21 +
  183.22 +#include <iostream>
  183.23 +
  183.24 +#include "test_tools.h"
  183.25 +#include <lemon/smart_graph.h>
  183.26 +#include <lemon/preflow.h>
  183.27 +#include <lemon/concepts/digraph.h>
  183.28 +#include <lemon/concepts/maps.h>
  183.29 +#include <lemon/lgf_reader.h>
  183.30 +#include <lemon/elevator.h>
  183.31 +
  183.32 +using namespace lemon;
  183.33 +
  183.34 +char test_lgf[] =
  183.35 +  "@nodes\n"
  183.36 +  "label\n"
  183.37 +  "0\n"
  183.38 +  "1\n"
  183.39 +  "2\n"
  183.40 +  "3\n"
  183.41 +  "4\n"
  183.42 +  "5\n"
  183.43 +  "6\n"
  183.44 +  "7\n"
  183.45 +  "8\n"
  183.46 +  "9\n"
  183.47 +  "@arcs\n"
  183.48 +  "    label capacity\n"
  183.49 +  "0 1 0     20\n"
  183.50 +  "0 2 1     0\n"
  183.51 +  "1 1 2     3\n"
  183.52 +  "1 2 3     8\n"
  183.53 +  "1 3 4     8\n"
  183.54 +  "2 5 5     5\n"
  183.55 +  "3 2 6     5\n"
  183.56 +  "3 5 7     5\n"
  183.57 +  "3 6 8     5\n"
  183.58 +  "4 3 9     3\n"
  183.59 +  "5 7 10    3\n"
  183.60 +  "5 6 11    10\n"
  183.61 +  "5 8 12    10\n"
  183.62 +  "6 8 13    8\n"
  183.63 +  "8 9 14    20\n"
  183.64 +  "8 1 15    5\n"
  183.65 +  "9 5 16    5\n"
  183.66 +  "@attributes\n"
  183.67 +  "source 1\n"
  183.68 +  "target 8\n";
  183.69 +
  183.70 +void checkPreflowCompile()
  183.71 +{
  183.72 +  typedef int VType;
  183.73 +  typedef concepts::Digraph Digraph;
  183.74 +
  183.75 +  typedef Digraph::Node Node;
  183.76 +  typedef Digraph::Arc Arc;
  183.77 +  typedef concepts::ReadMap<Arc,VType> CapMap;
  183.78 +  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
  183.79 +  typedef concepts::WriteMap<Node,bool> CutMap;
  183.80 +
  183.81 +  typedef Elevator<Digraph, Digraph::Node> Elev;
  183.82 +  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
  183.83 +
  183.84 +  Digraph g;
  183.85 +  Node n;
  183.86 +  Arc e;
  183.87 +  CapMap cap;
  183.88 +  FlowMap flow;
  183.89 +  CutMap cut;
  183.90 +  VType v;
  183.91 +  bool b;
  183.92 +
  183.93 +  typedef Preflow<Digraph, CapMap>
  183.94 +            ::SetFlowMap<FlowMap>
  183.95 +            ::SetElevator<Elev>
  183.96 +            ::SetStandardElevator<LinkedElev>
  183.97 +            ::Create PreflowType;
  183.98 +  PreflowType preflow_test(g, cap, n, n);
  183.99 +  const PreflowType& const_preflow_test = preflow_test;
 183.100 +  
 183.101 +  const PreflowType::Elevator& elev = const_preflow_test.elevator();
 183.102 +  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
 183.103 +  PreflowType::Tolerance tol = const_preflow_test.tolerance();
 183.104 +  preflow_test.tolerance(tol);
 183.105 +
 183.106 +  preflow_test
 183.107 +    .capacityMap(cap)
 183.108 +    .flowMap(flow)
 183.109 +    .source(n)
 183.110 +    .target(n);
 183.111 +
 183.112 +  preflow_test.init();
 183.113 +  preflow_test.init(cap);
 183.114 +  preflow_test.startFirstPhase();
 183.115 +  preflow_test.startSecondPhase();
 183.116 +  preflow_test.run();
 183.117 +  preflow_test.runMinCut();
 183.118 +
 183.119 +  v = const_preflow_test.flowValue();
 183.120 +  v = const_preflow_test.flow(e);
 183.121 +  const FlowMap& fm = const_preflow_test.flowMap();
 183.122 +  b = const_preflow_test.minCut(n);
 183.123 +  const_preflow_test.minCutMap(cut);
 183.124 +  
 183.125 +  ignore_unused_variable_warning(fm);
 183.126 +}
 183.127 +
 183.128 +int cutValue (const SmartDigraph& g,
 183.129 +              const SmartDigraph::NodeMap<bool>& cut,
 183.130 +              const SmartDigraph::ArcMap<int>& cap) {
 183.131 +
 183.132 +  int c=0;
 183.133 +  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
 183.134 +    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
 183.135 +  }
 183.136 +  return c;
 183.137 +}
 183.138 +
 183.139 +bool checkFlow(const SmartDigraph& g,
 183.140 +               const SmartDigraph::ArcMap<int>& flow,
 183.141 +               const SmartDigraph::ArcMap<int>& cap,
 183.142 +               SmartDigraph::Node s, SmartDigraph::Node t) {
 183.143 +
 183.144 +  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
 183.145 +    if (flow[e] < 0 || flow[e] > cap[e]) return false;
 183.146 +  }
 183.147 +
 183.148 +  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
 183.149 +    if (n == s || n == t) continue;
 183.150 +    int sum = 0;
 183.151 +    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
 183.152 +      sum += flow[e];
 183.153 +    }
 183.154 +    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
 183.155 +      sum -= flow[e];
 183.156 +    }
 183.157 +    if (sum != 0) return false;
 183.158 +  }
 183.159 +  return true;
 183.160 +}
 183.161 +
 183.162 +int main() {
 183.163 +
 183.164 +  typedef SmartDigraph Digraph;
 183.165 +
 183.166 +  typedef Digraph::Node Node;
 183.167 +  typedef Digraph::NodeIt NodeIt;
 183.168 +  typedef Digraph::ArcIt ArcIt;
 183.169 +  typedef Digraph::ArcMap<int> CapMap;
 183.170 +  typedef Digraph::ArcMap<int> FlowMap;
 183.171 +  typedef Digraph::NodeMap<bool> CutMap;
 183.172 +
 183.173 +  typedef Preflow<Digraph, CapMap> PType;
 183.174 +
 183.175 +  Digraph g;
 183.176 +  Node s, t;
 183.177 +  CapMap cap(g);
 183.178 +  std::istringstream input(test_lgf);
 183.179 +  DigraphReader<Digraph>(g,input).
 183.180 +    arcMap("capacity", cap).
 183.181 +    node("source",s).
 183.182 +    node("target",t).
 183.183 +    run();
 183.184 +
 183.185 +  PType preflow_test(g, cap, s, t);
 183.186 +  preflow_test.run();
 183.187 +
 183.188 +  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
 183.189 +        "The flow is not feasible.");
 183.190 +
 183.191 +  CutMap min_cut(g);
 183.192 +  preflow_test.minCutMap(min_cut);
 183.193 +  int min_cut_value=cutValue(g,min_cut,cap);
 183.194 +
 183.195 +  check(preflow_test.flowValue() == min_cut_value,
 183.196 +        "The max flow value is not equal to the three min cut values.");
 183.197 +
 183.198 +  FlowMap flow(g);
 183.199 +  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
 183.200 +
 183.201 +  int flow_value=preflow_test.flowValue();
 183.202 +
 183.203 +  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
 183.204 +  preflow_test.init(flow);
 183.205 +  preflow_test.startFirstPhase();
 183.206 +
 183.207 +  CutMap min_cut1(g);
 183.208 +  preflow_test.minCutMap(min_cut1);
 183.209 +  min_cut_value=cutValue(g,min_cut1,cap);
 183.210 +
 183.211 +  check(preflow_test.flowValue() == min_cut_value &&
 183.212 +        min_cut_value == 2*flow_value,
 183.213 +        "The max flow value or the min cut value is wrong.");
 183.214 +
 183.215 +  preflow_test.startSecondPhase();
 183.216 +
 183.217 +  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
 183.218 +        "The flow is not feasible.");
 183.219 +
 183.220 +  CutMap min_cut2(g);
 183.221 +  preflow_test.minCutMap(min_cut2);
 183.222 +  min_cut_value=cutValue(g,min_cut2,cap);
 183.223 +
 183.224 +  check(preflow_test.flowValue() == min_cut_value &&
 183.225 +        min_cut_value == 2*flow_value,
 183.226 +        "The max flow value or the three min cut values were not doubled");
 183.227 +
 183.228 +
 183.229 +  preflow_test.flowMap(flow);
 183.230 +
 183.231 +  NodeIt tmp1(g,s);
 183.232 +  ++tmp1;
 183.233 +  if ( tmp1 != INVALID ) s=tmp1;
 183.234 +
 183.235 +  NodeIt tmp2(g,t);
 183.236 +  ++tmp2;
 183.237 +  if ( tmp2 != INVALID ) t=tmp2;
 183.238 +
 183.239 +  preflow_test.source(s);
 183.240 +  preflow_test.target(t);
 183.241 +
 183.242 +  preflow_test.run();
 183.243 +
 183.244 +  CutMap min_cut3(g);
 183.245 +  preflow_test.minCutMap(min_cut3);
 183.246 +  min_cut_value=cutValue(g,min_cut3,cap);
 183.247 +
 183.248 +
 183.249 +  check(preflow_test.flowValue() == min_cut_value,
 183.250 +        "The max flow value or the three min cut values are incorrect.");
 183.251 +
 183.252 +  return 0;
 183.253 +}
   184.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   184.2 +++ b/test/radix_sort_test.cc	Thu Nov 05 15:50:01 2009 +0100
   184.3 @@ -0,0 +1,147 @@
   184.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   184.5 + *
   184.6 + * This file is a part of LEMON, a generic C++ optimization library.
   184.7 + *
   184.8 + * Copyright (C) 2003-2009
   184.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  184.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  184.11 + *
  184.12 + * Permission to use, modify and distribute this software is granted
  184.13 + * provided that this copyright notice appears in all copies. For
  184.14 + * precise terms see the accompanying LICENSE file.
  184.15 + *
  184.16 + * This software is provided "AS IS" with no warranty of any kind,
  184.17 + * express or implied, and with no claim as to its suitability for any
  184.18 + * purpose.
  184.19 + *
  184.20 + */
  184.21 +
  184.22 +#include <lemon/time_measure.h>
  184.23 +#include <lemon/smart_graph.h>
  184.24 +#include <lemon/maps.h>
  184.25 +#include <lemon/radix_sort.h>
  184.26 +#include <lemon/math.h>
  184.27 +
  184.28 +#include "test_tools.h"
  184.29 +
  184.30 +#include <vector>
  184.31 +#include <algorithm>
  184.32 +
  184.33 +using namespace lemon;
  184.34 +
  184.35 +static const int n = 10000;
  184.36 +
  184.37 +struct Negate {
  184.38 +  typedef int argument_type;
  184.39 +  typedef int result_type;
  184.40 +  int operator()(int a) { return - a; }
  184.41 +};
  184.42 +
  184.43 +int negate(int a) { return - a; }
  184.44 +
  184.45 +
  184.46 +void generateIntSequence(int n, std::vector<int>& data) {
  184.47 +  int prime = 9973;
  184.48 +  int root = 136, value = 1;
  184.49 +  for (int i = 0; i < n; ++i) {
  184.50 +    data.push_back(value - prime / 2);
  184.51 +    value = (value * root) % prime;
  184.52 +  }
  184.53 +}
  184.54 +
  184.55 +void generateCharSequence(int n, std::vector<unsigned char>& data) {
  184.56 +  int prime = 251;
  184.57 +  int root = 3, value = root;
  184.58 +  for (int i = 0; i < n; ++i) {
  184.59 +    data.push_back(static_cast<unsigned char>(value));
  184.60 +    value = (value * root) % prime;
  184.61 +  }
  184.62 +}
  184.63 +
  184.64 +void checkRadixSort() {
  184.65 +  {
  184.66 +    std::vector<int> data1;
  184.67 +    generateIntSequence(n, data1);
  184.68 +
  184.69 +    std::vector<int> data2(data1);
  184.70 +    std::sort(data1.begin(), data1.end());
  184.71 +
  184.72 +    radixSort(data2.begin(), data2.end());
  184.73 +    for (int i = 0; i < n; ++i) {
  184.74 +      check(data1[i] == data2[i], "Test failed");
  184.75 +    }
  184.76 +
  184.77 +    radixSort(data2.begin(), data2.end(), Negate());
  184.78 +    for (int i = 0; i < n; ++i) {
  184.79 +      check(data1[i] == data2[n - 1 - i], "Test failed");
  184.80 +    }
  184.81 +
  184.82 +    radixSort(data2.begin(), data2.end(), negate);
  184.83 +    for (int i = 0; i < n; ++i) {
  184.84 +      check(data1[i] == data2[n - 1 - i], "Test failed");
  184.85 +    }
  184.86 +
  184.87 +  }
  184.88 +
  184.89 +  {
  184.90 +    std::vector<unsigned char> data1(n);
  184.91 +    generateCharSequence(n, data1);
  184.92 +
  184.93 +    std::vector<unsigned char> data2(data1);
  184.94 +    std::sort(data1.begin(), data1.end());
  184.95 +
  184.96 +    radixSort(data2.begin(), data2.end());
  184.97 +    for (int i = 0; i < n; ++i) {
  184.98 +      check(data1[i] == data2[i], "Test failed");
  184.99 +    }
 184.100 +
 184.101 +  }
 184.102 +}
 184.103 +
 184.104 +
 184.105 +void checkStableRadixSort() {
 184.106 +  {
 184.107 +    std::vector<int> data1;
 184.108 +    generateIntSequence(n, data1);
 184.109 +
 184.110 +    std::vector<int> data2(data1);
 184.111 +    std::sort(data1.begin(), data1.end());
 184.112 +
 184.113 +    stableRadixSort(data2.begin(), data2.end());
 184.114 +    for (int i = 0; i < n; ++i) {
 184.115 +      check(data1[i] == data2[i], "Test failed");
 184.116 +    }
 184.117 +
 184.118 +    stableRadixSort(data2.begin(), data2.end(), Negate());
 184.119 +    for (int i = 0; i < n; ++i) {
 184.120 +      check(data1[i] == data2[n - 1 - i], "Test failed");
 184.121 +    }
 184.122 +
 184.123 +    stableRadixSort(data2.begin(), data2.end(), negate);
 184.124 +    for (int i = 0; i < n; ++i) {
 184.125 +      check(data1[i] == data2[n - 1 - i], "Test failed");
 184.126 +    }
 184.127 +  }
 184.128 +
 184.129 +  {
 184.130 +    std::vector<unsigned char> data1(n);
 184.131 +    generateCharSequence(n, data1);
 184.132 +
 184.133 +    std::vector<unsigned char> data2(data1);
 184.134 +    std::sort(data1.begin(), data1.end());
 184.135 +
 184.136 +    radixSort(data2.begin(), data2.end());
 184.137 +    for (int i = 0; i < n; ++i) {
 184.138 +      check(data1[i] == data2[i], "Test failed");
 184.139 +    }
 184.140 +
 184.141 +  }
 184.142 +}
 184.143 +
 184.144 +int main() {
 184.145 +
 184.146 +  checkRadixSort();
 184.147 +  checkStableRadixSort();
 184.148 +
 184.149 +  return 0;
 184.150 +}
   185.1 --- a/test/random_test.cc	Fri Oct 16 10:21:37 2009 +0200
   185.2 +++ b/test/random_test.cc	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   185.8 + * Copyright (C) 2003-2009
   185.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  185.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  185.11   *
   186.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   186.2 +++ b/test/suurballe_test.cc	Thu Nov 05 15:50:01 2009 +0100
   186.3 @@ -0,0 +1,241 @@
   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-2009
   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/list_graph.h>
  186.25 +#include <lemon/lgf_reader.h>
  186.26 +#include <lemon/path.h>
  186.27 +#include <lemon/suurballe.h>
  186.28 +#include <lemon/concepts/digraph.h>
  186.29 +
  186.30 +#include "test_tools.h"
  186.31 +
  186.32 +using namespace lemon;
  186.33 +
  186.34 +char test_lgf[] =
  186.35 +  "@nodes\n"
  186.36 +  "label\n"
  186.37 +  "1\n"
  186.38 +  "2\n"
  186.39 +  "3\n"
  186.40 +  "4\n"
  186.41 +  "5\n"
  186.42 +  "6\n"
  186.43 +  "7\n"
  186.44 +  "8\n"
  186.45 +  "9\n"
  186.46 +  "10\n"
  186.47 +  "11\n"
  186.48 +  "12\n"
  186.49 +  "@arcs\n"
  186.50 +  "      length\n"
  186.51 +  " 1  2  70\n"
  186.52 +  " 1  3 150\n"
  186.53 +  " 1  4  80\n"
  186.54 +  " 2  8  80\n"
  186.55 +  " 3  5 140\n"
  186.56 +  " 4  6  60\n"
  186.57 +  " 4  7  80\n"
  186.58 +  " 4  8 110\n"
  186.59 +  " 5  7  60\n"
  186.60 +  " 5 11 120\n"
  186.61 +  " 6  3   0\n"
  186.62 +  " 6  9 140\n"
  186.63 +  " 6 10  90\n"
  186.64 +  " 7  1  30\n"
  186.65 +  " 8 12  60\n"
  186.66 +  " 9 12  50\n"
  186.67 +  "10 12  70\n"
  186.68 +  "10  2 100\n"
  186.69 +  "10  7  60\n"
  186.70 +  "11 10  20\n"
  186.71 +  "12 11  30\n"
  186.72 +  "@attributes\n"
  186.73 +  "source  1\n"
  186.74 +  "target 12\n"
  186.75 +  "@end\n";
  186.76 +
  186.77 +// Check the interface of Suurballe
  186.78 +void checkSuurballeCompile()
  186.79 +{
  186.80 +  typedef int VType;
  186.81 +  typedef concepts::Digraph Digraph;
  186.82 +
  186.83 +  typedef Digraph::Node Node;
  186.84 +  typedef Digraph::Arc Arc;
  186.85 +  typedef concepts::ReadMap<Arc, VType> LengthMap;
  186.86 +  
  186.87 +  typedef Suurballe<Digraph, LengthMap> SuurballeType;
  186.88 +
  186.89 +  Digraph g;
  186.90 +  Node n;
  186.91 +  Arc e;
  186.92 +  LengthMap len;
  186.93 +  SuurballeType::FlowMap flow(g);
  186.94 +  SuurballeType::PotentialMap pi(g);
  186.95 +
  186.96 +  SuurballeType suurb_test(g, len);
  186.97 +  const SuurballeType& const_suurb_test = suurb_test;
  186.98 +
  186.99 +  suurb_test
 186.100 +    .flowMap(flow)
 186.101 +    .potentialMap(pi);
 186.102 +
 186.103 +  int k;
 186.104 +  k = suurb_test.run(n, n);
 186.105 +  k = suurb_test.run(n, n, k);
 186.106 +  suurb_test.init(n);
 186.107 +  k = suurb_test.findFlow(n);
 186.108 +  k = suurb_test.findFlow(n, k);
 186.109 +  suurb_test.findPaths();
 186.110 +  
 186.111 +  int f;
 186.112 +  VType c;
 186.113 +  c = const_suurb_test.totalLength();
 186.114 +  f = const_suurb_test.flow(e);
 186.115 +  const SuurballeType::FlowMap& fm =
 186.116 +    const_suurb_test.flowMap();
 186.117 +  c = const_suurb_test.potential(n);
 186.118 +  const SuurballeType::PotentialMap& pm =
 186.119 +    const_suurb_test.potentialMap();
 186.120 +  k = const_suurb_test.pathNum();
 186.121 +  Path<Digraph> p = const_suurb_test.path(k);
 186.122 +  
 186.123 +  ignore_unused_variable_warning(fm);
 186.124 +  ignore_unused_variable_warning(pm);
 186.125 +}
 186.126 +
 186.127 +// Check the feasibility of the flow
 186.128 +template <typename Digraph, typename FlowMap>
 186.129 +bool checkFlow( const Digraph& gr, const FlowMap& flow,
 186.130 +                typename Digraph::Node s, typename Digraph::Node t,
 186.131 +                int value )
 186.132 +{
 186.133 +  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 186.134 +  for (ArcIt e(gr); e != INVALID; ++e)
 186.135 +    if (!(flow[e] == 0 || flow[e] == 1)) return false;
 186.136 +
 186.137 +  for (NodeIt n(gr); n != INVALID; ++n) {
 186.138 +    int sum = 0;
 186.139 +    for (OutArcIt e(gr, n); e != INVALID; ++e)
 186.140 +      sum += flow[e];
 186.141 +    for (InArcIt e(gr, n); e != INVALID; ++e)
 186.142 +      sum -= flow[e];
 186.143 +    if (n == s && sum != value) return false;
 186.144 +    if (n == t && sum != -value) return false;
 186.145 +    if (n != s && n != t && sum != 0) return false;
 186.146 +  }
 186.147 +
 186.148 +  return true;
 186.149 +}
 186.150 +
 186.151 +// Check the optimalitiy of the flow
 186.152 +template < typename Digraph, typename CostMap,
 186.153 +           typename FlowMap, typename PotentialMap >
 186.154 +bool checkOptimality( const Digraph& gr, const CostMap& cost,
 186.155 +                      const FlowMap& flow, const PotentialMap& pi )
 186.156 +{
 186.157 +  // Check the "Complementary Slackness" optimality condition
 186.158 +  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 186.159 +  bool opt = true;
 186.160 +  for (ArcIt e(gr); e != INVALID; ++e) {
 186.161 +    typename CostMap::Value red_cost =
 186.162 +      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
 186.163 +    opt = (flow[e] == 0 && red_cost >= 0) ||
 186.164 +          (flow[e] == 1 && red_cost <= 0);
 186.165 +    if (!opt) break;
 186.166 +  }
 186.167 +  return opt;
 186.168 +}
 186.169 +
 186.170 +// Check a path
 186.171 +template <typename Digraph, typename Path>
 186.172 +bool checkPath( const Digraph& gr, const Path& path,
 186.173 +                typename Digraph::Node s, typename Digraph::Node t)
 186.174 +{
 186.175 +  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 186.176 +  Node n = s;
 186.177 +  for (int i = 0; i < path.length(); ++i) {
 186.178 +    if (gr.source(path.nth(i)) != n) return false;
 186.179 +    n = gr.target(path.nth(i));
 186.180 +  }
 186.181 +  return n == t;
 186.182 +}
 186.183 +
 186.184 +
 186.185 +int main()
 186.186 +{
 186.187 +  DIGRAPH_TYPEDEFS(ListDigraph);
 186.188 +
 186.189 +  // Read the test digraph
 186.190 +  ListDigraph digraph;
 186.191 +  ListDigraph::ArcMap<int> length(digraph);
 186.192 +  Node s, t;
 186.193 +
 186.194 +  std::istringstream input(test_lgf);
 186.195 +  DigraphReader<ListDigraph>(digraph, input).
 186.196 +    arcMap("length", length).
 186.197 +    node("source", s).
 186.198 +    node("target", t).
 186.199 +    run();
 186.200 +
 186.201 +  // Find 2 paths
 186.202 +  {
 186.203 +    Suurballe<ListDigraph> suurballe(digraph, length);
 186.204 +    check(suurballe.run(s, t) == 2, "Wrong number of paths");
 186.205 +    check(checkFlow(digraph, suurballe.flowMap(), s, t, 2),
 186.206 +          "The flow is not feasible");
 186.207 +    check(suurballe.totalLength() == 510, "The flow is not optimal");
 186.208 +    check(checkOptimality(digraph, length, suurballe.flowMap(),
 186.209 +                          suurballe.potentialMap()),
 186.210 +          "Wrong potentials");
 186.211 +    for (int i = 0; i < suurballe.pathNum(); ++i)
 186.212 +      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
 186.213 +  }
 186.214 +
 186.215 +  // Find 3 paths
 186.216 +  {
 186.217 +    Suurballe<ListDigraph> suurballe(digraph, length);
 186.218 +    check(suurballe.run(s, t, 3) == 3, "Wrong number of paths");
 186.219 +    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
 186.220 +          "The flow is not feasible");
 186.221 +    check(suurballe.totalLength() == 1040, "The flow is not optimal");
 186.222 +    check(checkOptimality(digraph, length, suurballe.flowMap(),
 186.223 +                          suurballe.potentialMap()),
 186.224 +          "Wrong potentials");
 186.225 +    for (int i = 0; i < suurballe.pathNum(); ++i)
 186.226 +      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
 186.227 +  }
 186.228 +
 186.229 +  // Find 5 paths (only 3 can be found)
 186.230 +  {
 186.231 +    Suurballe<ListDigraph> suurballe(digraph, length);
 186.232 +    check(suurballe.run(s, t, 5) == 3, "Wrong number of paths");
 186.233 +    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
 186.234 +          "The flow is not feasible");
 186.235 +    check(suurballe.totalLength() == 1040, "The flow is not optimal");
 186.236 +    check(checkOptimality(digraph, length, suurballe.flowMap(),
 186.237 +                          suurballe.potentialMap()),
 186.238 +          "Wrong potentials");
 186.239 +    for (int i = 0; i < suurballe.pathNum(); ++i)
 186.240 +      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
 186.241 +  }
 186.242 +
 186.243 +  return 0;
 186.244 +}
   187.1 --- a/test/test_tools.h	Fri Oct 16 10:21:37 2009 +0200
   187.2 +++ b/test/test_tools.h	Thu Nov 05 15:50:01 2009 +0100
   187.3 @@ -2,7 +2,7 @@
   187.4   *
   187.5   * This file is a part of LEMON, a generic C++ optimization library.
   187.6   *
   187.7 - * Copyright (C) 2003-2008
   187.8 + * Copyright (C) 2003-2009
   187.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  187.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  187.11   *
  187.12 @@ -37,10 +37,14 @@
  187.13  ///\code check(0==1,"This is obviously false.");\endcode will
  187.14  ///print something like this (and then exits).
  187.15  ///\verbatim file_name.cc:123: error: This is obviously false. \endverbatim
  187.16 -#define check(rc, msg) \
  187.17 -  if(!(rc)) { \
  187.18 -    std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
  187.19 -    abort(); \
  187.20 -  } else { } \
  187.21 +#define check(rc, msg)                                                  \
  187.22 +  {                                                                     \
  187.23 +    if(!(rc)) {                                                         \
  187.24 +      std::cerr << __FILE__ ":" << __LINE__ << ": error: "              \
  187.25 +                << msg << std::endl;                                    \
  187.26 +      abort();                                                          \
  187.27 +    } else { }                                                          \
  187.28 +  }                                                                     \
  187.29 +    
  187.30  
  187.31  #endif
   188.1 --- a/test/test_tools_fail.cc	Fri Oct 16 10:21:37 2009 +0200
   188.2 +++ b/test/test_tools_fail.cc	Thu Nov 05 15:50:01 2009 +0100
   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-2008
   188.8 + * Copyright (C) 2003-2009
   188.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  188.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  188.11   *
   189.1 --- a/test/test_tools_pass.cc	Fri Oct 16 10:21:37 2009 +0200
   189.2 +++ b/test/test_tools_pass.cc	Thu Nov 05 15:50:01 2009 +0100
   189.3 @@ -2,7 +2,7 @@
   189.4   *
   189.5   * This file is a part of LEMON, a generic C++ optimization library.
   189.6   *
   189.7 - * Copyright (C) 2003-2008
   189.8 + * Copyright (C) 2003-2009
   189.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  189.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  189.11   *
   190.1 --- a/test/time_measure_test.cc	Fri Oct 16 10:21:37 2009 +0200
   190.2 +++ b/test/time_measure_test.cc	Thu Nov 05 15:50:01 2009 +0100
   190.3 @@ -2,7 +2,7 @@
   190.4   *
   190.5   * This file is a part of LEMON, a generic C++ optimization library.
   190.6   *
   190.7 - * Copyright (C) 2003-2008
   190.8 + * Copyright (C) 2003-2009
   190.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  190.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  190.11   *
  190.12 @@ -39,18 +39,16 @@
  190.13  {
  190.14    Timer T;
  190.15    unsigned int n;
  190.16 -  for(n=0;T.realTime()<1.0;n++) ;
  190.17 +  for(n=0;T.realTime()<0.1;n++) ;
  190.18    std::cout << T << " (" << n << " time queries)\n";
  190.19 -  T.restart();
  190.20 -  while(T.realTime()<2.0) ;
  190.21 -  std::cout << T << '\n';
  190.22 +
  190.23    TimeStamp full;
  190.24    TimeStamp t;
  190.25 -  t=runningTimeTest(f,1,&n,&full);
  190.26 +  t=runningTimeTest(f,0.1,&n,&full);
  190.27    std::cout << t << " (" << n << " tests)\n";
  190.28    std::cout << "Total: " << full << "\n";
  190.29  
  190.30 -  t=runningTimeTest(g,1,&n,&full);
  190.31 +  t=runningTimeTest(g,0.1,&n,&full);
  190.32    std::cout << t << " (" << n << " tests)\n";
  190.33    std::cout << "Total: " << full << "\n";
  190.34  
   191.1 --- a/test/unionfind_test.cc	Fri Oct 16 10:21:37 2009 +0200
   191.2 +++ b/test/unionfind_test.cc	Thu Nov 05 15:50:01 2009 +0100
   191.3 @@ -2,7 +2,7 @@
   191.4   *
   191.5   * This file is a part of LEMON, a generic C++ optimization library.
   191.6   *
   191.7 - * Copyright (C) 2003-2008
   191.8 + * Copyright (C) 2003-2009
   191.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  191.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  191.11   *
   192.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   192.2 +++ b/tools/CMakeLists.txt	Thu Nov 05 15:50:01 2009 +0100
   192.3 @@ -0,0 +1,31 @@
   192.4 +INCLUDE_DIRECTORIES(
   192.5 +  ${PROJECT_SOURCE_DIR}
   192.6 +  ${PROJECT_BINARY_DIR}
   192.7 +)
   192.8 +
   192.9 +LINK_DIRECTORIES(
  192.10 +  ${PROJECT_BINARY_DIR}/lemon
  192.11 +)
  192.12 +
  192.13 +ADD_EXECUTABLE(lgf-gen lgf-gen.cc)
  192.14 +TARGET_LINK_LIBRARIES(lgf-gen lemon)
  192.15 +
  192.16 +ADD_EXECUTABLE(dimacs-to-lgf dimacs-to-lgf.cc)
  192.17 +TARGET_LINK_LIBRARIES(dimacs-to-lgf lemon)
  192.18 +
  192.19 +ADD_EXECUTABLE(dimacs-solver dimacs-solver.cc)
  192.20 +TARGET_LINK_LIBRARIES(dimacs-solver lemon)
  192.21 +
  192.22 +INSTALL(
  192.23 +  TARGETS lgf-gen dimacs-to-lgf dimacs-solver
  192.24 +  RUNTIME DESTINATION bin
  192.25 +  COMPONENT bin
  192.26 +)
  192.27 +
  192.28 +IF(NOT WIN32)
  192.29 +  INSTALL(
  192.30 +    PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/lemon-0.x-to-1.x.sh
  192.31 +    DESTINATION bin
  192.32 +    COMPONENT bin
  192.33 +  )
  192.34 +ENDIF()
   193.1 --- a/tools/Makefile.am	Fri Oct 16 10:21:37 2009 +0200
   193.2 +++ b/tools/Makefile.am	Thu Nov 05 15:50:01 2009 +0100
   193.3 @@ -1,6 +1,17 @@
   193.4 +EXTRA_DIST += \
   193.5 +	tools/CMakeLists.txt
   193.6 +
   193.7  if WANT_TOOLS
   193.8  
   193.9 -bin_PROGRAMS +=
  193.10 +bin_PROGRAMS += \
  193.11 +	tools/dimacs-solver \
  193.12 +	tools/dimacs-to-lgf \
  193.13 +	tools/lgf-gen
  193.14 +
  193.15  dist_bin_SCRIPTS += tools/lemon-0.x-to-1.x.sh
  193.16  
  193.17  endif WANT_TOOLS
  193.18 +
  193.19 +tools_dimacs_solver_SOURCES = tools/dimacs-solver.cc
  193.20 +tools_dimacs_to_lgf_SOURCES = tools/dimacs-to-lgf.cc
  193.21 +tools_lgf_gen_SOURCES = tools/lgf-gen.cc
   194.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   194.2 +++ b/tools/dimacs-solver.cc	Thu Nov 05 15:50:01 2009 +0100
   194.3 @@ -0,0 +1,277 @@
   194.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   194.5 + *
   194.6 + * This file is a part of LEMON, a generic C++ optimization library.
   194.7 + *
   194.8 + * Copyright (C) 2003-2009
   194.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  194.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  194.11 + *
  194.12 + * Permission to use, modify and distribute this software is granted
  194.13 + * provided that this copyright notice appears in all copies. For
  194.14 + * precise terms see the accompanying LICENSE file.
  194.15 + *
  194.16 + * This software is provided "AS IS" with no warranty of any kind,
  194.17 + * express or implied, and with no claim as to its suitability for any
  194.18 + * purpose.
  194.19 + *
  194.20 + */
  194.21 +
  194.22 +///\ingroup tools
  194.23 +///\file
  194.24 +///\brief DIMACS problem solver.
  194.25 +///
  194.26 +/// This program solves various problems given in DIMACS format.
  194.27 +///
  194.28 +/// See
  194.29 +/// \code
  194.30 +///   dimacs-solver --help
  194.31 +/// \endcode
  194.32 +/// for more info on usage.
  194.33 +
  194.34 +#include <iostream>
  194.35 +#include <fstream>
  194.36 +#include <cstring>
  194.37 +
  194.38 +#include <lemon/smart_graph.h>
  194.39 +#include <lemon/dimacs.h>
  194.40 +#include <lemon/lgf_writer.h>
  194.41 +#include <lemon/time_measure.h>
  194.42 +
  194.43 +#include <lemon/arg_parser.h>
  194.44 +#include <lemon/error.h>
  194.45 +
  194.46 +#include <lemon/dijkstra.h>
  194.47 +#include <lemon/preflow.h>
  194.48 +#include <lemon/matching.h>
  194.49 +#include <lemon/network_simplex.h>
  194.50 +
  194.51 +using namespace lemon;
  194.52 +typedef SmartDigraph Digraph;
  194.53 +DIGRAPH_TYPEDEFS(Digraph);
  194.54 +typedef SmartGraph Graph;
  194.55 +
  194.56 +template<class Value>
  194.57 +void solve_sp(ArgParser &ap, std::istream &is, std::ostream &,
  194.58 +              DimacsDescriptor &desc)
  194.59 +{
  194.60 +  bool report = !ap.given("q");
  194.61 +  Digraph g;
  194.62 +  Node s;
  194.63 +  Digraph::ArcMap<Value> len(g);
  194.64 +  Timer t;
  194.65 +  t.restart();
  194.66 +  readDimacsSp(is, g, len, s, desc);
  194.67 +  if(report) std::cerr << "Read the file: " << t << '\n';
  194.68 +  t.restart();
  194.69 +  Dijkstra<Digraph, Digraph::ArcMap<Value> > dij(g,len);
  194.70 +  if(report) std::cerr << "Setup Dijkstra class: " << t << '\n';
  194.71 +  t.restart();
  194.72 +  dij.run(s);
  194.73 +  if(report) std::cerr << "Run Dijkstra: " << t << '\n';
  194.74 +}
  194.75 +
  194.76 +template<class Value>
  194.77 +void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
  194.78 +               Value infty, DimacsDescriptor &desc)
  194.79 +{
  194.80 +  bool report = !ap.given("q");
  194.81 +  Digraph g;
  194.82 +  Node s,t;
  194.83 +  Digraph::ArcMap<Value> cap(g);
  194.84 +  Timer ti;
  194.85 +  ti.restart();
  194.86 +  readDimacsMax(is, g, cap, s, t, infty, desc);
  194.87 +  if(report) std::cerr << "Read the file: " << ti << '\n';
  194.88 +  ti.restart();
  194.89 +  Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
  194.90 +  if(report) std::cerr << "Setup Preflow class: " << ti << '\n';
  194.91 +  ti.restart();
  194.92 +  pre.run();
  194.93 +  if(report) std::cerr << "Run Preflow: " << ti << '\n';
  194.94 +  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';  
  194.95 +}
  194.96 +
  194.97 +template<class Value>
  194.98 +void solve_min(ArgParser &ap, std::istream &is, std::ostream &,
  194.99 +               Value infty, DimacsDescriptor &desc)
 194.100 +{
 194.101 +  bool report = !ap.given("q");
 194.102 +  Digraph g;
 194.103 +  Digraph::ArcMap<Value> lower(g), cap(g), cost(g);
 194.104 +  Digraph::NodeMap<Value> sup(g);
 194.105 +  Timer ti;
 194.106 +
 194.107 +  ti.restart();
 194.108 +  readDimacsMin(is, g, lower, cap, cost, sup, infty, desc);
 194.109 +  ti.stop();
 194.110 +  Value sum_sup = 0;
 194.111 +  for (Digraph::NodeIt n(g); n != INVALID; ++n) {
 194.112 +    sum_sup += sup[n];
 194.113 +  }
 194.114 +  if (report) {
 194.115 +    std::cerr << "Sum of supply values: " << sum_sup << "\n";
 194.116 +    if (sum_sup <= 0)
 194.117 +      std::cerr << "GEQ supply contraints are used for NetworkSimplex\n\n";
 194.118 +    else
 194.119 +      std::cerr << "LEQ supply contraints are used for NetworkSimplex\n\n";
 194.120 +  }
 194.121 +  if (report) std::cerr << "Read the file: " << ti << '\n';
 194.122 +
 194.123 +  ti.restart();
 194.124 +  NetworkSimplex<Digraph, Value> ns(g);
 194.125 +  ns.lowerMap(lower).upperMap(cap).costMap(cost).supplyMap(sup);
 194.126 +  if (sum_sup > 0) ns.supplyType(ns.LEQ);
 194.127 +  if (report) std::cerr << "Setup NetworkSimplex class: " << ti << '\n';
 194.128 +  ti.restart();
 194.129 +  bool res = ns.run();
 194.130 +  if (report) {
 194.131 +    std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
 194.132 +    std::cerr << "Feasible flow: " << (res ? "found" : "not found") << '\n';
 194.133 +    if (res) std::cerr << "Min flow cost: " << ns.totalCost() << '\n';
 194.134 +  }
 194.135 +}
 194.136 +
 194.137 +void solve_mat(ArgParser &ap, std::istream &is, std::ostream &,
 194.138 +              DimacsDescriptor &desc)
 194.139 +{
 194.140 +  bool report = !ap.given("q");
 194.141 +  Graph g;
 194.142 +  Timer ti;
 194.143 +  ti.restart();
 194.144 +  readDimacsMat(is, g, desc);
 194.145 +  if(report) std::cerr << "Read the file: " << ti << '\n';
 194.146 +  ti.restart();
 194.147 +  MaxMatching<Graph> mat(g);
 194.148 +  if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n';
 194.149 +  ti.restart();
 194.150 +  mat.run();
 194.151 +  if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
 194.152 +  if(report) std::cerr << "\nCardinality of max matching: "
 194.153 +                       << mat.matchingSize() << '\n';  
 194.154 +}
 194.155 +
 194.156 +
 194.157 +template<class Value>
 194.158 +void solve(ArgParser &ap, std::istream &is, std::ostream &os,
 194.159 +           DimacsDescriptor &desc)
 194.160 +{
 194.161 +  std::stringstream iss(static_cast<std::string>(ap["infcap"]));
 194.162 +  Value infty;
 194.163 +  iss >> infty;
 194.164 +  if(iss.fail())
 194.165 +    {
 194.166 +      std::cerr << "Cannot interpret '"
 194.167 +                << static_cast<std::string>(ap["infcap"]) << "' as infinite"
 194.168 +                << std::endl;
 194.169 +      exit(1);
 194.170 +    }
 194.171 +  
 194.172 +  switch(desc.type)
 194.173 +    {
 194.174 +    case DimacsDescriptor::MIN:
 194.175 +      solve_min<Value>(ap,is,os,infty,desc);
 194.176 +      break;
 194.177 +    case DimacsDescriptor::MAX:
 194.178 +      solve_max<Value>(ap,is,os,infty,desc);
 194.179 +      break;
 194.180 +    case DimacsDescriptor::SP:
 194.181 +      solve_sp<Value>(ap,is,os,desc);
 194.182 +      break;
 194.183 +    case DimacsDescriptor::MAT:
 194.184 +      solve_mat(ap,is,os,desc);
 194.185 +      break;
 194.186 +    default:
 194.187 +      break;
 194.188 +    }
 194.189 +}
 194.190 +
 194.191 +int main(int argc, const char *argv[]) {
 194.192 +  typedef SmartDigraph Digraph;
 194.193 +
 194.194 +  typedef Digraph::Arc Arc;
 194.195 +
 194.196 +  std::string inputName;
 194.197 +  std::string outputName;
 194.198 +
 194.199 +  ArgParser ap(argc, argv);
 194.200 +  ap.other("[INFILE [OUTFILE]]",
 194.201 +           "If either the INFILE or OUTFILE file is missing the standard\n"
 194.202 +           "     input/output will be used instead.")
 194.203 +    .boolOption("q", "Do not print any report")
 194.204 +    .boolOption("int","Use 'int' for capacities, costs etc. (default)")
 194.205 +    .optionGroup("datatype","int")
 194.206 +#ifdef LEMON_HAVE_LONG_LONG
 194.207 +    .boolOption("long","Use 'long long' for capacities, costs etc.")
 194.208 +    .optionGroup("datatype","long")
 194.209 +#endif
 194.210 +    .boolOption("double","Use 'double' for capacities, costs etc.")
 194.211 +    .optionGroup("datatype","double")
 194.212 +    .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
 194.213 +    .optionGroup("datatype","ldouble")
 194.214 +    .onlyOneGroup("datatype")
 194.215 +    .stringOption("infcap","Value used for 'very high' capacities","0")
 194.216 +    .run();
 194.217 +
 194.218 +  std::ifstream input;
 194.219 +  std::ofstream output;
 194.220 +
 194.221 +  switch(ap.files().size())
 194.222 +    {
 194.223 +    case 2:
 194.224 +      output.open(ap.files()[1].c_str());
 194.225 +      if (!output) {
 194.226 +        throw IoError("Cannot open the file for writing", ap.files()[1]);
 194.227 +      }
 194.228 +    case 1:
 194.229 +      input.open(ap.files()[0].c_str());
 194.230 +      if (!input) {
 194.231 +        throw IoError("File cannot be found", ap.files()[0]);
 194.232 +      }
 194.233 +    case 0:
 194.234 +      break;
 194.235 +    default:
 194.236 +      std::cerr << ap.commandName() << ": too many arguments\n";
 194.237 +      return 1;
 194.238 +    }
 194.239 +  std::istream& is = (ap.files().size()<1 ? std::cin : input);
 194.240 +  std::ostream& os = (ap.files().size()<2 ? std::cout : output);
 194.241 +
 194.242 +  DimacsDescriptor desc = dimacsType(is);
 194.243 +  
 194.244 +  if(!ap.given("q"))
 194.245 +    {
 194.246 +      std::cout << "Problem type: ";
 194.247 +      switch(desc.type)
 194.248 +        {
 194.249 +        case DimacsDescriptor::MIN:
 194.250 +          std::cout << "min";
 194.251 +          break;
 194.252 +        case DimacsDescriptor::MAX:
 194.253 +          std::cout << "max";
 194.254 +          break;
 194.255 +        case DimacsDescriptor::SP:
 194.256 +          std::cout << "sp";
 194.257 +        case DimacsDescriptor::MAT:
 194.258 +          std::cout << "mat";
 194.259 +          break;
 194.260 +        default:
 194.261 +          exit(1);
 194.262 +          break;
 194.263 +        }
 194.264 +      std::cout << "\nNum of nodes: " << desc.nodeNum;
 194.265 +      std::cout << "\nNum of arcs:  " << desc.edgeNum;
 194.266 +      std::cout << "\n\n";
 194.267 +    }
 194.268 +    
 194.269 +  if(ap.given("double"))
 194.270 +    solve<double>(ap,is,os,desc);
 194.271 +  else if(ap.given("ldouble"))
 194.272 +    solve<long double>(ap,is,os,desc);
 194.273 +#ifdef LEMON_HAVE_LONG_LONG
 194.274 +  else if(ap.given("long"))
 194.275 +    solve<long long>(ap,is,os,desc);
 194.276 +#endif
 194.277 +  else solve<int>(ap,is,os,desc);
 194.278 +
 194.279 +  return 0;
 194.280 +}
   195.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   195.2 +++ b/tools/dimacs-to-lgf.cc	Thu Nov 05 15:50:01 2009 +0100
   195.3 @@ -0,0 +1,148 @@
   195.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   195.5 + *
   195.6 + * This file is a part of LEMON, a generic C++ optimization library.
   195.7 + *
   195.8 + * Copyright (C) 2003-2009
   195.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  195.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  195.11 + *
  195.12 + * Permission to use, modify and distribute this software is granted
  195.13 + * provided that this copyright notice appears in all copies. For
  195.14 + * precise terms see the accompanying LICENSE file.
  195.15 + *
  195.16 + * This software is provided "AS IS" with no warranty of any kind,
  195.17 + * express or implied, and with no claim as to its suitability for any
  195.18 + * purpose.
  195.19 + *
  195.20 + */
  195.21 +
  195.22 +///\ingroup tools
  195.23 +///\file
  195.24 +///\brief DIMACS to LGF converter.
  195.25 +///
  195.26 +/// This program converts various DIMACS formats to the LEMON Digraph Format
  195.27 +/// (LGF).
  195.28 +///
  195.29 +/// See
  195.30 +/// \code
  195.31 +///   dimacs-to-lgf --help
  195.32 +/// \endcode
  195.33 +/// for more info on the usage.
  195.34 +
  195.35 +#include <iostream>
  195.36 +#include <fstream>
  195.37 +#include <cstring>
  195.38 +
  195.39 +#include <lemon/smart_graph.h>
  195.40 +#include <lemon/dimacs.h>
  195.41 +#include <lemon/lgf_writer.h>
  195.42 +
  195.43 +#include <lemon/arg_parser.h>
  195.44 +#include <lemon/error.h>
  195.45 +
  195.46 +using namespace std;
  195.47 +using namespace lemon;
  195.48 +
  195.49 +
  195.50 +int main(int argc, const char *argv[]) {
  195.51 +  typedef SmartDigraph Digraph;
  195.52 +
  195.53 +  typedef Digraph::Arc Arc;
  195.54 +  typedef Digraph::Node Node;
  195.55 +  typedef Digraph::ArcIt ArcIt;
  195.56 +  typedef Digraph::NodeIt NodeIt;
  195.57 +  typedef Digraph::ArcMap<double> DoubleArcMap;
  195.58 +  typedef Digraph::NodeMap<double> DoubleNodeMap;
  195.59 +
  195.60 +  std::string inputName;
  195.61 +  std::string outputName;
  195.62 +
  195.63 +  ArgParser ap(argc, argv);
  195.64 +  ap.other("[INFILE [OUTFILE]]",
  195.65 +           "If either the INFILE or OUTFILE file is missing the standard\n"
  195.66 +           "     input/output will be used instead.")
  195.67 +    .run();
  195.68 +
  195.69 +  ifstream input;
  195.70 +  ofstream output;
  195.71 +
  195.72 +  switch(ap.files().size())
  195.73 +    {
  195.74 +    case 2:
  195.75 +      output.open(ap.files()[1].c_str());
  195.76 +      if (!output) {
  195.77 +        throw IoError("Cannot open the file for writing", ap.files()[1]);
  195.78 +      }
  195.79 +    case 1:
  195.80 +      input.open(ap.files()[0].c_str());
  195.81 +      if (!input) {
  195.82 +        throw IoError("File cannot be found", ap.files()[0]);
  195.83 +      }
  195.84 +    case 0:
  195.85 +      break;
  195.86 +    default:
  195.87 +      cerr << ap.commandName() << ": too many arguments\n";
  195.88 +      return 1;
  195.89 +  }
  195.90 +  istream& is = (ap.files().size()<1 ? cin : input);
  195.91 +  ostream& os = (ap.files().size()<2 ? cout : output);
  195.92 +
  195.93 +  DimacsDescriptor desc = dimacsType(is);
  195.94 +  switch(desc.type)
  195.95 +    {
  195.96 +    case DimacsDescriptor::MIN:
  195.97 +      {
  195.98 +        Digraph digraph;
  195.99 +        DoubleArcMap lower(digraph), capacity(digraph), cost(digraph);
 195.100 +        DoubleNodeMap supply(digraph);
 195.101 +        readDimacsMin(is, digraph, lower, capacity, cost, supply, 0, desc);
 195.102 +        DigraphWriter<Digraph>(digraph, os).
 195.103 +          nodeMap("supply", supply).
 195.104 +          arcMap("lower", lower).
 195.105 +          arcMap("capacity", capacity).
 195.106 +          arcMap("cost", cost).
 195.107 +          attribute("problem","min").
 195.108 +          run();
 195.109 +      }
 195.110 +      break;
 195.111 +    case DimacsDescriptor::MAX:
 195.112 +      {
 195.113 +        Digraph digraph;
 195.114 +        Node s, t;
 195.115 +        DoubleArcMap capacity(digraph);
 195.116 +        readDimacsMax(is, digraph, capacity, s, t, 0, desc);
 195.117 +        DigraphWriter<Digraph>(digraph, os).
 195.118 +          arcMap("capacity", capacity).
 195.119 +          node("source", s).
 195.120 +          node("target", t).
 195.121 +          attribute("problem","max").
 195.122 +          run();
 195.123 +      }
 195.124 +      break;
 195.125 +    case DimacsDescriptor::SP:
 195.126 +      {
 195.127 +        Digraph digraph;
 195.128 +        Node s;
 195.129 +        DoubleArcMap capacity(digraph);
 195.130 +        readDimacsSp(is, digraph, capacity, s, desc);
 195.131 +        DigraphWriter<Digraph>(digraph, os).
 195.132 +          arcMap("capacity", capacity).
 195.133 +          node("source", s).
 195.134 +          attribute("problem","sp").
 195.135 +          run();
 195.136 +      }
 195.137 +      break;
 195.138 +    case DimacsDescriptor::MAT:
 195.139 +      {
 195.140 +        Digraph digraph;
 195.141 +        readDimacsMat(is, digraph,desc);
 195.142 +        DigraphWriter<Digraph>(digraph, os).
 195.143 +          attribute("problem","mat").
 195.144 +          run();
 195.145 +      }
 195.146 +      break;
 195.147 +    default:
 195.148 +      break;
 195.149 +    }
 195.150 +  return 0;
 195.151 +}
   196.1 --- a/tools/lemon-0.x-to-1.x.sh	Fri Oct 16 10:21:37 2009 +0200
   196.2 +++ b/tools/lemon-0.x-to-1.x.sh	Thu Nov 05 15:50:01 2009 +0100
   196.3 @@ -3,125 +3,132 @@
   196.4  set -e
   196.5  
   196.6  if [ $# -eq 0 -o x$1 = "x-h" -o x$1 = "x-help" -o x$1 = "x--help" ]; then
   196.7 -	echo "Usage:"
   196.8 -	echo "  $0 source-file"
   196.9 -	exit
  196.10 +    echo "Usage:"
  196.11 +    echo "  $0 source-file(s)"
  196.12 +    exit
  196.13  fi
  196.14  
  196.15 -TMP=`mktemp`
  196.16 -
  196.17 -sed	-e "s/undirected graph/_gr_aph_label_/g"\
  196.18 -	-e "s/undirected edge/_ed_ge_label_/g"\
  196.19 -	-e "s/graph_/_gr_aph_label__/g"\
  196.20 -	-e "s/_graph/__gr_aph_label_/g"\
  196.21 -	-e "s/UGraph/_Gr_aph_label_/g"\
  196.22 -	-e "s/uGraph/_gr_aph_label_/g"\
  196.23 -	-e "s/ugraph/_gr_aph_label_/g"\
  196.24 -	-e "s/Graph/_Digr_aph_label_/g"\
  196.25 -	-e "s/graph/_digr_aph_label_/g"\
  196.26 -	-e "s/UEdge/_Ed_ge_label_/g"\
  196.27 -	-e "s/uEdge/_ed_ge_label_/g"\
  196.28 -	-e "s/uedge/_ed_ge_label_/g"\
  196.29 -	-e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
  196.30 -	-e "s/Edge/_Ar_c_label_/g"\
  196.31 -	-e "s/edge/_ar_c_label_/g"\
  196.32 -	-e "s/ANode/_Re_d_label_/g"\
  196.33 -	-e "s/BNode/_Blu_e_label_/g"\
  196.34 -	-e "s/A-Node/_Re_d_label_/g"\
  196.35 -	-e "s/B-Node/_Blu_e_label_/g"\
  196.36 -	-e "s/anode/_re_d_label_/g"\
  196.37 -	-e "s/bnode/_blu_e_label_/g"\
  196.38 -	-e "s/aNode/_re_d_label_/g"\
  196.39 -	-e "s/bNode/_blu_e_label_/g"\
  196.40 -	-e "s/_Digr_aph_label_/Digraph/g"\
  196.41 -	-e "s/_digr_aph_label_/digraph/g"\
  196.42 -	-e "s/_Gr_aph_label_/Graph/g"\
  196.43 -	-e "s/_gr_aph_label_/graph/g"\
  196.44 -	-e "s/_Ar_c_label_/Arc/g"\
  196.45 -	-e "s/_ar_c_label_/arc/g"\
  196.46 -	-e "s/_Ed_ge_label_/Edge/g"\
  196.47 -	-e "s/_ed_ge_label_/edge/g"\
  196.48 -	-e "s/_In_cEd_geIt_label_/IncEdgeIt/g"\
  196.49 -	-e "s/_Re_d_label_/Red/g"\
  196.50 -	-e "s/_Blu_e_label_/Blue/g"\
  196.51 -	-e "s/_re_d_label_/red/g"\
  196.52 -	-e "s/_blu_e_label_/blue/g"\
  196.53 -	-e "s/\(\W\)DefPredMap\(\W\)/\1SetPredMap\2/g"\
  196.54 -	-e "s/\(\W\)DefPredMap$/\1SetPredMap/g"\
  196.55 -	-e "s/^DefPredMap\(\W\)/SetPredMap\1/g"\
  196.56 -	-e "s/^DefPredMap$/SetPredMap/g"\
  196.57 -	-e "s/\(\W\)DefDistMap\(\W\)/\1SetDistMap\2/g"\
  196.58 -	-e "s/\(\W\)DefDistMap$/\1SetDistMap/g"\
  196.59 -	-e "s/^DefDistMap\(\W\)/SetDistMap\1/g"\
  196.60 -	-e "s/^DefDistMap$/SetDistMap/g"\
  196.61 -	-e "s/\(\W\)DefReachedMap\(\W\)/\1SetReachedMap\2/g"\
  196.62 -	-e "s/\(\W\)DefReachedMap$/\1SetReachedMap/g"\
  196.63 -	-e "s/^DefReachedMap\(\W\)/SetReachedMap\1/g"\
  196.64 -	-e "s/^DefReachedMap$/SetReachedMap/g"\
  196.65 -	-e "s/\(\W\)DefProcessedMap\(\W\)/\1SetProcessedMap\2/g"\
  196.66 -	-e "s/\(\W\)DefProcessedMap$/\1SetProcessedMap/g"\
  196.67 -	-e "s/^DefProcessedMap\(\W\)/SetProcessedMap\1/g"\
  196.68 -	-e "s/^DefProcessedMap$/SetProcessedMap/g"\
  196.69 -	-e "s/\(\W\)DefHeap\(\W\)/\1SetHeap\2/g"\
  196.70 -	-e "s/\(\W\)DefHeap$/\1SetHeap/g"\
  196.71 -	-e "s/^DefHeap\(\W\)/SetHeap\1/g"\
  196.72 -	-e "s/^DefHeap$/SetHeap/g"\
  196.73 -	-e "s/\(\W\)DefStandardHeap\(\W\)/\1SetStandradHeap\2/g"\
  196.74 -	-e "s/\(\W\)DefStandardHeap$/\1SetStandradHeap/g"\
  196.75 -	-e "s/^DefStandardHeap\(\W\)/SetStandradHeap\1/g"\
  196.76 -	-e "s/^DefStandardHeap$/SetStandradHeap/g"\
  196.77 -	-e "s/\(\W\)DefOperationTraits\(\W\)/\1SetOperationTraits\2/g"\
  196.78 -	-e "s/\(\W\)DefOperationTraits$/\1SetOperationTraits/g"\
  196.79 -	-e "s/^DefOperationTraits\(\W\)/SetOperationTraits\1/g"\
  196.80 -	-e "s/^DefOperationTraits$/SetOperationTraits/g"\
  196.81 -	-e "s/\(\W\)DefProcessedMapToBeDefaultMap\(\W\)/\1SetStandardProcessedMap\2/g"\
  196.82 -	-e "s/\(\W\)DefProcessedMapToBeDefaultMap$/\1SetStandardProcessedMap/g"\
  196.83 -	-e "s/^DefProcessedMapToBeDefaultMap\(\W\)/SetStandardProcessedMap\1/g"\
  196.84 -	-e "s/^DefProcessedMapToBeDefaultMap$/SetStandardProcessedMap/g"\
  196.85 -	-e "s/\(\W\)IntegerMap\(\W\)/\1RangeMap\2/g"\
  196.86 -	-e "s/\(\W\)IntegerMap$/\1RangeMap/g"\
  196.87 -	-e "s/^IntegerMap\(\W\)/RangeMap\1/g"\
  196.88 -	-e "s/^IntegerMap$/RangeMap/g"\
  196.89 -	-e "s/\(\W\)integerMap\(\W\)/\1rangeMap\2/g"\
  196.90 -	-e "s/\(\W\)integerMap$/\1rangeMap/g"\
  196.91 -	-e "s/^integerMap\(\W\)/rangeMap\1/g"\
  196.92 -	-e "s/^integerMap$/rangeMap/g"\
  196.93 -	-e "s/\(\W\)copyGraph\(\W\)/\1graphCopy\2/g"\
  196.94 -	-e "s/\(\W\)copyGraph$/\1graphCopy/g"\
  196.95 -	-e "s/^copyGraph\(\W\)/graphCopy\1/g"\
  196.96 -	-e "s/^copyGraph$/graphCopy/g"\
  196.97 -	-e "s/\(\W\)copyDigraph\(\W\)/\1digraphCopy\2/g"\
  196.98 -	-e "s/\(\W\)copyDigraph$/\1digraphCopy/g"\
  196.99 -	-e "s/^copyDigraph\(\W\)/digraphCopy\1/g"\
 196.100 -	-e "s/^copyDigraph$/digraphCopy/g"\
 196.101 -	-e "s/\(\W\)\([sS]\)tdMap\(\W\)/\1\2parseMap\3/g"\
 196.102 -	-e "s/\(\W\)\([sS]\)tdMap$/\1\2parseMap/g"\
 196.103 -	-e "s/^\([sS]\)tdMap\(\W\)/\1parseMap\2/g"\
 196.104 -	-e "s/^\([sS]\)tdMap$/\1parseMap/g"\
 196.105 -	-e "s/\(\W\)\([Ff]\)unctorMap\(\W\)/\1\2unctorToMap\3/g"\
 196.106 -	-e "s/\(\W\)\([Ff]\)unctorMap$/\1\2unctorToMap/g"\
 196.107 -	-e "s/^\([Ff]\)unctorMap\(\W\)/\1unctorToMap\2/g"\
 196.108 -	-e "s/^\([Ff]\)unctorMap$/\1unctorToMap/g"\
 196.109 -	-e "s/\(\W\)\([Mm]\)apFunctor\(\W\)/\1\2apToFunctor\3/g"\
 196.110 -	-e "s/\(\W\)\([Mm]\)apFunctor$/\1\2apToFunctor/g"\
 196.111 -	-e "s/^\([Mm]\)apFunctor\(\W\)/\1apToFunctor\2/g"\
 196.112 -	-e "s/^\([Mm]\)apFunctor$/\1apToFunctor/g"\
 196.113 -	-e "s/\(\W\)\([Ff]\)orkWriteMap\(\W\)/\1\2orkMap\3/g"\
 196.114 -	-e "s/\(\W\)\([Ff]\)orkWriteMap$/\1\2orkMap/g"\
 196.115 -	-e "s/^\([Ff]\)orkWriteMap\(\W\)/\1orkMap\2/g"\
 196.116 -	-e "s/^\([Ff]\)orkWriteMap$/\1orkMap/g"\
 196.117 -	-e "s/\(\W\)StoreBoolMap\(\W\)/\1LoggerBoolMap\2/g"\
 196.118 -	-e "s/\(\W\)StoreBoolMap$/\1LoggerBoolMap/g"\
 196.119 -	-e "s/^StoreBoolMap\(\W\)/LoggerBoolMap\1/g"\
 196.120 -	-e "s/^StoreBoolMap$/LoggerBoolMap/g"\
 196.121 -	-e "s/\(\W\)storeBoolMap\(\W\)/\1loggerBoolMap\2/g"\
 196.122 -	-e "s/\(\W\)storeBoolMap$/\1loggerBoolMap/g"\
 196.123 -	-e "s/^storeBoolMap\(\W\)/loggerBoolMap\1/g"\
 196.124 -	-e "s/^storeBoolMap$/loggerBoolMap/g"\
 196.125 -	-e "s/\(\W\)BoundingBox\(\W\)/\1Box\2/g"\
 196.126 -	-e "s/\(\W\)BoundingBox$/\1Box/g"\
 196.127 -	-e "s/^BoundingBox\(\W\)/Box\1/g"\
 196.128 -	-e "s/^BoundingBox$/Box/g"\
 196.129 -<$1 > $TMP
 196.130 -
 196.131 -mv $TMP $1
 196.132 \ No newline at end of file
 196.133 +for i in $@
 196.134 +do
 196.135 +    echo Update $i...
 196.136 +    TMP=`mktemp`
 196.137 +    sed -e "s/\<undirected graph\>/_gr_aph_label_/g"\
 196.138 +        -e "s/\<undirected graphs\>/_gr_aph_label_s/g"\
 196.139 +        -e "s/\<undirected edge\>/_ed_ge_label_/g"\
 196.140 +        -e "s/\<undirected edges\>/_ed_ge_label_s/g"\
 196.141 +        -e "s/\<directed graph\>/_digr_aph_label_/g"\
 196.142 +        -e "s/\<directed graphs\>/_digr_aph_label_s/g"\
 196.143 +        -e "s/\<directed edge\>/_ar_c_label_/g"\
 196.144 +        -e "s/\<directed edges\>/_ar_c_label_s/g"\
 196.145 +        -e "s/UGraph/_Gr_aph_label_/g"\
 196.146 +        -e "s/u[Gg]raph/_gr_aph_label_/g"\
 196.147 +        -e "s/Graph\>/_Digr_aph_label_/g"\
 196.148 +        -e "s/\<graph\>/_digr_aph_label_/g"\
 196.149 +        -e "s/Graphs\>/_Digr_aph_label_s/g"\
 196.150 +        -e "s/\<graphs\>/_digr_aph_label_s/g"\
 196.151 +        -e "s/\([Gg]\)raph\([a-z]\)/_\1r_aph_label_\2/g"\
 196.152 +        -e "s/\([a-z_]\)graph/\1_gr_aph_label_/g"\
 196.153 +        -e "s/Graph/_Digr_aph_label_/g"\
 196.154 +        -e "s/graph/_digr_aph_label_/g"\
 196.155 +        -e "s/UEdge/_Ed_ge_label_/g"\
 196.156 +        -e "s/u[Ee]dge/_ed_ge_label_/g"\
 196.157 +        -e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
 196.158 +        -e "s/Edge\>/_Ar_c_label_/g"\
 196.159 +        -e "s/\<edge\>/_ar_c_label_/g"\
 196.160 +        -e "s/_edge\>/__ar_c_label_/g"\
 196.161 +        -e "s/Edges\>/_Ar_c_label_s/g"\
 196.162 +        -e "s/\<edges\>/_ar_c_label_s/g"\
 196.163 +        -e "s/_edges\>/__ar_c_label_s/g"\
 196.164 +        -e "s/\([Ee]\)dge\([a-z]\)/_\1d_ge_label_\2/g"\
 196.165 +        -e "s/\([a-z]\)edge/\1_ed_ge_label_/g"\
 196.166 +        -e "s/Edge/_Ar_c_label_/g"\
 196.167 +        -e "s/edge/_ar_c_label_/g"\
 196.168 +        -e "s/A[Nn]ode/_Re_d_label_/g"\
 196.169 +        -e "s/B[Nn]ode/_Blu_e_label_/g"\
 196.170 +        -e "s/A-[Nn]ode/_Re_d_label_/g"\
 196.171 +        -e "s/B-[Nn]ode/_Blu_e_label_/g"\
 196.172 +        -e "s/a[Nn]ode/_re_d_label_/g"\
 196.173 +        -e "s/b[Nn]ode/_blu_e_label_/g"\
 196.174 +        -e "s/\<UGRAPH_TYPEDEFS\([ \t]*([ \t]*\)typename[ \t]/TEMPLATE__GR_APH_TY_PEDE_FS_label_\1/g"\
 196.175 +        -e "s/\<GRAPH_TYPEDEFS\([ \t]*([ \t]*\)typename[ \t]/TEMPLATE__DIGR_APH_TY_PEDE_FS_label_\1/g"\
 196.176 +        -e "s/\<UGRAPH_TYPEDEFS\>/_GR_APH_TY_PEDE_FS_label_/g"\
 196.177 +        -e "s/\<GRAPH_TYPEDEFS\>/_DIGR_APH_TY_PEDE_FS_label_/g"\
 196.178 +        -e "s/_Digr_aph_label_/Digraph/g"\
 196.179 +        -e "s/_digr_aph_label_/digraph/g"\
 196.180 +        -e "s/_Gr_aph_label_/Graph/g"\
 196.181 +        -e "s/_gr_aph_label_/graph/g"\
 196.182 +        -e "s/_Ar_c_label_/Arc/g"\
 196.183 +        -e "s/_ar_c_label_/arc/g"\
 196.184 +        -e "s/_Ed_ge_label_/Edge/g"\
 196.185 +        -e "s/_ed_ge_label_/edge/g"\
 196.186 +        -e "s/_In_cEd_geIt_label_/IncEdgeIt/g"\
 196.187 +        -e "s/_Re_d_label_/Red/g"\
 196.188 +        -e "s/_Blu_e_label_/Blue/g"\
 196.189 +        -e "s/_re_d_label_/red/g"\
 196.190 +        -e "s/_blu_e_label_/blue/g"\
 196.191 +        -e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\
 196.192 +        -e "s/_DIGR_APH_TY_PEDE_FS_label_/DIGRAPH_TYPEDEFS/g"\
 196.193 +        -e "s/\<digraph_adaptor\.h\>/adaptors.h/g"\
 196.194 +        -e "s/\<digraph_utils\.h\>/core.h/g"\
 196.195 +        -e "s/\<digraph_reader\.h\>/lgf_reader.h/g"\
 196.196 +        -e "s/\<digraph_writer\.h\>/lgf_writer.h/g"\
 196.197 +        -e "s/\<topology\.h\>/connectivity.h/g"\
 196.198 +        -e "s/DigraphToEps/GraphToEps/g"\
 196.199 +        -e "s/digraphToEps/graphToEps/g"\
 196.200 +        -e "s/\<DefPredMap\>/SetPredMap/g"\
 196.201 +        -e "s/\<DefDistMap\>/SetDistMap/g"\
 196.202 +        -e "s/\<DefReachedMap\>/SetReachedMap/g"\
 196.203 +        -e "s/\<DefProcessedMap\>/SetProcessedMap/g"\
 196.204 +        -e "s/\<DefHeap\>/SetHeap/g"\
 196.205 +        -e "s/\<DefStandardHeap\>/SetStandradHeap/g"\
 196.206 +        -e "s/\<DefOperationTraits\>/SetOperationTraits/g"\
 196.207 +        -e "s/\<DefProcessedMapToBeDefaultMap\>/SetStandardProcessedMap/g"\
 196.208 +        -e "s/\<copyGraph\>/graphCopy/g"\
 196.209 +        -e "s/\<copyDigraph\>/digraphCopy/g"\
 196.210 +        -e "s/\<HyperCubeDigraph\>/HypercubeGraph/g"\
 196.211 +        -e "s/\<IntegerMap\>/RangeMap/g"\
 196.212 +        -e "s/\<integerMap\>/rangeMap/g"\
 196.213 +        -e "s/\<\([sS]\)tdMap\>/\1parseMap/g"\
 196.214 +        -e "s/\<\([Ff]\)unctorMap\>/\1unctorToMap/g"\
 196.215 +        -e "s/\<\([Mm]\)apFunctor\>/\1apToFunctor/g"\
 196.216 +        -e "s/\<\([Ff]\)orkWriteMap\>/\1orkMap/g"\
 196.217 +        -e "s/\<StoreBoolMap\>/LoggerBoolMap/g"\
 196.218 +        -e "s/\<storeBoolMap\>/loggerBoolMap/g"\
 196.219 +        -e "s/\<InvertableMap\>/CrossRefMap/g"\
 196.220 +        -e "s/\<invertableMap\>/crossRefMap/g"\
 196.221 +        -e "s/\<DescriptorMap\>/RangeIdMap/g"\
 196.222 +        -e "s/\<descriptorMap\>/rangeIdMap/g"\
 196.223 +        -e "s/\<BoundingBox\>/Box/g"\
 196.224 +        -e "s/\<readNauty\>/readNautyGraph/g"\
 196.225 +        -e "s/\<RevDigraphAdaptor\>/ReverseDigraph/g"\
 196.226 +        -e "s/\<revDigraphAdaptor\>/reverseDigraph/g"\
 196.227 +        -e "s/\<SubDigraphAdaptor\>/SubDigraph/g"\
 196.228 +        -e "s/\<subDigraphAdaptor\>/subDigraph/g"\
 196.229 +        -e "s/\<SubGraphAdaptor\>/SubGraph/g"\
 196.230 +        -e "s/\<subGraphAdaptor\>/subGraph/g"\
 196.231 +        -e "s/\<NodeSubDigraphAdaptor\>/FilterNodes/g"\
 196.232 +        -e "s/\<nodeSubDigraphAdaptor\>/filterNodes/g"\
 196.233 +        -e "s/\<ArcSubDigraphAdaptor\>/FilterArcs/g"\
 196.234 +        -e "s/\<arcSubDigraphAdaptor\>/filterArcs/g"\
 196.235 +        -e "s/\<UndirDigraphAdaptor\>/Undirector/g"\
 196.236 +        -e "s/\<undirDigraphAdaptor\>/undirector/g"\
 196.237 +        -e "s/\<ResDigraphAdaptor\>/ResidualDigraph/g"\
 196.238 +        -e "s/\<resDigraphAdaptor\>/residualDigraph/g"\
 196.239 +        -e "s/\<SplitDigraphAdaptor\>/SplitNodes/g"\
 196.240 +        -e "s/\<splitDigraphAdaptor\>/splitNodes/g"\
 196.241 +        -e "s/\<SubGraphAdaptor\>/SubGraph/g"\
 196.242 +        -e "s/\<subGraphAdaptor\>/subGraph/g"\
 196.243 +        -e "s/\<NodeSubGraphAdaptor\>/FilterNodes/g"\
 196.244 +        -e "s/\<nodeSubGraphAdaptor\>/filterNodes/g"\
 196.245 +        -e "s/\<ArcSubGraphAdaptor\>/FilterEdges/g"\
 196.246 +        -e "s/\<arcSubGraphAdaptor\>/filterEdges/g"\
 196.247 +        -e "s/\<DirGraphAdaptor\>/Orienter/g"\
 196.248 +        -e "s/\<dirGraphAdaptor\>/orienter/g"\
 196.249 +        -e "s/\<LpCplex\>/CplexLp/g"\
 196.250 +        -e "s/\<MipCplex\>/CplexMip/g"\
 196.251 +        -e "s/\<LpGlpk\>/GlpkLp/g"\
 196.252 +        -e "s/\<MipGlpk\>/GlpkMip/g"\
 196.253 +        -e "s/\<LpSoplex\>/SoplexLp/g"\
 196.254 +    <$i > $TMP
 196.255 +    mv $TMP $i
 196.256 +done
   197.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   197.2 +++ b/tools/lgf-gen.cc	Thu Nov 05 15:50:01 2009 +0100
   197.3 @@ -0,0 +1,834 @@
   197.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   197.5 + *
   197.6 + * This file is a part of LEMON, a generic C++ optimization library.
   197.7 + *
   197.8 + * Copyright (C) 2003-2009
   197.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  197.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  197.11 + *
  197.12 + * Permission to use, modify and distribute this software is granted
  197.13 + * provided that this copyright notice appears in all copies. For
  197.14 + * precise terms see the accompanying LICENSE file.
  197.15 + *
  197.16 + * This software is provided "AS IS" with no warranty of any kind,
  197.17 + * express or implied, and with no claim as to its suitability for any
  197.18 + * purpose.
  197.19 + *
  197.20 + */
  197.21 +
  197.22 +/// \ingroup tools
  197.23 +/// \file
  197.24 +/// \brief Special plane graph generator.
  197.25 +///
  197.26 +/// Graph generator application for various types of plane graphs.
  197.27 +///
  197.28 +/// See
  197.29 +/// \code
  197.30 +///   lgf-gen --help
  197.31 +/// \endcode
  197.32 +/// for more information on the usage.
  197.33 +
  197.34 +#include <algorithm>
  197.35 +#include <set>
  197.36 +#include <ctime>
  197.37 +#include <lemon/list_graph.h>
  197.38 +#include <lemon/random.h>
  197.39 +#include <lemon/dim2.h>
  197.40 +#include <lemon/bfs.h>
  197.41 +#include <lemon/counter.h>
  197.42 +#include <lemon/suurballe.h>
  197.43 +#include <lemon/graph_to_eps.h>
  197.44 +#include <lemon/lgf_writer.h>
  197.45 +#include <lemon/arg_parser.h>
  197.46 +#include <lemon/euler.h>
  197.47 +#include <lemon/math.h>
  197.48 +#include <lemon/kruskal.h>
  197.49 +#include <lemon/time_measure.h>
  197.50 +
  197.51 +using namespace lemon;
  197.52 +
  197.53 +typedef dim2::Point<double> Point;
  197.54 +
  197.55 +GRAPH_TYPEDEFS(ListGraph);
  197.56 +
  197.57 +bool progress=true;
  197.58 +
  197.59 +int N;
  197.60 +// int girth;
  197.61 +
  197.62 +ListGraph g;
  197.63 +
  197.64 +std::vector<Node> nodes;
  197.65 +ListGraph::NodeMap<Point> coords(g);
  197.66 +
  197.67 +
  197.68 +double totalLen(){
  197.69 +  double tlen=0;
  197.70 +  for(EdgeIt e(g);e!=INVALID;++e)
  197.71 +    tlen+=std::sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
  197.72 +  return tlen;
  197.73 +}
  197.74 +
  197.75 +int tsp_impr_num=0;
  197.76 +
  197.77 +const double EPSILON=1e-8;
  197.78 +bool tsp_improve(Node u, Node v)
  197.79 +{
  197.80 +  double luv=std::sqrt((coords[v]-coords[u]).normSquare());
  197.81 +  Node u2=u;
  197.82 +  Node v2=v;
  197.83 +  do {
  197.84 +    Node n;
  197.85 +    for(IncEdgeIt e(g,v2);(n=g.runningNode(e))==u2;++e) { }
  197.86 +    u2=v2;
  197.87 +    v2=n;
  197.88 +    if(luv+std::sqrt((coords[v2]-coords[u2]).normSquare())-EPSILON>
  197.89 +       std::sqrt((coords[u]-coords[u2]).normSquare())+
  197.90 +       std::sqrt((coords[v]-coords[v2]).normSquare()))
  197.91 +      {
  197.92 +         g.erase(findEdge(g,u,v));
  197.93 +         g.erase(findEdge(g,u2,v2));
  197.94 +        g.addEdge(u2,u);
  197.95 +        g.addEdge(v,v2);
  197.96 +        tsp_impr_num++;
  197.97 +        return true;
  197.98 +      }
  197.99 +  } while(v2!=u);
 197.100 +  return false;
 197.101 +}
 197.102 +
 197.103 +bool tsp_improve(Node u)
 197.104 +{
 197.105 +  for(IncEdgeIt e(g,u);e!=INVALID;++e)
 197.106 +    if(tsp_improve(u,g.runningNode(e))) return true;
 197.107 +  return false;
 197.108 +}
 197.109 +
 197.110 +void tsp_improve()
 197.111 +{
 197.112 +  bool b;
 197.113 +  do {
 197.114 +    b=false;
 197.115 +    for(NodeIt n(g);n!=INVALID;++n)
 197.116 +      if(tsp_improve(n)) b=true;
 197.117 +  } while(b);
 197.118 +}
 197.119 +
 197.120 +void tsp()
 197.121 +{
 197.122 +  for(int i=0;i<N;i++) g.addEdge(nodes[i],nodes[(i+1)%N]);
 197.123 +  tsp_improve();
 197.124 +}
 197.125 +
 197.126 +class Line
 197.127 +{
 197.128 +public:
 197.129 +  Point a;
 197.130 +  Point b;
 197.131 +  Line(Point _a,Point _b) :a(_a),b(_b) {}
 197.132 +  Line(Node _a,Node _b) : a(coords[_a]),b(coords[_b]) {}
 197.133 +  Line(const Arc &e) : a(coords[g.source(e)]),b(coords[g.target(e)]) {}
 197.134 +  Line(const Edge &e) : a(coords[g.u(e)]),b(coords[g.v(e)]) {}
 197.135 +};
 197.136 +
 197.137 +inline std::ostream& operator<<(std::ostream &os, const Line &l)
 197.138 +{
 197.139 +  os << l.a << "->" << l.b;
 197.140 +  return os;
 197.141 +}
 197.142 +
 197.143 +bool cross(Line a, Line b)
 197.144 +{
 197.145 +  Point ao=rot90(a.b-a.a);
 197.146 +  Point bo=rot90(b.b-b.a);
 197.147 +  return (ao*(b.a-a.a))*(ao*(b.b-a.a))<0 &&
 197.148 +    (bo*(a.a-b.a))*(bo*(a.b-b.a))<0;
 197.149 +}
 197.150 +
 197.151 +struct Parc
 197.152 +{
 197.153 +  Node a;
 197.154 +  Node b;
 197.155 +  double len;
 197.156 +};
 197.157 +
 197.158 +bool pedgeLess(Parc a,Parc b)
 197.159 +{
 197.160 +  return a.len<b.len;
 197.161 +}
 197.162 +
 197.163 +std::vector<Edge> arcs;
 197.164 +
 197.165 +namespace _delaunay_bits {
 197.166 +
 197.167 +  struct Part {
 197.168 +    int prev, curr, next;
 197.169 +
 197.170 +    Part(int p, int c, int n) : prev(p), curr(c), next(n) {}
 197.171 +  };
 197.172 +
 197.173 +  inline std::ostream& operator<<(std::ostream& os, const Part& part) {
 197.174 +    os << '(' << part.prev << ',' << part.curr << ',' << part.next << ')';
 197.175 +    return os;
 197.176 +  }
 197.177 +
 197.178 +  inline double circle_point(const Point& p, const Point& q, const Point& r) {
 197.179 +    double a = p.x * (q.y - r.y) + q.x * (r.y - p.y) + r.x * (p.y - q.y);
 197.180 +    if (a == 0) return std::numeric_limits<double>::quiet_NaN();
 197.181 +
 197.182 +    double d = (p.x * p.x + p.y * p.y) * (q.y - r.y) +
 197.183 +      (q.x * q.x + q.y * q.y) * (r.y - p.y) +
 197.184 +      (r.x * r.x + r.y * r.y) * (p.y - q.y);
 197.185 +
 197.186 +    double e = (p.x * p.x + p.y * p.y) * (q.x - r.x) +
 197.187 +      (q.x * q.x + q.y * q.y) * (r.x - p.x) +
 197.188 +      (r.x * r.x + r.y * r.y) * (p.x - q.x);
 197.189 +
 197.190 +    double f = (p.x * p.x + p.y * p.y) * (q.x * r.y - r.x * q.y) +
 197.191 +      (q.x * q.x + q.y * q.y) * (r.x * p.y - p.x * r.y) +
 197.192 +      (r.x * r.x + r.y * r.y) * (p.x * q.y - q.x * p.y);
 197.193 +
 197.194 +    return d / (2 * a) + std::sqrt((d * d + e * e) / (4 * a * a) + f / a);
 197.195 +  }
 197.196 +
 197.197 +  inline bool circle_form(const Point& p, const Point& q, const Point& r) {
 197.198 +    return rot90(q - p) * (r - q) < 0.0;
 197.199 +  }
 197.200 +
 197.201 +  inline double intersection(const Point& p, const Point& q, double sx) {
 197.202 +    const double epsilon = 1e-8;
 197.203 +
 197.204 +    if (p.x == q.x) return (p.y + q.y) / 2.0;
 197.205 +
 197.206 +    if (sx < p.x + epsilon) return p.y;
 197.207 +    if (sx < q.x + epsilon) return q.y;
 197.208 +
 197.209 +    double a = q.x - p.x;
 197.210 +    double b = (q.x - sx) * p.y - (p.x - sx) * q.y;
 197.211 +    double d = (q.x - sx) * (p.x - sx) * (p - q).normSquare();
 197.212 +    return (b - std::sqrt(d)) / a;
 197.213 +  }
 197.214 +
 197.215 +  struct YLess {
 197.216 +
 197.217 +
 197.218 +    YLess(const std::vector<Point>& points, double& sweep)
 197.219 +      : _points(points), _sweep(sweep) {}
 197.220 +
 197.221 +    bool operator()(const Part& l, const Part& r) const {
 197.222 +      const double epsilon = 1e-8;
 197.223 +
 197.224 +      //      std::cerr << l << " vs " << r << std::endl;
 197.225 +      double lbx = l.prev != -1 ?
 197.226 +        intersection(_points[l.prev], _points[l.curr], _sweep) :
 197.227 +        - std::numeric_limits<double>::infinity();
 197.228 +      double rbx = r.prev != -1 ?
 197.229 +        intersection(_points[r.prev], _points[r.curr], _sweep) :
 197.230 +        - std::numeric_limits<double>::infinity();
 197.231 +      double lex = l.next != -1 ?
 197.232 +        intersection(_points[l.curr], _points[l.next], _sweep) :
 197.233 +        std::numeric_limits<double>::infinity();
 197.234 +      double rex = r.next != -1 ?
 197.235 +        intersection(_points[r.curr], _points[r.next], _sweep) :
 197.236 +        std::numeric_limits<double>::infinity();
 197.237 +
 197.238 +      if (lbx > lex) std::swap(lbx, lex);
 197.239 +      if (rbx > rex) std::swap(rbx, rex);
 197.240 +
 197.241 +      if (lex < epsilon + rex && lbx + epsilon < rex) return true;
 197.242 +      if (rex < epsilon + lex && rbx + epsilon < lex) return false;
 197.243 +      return lex < rex;
 197.244 +    }
 197.245 +
 197.246 +    const std::vector<Point>& _points;
 197.247 +    double& _sweep;
 197.248 +  };
 197.249 +
 197.250 +  struct BeachIt;
 197.251 +
 197.252 +  typedef std::multimap<double, BeachIt> SpikeHeap;
 197.253 +
 197.254 +  typedef std::multimap<Part, SpikeHeap::iterator, YLess> Beach;
 197.255 +
 197.256 +  struct BeachIt {
 197.257 +    Beach::iterator it;
 197.258 +
 197.259 +    BeachIt(Beach::iterator iter) : it(iter) {}
 197.260 +  };
 197.261 +
 197.262 +}
 197.263 +
 197.264 +inline void delaunay() {
 197.265 +  Counter cnt("Number of arcs added: ");
 197.266 +
 197.267 +  using namespace _delaunay_bits;
 197.268 +
 197.269 +  typedef _delaunay_bits::Part Part;
 197.270 +  typedef std::vector<std::pair<double, int> > SiteHeap;
 197.271 +
 197.272 +
 197.273 +  std::vector<Point> points;
 197.274 +  std::vector<Node> nodes;
 197.275 +
 197.276 +  for (NodeIt it(g); it != INVALID; ++it) {
 197.277 +    nodes.push_back(it);
 197.278 +    points.push_back(coords[it]);
 197.279 +  }
 197.280 +
 197.281 +  SiteHeap siteheap(points.size());
 197.282 +
 197.283 +  double sweep;
 197.284 +
 197.285 +
 197.286 +  for (int i = 0; i < int(siteheap.size()); ++i) {
 197.287 +    siteheap[i] = std::make_pair(points[i].x, i);
 197.288 +  }
 197.289 +
 197.290 +  std::sort(siteheap.begin(), siteheap.end());
 197.291 +  sweep = siteheap.front().first;
 197.292 +
 197.293 +  YLess yless(points, sweep);
 197.294 +  Beach beach(yless);
 197.295 +
 197.296 +  SpikeHeap spikeheap;
 197.297 +
 197.298 +  std::set<std::pair<int, int> > arcs;
 197.299 +
 197.300 +  int siteindex = 0;
 197.301 +  {
 197.302 +    SiteHeap front;
 197.303 +
 197.304 +    while (siteindex < int(siteheap.size()) &&
 197.305 +           siteheap[0].first == siteheap[siteindex].first) {
 197.306 +      front.push_back(std::make_pair(points[siteheap[siteindex].second].y,
 197.307 +                                     siteheap[siteindex].second));
 197.308 +      ++siteindex;
 197.309 +    }
 197.310 +
 197.311 +    std::sort(front.begin(), front.end());
 197.312 +
 197.313 +    for (int i = 0; i < int(front.size()); ++i) {
 197.314 +      int prev = (i == 0 ? -1 : front[i - 1].second);
 197.315 +      int curr = front[i].second;
 197.316 +      int next = (i + 1 == int(front.size()) ? -1 : front[i + 1].second);
 197.317 +
 197.318 +      beach.insert(std::make_pair(Part(prev, curr, next),
 197.319 +                                  spikeheap.end()));
 197.320 +    }
 197.321 +  }
 197.322 +
 197.323 +  while (siteindex < int(points.size()) || !spikeheap.empty()) {
 197.324 +
 197.325 +    SpikeHeap::iterator spit = spikeheap.begin();
 197.326 +
 197.327 +    if (siteindex < int(points.size()) &&
 197.328 +        (spit == spikeheap.end() || siteheap[siteindex].first < spit->first)) {
 197.329 +      int site = siteheap[siteindex].second;
 197.330 +      sweep = siteheap[siteindex].first;
 197.331 +
 197.332 +      Beach::iterator bit = beach.upper_bound(Part(site, site, site));
 197.333 +
 197.334 +      if (bit->second != spikeheap.end()) {
 197.335 +        spikeheap.erase(bit->second);
 197.336 +      }
 197.337 +
 197.338 +      int prev = bit->first.prev;
 197.339 +      int curr = bit->first.curr;
 197.340 +      int next = bit->first.next;
 197.341 +
 197.342 +      beach.erase(bit);
 197.343 +
 197.344 +      SpikeHeap::iterator pit = spikeheap.end();
 197.345 +      if (prev != -1 &&
 197.346 +          circle_form(points[prev], points[curr], points[site])) {
 197.347 +        double x = circle_point(points[prev], points[curr], points[site]);
 197.348 +        pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
 197.349 +        pit->second.it =
 197.350 +          beach.insert(std::make_pair(Part(prev, curr, site), pit));
 197.351 +      } else {
 197.352 +        beach.insert(std::make_pair(Part(prev, curr, site), pit));
 197.353 +      }
 197.354 +
 197.355 +      beach.insert(std::make_pair(Part(curr, site, curr), spikeheap.end()));
 197.356 +
 197.357 +      SpikeHeap::iterator nit = spikeheap.end();
 197.358 +      if (next != -1 &&
 197.359 +          circle_form(points[site], points[curr],points[next])) {
 197.360 +        double x = circle_point(points[site], points[curr], points[next]);
 197.361 +        nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
 197.362 +        nit->second.it =
 197.363 +          beach.insert(std::make_pair(Part(site, curr, next), nit));
 197.364 +      } else {
 197.365 +        beach.insert(std::make_pair(Part(site, curr, next), nit));
 197.366 +      }
 197.367 +
 197.368 +      ++siteindex;
 197.369 +    } else {
 197.370 +      sweep = spit->first;
 197.371 +
 197.372 +      Beach::iterator bit = spit->second.it;
 197.373 +
 197.374 +      int prev = bit->first.prev;
 197.375 +      int curr = bit->first.curr;
 197.376 +      int next = bit->first.next;
 197.377 +
 197.378 +      {
 197.379 +        std::pair<int, int> arc;
 197.380 +
 197.381 +        arc = prev < curr ?
 197.382 +          std::make_pair(prev, curr) : std::make_pair(curr, prev);
 197.383 +
 197.384 +        if (arcs.find(arc) == arcs.end()) {
 197.385 +          arcs.insert(arc);
 197.386 +          g.addEdge(nodes[prev], nodes[curr]);
 197.387 +          ++cnt;
 197.388 +        }
 197.389 +
 197.390 +        arc = curr < next ?
 197.391 +          std::make_pair(curr, next) : std::make_pair(next, curr);
 197.392 +
 197.393 +        if (arcs.find(arc) == arcs.end()) {
 197.394 +          arcs.insert(arc);
 197.395 +          g.addEdge(nodes[curr], nodes[next]);
 197.396 +          ++cnt;
 197.397 +        }
 197.398 +      }
 197.399 +
 197.400 +      Beach::iterator pbit = bit; --pbit;
 197.401 +      int ppv = pbit->first.prev;
 197.402 +      Beach::iterator nbit = bit; ++nbit;
 197.403 +      int nnt = nbit->first.next;
 197.404 +
 197.405 +      if (bit->second != spikeheap.end()) spikeheap.erase(bit->second);
 197.406 +      if (pbit->second != spikeheap.end()) spikeheap.erase(pbit->second);
 197.407 +      if (nbit->second != spikeheap.end()) spikeheap.erase(nbit->second);
 197.408 +
 197.409 +      beach.erase(nbit);
 197.410 +      beach.erase(bit);
 197.411 +      beach.erase(pbit);
 197.412 +
 197.413 +      SpikeHeap::iterator pit = spikeheap.end();
 197.414 +      if (ppv != -1 && ppv != next &&
 197.415 +          circle_form(points[ppv], points[prev], points[next])) {
 197.416 +        double x = circle_point(points[ppv], points[prev], points[next]);
 197.417 +        if (x < sweep) x = sweep;
 197.418 +        pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
 197.419 +        pit->second.it =
 197.420 +          beach.insert(std::make_pair(Part(ppv, prev, next), pit));
 197.421 +      } else {
 197.422 +        beach.insert(std::make_pair(Part(ppv, prev, next), pit));
 197.423 +      }
 197.424 +
 197.425 +      SpikeHeap::iterator nit = spikeheap.end();
 197.426 +      if (nnt != -1 && prev != nnt &&
 197.427 +          circle_form(points[prev], points[next], points[nnt])) {
 197.428 +        double x = circle_point(points[prev], points[next], points[nnt]);
 197.429 +        if (x < sweep) x = sweep;
 197.430 +        nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
 197.431 +        nit->second.it =
 197.432 +          beach.insert(std::make_pair(Part(prev, next, nnt), nit));
 197.433 +      } else {
 197.434 +        beach.insert(std::make_pair(Part(prev, next, nnt), nit));
 197.435 +      }
 197.436 +
 197.437 +    }
 197.438 +  }
 197.439 +
 197.440 +  for (Beach::iterator it = beach.begin(); it != beach.end(); ++it) {
 197.441 +    int curr = it->first.curr;
 197.442 +    int next = it->first.next;
 197.443 +
 197.444 +    if (next == -1) continue;
 197.445 +
 197.446 +    std::pair<int, int> arc;
 197.447 +
 197.448 +    arc = curr < next ?
 197.449 +      std::make_pair(curr, next) : std::make_pair(next, curr);
 197.450 +
 197.451 +    if (arcs.find(arc) == arcs.end()) {
 197.452 +      arcs.insert(arc);
 197.453 +      g.addEdge(nodes[curr], nodes[next]);
 197.454 +      ++cnt;
 197.455 +    }
 197.456 +  }
 197.457 +}
 197.458 +
 197.459 +void sparse(int d)
 197.460 +{
 197.461 +  Counter cnt("Number of arcs removed: ");
 197.462 +  Bfs<ListGraph> bfs(g);
 197.463 +  for(std::vector<Edge>::reverse_iterator ei=arcs.rbegin();
 197.464 +      ei!=arcs.rend();++ei)
 197.465 +    {
 197.466 +      Node a=g.u(*ei);
 197.467 +      Node b=g.v(*ei);
 197.468 +      g.erase(*ei);
 197.469 +      bfs.run(a,b);
 197.470 +      if(bfs.predArc(b)==INVALID || bfs.dist(b)>d)
 197.471 +        g.addEdge(a,b);
 197.472 +      else cnt++;
 197.473 +    }
 197.474 +}
 197.475 +
 197.476 +void sparse2(int d)
 197.477 +{
 197.478 +  Counter cnt("Number of arcs removed: ");
 197.479 +  for(std::vector<Edge>::reverse_iterator ei=arcs.rbegin();
 197.480 +      ei!=arcs.rend();++ei)
 197.481 +    {
 197.482 +      Node a=g.u(*ei);
 197.483 +      Node b=g.v(*ei);
 197.484 +      g.erase(*ei);
 197.485 +      ConstMap<Arc,int> cegy(1);
 197.486 +      Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
 197.487 +      int k=sur.run(a,b,2);
 197.488 +      if(k<2 || sur.totalLength()>d)
 197.489 +        g.addEdge(a,b);
 197.490 +      else cnt++;
 197.491 +//       else std::cout << "Remove arc " << g.id(a) << "-" << g.id(b) << '\n';
 197.492 +    }
 197.493 +}
 197.494 +
 197.495 +void sparseTriangle(int d)
 197.496 +{
 197.497 +  Counter cnt("Number of arcs added: ");
 197.498 +  std::vector<Parc> pedges;
 197.499 +  for(NodeIt n(g);n!=INVALID;++n)
 197.500 +    for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
 197.501 +      {
 197.502 +        Parc p;
 197.503 +        p.a=n;
 197.504 +        p.b=m;
 197.505 +        p.len=(coords[m]-coords[n]).normSquare();
 197.506 +        pedges.push_back(p);
 197.507 +      }
 197.508 +  std::sort(pedges.begin(),pedges.end(),pedgeLess);
 197.509 +  for(std::vector<Parc>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
 197.510 +    {
 197.511 +      Line li(pi->a,pi->b);
 197.512 +      EdgeIt e(g);
 197.513 +      for(;e!=INVALID && !cross(e,li);++e) ;
 197.514 +      Edge ne;
 197.515 +      if(e==INVALID) {
 197.516 +        ConstMap<Arc,int> cegy(1);
 197.517 +        Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
 197.518 +        int k=sur.run(pi->a,pi->b,2);
 197.519 +        if(k<2 || sur.totalLength()>d)
 197.520 +          {
 197.521 +            ne=g.addEdge(pi->a,pi->b);
 197.522 +            arcs.push_back(ne);
 197.523 +            cnt++;
 197.524 +          }
 197.525 +      }
 197.526 +    }
 197.527 +}
 197.528 +
 197.529 +template <typename Graph, typename CoordMap>
 197.530 +class LengthSquareMap {
 197.531 +public:
 197.532 +  typedef typename Graph::Edge Key;
 197.533 +  typedef typename CoordMap::Value::Value Value;
 197.534 +
 197.535 +  LengthSquareMap(const Graph& graph, const CoordMap& coords)
 197.536 +    : _graph(graph), _coords(coords) {}
 197.537 +
 197.538 +  Value operator[](const Key& key) const {
 197.539 +    return (_coords[_graph.v(key)] -
 197.540 +            _coords[_graph.u(key)]).normSquare();
 197.541 +  }
 197.542 +
 197.543 +private:
 197.544 +
 197.545 +  const Graph& _graph;
 197.546 +  const CoordMap& _coords;
 197.547 +};
 197.548 +
 197.549 +void minTree() {
 197.550 +  std::vector<Parc> pedges;
 197.551 +  Timer T;
 197.552 +  std::cout << T.realTime() << "s: Creating delaunay triangulation...\n";
 197.553 +  delaunay();
 197.554 +  std::cout << T.realTime() << "s: Calculating spanning tree...\n";
 197.555 +  LengthSquareMap<ListGraph, ListGraph::NodeMap<Point> > ls(g, coords);
 197.556 +  ListGraph::EdgeMap<bool> tree(g);
 197.557 +  kruskal(g, ls, tree);
 197.558 +  std::cout << T.realTime() << "s: Removing non tree arcs...\n";
 197.559 +  std::vector<Edge> remove;
 197.560 +  for (EdgeIt e(g); e != INVALID; ++e) {
 197.561 +    if (!tree[e]) remove.push_back(e);
 197.562 +  }
 197.563 +  for(int i = 0; i < int(remove.size()); ++i) {
 197.564 +    g.erase(remove[i]);
 197.565 +  }
 197.566 +  std::cout << T.realTime() << "s: Done\n";
 197.567 +}
 197.568 +
 197.569 +void tsp2()
 197.570 +{
 197.571 +  std::cout << "Find a tree..." << std::endl;
 197.572 +
 197.573 +  minTree();
 197.574 +
 197.575 +  std::cout << "Total arc length (tree) : " << totalLen() << std::endl;
 197.576 +
 197.577 +  std::cout << "Make it Euler..." << std::endl;
 197.578 +
 197.579 +  {
 197.580 +    std::vector<Node> leafs;
 197.581 +    for(NodeIt n(g);n!=INVALID;++n)
 197.582 +      if(countIncEdges(g,n)%2==1) leafs.push_back(n);
 197.583 +
 197.584 +//    for(unsigned int i=0;i<leafs.size();i+=2)
 197.585 +//       g.addArc(leafs[i],leafs[i+1]);
 197.586 +
 197.587 +    std::vector<Parc> pedges;
 197.588 +    for(unsigned int i=0;i<leafs.size()-1;i++)
 197.589 +      for(unsigned int j=i+1;j<leafs.size();j++)
 197.590 +        {
 197.591 +          Node n=leafs[i];
 197.592 +          Node m=leafs[j];
 197.593 +          Parc p;
 197.594 +          p.a=n;
 197.595 +          p.b=m;
 197.596 +          p.len=(coords[m]-coords[n]).normSquare();
 197.597 +          pedges.push_back(p);
 197.598 +        }
 197.599 +    std::sort(pedges.begin(),pedges.end(),pedgeLess);
 197.600 +    for(unsigned int i=0;i<pedges.size();i++)
 197.601 +      if(countIncEdges(g,pedges[i].a)%2 &&
 197.602 +         countIncEdges(g,pedges[i].b)%2)
 197.603 +        g.addEdge(pedges[i].a,pedges[i].b);
 197.604 +  }
 197.605 +
 197.606 +  for(NodeIt n(g);n!=INVALID;++n)
 197.607 +    if(countIncEdges(g,n)%2 || countIncEdges(g,n)==0 )
 197.608 +      std::cout << "GEBASZ!!!" << std::endl;
 197.609 +
 197.610 +  for(EdgeIt e(g);e!=INVALID;++e)
 197.611 +    if(g.u(e)==g.v(e))
 197.612 +      std::cout << "LOOP GEBASZ!!!" << std::endl;
 197.613 +
 197.614 +  std::cout << "Number of arcs : " << countEdges(g) << std::endl;
 197.615 +
 197.616 +  std::cout << "Total arc length (euler) : " << totalLen() << std::endl;
 197.617 +
 197.618 +  ListGraph::EdgeMap<Arc> enext(g);
 197.619 +  {
 197.620 +    EulerIt<ListGraph> e(g);
 197.621 +    Arc eo=e;
 197.622 +    Arc ef=e;
 197.623 +//     std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl;
 197.624 +    for(++e;e!=INVALID;++e)
 197.625 +      {
 197.626 +//         std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl;
 197.627 +        enext[eo]=e;
 197.628 +        eo=e;
 197.629 +      }
 197.630 +    enext[eo]=ef;
 197.631 +  }
 197.632 +
 197.633 +  std::cout << "Creating a tour from that..." << std::endl;
 197.634 +
 197.635 +  int nnum = countNodes(g);
 197.636 +  int ednum = countEdges(g);
 197.637 +
 197.638 +  for(Arc p=enext[EdgeIt(g)];ednum>nnum;p=enext[p])
 197.639 +    {
 197.640 +//       std::cout << "Checking arc " << g.id(p) << std::endl;
 197.641 +      Arc e=enext[p];
 197.642 +      Arc f=enext[e];
 197.643 +      Node n2=g.source(f);
 197.644 +      Node n1=g.oppositeNode(n2,e);
 197.645 +      Node n3=g.oppositeNode(n2,f);
 197.646 +      if(countIncEdges(g,n2)>2)
 197.647 +        {
 197.648 +//           std::cout << "Remove an Arc" << std::endl;
 197.649 +          Arc ff=enext[f];
 197.650 +          g.erase(e);
 197.651 +          g.erase(f);
 197.652 +          if(n1!=n3)
 197.653 +            {
 197.654 +              Arc ne=g.direct(g.addEdge(n1,n3),n1);
 197.655 +              enext[p]=ne;
 197.656 +              enext[ne]=ff;
 197.657 +              ednum--;
 197.658 +            }
 197.659 +          else {
 197.660 +            enext[p]=ff;
 197.661 +            ednum-=2;
 197.662 +          }
 197.663 +        }
 197.664 +    }
 197.665 +
 197.666 +  std::cout << "Total arc length (tour) : " << totalLen() << std::endl;
 197.667 +
 197.668 +  std::cout << "2-opt the tour..." << std::endl;
 197.669 +
 197.670 +  tsp_improve();
 197.671 +
 197.672 +  std::cout << "Total arc length (2-opt tour) : " << totalLen() << std::endl;
 197.673 +}
 197.674 +
 197.675 +
 197.676 +int main(int argc,const char **argv)
 197.677 +{
 197.678 +  ArgParser ap(argc,argv);
 197.679 +
 197.680 +//   bool eps;
 197.681 +  bool disc_d, square_d, gauss_d;
 197.682 +//   bool tsp_a,two_a,tree_a;
 197.683 +  int num_of_cities=1;
 197.684 +  double area=1;
 197.685 +  N=100;
 197.686 +//   girth=10;
 197.687 +  std::string ndist("disc");
 197.688 +  ap.refOption("n", "Number of nodes (default is 100)", N)
 197.689 +    .intOption("g", "Girth parameter (default is 10)", 10)
 197.690 +    .refOption("cities", "Number of cities (default is 1)", num_of_cities)
 197.691 +    .refOption("area", "Full relative area of the cities (default is 1)", area)
 197.692 +    .refOption("disc", "Nodes are evenly distributed on a unit disc (default)",
 197.693 +               disc_d)
 197.694 +    .optionGroup("dist", "disc")
 197.695 +    .refOption("square", "Nodes are evenly distributed on a unit square",
 197.696 +               square_d)
 197.697 +    .optionGroup("dist", "square")
 197.698 +    .refOption("gauss", "Nodes are located according to a two-dim Gauss "
 197.699 +               "distribution", gauss_d)
 197.700 +    .optionGroup("dist", "gauss")
 197.701 +    .onlyOneGroup("dist")
 197.702 +    .boolOption("eps", "Also generate .eps output (<prefix>.eps)")
 197.703 +    .boolOption("nonodes", "Draw only the edges in the generated .eps output")
 197.704 +    .boolOption("dir", "Directed graph is generated (each edge is replaced by "
 197.705 +                "two directed arcs)")
 197.706 +    .boolOption("2con", "Create a two connected planar graph")
 197.707 +    .optionGroup("alg","2con")
 197.708 +    .boolOption("tree", "Create a min. cost spanning tree")
 197.709 +    .optionGroup("alg","tree")
 197.710 +    .boolOption("tsp", "Create a TSP tour")
 197.711 +    .optionGroup("alg","tsp")
 197.712 +    .boolOption("tsp2", "Create a TSP tour (tree based)")
 197.713 +    .optionGroup("alg","tsp2")
 197.714 +    .boolOption("dela", "Delaunay triangulation graph")
 197.715 +    .optionGroup("alg","dela")
 197.716 +    .onlyOneGroup("alg")
 197.717 +    .boolOption("rand", "Use time seed for random number generator")
 197.718 +    .optionGroup("rand", "rand")
 197.719 +    .intOption("seed", "Random seed", -1)
 197.720 +    .optionGroup("rand", "seed")
 197.721 +    .onlyOneGroup("rand")
 197.722 +    .other("[prefix]","Prefix of the output files. Default is 'lgf-gen-out'")
 197.723 +    .run();
 197.724 +
 197.725 +  if (ap["rand"]) {
 197.726 +    int seed = int(time(0));
 197.727 +    std::cout << "Random number seed: " << seed << std::endl;
 197.728 +    rnd = Random(seed);
 197.729 +  }
 197.730 +  if (ap.given("seed")) {
 197.731 +    int seed = ap["seed"];
 197.732 +    std::cout << "Random number seed: " << seed << std::endl;
 197.733 +    rnd = Random(seed);
 197.734 +  }
 197.735 +
 197.736 +  std::string prefix;
 197.737 +  switch(ap.files().size())
 197.738 +    {
 197.739 +    case 0:
 197.740 +      prefix="lgf-gen-out";
 197.741 +      break;
 197.742 +    case 1:
 197.743 +      prefix=ap.files()[0];
 197.744 +      break;
 197.745 +    default:
 197.746 +      std::cerr << "\nAt most one prefix can be given\n\n";
 197.747 +      exit(1);
 197.748 +    }
 197.749 +
 197.750 +  double sum_sizes=0;
 197.751 +  std::vector<double> sizes;
 197.752 +  std::vector<double> cum_sizes;
 197.753 +  for(int s=0;s<num_of_cities;s++)
 197.754 +    {
 197.755 +      //         sum_sizes+=rnd.exponential();
 197.756 +      double d=rnd();
 197.757 +      sum_sizes+=d;
 197.758 +      sizes.push_back(d);
 197.759 +      cum_sizes.push_back(sum_sizes);
 197.760 +    }
 197.761 +  int i=0;
 197.762 +  for(int s=0;s<num_of_cities;s++)
 197.763 +    {
 197.764 +      Point center=(num_of_cities==1?Point(0,0):rnd.disc());
 197.765 +      if(gauss_d)
 197.766 +        for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
 197.767 +          Node n=g.addNode();
 197.768 +          nodes.push_back(n);
 197.769 +          coords[n]=center+rnd.gauss2()*area*
 197.770 +            std::sqrt(sizes[s]/sum_sizes);
 197.771 +        }
 197.772 +      else if(square_d)
 197.773 +        for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
 197.774 +          Node n=g.addNode();
 197.775 +          nodes.push_back(n);
 197.776 +          coords[n]=center+Point(rnd()*2-1,rnd()*2-1)*area*
 197.777 +            std::sqrt(sizes[s]/sum_sizes);
 197.778 +        }
 197.779 +      else if(disc_d || true)
 197.780 +        for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
 197.781 +          Node n=g.addNode();
 197.782 +          nodes.push_back(n);
 197.783 +          coords[n]=center+rnd.disc()*area*
 197.784 +            std::sqrt(sizes[s]/sum_sizes);
 197.785 +        }
 197.786 +    }
 197.787 +
 197.788 +//   for (ListGraph::NodeIt n(g); n != INVALID; ++n) {
 197.789 +//     std::cerr << coords[n] << std::endl;
 197.790 +//   }
 197.791 +
 197.792 +  if(ap["tsp"]) {
 197.793 +    tsp();
 197.794 +    std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
 197.795 +  }
 197.796 +  if(ap["tsp2"]) {
 197.797 +    tsp2();
 197.798 +    std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
 197.799 +  }
 197.800 +  else if(ap["2con"]) {
 197.801 +    std::cout << "Make triangles\n";
 197.802 +    //   triangle();
 197.803 +    sparseTriangle(ap["g"]);
 197.804 +    std::cout << "Make it sparser\n";
 197.805 +    sparse2(ap["g"]);
 197.806 +  }
 197.807 +  else if(ap["tree"]) {
 197.808 +    minTree();
 197.809 +  }
 197.810 +  else if(ap["dela"]) {
 197.811 +    delaunay();
 197.812 +  }
 197.813 +
 197.814 +
 197.815 +  std::cout << "Number of nodes    : " << countNodes(g) << std::endl;
 197.816 +  std::cout << "Number of arcs    : " << countEdges(g) << std::endl;
 197.817 +  double tlen=0;
 197.818 +  for(EdgeIt e(g);e!=INVALID;++e)
 197.819 +    tlen+=std::sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
 197.820 +  std::cout << "Total arc length  : " << tlen << std::endl;
 197.821 +
 197.822 +  if(ap["eps"])
 197.823 +    graphToEps(g,prefix+".eps").scaleToA4().
 197.824 +      scale(600).nodeScale(.005).arcWidthScale(.001).preScale(false).
 197.825 +      coords(coords).hideNodes(ap.given("nonodes")).run();
 197.826 +
 197.827 +  if(ap["dir"])
 197.828 +    DigraphWriter<ListGraph>(g,prefix+".lgf").
 197.829 +      nodeMap("coordinates_x",scaleMap(xMap(coords),600)).
 197.830 +      nodeMap("coordinates_y",scaleMap(yMap(coords),600)).
 197.831 +      run();
 197.832 +  else GraphWriter<ListGraph>(g,prefix+".lgf").
 197.833 +         nodeMap("coordinates_x",scaleMap(xMap(coords),600)).
 197.834 +         nodeMap("coordinates_y",scaleMap(yMap(coords),600)).
 197.835 +         run();
 197.836 +}
 197.837 +