1.1 --- a/.hgignore Mon Jan 12 23:11:39 2009 +0100
1.2 +++ b/.hgignore Thu Nov 05 15:48:01 2009 +0100
1.3 @@ -22,6 +22,7 @@
1.4 lemon/libemon.la
1.5 lemon/stamp-h2
1.6 doc/Doxyfile
1.7 +cmake/version.cmake
1.8 .dirstamp
1.9 .libs/*
1.10 .deps/*
1.11 @@ -39,11 +40,11 @@
1.12 ^doc/.*\.tag
1.13 ^autom4te.cache/.*
1.14 ^build-aux/.*
1.15 -^objs.*/.*
1.16 +^.*objs.*/.*
1.17 ^test/[a-z_]*$
1.18 ^tools/[a-z-_]*$
1.19 ^demo/.*_demo$
1.20 -^build/.*
1.21 +^.*build.*/.*
1.22 ^doc/gen-images/.*
1.23 CMakeFiles
1.24 DartTestfile.txt
2.1 --- a/CMakeLists.txt Mon Jan 12 23:11:39 2009 +0100
2.2 +++ b/CMakeLists.txt Thu Nov 05 15:48:01 2009 +0100
2.3 @@ -1,34 +1,75 @@
2.4 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
2.5
2.6 SET(PROJECT_NAME "LEMON")
2.7 -SET(PROJECT_VERSION "hg-tip" CACHE STRING "The version string.")
2.8 -
2.9 PROJECT(${PROJECT_NAME})
2.10
2.11 -SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
2.12 +IF(EXISTS ${PROJECT_SOURCE_DIR}/cmake/version.cmake)
2.13 + INCLUDE(${PROJECT_SOURCE_DIR}/cmake/version.cmake)
2.14 +ELSEIF(DEFINED ENV{LEMON_VERSION})
2.15 + SET(LEMON_VERSION $ENV{LEMON_VERSION} CACHE STRING "LEMON version string.")
2.16 +ELSE()
2.17 + EXECUTE_PROCESS(
2.18 + COMMAND hg id -i
2.19 + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
2.20 + OUTPUT_VARIABLE HG_REVISION
2.21 + ERROR_QUIET
2.22 + OUTPUT_STRIP_TRAILING_WHITESPACE
2.23 + )
2.24 + IF(HG_REVISION STREQUAL "")
2.25 + SET(HG_REVISION "hg-tip")
2.26 + ENDIF()
2.27 + SET(LEMON_VERSION ${HG_REVISION} CACHE STRING "LEMON version string.")
2.28 +ENDIF()
2.29
2.30 -INCLUDE(FindDoxygen)
2.31 -INCLUDE(FindGhostscript)
2.32 +SET(PROJECT_VERSION ${LEMON_VERSION})
2.33 +
2.34 +SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
2.35 +
2.36 +FIND_PACKAGE(Doxygen)
2.37 +FIND_PACKAGE(Ghostscript)
2.38 +FIND_PACKAGE(GLPK 4.33)
2.39 +FIND_PACKAGE(CPLEX)
2.40 +FIND_PACKAGE(COIN)
2.41 +
2.42 +INCLUDE(CheckTypeSize)
2.43 +CHECK_TYPE_SIZE("long long" LONG_LONG)
2.44 +SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
2.45 +
2.46 +INCLUDE(FindPythonInterp)
2.47
2.48 ENABLE_TESTING()
2.49
2.50 ADD_SUBDIRECTORY(lemon)
2.51 -ADD_SUBDIRECTORY(demo)
2.52 -ADD_SUBDIRECTORY(doc)
2.53 -ADD_SUBDIRECTORY(test)
2.54 +IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
2.55 + ADD_SUBDIRECTORY(demo)
2.56 + ADD_SUBDIRECTORY(tools)
2.57 + ADD_SUBDIRECTORY(doc)
2.58 + ADD_SUBDIRECTORY(test)
2.59 +ENDIF()
2.60
2.61 -IF(WIN32)
2.62 - INSTALL(FILES ${CMAKE_SOURCE_DIR}/cmake/nsis/lemon.ico
2.63 - DESTINATION bin)
2.64 -ENDIF(WIN32)
2.65 +CONFIGURE_FILE(
2.66 + ${PROJECT_SOURCE_DIR}/cmake/LEMONConfig.cmake.in
2.67 + ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
2.68 + @ONLY
2.69 +)
2.70 +IF(UNIX)
2.71 + INSTALL(
2.72 + FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
2.73 + DESTINATION share/lemon/cmake
2.74 + )
2.75 +ELSEIF(WIN32)
2.76 + INSTALL(
2.77 + FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
2.78 + DESTINATION cmake
2.79 + )
2.80 +ENDIF()
2.81
2.82 -IF(WIN32)
2.83 +IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR} AND WIN32)
2.84 SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
2.85 - SET(CPACK_PACKAGE_VENDOR
2.86 - "EGRES - Egervary Research Group on Combinatorial Optimization")
2.87 + SET(CPACK_PACKAGE_VENDOR "EGRES")
2.88 SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
2.89 - "LEMON - Library of Efficient Models and Optimization in Networks")
2.90 - SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
2.91 + "LEMON - Library for Efficient Modeling and Optimization in Networks")
2.92 + SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
2.93
2.94 SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
2.95
2.96 @@ -37,48 +78,50 @@
2.97 SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
2.98 "${PROJECT_NAME} ${PROJECT_VERSION}")
2.99
2.100 - # Variables to generate a component-based installer.
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 "Static library")
2.106 - #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
2.107 + SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
2.108 + SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
2.109 + SET(CPACK_COMPONENT_BIN_DISPLAY_NAME "Command line utilities")
2.110 + SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
2.111
2.112 - #SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
2.113 - # "C++ header files for use with the LEMON library")
2.114 - #SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
2.115 - # "Static library used to build programs with LEMON")
2.116 - #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
2.117 - # "Doxygen generated documentation")
2.118 + SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
2.119 + "C++ header files")
2.120 + SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
2.121 + "DLL and import library")
2.122 + SET(CPACK_COMPONENT_BIN_DESCRIPTION
2.123 + "Command line utilities")
2.124 + SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
2.125 + "Doxygen generated documentation")
2.126
2.127 - #SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
2.128 + SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
2.129
2.130 - #SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
2.131 - #SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
2.132 - #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
2.133 + SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
2.134 + SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
2.135 + SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
2.136
2.137 - #SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
2.138 - # "Components needed to develop software using LEMON")
2.139 - #SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
2.140 - # "Documentation of LEMON")
2.141 + SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
2.142 + "Components needed to develop software using LEMON")
2.143 + SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
2.144 + "Documentation of LEMON")
2.145
2.146 - #SET(CPACK_ALL_INSTALL_TYPES Full Developer)
2.147 + SET(CPACK_ALL_INSTALL_TYPES Full Developer)
2.148
2.149 - #SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
2.150 - #SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
2.151 - #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
2.152 + SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
2.153 + SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
2.154 + SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
2.155
2.156 SET(CPACK_GENERATOR "NSIS")
2.157 - SET(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/lemon.ico")
2.158 - SET(CPACK_NSIS_MUI_UNIICON "${CMAKE_SOURCE_DIR}/cmake/nsis/uninstall.ico")
2.159 - #SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
2.160 + SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis/lemon.ico")
2.161 + SET(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/cmake/nsis/uninstall.ico")
2.162 + #SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
2.163 SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico")
2.164 SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
2.165 SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu")
2.166 SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lemon.cs.elte.hu")
2.167 SET(CPACK_NSIS_CONTACT "lemon-user@lemon.cs.elte.hu")
2.168 SET(CPACK_NSIS_CREATE_ICONS_EXTRA "
2.169 - CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\doc\\\\index.html\\\"
2.170 + CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\share\\\\doc\\\\index.html\\\"
2.171 ")
2.172 SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
2.173 !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
2.174 @@ -86,4 +129,4 @@
2.175 ")
2.176
2.177 INCLUDE(CPack)
2.178 -ENDIF(WIN32)
2.179 +ENDIF()
3.1 --- a/INSTALL Mon Jan 12 23:11:39 2009 +0100
3.2 +++ b/INSTALL Thu Nov 05 15:48:01 2009 +0100
3.3 @@ -5,6 +5,12 @@
3.4 tarballs and successfully extracted it. The latest version of LEMON is
3.5 available at our web page (http://lemon.cs.elte.hu/).
3.6
3.7 +LEMON provides two different build environments, one is based on "autotool",
3.8 +while the other is based on "cmake". This file contains instructions only for
3.9 +the former one, which is the recommended build environment on Linux, Mac OSX
3.10 +and other unices or if you use Cygwin on Windows. For cmake installation
3.11 +instructions visit http://lemon.cs.elte.hu.
3.12 +
3.13 In order to install LEMON from the extracted source tarball you have to
3.14 issue the following commands:
3.15
3.16 @@ -21,8 +27,8 @@
3.17 3. `make'
3.18
3.19 This command compiles the non-template part of LEMON into libemon.a
3.20 - file. It also compiles the programs in the tools and demo subdirectories
3.21 - when enabled.
3.22 + file. It also compiles the programs in the tools subdirectory by
3.23 + default.
3.24
3.25 4. `make check'
3.26
3.27 @@ -69,14 +75,6 @@
3.28
3.29 Set the installation prefix to PREFIX. By default it is /usr/local.
3.30
3.31 ---enable-demo
3.32 -
3.33 - Build the examples in the demo subdirectory.
3.34 -
3.35 ---disable-demo
3.36 -
3.37 - Do not build the examples in the demo subdirectory (default).
3.38 -
3.39 --enable-tools
3.40
3.41 Build the programs in the tools subdirectory (default).
3.42 @@ -152,3 +150,26 @@
3.43 --without-soplex
3.44
3.45 Disable SoPlex support.
3.46 +
3.47 +--with-coin[=PREFIX]
3.48 +
3.49 + Enable support for COIN-OR solvers (CLP and CBC). You should
3.50 + specify the prefix too. (by default, COIN-OR tools install
3.51 + themselves to the source code directory). This command enables the
3.52 + solvers that are actually found.
3.53 +
3.54 +--with-coin-includedir=DIR
3.55 +
3.56 + The directory where the COIN-OR header files are located. This is
3.57 + only useful when the COIN-OR headers and libraries are not under
3.58 + the same prefix (which is unlikely).
3.59 +
3.60 +--with-coin-libdir=DIR
3.61 +
3.62 + The directory where the COIN-OR libraries are located. This is only
3.63 + useful when the COIN-OR headers and libraries are not under the
3.64 + same prefix (which is unlikely).
3.65 +
3.66 +--without-coin
3.67 +
3.68 + Disable COIN-OR support.
4.1 --- a/LICENSE Mon Jan 12 23:11:39 2009 +0100
4.2 +++ b/LICENSE Thu Nov 05 15:48:01 2009 +0100
4.3 @@ -1,10 +1,14 @@
4.4 -LEMON code without an explicit copyright is covered by the following
4.5 +LEMON code without an explicit copyright notice is covered by the following
4.6 copyright/license.
4.7
4.8 Copyright (C) 2003-2009 Egervary Jeno Kombinatorikus Optimalizalasi
4.9 Kutatocsoport (Egervary Combinatorial Optimization Research Group,
4.10 EGRES).
4.11
4.12 +===========================================================================
4.13 +Boost Software License, Version 1.0
4.14 +===========================================================================
4.15 +
4.16 Permission is hereby granted, free of charge, to any person or organization
4.17 obtaining a copy of the software and accompanying documentation covered by
4.18 this license (the "Software") to use, reproduce, display, distribute,
4.19 @@ -26,8 +30,3 @@
4.20 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
4.21 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
4.22 DEALINGS IN THE SOFTWARE.
4.23 -
4.24 -===========================================================================
4.25 -This license is a verbatim copy of the Boost Software License, Version 1.0.
4.26 -
4.27 -
5.1 --- a/Makefile.am Mon Jan 12 23:11:39 2009 +0100
5.2 +++ b/Makefile.am Thu Nov 05 15:48:01 2009 +0100
5.3 @@ -11,8 +11,17 @@
5.4 m4/lx_check_cplex.m4 \
5.5 m4/lx_check_glpk.m4 \
5.6 m4/lx_check_soplex.m4 \
5.7 + m4/lx_check_coin.m4 \
5.8 CMakeLists.txt \
5.9 - cmake
5.10 + cmake/FindGhostscript.cmake \
5.11 + cmake/FindCPLEX.cmake \
5.12 + cmake/FindGLPK.cmake \
5.13 + cmake/FindCOIN.cmake \
5.14 + cmake/LEMONConfig.cmake.in \
5.15 + cmake/version.cmake.in \
5.16 + cmake/version.cmake \
5.17 + cmake/nsis/lemon.ico \
5.18 + cmake/nsis/uninstall.ico
5.19
5.20 pkgconfigdir = $(libdir)/pkgconfig
5.21 lemondir = $(pkgincludedir)
5.22 @@ -34,9 +43,13 @@
5.23 include lemon/Makefile.am
5.24 include test/Makefile.am
5.25 include doc/Makefile.am
5.26 -include demo/Makefile.am
5.27 include tools/Makefile.am
5.28
5.29 +DIST_SUBDIRS = demo
5.30 +
5.31 +demo:
5.32 + $(MAKE) $(AM_MAKEFLAGS) -C demo
5.33 +
5.34 MRPROPERFILES = \
5.35 aclocal.m4 \
5.36 config.h.in \
5.37 @@ -63,4 +76,4 @@
5.38 zcat $(PACKAGE)-$(VERSION).tar.gz | \
5.39 bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
5.40
5.41 -.PHONY: mrproper dist-bz2 distcheck-bz2
5.42 +.PHONY: demo mrproper dist-bz2 distcheck-bz2
6.1 --- a/NEWS Mon Jan 12 23:11:39 2009 +0100
6.2 +++ b/NEWS Thu Nov 05 15:48:01 2009 +0100
6.3 @@ -1,3 +1,97 @@
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,
6.94 + http://www.coin-or.org) project is an initiative to spur the
6.95 + development of open-source software for the operations research
6.96 + community.
6.97 +
6.98 2008-10-13 Version 1.0 released
6.99
6.100 This is the first stable release of LEMON. Compared to the 0.x
7.1 --- a/README Mon Jan 12 23:11:39 2009 +0100
7.2 +++ b/README Thu Nov 05 15:48: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:48: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:48: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:48: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 --- a/cmake/FindGhostscript.cmake Mon Jan 12 23:11:39 2009 +0100
11.2 +++ b/cmake/FindGhostscript.cmake Thu Nov 05 15:48:01 2009 +0100
11.3 @@ -3,7 +3,7 @@
11.4 FIND_PROGRAM(GHOSTSCRIPT_EXECUTABLE
11.5 NAMES gs gswin32c
11.6 PATHS "$ENV{ProgramFiles}/gs"
11.7 - PATH_SUFFIXES gs8.61/bin gs8.62/bin
11.8 + PATH_SUFFIXES gs8.61/bin gs8.62/bin gs8.63/bin gs8.64/bin gs8.65/bin
11.9 DOC "Ghostscript: PostScript and PDF language interpreter and previewer."
11.10 )
11.11
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/cmake/LEMONConfig.cmake.in Thu Nov 05 15:48:01 2009 +0100
12.3 @@ -0,0 +1,13 @@
12.4 +SET(LEMON_INCLUDE_DIR "@CMAKE_INSTALL_PREFIX@/include" CACHE PATH "LEMON include directory")
12.5 +SET(LEMON_INCLUDE_DIRS "${LEMON_INCLUDE_DIR}")
12.6 +
12.7 +IF(UNIX)
12.8 + SET(LEMON_LIB_NAME "libemon.a")
12.9 +ELSEIF(WIN32)
12.10 + SET(LEMON_LIB_NAME "lemon.lib")
12.11 +ENDIF(UNIX)
12.12 +
12.13 +SET(LEMON_LIBRARY "@CMAKE_INSTALL_PREFIX@/lib/${LEMON_LIB_NAME}" CACHE FILEPATH "LEMON library")
12.14 +SET(LEMON_LIBRARIES "${LEMON_LIBRARY}")
12.15 +
12.16 +MARK_AS_ADVANCED(LEMON_LIBRARY LEMON_INCLUDE_DIR)
13.1 Binary file cmake/nsis/lemon.ico has changed
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/cmake/version.cmake.in Thu Nov 05 15:48:01 2009 +0100
14.3 @@ -0,0 +1,1 @@
14.4 +SET(LEMON_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.")
15.1 --- a/configure.ac Mon Jan 12 23:11:39 2009 +0100
15.2 +++ b/configure.ac Thu Nov 05 15:48:01 2009 +0100
15.3 @@ -2,14 +2,17 @@
15.4
15.5 dnl Version information.
15.6 m4_define([lemon_version_number],
15.7 - [m4_normalize(esyscmd([echo ${LEMON_VERSION}]))])
15.8 + [m4_normalize(esyscmd([echo ${LEMON_VERSION}]))])
15.9 dnl m4_define([lemon_version_number], [])
15.10 m4_define([lemon_hg_path], [m4_normalize(esyscmd([./scripts/chg-len.py]))])
15.11 -m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i]))])
15.12 +m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i 2> /dev/null]))])
15.13 m4_define([lemon_version], [ifelse(lemon_version_number(),
15.14 - [],
15.15 - [lemon_hg_path().lemon_hg_revision()],
15.16 - [lemon_version_number()])])
15.17 + [],
15.18 + [ifelse(lemon_hg_revision(),
15.19 + [],
15.20 + [hg-tip],
15.21 + [lemon_hg_path().lemon_hg_revision()])],
15.22 + [lemon_version_number()])])
15.23
15.24 AC_PREREQ([2.59])
15.25 AC_INIT([LEMON], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon])
15.26 @@ -19,9 +22,17 @@
15.27 AC_CONFIG_SRCDIR([lemon/list_graph.h])
15.28 AC_CONFIG_HEADERS([config.h lemon/config.h])
15.29
15.30 +AC_DEFINE([LEMON_VERSION], [lemon_version()], [The version string])
15.31 +
15.32 dnl Do compilation tests using the C++ compiler.
15.33 AC_LANG([C++])
15.34
15.35 +dnl Check the existence of long long type.
15.36 +AC_CHECK_TYPE(long long, [long_long_found=yes], [long_long_found=no])
15.37 +if test x"$long_long_found" = x"yes"; then
15.38 + AC_DEFINE([LEMON_HAVE_LONG_LONG], [1], [Define to 1 if you have long long.])
15.39 +fi
15.40 +
15.41 dnl Checks for programs.
15.42 AC_PROG_CXX
15.43 AC_PROG_CXXCPP
15.44 @@ -30,6 +41,7 @@
15.45 AC_PROG_LIBTOOL
15.46
15.47 AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
15.48 +AC_CHECK_PROG([python_found],[python],[yes],[no])
15.49 AC_CHECK_PROG([gs_found],[gs],[yes],[no])
15.50
15.51 dnl Detect Intel compiler.
15.52 @@ -53,24 +65,11 @@
15.53 LX_CHECK_GLPK
15.54 LX_CHECK_CPLEX
15.55 LX_CHECK_SOPLEX
15.56 -LX_CHECK_CLP
15.57 +LX_CHECK_COIN
15.58
15.59 AM_CONDITIONAL([HAVE_LP], [test x"$lx_lp_found" = x"yes"])
15.60 AM_CONDITIONAL([HAVE_MIP], [test x"$lx_mip_found" = x"yes"])
15.61
15.62 -dnl Disable/enable building the demo programs.
15.63 -AC_ARG_ENABLE([demo],
15.64 -AS_HELP_STRING([--enable-demo], [build the demo programs])
15.65 -AS_HELP_STRING([--disable-demo], [do not build the demo programs @<:@default@:>@]),
15.66 - [], [enable_demo=no])
15.67 -AC_MSG_CHECKING([whether to build the demo programs])
15.68 -if test x"$enable_demo" != x"no"; then
15.69 - AC_MSG_RESULT([yes])
15.70 -else
15.71 - AC_MSG_RESULT([no])
15.72 -fi
15.73 -AM_CONDITIONAL([WANT_DEMO], [test x"$enable_demo" != x"no"])
15.74 -
15.75 dnl Disable/enable building the binary tools.
15.76 AC_ARG_ENABLE([tools],
15.77 AS_HELP_STRING([--enable-tools], [build additional tools @<:@default@:>@])
15.78 @@ -100,10 +99,12 @@
15.79
15.80 dnl Add dependencies on files generated by configure.
15.81 AC_SUBST([CONFIG_STATUS_DEPENDENCIES],
15.82 - ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/lemon/lemon.pc.in'])
15.83 + ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in'])
15.84
15.85 AC_CONFIG_FILES([
15.86 Makefile
15.87 +demo/Makefile
15.88 +cmake/version.cmake
15.89 doc/Doxyfile
15.90 lemon/lemon.pc
15.91 ])
15.92 @@ -118,12 +119,14 @@
15.93 echo C++ compiler.................. : $CXX
15.94 echo C++ compiles flags............ : $WARNINGCXXFLAGS $CXXFLAGS
15.95 echo
15.96 +echo Compiler supports long long... : $long_long_found
15.97 +echo
15.98 echo GLPK support.................. : $lx_glpk_found
15.99 echo CPLEX support................. : $lx_cplex_found
15.100 echo SOPLEX support................ : $lx_soplex_found
15.101 echo CLP support................... : $lx_clp_found
15.102 +echo CBC support................... : $lx_cbc_found
15.103 echo
15.104 -echo Build demo programs........... : $enable_demo
15.105 echo Build additional tools........ : $enable_tools
15.106 echo
15.107 echo The packace will be installed in
16.1 --- a/demo/CMakeLists.txt Mon Jan 12 23:11:39 2009 +0100
16.2 +++ b/demo/CMakeLists.txt Thu Nov 05 15:48:01 2009 +0100
16.3 @@ -1,13 +1,19 @@
16.4 -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
16.5 +INCLUDE_DIRECTORIES(
16.6 + ${PROJECT_SOURCE_DIR}
16.7 + ${PROJECT_BINARY_DIR}
16.8 +)
16.9
16.10 -LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
16.11 +LINK_DIRECTORIES(
16.12 + ${PROJECT_BINARY_DIR}/lemon
16.13 +)
16.14
16.15 SET(DEMOS
16.16 arg_parser_demo
16.17 graph_to_eps_demo
16.18 - lgf_demo)
16.19 + lgf_demo
16.20 +)
16.21
16.22 FOREACH(DEMO_NAME ${DEMOS})
16.23 ADD_EXECUTABLE(${DEMO_NAME} ${DEMO_NAME}.cc)
16.24 TARGET_LINK_LIBRARIES(${DEMO_NAME} lemon)
16.25 -ENDFOREACH(DEMO_NAME)
16.26 +ENDFOREACH()
17.1 --- a/demo/Makefile.am Mon Jan 12 23:11:39 2009 +0100
17.2 +++ b/demo/Makefile.am Thu Nov 05 15:48:01 2009 +0100
17.3 @@ -1,16 +1,17 @@
17.4 -EXTRA_DIST += \
17.5 - demo/CMakeLists.txt \
17.6 - demo/digraph.lgf
17.7 +AM_CXXFLAGS = $(WARNINGCXXFLAGS)
17.8
17.9 -if WANT_DEMO
17.10 +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
17.11 +LDADD = $(top_builddir)/lemon/libemon.la
17.12
17.13 -noinst_PROGRAMS += \
17.14 - demo/arg_parser_demo \
17.15 - demo/graph_to_eps_demo \
17.16 - demo/lgf_demo
17.17 +EXTRA_DIST = \
17.18 + CMakeLists.txt \
17.19 + digraph.lgf
17.20
17.21 -endif WANT_DEMO
17.22 +noinst_PROGRAMS = \
17.23 + arg_parser_demo \
17.24 + graph_to_eps_demo \
17.25 + lgf_demo
17.26
17.27 -demo_arg_parser_demo_SOURCES = demo/arg_parser_demo.cc
17.28 -demo_graph_to_eps_demo_SOURCES = demo/graph_to_eps_demo.cc
17.29 -demo_lgf_demo_SOURCES = demo/lgf_demo.cc
17.30 +arg_parser_demo_SOURCES = arg_parser_demo.cc
17.31 +graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc
17.32 +lgf_demo_SOURCES = lgf_demo.cc
18.1 --- a/demo/graph_to_eps_demo.cc Mon Jan 12 23:11:39 2009 +0100
18.2 +++ b/demo/graph_to_eps_demo.cc Thu Nov 05 15:48:01 2009 +0100
18.3 @@ -182,7 +182,7 @@
18.4 ListDigraph::NodeMap<int> hcolors(h);
18.5 ListDigraph::NodeMap<Point> hcoords(h);
18.6
18.7 - int cols=int(sqrt(double(palette.size())));
18.8 + int cols=int(std::sqrt(double(palette.size())));
18.9 for(int i=0;i<int(paletteW.size());i++) {
18.10 Node n=h.addNode();
18.11 hcoords[n]=Point(1+i%cols,1+i/cols);
19.1 --- a/doc/CMakeLists.txt Mon Jan 12 23:11:39 2009 +0100
19.2 +++ b/doc/CMakeLists.txt Thu Nov 05 15:48:01 2009 +0100
19.3 @@ -1,43 +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/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
19.52 - 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.53 - 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.54 - 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.55 - 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.56 - 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.57 - COMMAND rm -rf html
19.58 - COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
19.59 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
19.60 + INSTALL(
19.61 + DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
19.62 + DESTINATION share/doc/lemon/html
19.63 + COMPONENT html_documentation
19.64 + )
19.65 ELSEIF(WIN32)
19.66 - ADD_CUSTOM_TARGET(html
19.67 - COMMAND if exist gen-images rmdir /s /q gen-images
19.68 - COMMAND mkdir gen-images
19.69 - 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.70 - 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.71 - 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.72 - 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.73 - 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.74 - COMMAND if exist html rmdir /s /q html
19.75 - COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
19.76 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
19.77 - ENDIF(UNIX)
19.78 -ENDIF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
19.79 + INSTALL(
19.80 + DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
19.81 + DESTINATION doc
19.82 + COMPONENT html_documentation
19.83 + )
19.84 + ENDIF()
19.85
19.86 -INSTALL(
19.87 - DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
19.88 - DESTINATION doc
19.89 - COMPONENT html_documentation)
19.90 +ENDIF()
20.1 --- a/doc/Doxyfile.in Mon Jan 12 23:11:39 2009 +0100
20.2 +++ b/doc/Doxyfile.in Thu Nov 05 15:48: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 @@ -91,7 +90,8 @@
20.18 "@abs_top_srcdir@/lemon/concepts" \
20.19 "@abs_top_srcdir@/demo" \
20.20 "@abs_top_srcdir@/tools" \
20.21 - "@abs_top_srcdir@/test/test_tools.h"
20.22 + "@abs_top_srcdir@/test/test_tools.h" \
20.23 + "@abs_top_builddir@/doc/references.dox"
20.24 INPUT_ENCODING = UTF-8
20.25 FILE_PATTERNS = *.h \
20.26 *.cc \
20.27 @@ -223,7 +223,7 @@
20.28 EXPAND_AS_DEFINED =
20.29 SKIP_FUNCTION_MACROS = YES
20.30 #---------------------------------------------------------------------------
20.31 -# Configuration::additions related to external references
20.32 +# Options related to the search engine
20.33 #---------------------------------------------------------------------------
20.34 TAGFILES = "@abs_top_srcdir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/ "
20.35 GENERATE_TAGFILE = html/lemon.tag
21.1 --- a/doc/Makefile.am Mon Jan 12 23:11:39 2009 +0100
21.2 +++ b/doc/Makefile.am Thu Nov 05 15:48:01 2009 +0100
21.3 @@ -8,6 +8,7 @@
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 @@ -21,8 +22,17 @@
21.12 nodeshape_3.eps \
21.13 nodeshape_4.eps
21.14
21.15 +DOC_EPS_IMAGES27 = \
21.16 + bipartite_matching.eps \
21.17 + bipartite_partitions.eps \
21.18 + connected_components.eps \
21.19 + edge_biconnected_components.eps \
21.20 + node_biconnected_components.eps \
21.21 + strongly_connected_components.eps
21.22 +
21.23 DOC_EPS_IMAGES = \
21.24 - $(DOC_EPS_IMAGES18)
21.25 + $(DOC_EPS_IMAGES18) \
21.26 + $(DOC_EPS_IMAGES27)
21.27
21.28 DOC_PNG_IMAGES = \
21.29 $(DOC_EPS_IMAGES:%.eps=doc/gen-images/%.png)
21.30 @@ -45,7 +55,30 @@
21.31 exit 1; \
21.32 fi
21.33
21.34 -html-local: $(DOC_PNG_IMAGES)
21.35 +$(DOC_EPS_IMAGES27:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
21.36 + -mkdir doc/gen-images
21.37 + if test ${gs_found} = yes; then \
21.38 + $(GS_COMMAND) -sDEVICE=pngalpha -r27 -sOutputFile=$@ $<; \
21.39 + else \
21.40 + echo; \
21.41 + echo "Ghostscript not found."; \
21.42 + echo; \
21.43 + exit 1; \
21.44 + fi
21.45 +
21.46 +references.dox: doc/references.bib
21.47 + if test ${python_found} = yes; then \
21.48 + cd doc; \
21.49 + python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \
21.50 + cd ..; \
21.51 + else \
21.52 + echo; \
21.53 + echo "Python not found."; \
21.54 + echo; \
21.55 + exit 1; \
21.56 + fi
21.57 +
21.58 +html-local: $(DOC_PNG_IMAGES) references.dox
21.59 if test ${doxygen_found} = yes; then \
21.60 cd doc; \
21.61 doxygen Doxyfile; \
21.62 @@ -70,19 +103,19 @@
21.63
21.64 install-html-local: doc/html
21.65 @$(NORMAL_INSTALL)
21.66 - $(mkinstalldirs) $(DESTDIR)$(htmldir)/docs
21.67 + $(mkinstalldirs) $(DESTDIR)$(htmldir)/html
21.68 for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
21.69 f="`echo $$p | sed -e 's|^.*/||'`"; \
21.70 - echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/docs/$$f"; \
21.71 - $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/docs/$$f; \
21.72 + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f"; \
21.73 + $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f; \
21.74 done
21.75
21.76 uninstall-local:
21.77 @$(NORMAL_UNINSTALL)
21.78 for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
21.79 f="`echo $$p | sed -e 's|^.*/||'`"; \
21.80 - echo " rm -f $(DESTDIR)$(htmldir)/docs/$$f"; \
21.81 - rm -f $(DESTDIR)$(htmldir)/docs/$$f; \
21.82 + echo " rm -f $(DESTDIR)$(htmldir)/html/$$f"; \
21.83 + rm -f $(DESTDIR)$(htmldir)/html/$$f; \
21.84 done
21.85
21.86 .PHONY: update-external-tags
22.1 --- a/doc/groups.dox Mon Jan 12 23:11:39 2009 +0100
22.2 +++ b/doc/groups.dox Thu Nov 05 15:48:01 2009 +0100
22.3 @@ -20,7 +20,7 @@
22.4
22.5 /**
22.6 @defgroup datas Data Structures
22.7 -This group describes the several data structures implemented in LEMON.
22.8 +This group contains the several data structures implemented in LEMON.
22.9 */
22.10
22.11 /**
22.12 @@ -138,21 +138,11 @@
22.13 */
22.14
22.15 /**
22.16 -@defgroup semi_adaptors Semi-Adaptor Classes for Graphs
22.17 -@ingroup graphs
22.18 -\brief Graph types between real graphs and graph adaptors.
22.19 -
22.20 -This group describes some graph types between real graphs and graph adaptors.
22.21 -These classes wrap graphs to give new functionality as the adaptors do it.
22.22 -On the other hand they are not light-weight structures as the adaptors.
22.23 -*/
22.24 -
22.25 -/**
22.26 @defgroup maps Maps
22.27 @ingroup datas
22.28 \brief Map structures implemented in LEMON.
22.29
22.30 -This group describes the map structures implemented in LEMON.
22.31 +This group contains the map structures implemented in LEMON.
22.32
22.33 LEMON provides several special purpose maps and map adaptors that e.g. combine
22.34 new maps from existing ones.
22.35 @@ -165,7 +155,7 @@
22.36 @ingroup maps
22.37 \brief Special graph-related maps.
22.38
22.39 -This group describes maps that are specifically designed to assign
22.40 +This group contains maps that are specifically designed to assign
22.41 values to the nodes and arcs/edges of graphs.
22.42
22.43 If you are looking for the standard graph maps (\c NodeMap, \c ArcMap,
22.44 @@ -177,7 +167,7 @@
22.45 \ingroup maps
22.46 \brief Tools to create new maps from existing ones
22.47
22.48 -This group describes map adaptors that are used to create "implicit"
22.49 +This group contains map adaptors that are used to create "implicit"
22.50 maps from other maps.
22.51
22.52 Most of them are \ref concepts::ReadMap "read-only maps".
22.53 @@ -236,19 +226,11 @@
22.54 */
22.55
22.56 /**
22.57 -@defgroup matrices Matrices
22.58 -@ingroup datas
22.59 -\brief Two dimensional data storages implemented in LEMON.
22.60 -
22.61 -This group describes two dimensional data storages implemented in LEMON.
22.62 -*/
22.63 -
22.64 -/**
22.65 @defgroup paths Path Structures
22.66 @ingroup datas
22.67 \brief %Path structures implemented in LEMON.
22.68
22.69 -This group describes the path structures implemented in LEMON.
22.70 +This group contains the path structures implemented in LEMON.
22.71
22.72 LEMON provides flexible data structures to work with paths.
22.73 All of them have similar interfaces and they can be copied easily with
22.74 @@ -256,7 +238,36 @@
22.75 efficient to have e.g. the Dijkstra algorithm to store its result in
22.76 any kind of path structure.
22.77
22.78 -\sa lemon::concepts::Path
22.79 +\sa \ref concepts::Path "Path concept"
22.80 +*/
22.81 +
22.82 +/**
22.83 +@defgroup heaps Heap Structures
22.84 +@ingroup datas
22.85 +\brief %Heap structures implemented in LEMON.
22.86 +
22.87 +This group contains the heap structures implemented in LEMON.
22.88 +
22.89 +LEMON provides several heap classes. They are efficient implementations
22.90 +of the abstract data type \e priority \e queue. They store items with
22.91 +specified values called \e priorities in such a way that finding and
22.92 +removing the item with minimum priority are efficient.
22.93 +The basic operations are adding and erasing items, changing the priority
22.94 +of an item, etc.
22.95 +
22.96 +Heaps are crucial in several algorithms, such as Dijkstra and Prim.
22.97 +The heap implementations have the same interface, thus any of them can be
22.98 +used easily in such algorithms.
22.99 +
22.100 +\sa \ref concepts::Heap "Heap concept"
22.101 +*/
22.102 +
22.103 +/**
22.104 +@defgroup matrices Matrices
22.105 +@ingroup datas
22.106 +\brief Two dimensional data storages implemented in LEMON.
22.107 +
22.108 +This group contains two dimensional data storages implemented in LEMON.
22.109 */
22.110
22.111 /**
22.112 @@ -264,16 +275,38 @@
22.113 @ingroup datas
22.114 \brief Auxiliary data structures implemented in LEMON.
22.115
22.116 -This group describes some data structures implemented in LEMON in
22.117 +This group contains some data structures implemented in LEMON in
22.118 order to make it easier to implement combinatorial algorithms.
22.119 */
22.120
22.121 /**
22.122 +@defgroup geomdat Geometric Data Structures
22.123 +@ingroup auxdat
22.124 +\brief Geometric data structures implemented in LEMON.
22.125 +
22.126 +This group contains geometric data structures implemented in LEMON.
22.127 +
22.128 + - \ref lemon::dim2::Point "dim2::Point" implements a two dimensional
22.129 + vector with the usual operations.
22.130 + - \ref lemon::dim2::Box "dim2::Box" can be used to determine the
22.131 + rectangular bounding box of a set of \ref lemon::dim2::Point
22.132 + "dim2::Point"'s.
22.133 +*/
22.134 +
22.135 +/**
22.136 +@defgroup matrices Matrices
22.137 +@ingroup auxdat
22.138 +\brief Two dimensional data storages implemented in LEMON.
22.139 +
22.140 +This group contains two dimensional data storages implemented in LEMON.
22.141 +*/
22.142 +
22.143 +/**
22.144 @defgroup algs Algorithms
22.145 -\brief This group describes the several algorithms
22.146 +\brief This group contains the several algorithms
22.147 implemented in LEMON.
22.148
22.149 -This group describes the several algorithms
22.150 +This group contains the several algorithms
22.151 implemented in LEMON.
22.152 */
22.153
22.154 @@ -282,8 +315,9 @@
22.155 @ingroup algs
22.156 \brief Common graph search algorithms.
22.157
22.158 -This group describes the common graph search algorithms, namely
22.159 -\e breadth-first \e search (BFS) and \e depth-first \e search (DFS).
22.160 +This group contains the common graph search algorithms, namely
22.161 +\e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
22.162 +\ref clrs01algorithms.
22.163 */
22.164
22.165 /**
22.166 @@ -291,7 +325,8 @@
22.167 @ingroup algs
22.168 \brief Algorithms for finding shortest paths.
22.169
22.170 -This group describes the algorithms for finding shortest paths in digraphs.
22.171 +This group contains the algorithms for finding shortest paths in digraphs
22.172 +\ref clrs01algorithms.
22.173
22.174 - \ref Dijkstra algorithm for finding shortest paths from a source node
22.175 when all arc lengths are non-negative.
22.176 @@ -308,72 +343,83 @@
22.177 */
22.178
22.179 /**
22.180 +@defgroup spantree Minimum Spanning Tree Algorithms
22.181 +@ingroup algs
22.182 +\brief Algorithms for finding minimum cost spanning trees and arborescences.
22.183 +
22.184 +This group contains the algorithms for finding minimum cost spanning
22.185 +trees and arborescences \ref clrs01algorithms.
22.186 +*/
22.187 +
22.188 +/**
22.189 @defgroup max_flow Maximum Flow Algorithms
22.190 @ingroup algs
22.191 \brief Algorithms for finding maximum flows.
22.192
22.193 -This group describes the algorithms for finding maximum flows and
22.194 -feasible circulations.
22.195 +This group contains the algorithms for finding maximum flows and
22.196 +feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
22.197
22.198 The \e maximum \e flow \e problem is to find a flow of maximum value between
22.199 a single source and a single target. Formally, there is a \f$G=(V,A)\f$
22.200 -digraph, a \f$cap:A\rightarrow\mathbf{R}^+_0\f$ capacity function and
22.201 +digraph, a \f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function and
22.202 \f$s, t \in V\f$ source and target nodes.
22.203 -A maximum flow is an \f$f:A\rightarrow\mathbf{R}^+_0\f$ solution of the
22.204 +A maximum flow is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ solution of the
22.205 following optimization problem.
22.206
22.207 -\f[ \max\sum_{a\in\delta_{out}(s)}f(a) - \sum_{a\in\delta_{in}(s)}f(a) \f]
22.208 -\f[ \sum_{a\in\delta_{out}(v)} f(a) = \sum_{a\in\delta_{in}(v)} f(a)
22.209 - \qquad \forall v\in V\setminus\{s,t\} \f]
22.210 -\f[ 0 \leq f(a) \leq cap(a) \qquad \forall a\in A \f]
22.211 +\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f]
22.212 +\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu)
22.213 + \quad \forall u\in V\setminus\{s,t\} \f]
22.214 +\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
22.215
22.216 LEMON contains several algorithms for solving maximum flow problems:
22.217 -- \ref EdmondsKarp Edmonds-Karp algorithm.
22.218 -- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm.
22.219 -- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees.
22.220 -- \ref GoldbergTarjan Preflow push-relabel algorithm with dynamic trees.
22.221 +- \ref EdmondsKarp Edmonds-Karp algorithm
22.222 + \ref edmondskarp72theoretical.
22.223 +- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
22.224 + \ref goldberg88newapproach.
22.225 +- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
22.226 + \ref dinic70algorithm, \ref sleator83dynamic.
22.227 +- \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
22.228 + \ref goldberg88newapproach, \ref sleator83dynamic.
22.229
22.230 -In most cases the \ref Preflow "Preflow" algorithm provides the
22.231 +In most cases the \ref Preflow algorithm provides the
22.232 fastest method for computing a maximum flow. All implementations
22.233 -provides functions to also query the minimum cut, which is the dual
22.234 -problem of the maximum flow.
22.235 +also provide functions to query the minimum cut, which is the dual
22.236 +problem of maximum flow.
22.237 +
22.238 +\ref Circulation is a preflow push-relabel algorithm implemented directly
22.239 +for finding feasible circulations, which is a somewhat different problem,
22.240 +but it is strongly related to maximum flow.
22.241 +For more information, see \ref Circulation.
22.242 */
22.243
22.244 /**
22.245 -@defgroup min_cost_flow Minimum Cost Flow Algorithms
22.246 +@defgroup min_cost_flow_algs Minimum Cost Flow Algorithms
22.247 @ingroup algs
22.248
22.249 \brief Algorithms for finding minimum cost flows and circulations.
22.250
22.251 -This group describes the algorithms for finding minimum cost flows and
22.252 -circulations.
22.253 +This group contains the algorithms for finding minimum cost flows and
22.254 +circulations \ref amo93networkflows. For more information about this
22.255 +problem and its dual solution, see \ref min_cost_flow
22.256 +"Minimum Cost Flow Problem".
22.257
22.258 -The \e minimum \e cost \e flow \e problem is to find a feasible flow of
22.259 -minimum total cost from a set of supply nodes to a set of demand nodes
22.260 -in a network with capacity constraints and arc costs.
22.261 -Formally, let \f$G=(V,A)\f$ be a digraph,
22.262 -\f$lower, upper: A\rightarrow\mathbf{Z}^+_0\f$ denote the lower and
22.263 -upper bounds for the flow values on the arcs,
22.264 -\f$cost: A\rightarrow\mathbf{Z}^+_0\f$ denotes the cost per unit flow
22.265 -on the arcs, and
22.266 -\f$supply: V\rightarrow\mathbf{Z}\f$ denotes the supply/demand values
22.267 -of the nodes.
22.268 -A minimum cost flow is an \f$f:A\rightarrow\mathbf{R}^+_0\f$ solution of
22.269 -the following optimization problem.
22.270 +LEMON contains several algorithms for this problem.
22.271 + - \ref NetworkSimplex Primal Network Simplex algorithm with various
22.272 + pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
22.273 + - \ref CostScaling Push-Relabel and Augment-Relabel algorithms based on
22.274 + cost scaling \ref goldberg90approximation, \ref goldberg97efficient,
22.275 + \ref bunnagel98efficient.
22.276 + - \ref CapacityScaling Successive Shortest %Path algorithm with optional
22.277 + capacity scaling \ref edmondskarp72theoretical.
22.278 + - \ref CancelAndTighten The Cancel and Tighten algorithm
22.279 + \ref goldberg89cyclecanceling.
22.280 + - \ref CycleCanceling Cycle-Canceling algorithms
22.281 + \ref klein67primal, \ref goldberg89cyclecanceling.
22.282
22.283 -\f[ \min\sum_{a\in A} f(a) cost(a) \f]
22.284 -\f[ \sum_{a\in\delta_{out}(v)} f(a) - \sum_{a\in\delta_{in}(v)} f(a) =
22.285 - supply(v) \qquad \forall v\in V \f]
22.286 -\f[ lower(a) \leq f(a) \leq upper(a) \qquad \forall a\in A \f]
22.287 -
22.288 -LEMON contains several algorithms for solving minimum cost flow problems:
22.289 - - \ref CycleCanceling Cycle-canceling algorithms.
22.290 - - \ref CapacityScaling Successive shortest path algorithm with optional
22.291 - capacity scaling.
22.292 - - \ref CostScaling Push-relabel and augment-relabel algorithms based on
22.293 - cost scaling.
22.294 - - \ref NetworkSimplex Primal network simplex algorithm with various
22.295 - pivot strategies.
22.296 +In general NetworkSimplex is the most efficient implementation,
22.297 +but in special cases other algorithms could be faster.
22.298 +For example, if the total supply and/or capacities are rather small,
22.299 +CapacityScaling is usually the fastest algorithm (without effective scaling).
22.300 */
22.301
22.302 /**
22.303 @@ -382,7 +428,7 @@
22.304
22.305 \brief Algorithms for finding minimum cut in graphs.
22.306
22.307 -This group describes the algorithms for finding minimum cut in graphs.
22.308 +This group contains the algorithms for finding minimum cut in graphs.
22.309
22.310 The \e minimum \e cut \e problem is to find a non-empty and non-complete
22.311 \f$X\f$ subset of the nodes with minimum overall capacity on
22.312 @@ -391,7 +437,7 @@
22.313 cut is the \f$X\f$ solution of the next optimization problem:
22.314
22.315 \f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
22.316 - \sum_{uv\in A, u\in X, v\not\in X}cap(uv) \f]
22.317 + \sum_{uv\in A: u\in X, v\not\in X}cap(uv) \f]
22.318
22.319 LEMON contains several algorithms related to minimum cut problems:
22.320
22.321 @@ -399,7 +445,7 @@
22.322 in directed graphs.
22.323 - \ref NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
22.324 calculating minimum cut in undirected graphs.
22.325 -- \ref GomoryHuTree "Gomory-Hu tree computation" for calculating
22.326 +- \ref GomoryHu "Gomory-Hu tree computation" for calculating
22.327 all-pairs minimum cut in undirected graphs.
22.328
22.329 If you want to find minimum cut just between two distinict nodes,
22.330 @@ -407,27 +453,40 @@
22.331 */
22.332
22.333 /**
22.334 -@defgroup graph_prop Connectivity and Other Graph Properties
22.335 +@defgroup min_mean_cycle Minimum Mean Cycle Algorithms
22.336 @ingroup algs
22.337 -\brief Algorithms for discovering the graph properties
22.338 +\brief Algorithms for finding minimum mean cycles.
22.339
22.340 -This group describes the algorithms for discovering the graph properties
22.341 -like connectivity, bipartiteness, euler property, simplicity etc.
22.342 +This group contains the algorithms for finding minimum mean cycles
22.343 +\ref clrs01algorithms, \ref amo93networkflows.
22.344
22.345 -\image html edge_biconnected_components.png
22.346 -\image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
22.347 -*/
22.348 +The \e minimum \e mean \e cycle \e problem is to find a directed cycle
22.349 +of minimum mean length (cost) in a digraph.
22.350 +The mean length of a cycle is the average length of its arcs, i.e. the
22.351 +ratio between the total length of the cycle and the number of arcs on it.
22.352
22.353 -/**
22.354 -@defgroup planar Planarity Embedding and Drawing
22.355 -@ingroup algs
22.356 -\brief Algorithms for planarity checking, embedding and drawing
22.357 +This problem has an important connection to \e conservative \e length
22.358 +\e functions, too. A length function on the arcs of a digraph is called
22.359 +conservative if and only if there is no directed cycle of negative total
22.360 +length. For an arbitrary length function, the negative of the minimum
22.361 +cycle mean is the smallest \f$\epsilon\f$ value so that increasing the
22.362 +arc lengths uniformly by \f$\epsilon\f$ results in a conservative length
22.363 +function.
22.364
22.365 -This group describes the algorithms for planarity checking,
22.366 -embedding and drawing.
22.367 +LEMON contains three algorithms for solving the minimum mean cycle problem:
22.368 +- \ref Karp "Karp"'s original algorithm \ref amo93networkflows,
22.369 + \ref dasdan98minmeancycle.
22.370 +- \ref HartmannOrlin "Hartmann-Orlin"'s algorithm, which is an improved
22.371 + version of Karp's algorithm \ref dasdan98minmeancycle.
22.372 +- \ref Howard "Howard"'s policy iteration algorithm
22.373 + \ref dasdan98minmeancycle.
22.374
22.375 -\image html planar.png
22.376 -\image latex planar.eps "Plane graph" width=\textwidth
22.377 +In practice, the Howard algorithm proved to be by far the most efficient
22.378 +one, though the best known theoretical bound on its running time is
22.379 +exponential.
22.380 +Both Karp and HartmannOrlin algorithms run in time O(ne) and use space
22.381 +O(n<sup>2</sup>+e), but the latter one is typically faster due to the
22.382 +applied early termination scheme.
22.383 */
22.384
22.385 /**
22.386 @@ -435,9 +494,10 @@
22.387 @ingroup algs
22.388 \brief Algorithms for finding matchings in graphs and bipartite graphs.
22.389
22.390 -This group contains algorithm objects and functions to calculate
22.391 +This group contains the algorithms for calculating
22.392 matchings in graphs and bipartite graphs. The general matching problem is
22.393 -finding a subset of the arcs which does not shares common endpoints.
22.394 +finding a subset of the edges for which each node has at most one incident
22.395 +edge.
22.396
22.397 There are several different algorithms for calculate matchings in
22.398 graphs. The matching problems in bipartite graphs are generally
22.399 @@ -470,12 +530,36 @@
22.400 */
22.401
22.402 /**
22.403 -@defgroup spantree Minimum Spanning Tree Algorithms
22.404 +@defgroup graph_properties Connectivity and Other Graph Properties
22.405 @ingroup algs
22.406 -\brief Algorithms for finding a minimum cost spanning tree in a graph.
22.407 +\brief Algorithms for discovering the graph properties
22.408
22.409 -This group describes the algorithms for finding a minimum cost spanning
22.410 -tree in a graph.
22.411 +This group contains the algorithms for discovering the graph properties
22.412 +like connectivity, bipartiteness, euler property, simplicity etc.
22.413 +
22.414 +\image html connected_components.png
22.415 +\image latex connected_components.eps "Connected components" width=\textwidth
22.416 +*/
22.417 +
22.418 +/**
22.419 +@defgroup planar Planarity Embedding and Drawing
22.420 +@ingroup algs
22.421 +\brief Algorithms for planarity checking, embedding and drawing
22.422 +
22.423 +This group contains the algorithms for planarity checking,
22.424 +embedding and drawing.
22.425 +
22.426 +\image html planar.png
22.427 +\image latex planar.eps "Plane graph" width=\textwidth
22.428 +*/
22.429 +
22.430 +/**
22.431 +@defgroup approx Approximation Algorithms
22.432 +@ingroup algs
22.433 +\brief Approximation algorithms.
22.434 +
22.435 +This group contains the approximation and heuristic algorithms
22.436 +implemented in LEMON.
22.437 */
22.438
22.439 /**
22.440 @@ -483,36 +567,30 @@
22.441 @ingroup algs
22.442 \brief Auxiliary algorithms implemented in LEMON.
22.443
22.444 -This group describes some algorithms implemented in LEMON
22.445 +This group contains some algorithms implemented in LEMON
22.446 in order to make it easier to implement complex algorithms.
22.447 */
22.448
22.449 /**
22.450 -@defgroup approx Approximation Algorithms
22.451 -@ingroup algs
22.452 -\brief Approximation algorithms.
22.453 +@defgroup gen_opt_group General Optimization Tools
22.454 +\brief This group contains some general optimization frameworks
22.455 +implemented in LEMON.
22.456
22.457 -This group describes the approximation and heuristic algorithms
22.458 +This group contains some general optimization frameworks
22.459 implemented in LEMON.
22.460 */
22.461
22.462 /**
22.463 -@defgroup gen_opt_group General Optimization Tools
22.464 -\brief This group describes some general optimization frameworks
22.465 -implemented in LEMON.
22.466 +@defgroup lp_group LP and MIP Solvers
22.467 +@ingroup gen_opt_group
22.468 +\brief LP and MIP solver interfaces for LEMON.
22.469
22.470 -This group describes some general optimization frameworks
22.471 -implemented in LEMON.
22.472 -*/
22.473 +This group contains LP and MIP solver interfaces for LEMON.
22.474 +Various LP solvers could be used in the same manner with this
22.475 +high-level interface.
22.476
22.477 -/**
22.478 -@defgroup lp_group Lp and Mip Solvers
22.479 -@ingroup gen_opt_group
22.480 -\brief Lp and Mip solver interfaces for LEMON.
22.481 -
22.482 -This group describes Lp and Mip solver interfaces for LEMON. The
22.483 -various LP solvers could be used in the same manner with this
22.484 -interface.
22.485 +The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
22.486 +\ref cplex, \ref soplex.
22.487 */
22.488
22.489 /**
22.490 @@ -529,7 +607,7 @@
22.491 @ingroup gen_opt_group
22.492 \brief Metaheuristics for LEMON library.
22.493
22.494 -This group describes some metaheuristic optimization tools.
22.495 +This group contains some metaheuristic optimization tools.
22.496 */
22.497
22.498 /**
22.499 @@ -544,7 +622,7 @@
22.500 @ingroup utils
22.501 \brief Simple basic graph utilities.
22.502
22.503 -This group describes some simple basic graph utilities.
22.504 +This group contains some simple basic graph utilities.
22.505 */
22.506
22.507 /**
22.508 @@ -552,7 +630,7 @@
22.509 @ingroup utils
22.510 \brief Tools for development, debugging and testing.
22.511
22.512 -This group describes several useful tools for development,
22.513 +This group contains several useful tools for development,
22.514 debugging and testing.
22.515 */
22.516
22.517 @@ -561,7 +639,7 @@
22.518 @ingroup misc
22.519 \brief Simple tools for measuring the performance of algorithms.
22.520
22.521 -This group describes simple tools for measuring the performance
22.522 +This group contains simple tools for measuring the performance
22.523 of algorithms.
22.524 */
22.525
22.526 @@ -570,14 +648,14 @@
22.527 @ingroup utils
22.528 \brief Exceptions defined in LEMON.
22.529
22.530 -This group describes the exceptions defined in LEMON.
22.531 +This group contains the exceptions defined in LEMON.
22.532 */
22.533
22.534 /**
22.535 @defgroup io_group Input-Output
22.536 \brief Graph Input-Output methods
22.537
22.538 -This group describes the tools for importing and exporting graphs
22.539 +This group contains the tools for importing and exporting graphs
22.540 and graph related data. Now it supports the \ref lgf-format
22.541 "LEMON Graph Format", the \c DIMACS format and the encapsulated
22.542 postscript (EPS) format.
22.543 @@ -588,7 +666,7 @@
22.544 @ingroup io_group
22.545 \brief Reading and writing LEMON Graph Format.
22.546
22.547 -This group describes methods for reading and writing
22.548 +This group contains methods for reading and writing
22.549 \ref lgf-format "LEMON Graph Format".
22.550 */
22.551
22.552 @@ -597,12 +675,12 @@
22.553 @ingroup io_group
22.554 \brief General \c EPS drawer and graph exporter
22.555
22.556 -This group describes general \c EPS drawing methods and special
22.557 +This group contains general \c EPS drawing methods and special
22.558 graph exporting tools.
22.559 */
22.560
22.561 /**
22.562 -@defgroup dimacs_group DIMACS format
22.563 +@defgroup dimacs_group DIMACS Format
22.564 @ingroup io_group
22.565 \brief Read and write files in DIMACS format
22.566
22.567 @@ -621,7 +699,7 @@
22.568 @defgroup concept Concepts
22.569 \brief Skeleton classes and concept checking classes
22.570
22.571 -This group describes the data/algorithm skeletons and concept checking
22.572 +This group contains the data/algorithm skeletons and concept checking
22.573 classes implemented in LEMON.
22.574
22.575 The purpose of the classes in this group is fourfold.
22.576 @@ -651,8 +729,8 @@
22.577 @ingroup concept
22.578 \brief Skeleton and concept checking classes for graph structures
22.579
22.580 -This group describes the skeletons and concept checking classes of LEMON's
22.581 -graph structures and helper classes used to implement these.
22.582 +This group contains the skeletons and concept checking classes of
22.583 +graph structures.
22.584 */
22.585
22.586 /**
22.587 @@ -660,19 +738,7 @@
22.588 @ingroup concept
22.589 \brief Skeleton and concept checking classes for maps
22.590
22.591 -This group describes the skeletons and concept checking classes of maps.
22.592 -*/
22.593 -
22.594 -/**
22.595 -\anchor demoprograms
22.596 -
22.597 -@defgroup demos Demo Programs
22.598 -
22.599 -Some demo programs are listed here. Their full source codes can be found in
22.600 -the \c demo subdirectory of the source tree.
22.601 -
22.602 -It order to compile them, use <tt>--enable-demo</tt> configure option when
22.603 -build the library.
22.604 +This group contains the skeletons and concept checking classes of maps.
22.605 */
22.606
22.607 /**
22.608 @@ -684,4 +750,16 @@
22.609 them, as well.
22.610 */
22.611
22.612 +/**
22.613 +\anchor demoprograms
22.614 +
22.615 +@defgroup demos Demo Programs
22.616 +
22.617 +Some demo programs are listed here. Their full source codes can be found in
22.618 +the \c demo subdirectory of the source tree.
22.619 +
22.620 +In order to compile them, use the <tt>make demo</tt> or the
22.621 +<tt>make check</tt> commands.
22.622 +*/
22.623 +
22.624 }
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/doc/images/bipartite_matching.eps Thu Nov 05 15:48:01 2009 +0100
23.3 @@ -0,0 +1,586 @@
23.4 +%!PS-Adobe-3.0 EPSF-3.0
23.5 +%%BoundingBox: 15 18 829 570
23.6 +%%HiResBoundingBox: 15.1913 18.4493 828.078 569.438
23.7 +%%Creator: Karbon14 EPS Exportfilter 0.5
23.8 +%%CreationDate: (04/15/06 15:20:26)
23.9 +%%For: (Balazs Dezso) ()
23.10 +%%Title: ()
23.11 +
23.12 +/N {newpath} def
23.13 +/C {closepath} def
23.14 +/m {moveto} def
23.15 +/c {curveto} def
23.16 +/l {lineto} def
23.17 +/s {stroke} def
23.18 +/f {fill} def
23.19 +/w {setlinewidth} def
23.20 +/d {setdash} def
23.21 +/r {setrgbcolor} def
23.22 +/S {gsave} def
23.23 +/R {grestore} def
23.24 +
23.25 +N
23.26 +251.402 32.047 m
23.27 +532.945 293.946 814.484 555.844 814.484 555.844 c
23.28 +[] 0 d 1 0 0 r 3.92814 w s
23.29 +
23.30 +N
23.31 +749.012 32.047 m
23.32 +742.465 293.946 735.918 555.844 735.918 555.844 c
23.33 +[] 0 d 0 0 0 r 1.96407 w s
23.34 +
23.35 +N
23.36 +539.492 32.047 m
23.37 +637.703 293.946 735.918 555.844 735.918 555.844 c
23.38 +[] 0 d 0 0 0 r 1.96407 w s
23.39 +
23.40 +N
23.41 +172.832 32.047 m
23.42 +454.375 293.946 735.918 555.844 735.918 555.844 c
23.43 +[] 0 d 0 0 0 r 1.96407 w s
23.44 +
23.45 +N
23.46 +107.355 32.047 m
23.47 +421.637 293.946 735.918 555.844 735.918 555.844 c
23.48 +[] 0 d 1 0 0 r 3.92814 w s
23.49 +
23.50 +N
23.51 +644.25 555.844 m
23.52 +696.633 293.946 749.012 32.047 749.012 32.047 c
23.53 +[] 0 d 0 0 0 r 1.96407 w s
23.54 +
23.55 +N
23.56 +474.016 555.844 m
23.57 +611.516 293.946 749.012 32.047 749.012 32.047 c
23.58 +[] 0 d 1 0 0 r 3.92814 w s
23.59 +
23.60 +N
23.61 +683.535 32.047 m
23.62 +663.894 293.946 644.25 555.844 644.25 555.844 c
23.63 +[] 0 d 0 0 0 r 1.96407 w s
23.64 +
23.65 +N
23.66 +120.453 555.844 m
23.67 +401.992 293.946 683.535 32.047 683.535 32.047 c
23.68 +[] 0 d 0 0 0 r 1.96407 w s
23.69 +
23.70 +N
23.71 +28.7853 555.844 m
23.72 +356.16 293.946 683.535 32.047 683.535 32.047 c
23.73 +[] 0 d 1 0 0 r 3.92814 w s
23.74 +
23.75 +N
23.76 +539.492 32.047 m
23.77 +546.039 293.946 552.586 555.844 552.586 555.844 c
23.78 +[] 0 d 1 0 0 r 3.92814 w s
23.79 +
23.80 +N
23.81 +316.875 32.047 m
23.82 +349.613 293.946 382.351 555.844 382.351 555.844 c
23.83 +[] 0 d 1 0 0 r 3.92814 w s
23.84 +
23.85 +N
23.86 +107.355 32.047 m
23.87 +244.855 293.946 382.351 555.844 382.351 555.844 c
23.88 +[] 0 d 0 0 0 r 1.96407 w s
23.89 +
23.90 +N
23.91 +290.687 555.844 m
23.92 +375.805 293.946 460.922 32.047 460.922 32.047 c
23.93 +[] 0 d 1 0 0 r 3.92814 w s
23.94 +
23.95 +N
23.96 +120.453 555.844 m
23.97 +290.687 293.946 460.922 32.047 460.922 32.047 c
23.98 +[] 0 d 0 0 0 r 1.96407 w s
23.99 +
23.100 +N
23.101 +172.832 32.047 m
23.102 +146.64 293.946 120.453 555.844 120.453 555.844 c
23.103 +[] 0 d 1 0 0 r 3.92814 w s
23.104 +
23.105 +N
23.106 +15.6913 555.844 m
23.107 +15.6913 555.844 l
23.108 +15.6913 548.614 21.5553 542.75 28.7853 542.75 c
23.109 +36.0163 542.75 41.8833 548.614 41.8833 555.844 c
23.110 +41.8833 563.075 36.0163 568.938 28.7853 568.938 c
23.111 +21.5553 568.938 15.6913 563.075 15.6913 555.844 c
23.112 +15.6913 555.844 l
23.113 +C
23.114 +S 0 0 0 r f R
23.115 +
23.116 +N
23.117 +16.8833 555.844 m
23.118 +16.8833 555.844 l
23.119 +16.8833 549.27 22.2113 543.942 28.7853 543.942 c
23.120 +35.3593 543.942 40.6913 549.27 40.6913 555.844 c
23.121 +40.6913 562.418 35.3593 567.747 28.7853 567.747 c
23.122 +22.2113 567.747 16.8833 562.418 16.8833 555.844 c
23.123 +16.8833 555.844 l
23.124 +C
23.125 +S 1 0.5 1 r f R
23.126 +
23.127 +N
23.128 +107.355 555.844 m
23.129 +107.355 555.844 l
23.130 +107.355 548.614 113.223 542.75 120.453 542.75 c
23.131 +127.683 542.75 133.547 548.614 133.547 555.844 c
23.132 +133.547 563.075 127.683 568.938 120.453 568.938 c
23.133 +113.223 568.938 107.355 563.075 107.355 555.844 c
23.134 +107.355 555.844 l
23.135 +C
23.136 +S 0 0 0 r f R
23.137 +
23.138 +N
23.139 +108.547 555.844 m
23.140 +108.547 555.844 l
23.141 +108.547 549.27 113.879 543.942 120.453 543.942 c
23.142 +127.027 543.942 132.355 549.27 132.355 555.844 c
23.143 +132.355 562.418 127.027 567.747 120.453 567.747 c
23.144 +113.879 567.747 108.547 562.418 108.547 555.844 c
23.145 +108.547 555.844 l
23.146 +C
23.147 +S 1 0 1 r f R
23.148 +
23.149 +N
23.150 +199.019 555.844 m
23.151 +199.019 555.844 l
23.152 +199.019 548.614 204.887 542.75 212.117 542.75 c
23.153 +219.348 542.75 225.211 548.614 225.211 555.844 c
23.154 +225.211 563.075 219.348 568.938 212.117 568.938 c
23.155 +204.887 568.938 199.019 563.075 199.019 555.844 c
23.156 +199.019 555.844 l
23.157 +C
23.158 +S 0 0 0 r f R
23.159 +
23.160 +N
23.161 +200.211 555.844 m
23.162 +200.211 555.844 l
23.163 +200.211 549.27 205.543 543.942 212.117 543.942 c
23.164 +218.691 543.942 224.019 549.27 224.019 555.844 c
23.165 +224.019 562.418 218.691 567.747 212.117 567.747 c
23.166 +205.543 567.747 200.211 562.418 200.211 555.844 c
23.167 +200.211 555.844 l
23.168 +C
23.169 +S 1 0.5 1 r f R
23.170 +
23.171 +N
23.172 +277.59 555.844 m
23.173 +277.59 555.844 l
23.174 +277.59 548.614 283.457 542.75 290.687 542.75 c
23.175 +297.918 542.75 303.781 548.614 303.781 555.844 c
23.176 +303.781 563.075 297.918 568.938 290.687 568.938 c
23.177 +283.457 568.938 277.59 563.075 277.59 555.844 c
23.178 +277.59 555.844 l
23.179 +C
23.180 +S 0 0 0 r f R
23.181 +
23.182 +N
23.183 +278.781 555.844 m
23.184 +278.781 555.844 l
23.185 +278.781 549.27 284.113 543.942 290.687 543.942 c
23.186 +297.262 543.942 302.59 549.27 302.59 555.844 c
23.187 +302.59 562.418 297.262 567.747 290.687 567.747 c
23.188 +284.113 567.747 278.781 562.418 278.781 555.844 c
23.189 +278.781 555.844 l
23.190 +C
23.191 +S 1 0 1 r f R
23.192 +
23.193 +N
23.194 +369.258 555.844 m
23.195 +369.258 555.844 l
23.196 +369.258 548.614 375.121 542.75 382.351 542.75 c
23.197 +389.582 542.75 395.445 548.614 395.445 555.844 c
23.198 +395.445 563.075 389.582 568.938 382.351 568.938 c
23.199 +375.121 568.938 369.258 563.075 369.258 555.844 c
23.200 +369.258 555.844 l
23.201 +C
23.202 +S 0 0 0 r f R
23.203 +
23.204 +N
23.205 +370.445 555.844 m
23.206 +370.445 555.844 l
23.207 +370.445 549.27 375.777 543.942 382.351 543.942 c
23.208 +388.926 543.942 394.258 549.27 394.258 555.844 c
23.209 +394.258 562.418 388.926 567.747 382.351 567.747 c
23.210 +375.777 567.747 370.445 562.418 370.445 555.844 c
23.211 +370.445 555.844 l
23.212 +C
23.213 +S 1 0 1 r f R
23.214 +
23.215 +N
23.216 +460.922 555.844 m
23.217 +460.922 555.844 l
23.218 +460.922 548.614 466.785 542.75 474.016 542.75 c
23.219 +481.246 542.75 487.109 548.614 487.109 555.844 c
23.220 +487.109 563.075 481.246 568.938 474.016 568.938 c
23.221 +466.785 568.938 460.922 563.075 460.922 555.844 c
23.222 +460.922 555.844 l
23.223 +C
23.224 +S 0 0 0 r f R
23.225 +
23.226 +N
23.227 +462.113 555.844 m
23.228 +462.113 555.844 l
23.229 +462.113 549.27 467.441 543.942 474.016 543.942 c
23.230 +480.59 543.942 485.922 549.27 485.922 555.844 c
23.231 +485.922 562.418 480.59 567.747 474.016 567.747 c
23.232 +467.441 567.747 462.113 562.418 462.113 555.844 c
23.233 +462.113 555.844 l
23.234 +C
23.235 +S 1 0.5 1 r f R
23.236 +
23.237 +N
23.238 +539.492 555.844 m
23.239 +539.492 555.844 l
23.240 +539.492 548.614 545.355 542.75 552.586 542.75 c
23.241 +559.816 542.75 565.68 548.614 565.68 555.844 c
23.242 +565.68 563.075 559.816 568.938 552.586 568.938 c
23.243 +545.355 568.938 539.492 563.075 539.492 555.844 c
23.244 +539.492 555.844 l
23.245 +C
23.246 +S 0 0 0 r f R
23.247 +
23.248 +N
23.249 +540.683 555.844 m
23.250 +540.683 555.844 l
23.251 +540.683 549.27 546.012 543.942 552.586 543.942 c
23.252 +559.16 543.942 564.492 549.27 564.492 555.844 c
23.253 +564.492 562.418 559.16 567.747 552.586 567.747 c
23.254 +546.012 567.747 540.683 562.418 540.683 555.844 c
23.255 +540.683 555.844 l
23.256 +C
23.257 +S 1 0 1 r f R
23.258 +
23.259 +N
23.260 +631.156 555.844 m
23.261 +631.156 555.844 l
23.262 +631.156 548.614 637.019 542.75 644.25 542.75 c
23.263 +651.48 542.75 657.348 548.614 657.348 555.844 c
23.264 +657.348 563.075 651.48 568.938 644.25 568.938 c
23.265 +637.019 568.938 631.156 563.075 631.156 555.844 c
23.266 +631.156 555.844 l
23.267 +C
23.268 +S 0 0 0 r f R
23.269 +
23.270 +N
23.271 +632.348 555.844 m
23.272 +632.348 555.844 l
23.273 +632.348 549.27 637.676 543.942 644.25 543.942 c
23.274 +650.824 543.942 656.156 549.27 656.156 555.844 c
23.275 +656.156 562.418 650.824 567.747 644.25 567.747 c
23.276 +637.676 567.747 632.348 562.418 632.348 555.844 c
23.277 +632.348 555.844 l
23.278 +C
23.279 +S 1 0.5 1 r f R
23.280 +
23.281 +N
23.282 +722.82 555.844 m
23.283 +722.82 555.844 l
23.284 +722.82 548.614 728.687 542.75 735.918 542.75 c
23.285 +743.149 542.75 749.012 548.614 749.012 555.844 c
23.286 +749.012 563.075 743.149 568.938 735.918 568.938 c
23.287 +728.687 568.938 722.82 563.075 722.82 555.844 c
23.288 +722.82 555.844 l
23.289 +C
23.290 +S 0 0 0 r f R
23.291 +
23.292 +N
23.293 +724.012 555.844 m
23.294 +724.012 555.844 l
23.295 +724.012 549.27 729.344 543.942 735.918 543.942 c
23.296 +742.492 543.942 747.82 549.27 747.82 555.844 c
23.297 +747.82 562.418 742.492 567.747 735.918 567.747 c
23.298 +729.344 567.747 724.012 562.418 724.012 555.844 c
23.299 +724.012 555.844 l
23.300 +C
23.301 +S 1 0 1 r f R
23.302 +
23.303 +N
23.304 +801.391 555.844 m
23.305 +801.391 555.844 l
23.306 +801.391 548.614 807.254 542.75 814.484 542.75 c
23.307 +821.715 542.75 827.578 548.614 827.578 555.844 c
23.308 +827.578 563.075 821.715 568.938 814.484 568.938 c
23.309 +807.254 568.938 801.391 563.075 801.391 555.844 c
23.310 +801.391 555.844 l
23.311 +C
23.312 +S 0 0 0 r f R
23.313 +
23.314 +N
23.315 +802.582 555.844 m
23.316 +802.582 555.844 l
23.317 +802.582 549.27 807.91 543.942 814.484 543.942 c
23.318 +821.059 543.942 826.387 549.27 826.387 555.844 c
23.319 +826.387 562.418 821.059 567.747 814.484 567.747 c
23.320 +807.91 567.747 802.582 562.418 802.582 555.844 c
23.321 +802.582 555.844 l
23.322 +C
23.323 +S 1 0 1 r f R
23.324 +
23.325 +N
23.326 +15.6913 32.047 m
23.327 +15.6913 32.047 l
23.328 +15.6913 24.8165 21.5553 18.9493 28.7853 18.9493 c
23.329 +36.0163 18.9493 41.8833 24.8165 41.8833 32.047 c
23.330 +41.8833 39.2775 36.0163 45.1407 28.7853 45.1407 c
23.331 +21.5553 45.1407 15.6913 39.2775 15.6913 32.047 c
23.332 +15.6913 32.047 l
23.333 +C
23.334 +S 0 0 0 r f R
23.335 +
23.336 +N
23.337 +16.8833 32.047 m
23.338 +16.8833 32.047 l
23.339 +16.8833 25.4728 22.2113 20.1407 28.7853 20.1407 c
23.340 +35.3593 20.1407 40.6913 25.4728 40.6913 32.047 c
23.341 +40.6913 38.6212 35.3593 43.9493 28.7853 43.9493 c
23.342 +22.2113 43.9493 16.8833 38.6212 16.8833 32.047 c
23.343 +16.8833 32.047 l
23.344 +C
23.345 +S 0.5 0.5 1 r f R
23.346 +
23.347 +N
23.348 +94.2623 32.047 m
23.349 +94.2623 32.047 l
23.350 +94.2623 24.8165 100.125 18.9493 107.355 18.9493 c
23.351 +114.586 18.9493 120.453 24.8165 120.453 32.047 c
23.352 +120.453 39.2775 114.586 45.1407 107.355 45.1407 c
23.353 +100.125 45.1407 94.2623 39.2775 94.2623 32.047 c
23.354 +94.2623 32.047 l
23.355 +C
23.356 +S 0 0 0 r f R
23.357 +
23.358 +N
23.359 +95.4533 32.047 m
23.360 +95.4533 32.047 l
23.361 +95.4533 25.4728 100.781 20.1407 107.355 20.1407 c
23.362 +113.93 20.1407 119.262 25.4728 119.262 32.047 c
23.363 +119.262 38.6212 113.93 43.9493 107.355 43.9493 c
23.364 +100.781 43.9493 95.4533 38.6212 95.4533 32.047 c
23.365 +95.4533 32.047 l
23.366 +C
23.367 +S 0.5 0.5 1 r f R
23.368 +
23.369 +N
23.370 +159.734 32.047 m
23.371 +159.734 32.047 l
23.372 +159.734 24.8165 165.601 18.9493 172.832 18.9493 c
23.373 +180.062 18.9493 185.926 24.8165 185.926 32.047 c
23.374 +185.926 39.2775 180.062 45.1407 172.832 45.1407 c
23.375 +165.601 45.1407 159.734 39.2775 159.734 32.047 c
23.376 +159.734 32.047 l
23.377 +C
23.378 +S 0 0 0 r f R
23.379 +
23.380 +N
23.381 +160.926 32.047 m
23.382 +160.926 32.047 l
23.383 +160.926 25.4728 166.258 20.1407 172.832 20.1407 c
23.384 +179.406 20.1407 184.734 25.4728 184.734 32.047 c
23.385 +184.734 38.6212 179.406 43.9493 172.832 43.9493 c
23.386 +166.258 43.9493 160.926 38.6212 160.926 32.047 c
23.387 +160.926 32.047 l
23.388 +C
23.389 +S 0.5 0.5 1 r f R
23.390 +
23.391 +N
23.392 +238.305 32.047 m
23.393 +238.305 32.047 l
23.394 +238.305 24.8165 244.172 18.9493 251.402 18.9493 c
23.395 +258.633 18.9493 264.496 24.8165 264.496 32.047 c
23.396 +264.496 39.2775 258.633 45.1407 251.402 45.1407 c
23.397 +244.172 45.1407 238.305 39.2775 238.305 32.047 c
23.398 +238.305 32.047 l
23.399 +C
23.400 +S 0 0 0 r f R
23.401 +
23.402 +N
23.403 +239.496 32.047 m
23.404 +239.496 32.047 l
23.405 +239.496 25.4728 244.828 20.1407 251.402 20.1407 c
23.406 +257.976 20.1407 263.305 25.4728 263.305 32.047 c
23.407 +263.305 38.6212 257.976 43.9493 251.402 43.9493 c
23.408 +244.828 43.9493 239.496 38.6212 239.496 32.047 c
23.409 +239.496 32.047 l
23.410 +C
23.411 +S 0.5 0.5 1 r f R
23.412 +
23.413 +N
23.414 +303.781 32.047 m
23.415 +303.781 32.047 l
23.416 +303.781 24.8165 309.644 18.9493 316.875 18.9493 c
23.417 +324.105 18.9493 329.973 24.8165 329.973 32.047 c
23.418 +329.973 39.2775 324.105 45.1407 316.875 45.1407 c
23.419 +309.644 45.1407 303.781 39.2775 303.781 32.047 c
23.420 +303.781 32.047 l
23.421 +C
23.422 +S 0 0 0 r f R
23.423 +
23.424 +N
23.425 +304.973 32.047 m
23.426 +304.973 32.047 l
23.427 +304.973 25.4728 310.301 20.1407 316.875 20.1407 c
23.428 +323.449 20.1407 328.781 25.4728 328.781 32.047 c
23.429 +328.781 38.6212 323.449 43.9493 316.875 43.9493 c
23.430 +310.301 43.9493 304.973 38.6212 304.973 32.047 c
23.431 +304.973 32.047 l
23.432 +C
23.433 +S 0.5 0.5 1 r f R
23.434 +
23.435 +N
23.436 +382.351 32.047 m
23.437 +382.351 32.047 l
23.438 +382.351 24.8165 388.215 18.9493 395.445 18.9493 c
23.439 +402.676 18.9493 408.543 24.8165 408.543 32.047 c
23.440 +408.543 39.2775 402.676 45.1407 395.445 45.1407 c
23.441 +388.215 45.1407 382.351 39.2775 382.351 32.047 c
23.442 +382.351 32.047 l
23.443 +C
23.444 +S 0 0 0 r f R
23.445 +
23.446 +N
23.447 +383.543 32.047 m
23.448 +383.543 32.047 l
23.449 +383.543 25.4728 388.871 20.1407 395.445 20.1407 c
23.450 +402.019 20.1407 407.351 25.4728 407.351 32.047 c
23.451 +407.351 38.6212 402.019 43.9493 395.445 43.9493 c
23.452 +388.871 43.9493 383.543 38.6212 383.543 32.047 c
23.453 +383.543 32.047 l
23.454 +C
23.455 +S 0.5 0.5 1 r f R
23.456 +
23.457 +N
23.458 +447.828 32.047 m
23.459 +447.828 32.047 l
23.460 +447.828 24.8165 453.691 18.9493 460.922 18.9493 c
23.461 +468.152 18.9493 474.016 24.8165 474.016 32.047 c
23.462 +474.016 39.2775 468.152 45.1407 460.922 45.1407 c
23.463 +453.691 45.1407 447.828 39.2775 447.828 32.047 c
23.464 +447.828 32.047 l
23.465 +C
23.466 +S 0 0 0 r f R
23.467 +
23.468 +N
23.469 +449.016 32.047 m
23.470 +449.016 32.047 l
23.471 +449.016 25.4728 454.348 20.1407 460.922 20.1407 c
23.472 +467.496 20.1407 472.824 25.4728 472.824 32.047 c
23.473 +472.824 38.6212 467.496 43.9493 460.922 43.9493 c
23.474 +454.348 43.9493 449.016 38.6212 449.016 32.047 c
23.475 +449.016 32.047 l
23.476 +C
23.477 +S 0.5 0.5 1 r f R
23.478 +
23.479 +N
23.480 +526.394 32.047 m
23.481 +526.394 32.047 l
23.482 +526.394 24.8165 532.262 18.9493 539.492 18.9493 c
23.483 +546.723 18.9493 552.586 24.8165 552.586 32.047 c
23.484 +552.586 39.2775 546.723 45.1407 539.492 45.1407 c
23.485 +532.262 45.1407 526.394 39.2775 526.394 32.047 c
23.486 +526.394 32.047 l
23.487 +C
23.488 +S 0 0 0 r f R
23.489 +
23.490 +N
23.491 +527.586 32.047 m
23.492 +527.586 32.047 l
23.493 +527.586 25.4728 532.918 20.1407 539.492 20.1407 c
23.494 +546.066 20.1407 551.394 25.4728 551.394 32.047 c
23.495 +551.394 38.6212 546.066 43.9493 539.492 43.9493 c
23.496 +532.918 43.9493 527.586 38.6212 527.586 32.047 c
23.497 +527.586 32.047 l
23.498 +C
23.499 +S 0.5 0.5 1 r f R
23.500 +
23.501 +N
23.502 +591.871 32.047 m
23.503 +591.871 32.047 l
23.504 +591.871 24.8165 597.734 18.9493 604.965 18.9493 c
23.505 +612.195 18.9493 618.062 24.8165 618.062 32.047 c
23.506 +618.062 39.2775 612.195 45.1407 604.965 45.1407 c
23.507 +597.734 45.1407 591.871 39.2775 591.871 32.047 c
23.508 +591.871 32.047 l
23.509 +C
23.510 +S 0 0 0 r f R
23.511 +
23.512 +N
23.513 +593.062 32.047 m
23.514 +593.062 32.047 l
23.515 +593.062 25.4728 598.39 20.1407 604.965 20.1407 c
23.516 +611.539 20.1407 616.871 25.4728 616.871 32.047 c
23.517 +616.871 38.6212 611.539 43.9493 604.965 43.9493 c
23.518 +598.39 43.9493 593.062 38.6212 593.062 32.047 c
23.519 +593.062 32.047 l
23.520 +C
23.521 +S 0.5 0.5 1 r f R
23.522 +
23.523 +N
23.524 +670.441 32.047 m
23.525 +670.441 32.047 l
23.526 +670.441 24.8165 676.305 18.9493 683.535 18.9493 c
23.527 +690.766 18.9493 696.633 24.8165 696.633 32.047 c
23.528 +696.633 39.2775 690.766 45.1407 683.535 45.1407 c
23.529 +676.305 45.1407 670.441 39.2775 670.441 32.047 c
23.530 +670.441 32.047 l
23.531 +C
23.532 +S 0 0 0 r f R
23.533 +
23.534 +N
23.535 +671.633 32.047 m
23.536 +671.633 32.047 l
23.537 +671.633 25.4728 676.961 20.1407 683.535 20.1407 c
23.538 +690.109 20.1407 695.441 25.4728 695.441 32.047 c
23.539 +695.441 38.6212 690.109 43.9493 683.535 43.9493 c
23.540 +676.961 43.9493 671.633 38.6212 671.633 32.047 c
23.541 +671.633 32.047 l
23.542 +C
23.543 +S 0 0 1 r f R
23.544 +
23.545 +N
23.546 +735.918 32.047 m
23.547 +735.918 32.047 l
23.548 +735.918 24.8165 741.781 18.9493 749.012 18.9493 c
23.549 +756.242 18.9493 762.106 24.8165 762.106 32.047 c
23.550 +762.106 39.2775 756.242 45.1407 749.012 45.1407 c
23.551 +741.781 45.1407 735.918 39.2775 735.918 32.047 c
23.552 +735.918 32.047 l
23.553 +C
23.554 +S 0 0 0 r f R
23.555 +
23.556 +N
23.557 +737.105 32.047 m
23.558 +737.105 32.047 l
23.559 +737.105 25.4728 742.437 20.1407 749.012 20.1407 c
23.560 +755.586 20.1407 760.914 25.4728 760.914 32.047 c
23.561 +760.914 38.6212 755.586 43.9493 749.012 43.9493 c
23.562 +742.437 43.9493 737.105 38.6212 737.105 32.047 c
23.563 +737.105 32.047 l
23.564 +C
23.565 +S 0 0 1 r f R
23.566 +
23.567 +N
23.568 +801.391 32.047 m
23.569 +801.391 32.047 l
23.570 +801.391 24.8165 807.254 18.9493 814.484 18.9493 c
23.571 +821.715 18.9493 827.578 24.8165 827.578 32.047 c
23.572 +827.578 39.2775 821.715 45.1407 814.484 45.1407 c
23.573 +807.254 45.1407 801.391 39.2775 801.391 32.047 c
23.574 +801.391 32.047 l
23.575 +C
23.576 +S 0 0 0 r f R
23.577 +
23.578 +N
23.579 +802.582 32.047 m
23.580 +802.582 32.047 l
23.581 +802.582 25.4728 807.91 20.1407 814.484 20.1407 c
23.582 +821.059 20.1407 826.387 25.4728 826.387 32.047 c
23.583 +826.387 38.6212 821.059 43.9493 814.484 43.9493 c
23.584 +807.91 43.9493 802.582 38.6212 802.582 32.047 c
23.585 +802.582 32.047 l
23.586 +C
23.587 +S 0.5 0.5 1 r f R
23.588 +
23.589 +%%EOF
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/doc/images/bipartite_partitions.eps Thu Nov 05 15:48:01 2009 +0100
24.3 @@ -0,0 +1,114 @@
24.4 +%!PS-Adobe-2.0 EPSF-2.0
24.5 +%%Creator: LEMON, graphToEps()
24.6 +%%CreationDate: Tue Nov 15 16:51:43 2005
24.7 +%%BoundingBox: 0 0 842 596
24.8 +%%EndComments
24.9 +/lb { setlinewidth setrgbcolor newpath moveto
24.10 + 4 2 roll 1 index 1 index curveto stroke } bind def
24.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
24.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
24.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
24.14 + 2 index 1 index sub 2 index 2 index add lineto
24.15 + 2 index 1 index sub 2 index 2 index sub lineto
24.16 + 2 index 1 index add 2 index 2 index sub lineto
24.17 + closepath pop pop pop} bind def
24.18 +/di { newpath 2 index 1 index add 2 index moveto
24.19 + 2 index 2 index 2 index add lineto
24.20 + 2 index 1 index sub 2 index lineto
24.21 + 2 index 2 index 2 index sub lineto
24.22 + closepath pop pop pop} bind def
24.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
24.24 + setrgbcolor 1.1 div c fill
24.25 + } bind def
24.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
24.27 + setrgbcolor 1.1 div sq fill
24.28 + } bind def
24.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
24.30 + setrgbcolor 1.1 div di fill
24.31 + } bind def
24.32 +/arrl 1 def
24.33 +/arrw 0.3 def
24.34 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
24.35 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
24.36 + /w exch def /len exch def
24.37 + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
24.38 + len w sub arrl sub dx dy lrl
24.39 + arrw dy dx neg lrl
24.40 + dx arrl w add mul dy w 2 div arrw add mul sub
24.41 + dy arrl w add mul dx w 2 div arrw add mul add rlineto
24.42 + dx arrl w add mul neg dy w 2 div arrw add mul sub
24.43 + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
24.44 + arrw dy dx neg lrl
24.45 + len w sub arrl sub neg dx dy lrl
24.46 + closepath fill } bind def
24.47 +/cshow { 2 index 2 index moveto dup stringwidth pop
24.48 + neg 2 div fosi .35 mul neg rmoveto show pop pop} def
24.49 +
24.50 +gsave
24.51 +90 rotate
24.52 +0 -842 translate
24.53 +71.6378 15 translate
24.54 +0.389093 dup scale
24.55 +90 rotate
24.56 +1197.47 -613.138 translate
24.57 +%Edges:
24.58 +gsave
24.59 +513.857 -446.322 296.569 -487.43 79.2808 -528.539 0 0 0 2 lb
24.60 +513.857 -446.322 575.52 -315.655 637.183 -184.989 0 0 0 2 lb
24.61 +393.468 566.711 494.771 434.577 596.074 302.442 0 0 0 2 lb
24.62 +393.468 566.711 155.625 579.925 -82.2171 593.138 0 0 0 2 lb
24.63 +393.468 566.711 251.056 450.726 108.644 334.741 0 0 0 2 lb
24.64 +869.153 52.8539 732.613 177.648 596.074 302.442 0 0 0 2 lb
24.65 +869.153 52.8539 753.168 -66.0676 637.183 -184.989 0 0 0 2 lb
24.66 +-82.2171 593.138 -91.0261 346.487 -99.8351 99.8351 0 0 0 2 lb
24.67 +-663.61 546.157 -753.168 394.936 -842.726 243.715 0 0 0 2 lb
24.68 +-663.61 546.157 -574.052 437.513 -484.494 328.869 0 0 0 2 lb
24.69 +-1077.63 161.498 -960.178 202.606 -842.726 243.715 0 0 0 2 lb
24.70 +-1077.63 161.498 -968.987 66.0674 -860.344 -29.3633 0 0 0 2 lb
24.71 +-1177.47 -234.906 -1029.18 -381.722 -880.898 -528.539 0 0 0 2 lb
24.72 +-1177.47 -234.906 -1018.91 -132.135 -860.344 -29.3633 0 0 0 2 lb
24.73 +-880.898 -528.539 -744.359 -387.595 -607.82 -246.651 0 0 0 2 lb
24.74 +-499.175 -499.175 -355.295 -475.685 -211.415 -452.194 0 0 0 2 lb
24.75 +-499.175 -499.175 -553.498 -372.913 -607.82 -246.651 0 0 0 2 lb
24.76 +-499.175 -499.175 -386.587 -315.087 -274 -131 0 0 0 2 lb
24.77 +79.2808 -528.539 -66.0671 -490.366 -211.415 -452.194 0 0 0 2 lb
24.78 +637.183 -184.989 421.363 -253.993 205.543 -322.996 0 0 0 2 lb
24.79 +205.543 -322.996 162.966 -226.097 120.389 -129.198 0 0 0 2 lb
24.80 +399.34 88.0898 259.865 -20.5541 120.389 -129.198 0 0 0 2 lb
24.81 +399.34 88.0898 253.992 211.415 108.644 334.741 0 0 0 2 lb
24.82 +-842.726 243.715 -471.281 171.775 -99.8351 99.8351 0 0 0 2 lb
24.83 +-842.726 243.715 -558.363 56.3575 -274 -131 0 0 0 2 lb
24.84 +-860.344 -29.3633 -734.082 -138.007 -607.82 -246.651 0 0 0 2 lb
24.85 +-211.415 -452.194 -45.513 -290.696 120.389 -129.198 0 0 0 2 lb
24.86 +-99.8351 99.8351 4.40445 217.288 108.644 334.741 0 0 0 2 lb
24.87 +-99.8351 99.8351 -292.165 214.352 -484.494 328.869 0 0 0 2 lb
24.88 +120.389 -129.198 -76.8055 -130.099 -274 -131 0 0 0 2 lb
24.89 +grestore
24.90 +%Nodes:
24.91 +gsave
24.92 +-274 -131 20 1 0 0 nc
24.93 +-607.82 -246.651 20 1 0 0 nc
24.94 +-484.494 328.869 20 0 0 1 nc
24.95 +108.644 334.741 20 0 0 1 nc
24.96 +120.389 -129.198 20 0 0 1 nc
24.97 +-99.8351 99.8351 20 1 0 0 nc
24.98 +-211.415 -452.194 20 1 0 0 nc
24.99 +-860.344 -29.3633 20 0 0 1 nc
24.100 +-842.726 243.715 20 0 0 1 nc
24.101 +399.34 88.0898 20 1 0 0 nc
24.102 +205.543 -322.996 20 1 0 0 nc
24.103 +637.183 -184.989 20 0 0 1 nc
24.104 +79.2808 -528.539 20 0 0 1 nc
24.105 +-499.175 -499.175 20 0 0 1 nc
24.106 +-880.898 -528.539 20 0 0 1 nc
24.107 +-1177.47 -234.906 20 1 0 0 nc
24.108 +-1077.63 161.498 20 1 0 0 nc
24.109 +-663.61 546.157 20 1 0 0 nc
24.110 +-82.2171 593.138 20 0 0 1 nc
24.111 +596.074 302.442 20 0 0 1 nc
24.112 +869.153 52.8539 20 1 0 0 nc
24.113 +393.468 566.711 20 1 0 0 nc
24.114 +513.857 -446.322 20 1 0 0 nc
24.115 +grestore
24.116 +grestore
24.117 +showpage
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/doc/images/connected_components.eps Thu Nov 05 15:48:01 2009 +0100
25.3 @@ -0,0 +1,159 @@
25.4 +%!PS-Adobe-2.0 EPSF-2.0
25.5 +%%Creator: LEMON, graphToEps()
25.6 +%%CreationDate: Fri Nov 4 13:47:12 2005
25.7 +%%BoundingBox: 0 0 842 596
25.8 +%%EndComments
25.9 +/lb { setlinewidth setrgbcolor newpath moveto
25.10 + 4 2 roll 1 index 1 index curveto stroke } bind def
25.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
25.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
25.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
25.14 + 2 index 1 index sub 2 index 2 index add lineto
25.15 + 2 index 1 index sub 2 index 2 index sub lineto
25.16 + 2 index 1 index add 2 index 2 index sub lineto
25.17 + closepath pop pop pop} bind def
25.18 +/di { newpath 2 index 1 index add 2 index moveto
25.19 + 2 index 2 index 2 index add lineto
25.20 + 2 index 1 index sub 2 index lineto
25.21 + 2 index 2 index 2 index sub lineto
25.22 + closepath pop pop pop} bind def
25.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
25.24 + setrgbcolor 1.1 div c fill
25.25 + } bind def
25.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
25.27 + setrgbcolor 1.1 div sq fill
25.28 + } bind def
25.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
25.30 + setrgbcolor 1.1 div di fill
25.31 + } bind def
25.32 +/arrl 1 def
25.33 +/arrw 0.3 def
25.34 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
25.35 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
25.36 + /w exch def /len exch def
25.37 + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
25.38 + len w sub arrl sub dx dy lrl
25.39 + arrw dy dx neg lrl
25.40 + dx arrl w add mul dy w 2 div arrw add mul sub
25.41 + dy arrl w add mul dx w 2 div arrw add mul add rlineto
25.42 + dx arrl w add mul neg dy w 2 div arrw add mul sub
25.43 + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
25.44 + arrw dy dx neg lrl
25.45 + len w sub arrl sub neg dx dy lrl
25.46 + closepath fill } bind def
25.47 +/cshow { 2 index 2 index moveto dup stringwidth pop
25.48 + neg 2 div fosi .35 mul neg rmoveto show pop pop} def
25.49 +
25.50 +gsave
25.51 +90 rotate
25.52 +0 -842 translate
25.53 +71.0944 15 translate
25.54 +0.434694 dup scale
25.55 +90 rotate
25.56 +860.856 -588.349 translate
25.57 +%Edges:
25.58 +gsave
25.59 +574.035 177.301 622.149 225.748 670.264 274.195 0 0 0 2 lb
25.60 +694.579 115.483 682.421 194.839 670.264 274.195 0 0 0 2 lb
25.61 +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 0 2 lb
25.62 +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 0 2 lb
25.63 +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 0 2 lb
25.64 +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 0 2 lb
25.65 +286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 0 2 lb
25.66 +438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 0 2 lb
25.67 +438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 0 2 lb
25.68 +397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 0 2 lb
25.69 +366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 0 2 lb
25.70 +271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 0 2 lb
25.71 +271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 0 2 lb
25.72 +277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 0 2 lb
25.73 +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0 0 2 lb
25.74 +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0 2 lb
25.75 +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0 2 lb
25.76 +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0 2 lb
25.77 +906.312 201.403 946.592 42.798 986.873 -115.807 0 0 0 2 lb
25.78 +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 0 2 lb
25.79 +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 0 2 lb
25.80 +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0 0 0 2 lb
25.81 +422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 0 2 lb
25.82 +422.945 521.129 376.371 417.911 329.797 314.692 0 0 0 2 lb
25.83 +422.945 521.129 474.554 276.928 526.164 32.7279 0 0 0 2 lb
25.84 +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 0 2 lb
25.85 +329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 0 2 lb
25.86 +-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 0 2 lb
25.87 +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 0 2 lb
25.88 +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 0 2 lb
25.89 +526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 0 2 lb
25.90 +730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 0 2 lb
25.91 +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 0 0 0 2 lb
25.92 +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 0 2 lb
25.93 +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 0 2 lb
25.94 +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 0 2 lb
25.95 +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 0 2 lb
25.96 +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 0 2 lb
25.97 +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 0 2 lb
25.98 +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 0 2 lb
25.99 +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 0 2 lb
25.100 +116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 0 2 lb
25.101 +-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 0 2 lb
25.102 +-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 0 2 lb
25.103 +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 0 2 lb
25.104 +-180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 0 2 lb
25.105 +-180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 0 2 lb
25.106 +-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 0 2 lb
25.107 +-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 0 2 lb
25.108 +-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 0 2 lb
25.109 +670.264 274.195 629.188 409.347 588.113 544.499 0 0 0 2 lb
25.110 +670.264 274.195 797.466 341.771 924.667 409.347 0 0 0 2 lb
25.111 +588.113 544.499 756.39 476.923 924.667 409.347 0 0 0 2 lb
25.112 +-689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 0 2 lb
25.113 +-689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 0 2 lb
25.114 +grestore
25.115 +%Nodes:
25.116 +gsave
25.117 +-567.302 43.6423 20 0 0 0 nc
25.118 +-689.204 -237.261 20 0 0 0 nc
25.119 +924.667 409.347 20 1 0 0 nc
25.120 +588.113 544.499 20 1 0 0 nc
25.121 +670.264 274.195 20 1 0 0 nc
25.122 +-371.2 568.349 20 0 1 0 nc
25.123 +-132.697 451.748 20 0 1 0 nc
25.124 +-416.25 345.746 20 0 1 0 nc
25.125 +-180.397 245.045 20 0 1 0 nc
25.126 +-13.4452 133.743 20 0 1 0 nc
25.127 +-262.548 107.243 20 0 1 0 nc
25.128 +201.208 38.3422 20 0 1 0 nc
25.129 +116.407 -173.66 20 0 1 0 nc
25.130 +-26.6953 -19.9585 20 0 1 0 nc
25.131 +-539.894 -262.64 20 0 0 1 nc
25.132 +-323.543 -433.964 20 0 0 1 nc
25.133 +-309.657 -57.9033 20 0 0 1 nc
25.134 +-67.9734 -347.42 20 0 0 1 nc
25.135 +415.393 -289.516 20 0 0 1 nc
25.136 +730.084 -307.139 20 0 0 1 nc
25.137 +526.164 32.7279 20 0 0 1 nc
25.138 +762.812 -17.6227 20 0 0 1 nc
25.139 +-67.9734 319.727 20 0 0 1 nc
25.140 +329.797 314.692 20 0 0 1 nc
25.141 +-5.03507 561.41 20 0 0 1 nc
25.142 +422.945 521.129 20 0 0 1 nc
25.143 +-470.779 158.605 20 0 0 1 nc
25.144 +986.873 -115.807 20 0 0 1 nc
25.145 +906.312 201.403 20 0 0 1 nc
25.146 +-767.847 113.289 20 0 0 1 nc
25.147 +-579.033 445.603 20 0 0 1 nc
25.148 +-840.856 -246.718 20 0 0 1 nc
25.149 +206.221 -205.967 20 1 1 0 nc
25.150 +277.311 -252.33 20 1 1 0 nc
25.151 +271.13 -175.058 20 1 1 0 nc
25.152 +366.947 -110.15 20 1 1 0 nc
25.153 +397.855 -196.694 20 1 1 0 nc
25.154 +438.037 -88.514 20 1 1 0 nc
25.155 +286.584 -48.3327 20 1 1 0 nc
25.156 +212.403 -23.6057 20 1 1 0 nc
25.157 +280.402 10.3938 20 1 1 0 nc
25.158 +694.579 115.483 20 1 0 0 nc
25.159 +574.035 177.301 20 1 0 0 nc
25.160 +grestore
25.161 +grestore
25.162 +showpage
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/doc/images/edge_biconnected_components.eps Thu Nov 05 15:48:01 2009 +0100
26.3 @@ -0,0 +1,159 @@
26.4 +%!PS-Adobe-2.0 EPSF-2.0
26.5 +%%Creator: LEMON, graphToEps()
26.6 +%%CreationDate: Fri Nov 4 13:47:12 2005
26.7 +%%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.0944 15 translate
26.54 +0.434694 dup scale
26.55 +90 rotate
26.56 +860.856 -588.349 translate
26.57 +%Edges:
26.58 +gsave
26.59 +574.035 177.301 622.149 225.748 670.264 274.195 1 0 0 2 lb
26.60 +694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 2 lb
26.61 +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 1 2 lb
26.62 +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 1 2 lb
26.63 +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 1 2 lb
26.64 +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 1 2 lb
26.65 +286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 1 2 lb
26.66 +438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 1 2 lb
26.67 +438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 1 2 lb
26.68 +397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 1 2 lb
26.69 +366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 1 2 lb
26.70 +271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 1 2 lb
26.71 +271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 1 2 lb
26.72 +277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 1 2 lb
26.73 +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 1 0 0 2 lb
26.74 +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 1 2 lb
26.75 +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 1 2 lb
26.76 +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 1 2 lb
26.77 +906.312 201.403 946.592 42.798 986.873 -115.807 0 0 1 2 lb
26.78 +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 1 2 lb
26.79 +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 1 2 lb
26.80 +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 1 0 0 2 lb
26.81 +422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 1 2 lb
26.82 +422.945 521.129 376.371 417.911 329.797 314.692 0 0 1 2 lb
26.83 +422.945 521.129 474.554 276.928 526.164 32.7279 0 0 1 2 lb
26.84 +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 1 2 lb
26.85 +329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 1 2 lb
26.86 +-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 1 2 lb
26.87 +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 1 2 lb
26.88 +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 1 2 lb
26.89 +526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 1 2 lb
26.90 +730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 1 2 lb
26.91 +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0 0 2 lb
26.92 +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 1 2 lb
26.93 +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 1 2 lb
26.94 +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 1 2 lb
26.95 +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 1 2 lb
26.96 +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 1 2 lb
26.97 +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 1 2 lb
26.98 +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 1 2 lb
26.99 +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 1 2 lb
26.100 +116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 1 2 lb
26.101 +-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 1 2 lb
26.102 +-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 1 2 lb
26.103 +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 1 2 lb
26.104 +-180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 1 2 lb
26.105 +-180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 1 2 lb
26.106 +-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 1 2 lb
26.107 +-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 1 2 lb
26.108 +-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 1 2 lb
26.109 +670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 2 lb
26.110 +670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 2 lb
26.111 +588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 2 lb
26.112 +-689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 1 2 lb
26.113 +-689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 1 2 lb
26.114 +grestore
26.115 +%Nodes:
26.116 +gsave
26.117 +-567.302 43.6423 20 0 0 0 nc
26.118 +-689.204 -237.261 20 0 0 0 nc
26.119 +924.667 409.347 20 0 0 1 nc
26.120 +588.113 544.499 20 0 0 1 nc
26.121 +670.264 274.195 20 0 0 1 nc
26.122 +-371.2 568.349 20 1 1 0 nc
26.123 +-132.697 451.748 20 1 1 0 nc
26.124 +-416.25 345.746 20 1 1 0 nc
26.125 +-180.397 245.045 20 1 1 0 nc
26.126 +-13.4452 133.743 20 1 1 0 nc
26.127 +-262.548 107.243 20 1 1 0 nc
26.128 +201.208 38.3422 20 1 1 0 nc
26.129 +116.407 -173.66 20 1 1 0 nc
26.130 +-26.6953 -19.9585 20 1 1 0 nc
26.131 +-539.894 -262.64 20 0 0.5 0 nc
26.132 +-323.543 -433.964 20 0 0.5 0 nc
26.133 +-309.657 -57.9033 20 0 0.5 0 nc
26.134 +-67.9734 -347.42 20 0 0.5 0 nc
26.135 +415.393 -289.516 20 0.5 0 0 nc
26.136 +730.084 -307.139 20 0.5 0 0 nc
26.137 +526.164 32.7279 20 0.5 0 0 nc
26.138 +762.812 -17.6227 20 0.5 0 0 nc
26.139 +-67.9734 319.727 20 0.5 0 0 nc
26.140 +329.797 314.692 20 0.5 0 0 nc
26.141 +-5.03507 561.41 20 0.5 0 0 nc
26.142 +422.945 521.129 20 0.5 0 0 nc
26.143 +-470.779 158.605 20 0 1 1 nc
26.144 +986.873 -115.807 20 0.5 0 0 nc
26.145 +906.312 201.403 20 0.5 0 0 nc
26.146 +-767.847 113.289 20 0 1 1 nc
26.147 +-579.033 445.603 20 0 1 1 nc
26.148 +-840.856 -246.718 20 1 0 1 nc
26.149 +206.221 -205.967 20 0 0 0.5 nc
26.150 +277.311 -252.33 20 0 0 0.5 nc
26.151 +271.13 -175.058 20 0 0 0.5 nc
26.152 +366.947 -110.15 20 0 0 0.5 nc
26.153 +397.855 -196.694 20 0 0 0.5 nc
26.154 +438.037 -88.514 20 0 0 0.5 nc
26.155 +286.584 -48.3327 20 0 0 0.5 nc
26.156 +212.403 -23.6057 20 0 0 0.5 nc
26.157 +280.402 10.3938 20 0 0 0.5 nc
26.158 +694.579 115.483 20 1 0 0 nc
26.159 +574.035 177.301 20 0 1 0 nc
26.160 +grestore
26.161 +grestore
26.162 +showpage
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/doc/images/node_biconnected_components.eps Thu Nov 05 15:48: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 1 0 5 lb
27.60 +694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 5 lb
27.61 +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 1 1 0.5 5 lb
27.62 +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 1 1 0.5 5 lb
27.63 +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 1 1 0.5 5 lb
27.64 +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 1 0.5 1 5 lb
27.65 +286.584 -48.3327 278.857 -111.695 271.13 -175.058 1 0.5 1 5 lb
27.66 +438.037 -88.514 417.946 -142.604 397.855 -196.694 0.5 0.5 1 5 lb
27.67 +438.037 -88.514 402.492 -99.332 366.947 -110.15 0.5 0.5 1 5 lb
27.68 +397.855 -196.694 382.401 -153.422 366.947 -110.15 0.5 0.5 1 5 lb
27.69 +366.947 -110.15 319.038 -142.604 271.13 -175.058 1 0.5 1 5 lb
27.70 +271.13 -175.058 274.221 -213.694 277.311 -252.33 0.5 1 1 5 lb
27.71 +271.13 -175.058 238.675 -190.512 206.221 -205.967 0.5 1 1 5 lb
27.72 +277.311 -252.33 241.766 -229.149 206.221 -205.967 0.5 1 1 5 lb
27.73 +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0.5 0 5 lb
27.74 +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0.5 5 lb
27.75 +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0.5 5 lb
27.76 +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0.5 5 lb
27.77 +906.312 201.403 946.592 42.798 986.873 -115.807 0 0.5 0.5 5 lb
27.78 +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0.5 0.5 5 lb
27.79 +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0.5 0.5 5 lb
27.80 +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0.5 0.5 0 5 lb
27.81 +422.945 521.129 208.955 541.269 -5.03507 561.41 0.5 0 0.5 5 lb
27.82 +422.945 521.129 376.371 417.911 329.797 314.692 0.5 0 0.5 5 lb
27.83 +422.945 521.129 474.554 276.928 526.164 32.7279 0.5 0 0.5 5 lb
27.84 +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0.5 0 0.5 5 lb
27.85 +329.797 314.692 130.912 317.209 -67.9734 319.727 0.5 0 0.5 5 lb
27.86 +-67.9734 319.727 229.095 176.227 526.164 32.7279 0.5 0 0.5 5 lb
27.87 +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0.5 0.5 0.5 5 lb
27.88 +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0.5 0.5 0.5 5 lb
27.89 +526.164 32.7279 470.779 -128.394 415.393 -289.516 0.5 0.5 0.5 5 lb
27.90 +730.084 -307.139 572.738 -298.327 415.393 -289.516 0.5 0.5 0.5 5 lb
27.91 +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0.5 0.5 5 lb
27.92 +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0.5 1 0.5 5 lb
27.93 +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0.5 1 0.5 5 lb
27.94 +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0.5 1 0.5 5 lb
27.95 +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0.5 1 0.5 5 lb
27.96 +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 1 1 0 5 lb
27.97 +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 1 1 0 5 lb
27.98 +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 1 0 1 5 lb
27.99 +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 1 0 1 5 lb
27.100 +116.407 -173.66 158.808 -67.6589 201.208 38.3422 1 1 0 5 lb
27.101 +-262.548 107.243 -137.997 120.493 -13.4452 133.743 1 0 1 5 lb
27.102 +-262.548 107.243 -221.472 176.144 -180.397 245.045 1 0 1 5 lb
27.103 +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 1 0 1 5 lb
27.104 +-180.397 245.045 -140.307 344.649 -132.697 451.748 0 1 1 5 lb
27.105 +-180.397 245.045 -172.787 352.144 -132.697 451.748 0 1 1 5 lb
27.106 +-416.25 345.746 -274.474 398.747 -132.697 451.748 0.5 0 0 5 lb
27.107 +-416.25 345.746 -393.725 457.048 -371.2 568.349 0.5 0 0 5 lb
27.108 +-132.697 451.748 -251.948 510.048 -371.2 568.349 0.5 0 0 5 lb
27.109 +670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 5 lb
27.110 +670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 5 lb
27.111 +588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 5 lb
27.112 +-689.204 -237.261 -612.964 -103.444 -567.302 43.6423 0 0 0 5 lb
27.113 +-689.204 -237.261 -643.542 -90.1744 -567.302 43.6423 0 0 0 5 lb
27.114 +grestore
27.115 +%Nodes:
27.116 +gsave
27.117 +-567.302 43.6423 20 0 0 1 nc
27.118 +-689.204 -237.261 20 0 0 1 nc
27.119 +924.667 409.347 20 0 0 1 nc
27.120 +588.113 544.499 20 0 0 1 nc
27.121 +670.264 274.195 20 1 0 0 nc
27.122 +-371.2 568.349 20 0 0 1 nc
27.123 +-132.697 451.748 20 1 0 0 nc
27.124 +-416.25 345.746 20 0 0 1 nc
27.125 +-180.397 245.045 20 1 0 0 nc
27.126 +-13.4452 133.743 20 0 0 1 nc
27.127 +-262.548 107.243 20 0 0 1 nc
27.128 +201.208 38.3422 20 0 0 1 nc
27.129 +116.407 -173.66 20 0 0 1 nc
27.130 +-26.6953 -19.9585 20 1 0 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 1 0 0 nc
27.134 +-67.9734 -347.42 20 1 0 0 nc
27.135 +415.393 -289.516 20 1 0 0 nc
27.136 +730.084 -307.139 20 0 0 1 nc
27.137 +526.164 32.7279 20 1 0 0 nc
27.138 +762.812 -17.6227 20 1 0 0 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 1 0 0 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 1 0 0 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 0 0 1 nc
27.150 +277.311 -252.33 20 0 0 1 nc
27.151 +271.13 -175.058 20 1 0 0 nc
27.152 +366.947 -110.15 20 1 0 0 nc
27.153 +397.855 -196.694 20 0 0 1 nc
27.154 +438.037 -88.514 20 0 0 1 nc
27.155 +286.584 -48.3327 20 1 0 0 nc
27.156 +212.403 -23.6057 20 0 0 1 nc
27.157 +280.402 10.3938 20 0 0 1 nc
27.158 +694.579 115.483 20 0 0 1 nc
27.159 +574.035 177.301 20 0 0 1 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/strongly_connected_components.eps Thu Nov 05 15:48:01 2009 +0100
28.3 @@ -0,0 +1,180 @@
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 10 def
28.33 +/arrw 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 +77.1122 15 translate
28.54 +0.585745 dup scale
28.55 +90 rotate
28.56 +695.963 -397.916 translate
28.57 +%Edges:
28.58 +gsave
28.59 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.60 +218.178 27.2723 moveto
28.61 +192.373 -40.1551 188.622 -49.9556 169.228 -100.631 curveto stroke
28.62 +newpath 164.939 -111.838 moveto 165.492 -99.2013 lineto 172.964 -102.061 lineto closepath fill
28.63 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.64 +44.8044 15.5841 moveto
28.65 +119.293 20.6059 129.775 21.3125 186.25 25.1199 curveto stroke
28.66 +newpath 198.223 25.927 moveto 186.519 21.1289 lineto 185.981 29.1108 lineto closepath fill
28.67 +2 setlinewidth 1 0 0 setrgbcolor newpath
28.68 +218.178 27.2723 moveto
28.69 +285.395 -87.4449 290.763 -96.6058 348.102 -194.464 curveto stroke
28.70 +newpath 354.169 -204.818 moveto 344.651 -196.487 lineto 351.554 -192.442 lineto closepath fill
28.71 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.72 +157.79 -130.517 moveto
28.73 +108.71 -67.0521 102.27 -58.7243 64.3804 -9.72954 curveto stroke
28.74 +newpath 57.0394 -0.236898 moveto 67.5446 -7.28254 lineto 61.2162 -12.1765 lineto closepath fill
28.75 +2 setlinewidth 1 0 0 setrgbcolor newpath
28.76 +-105.193 -261.035 moveto
28.77 +-35.6576 -132.801 -30.5923 -123.459 29.5506 -12.5464 curveto stroke
28.78 +newpath 35.2708 -1.99743 moveto 33.0669 -14.4531 lineto 26.0343 -10.6397 lineto closepath fill
28.79 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.80 +-465.576 -42.8564 moveto
28.81 +-559.078 -25.5413 -569.47 -23.6169 -644.498 -9.72286 curveto stroke
28.82 +newpath -656.297 -7.5378 moveto -643.77 -5.78973 lineto -645.226 -13.656 lineto closepath fill
28.83 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.84 +-574.666 -153.893 moveto
28.85 +-528.842 -107.252 -521.515 -99.794 -488.002 -65.683 curveto stroke
28.86 +newpath -479.592 -57.123 moveto -485.149 -68.4863 lineto -490.856 -62.8797 lineto closepath fill
28.87 +2 setlinewidth 1 0 0 setrgbcolor newpath
28.88 +-490.901 120.777 moveto
28.89 +-480.122 51.1328 -478.519 40.7713 -470.47 -11.2329 curveto stroke
28.90 +newpath -468.635 -23.0917 moveto -474.423 -11.8447 lineto -466.517 -10.6212 lineto closepath fill
28.91 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.92 +-675.963 -3.89604 moveto
28.93 +-632.116 -68.8235 -626.228 -77.5422 -592.575 -127.374 curveto stroke
28.94 +newpath -585.859 -137.319 moveto -595.89 -129.612 lineto -589.26 -125.135 lineto closepath fill
28.95 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.96 +-490.901 120.777 moveto
28.97 +-435.445 215.844 -430.107 224.995 -384.3 303.522 curveto stroke
28.98 +newpath -378.253 313.887 moveto -380.845 301.507 lineto -387.755 305.537 lineto closepath fill
28.99 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.100 +-266.879 114.933 moveto
28.101 +-367.067 117.547 -377.642 117.822 -458.912 119.943 curveto stroke
28.102 +newpath -470.908 120.255 moveto -458.807 123.941 lineto -459.016 115.944 lineto closepath fill
28.103 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.104 +-368.176 331.163 moveto
28.105 +-322.511 233.685 -318.018 224.095 -280.454 143.911 curveto stroke
28.106 +newpath -275.364 133.044 moveto -284.076 142.214 lineto -276.832 145.608 lineto closepath fill
28.107 +2 setlinewidth 1 0 0 setrgbcolor newpath
28.108 +-266.879 114.933 moveto
28.109 +-224.004 235.52 -220.448 245.52 -184.094 347.765 curveto stroke
28.110 +newpath -180.074 359.072 moveto -180.325 346.425 lineto -187.863 349.105 lineto closepath fill
28.111 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.112 +-251.294 -335.059 moveto
28.113 +-189.25 -303.624 -179.902 -298.887 -133.738 -275.498 curveto stroke
28.114 +newpath -123.034 -270.074 moveto -131.93 -279.066 lineto -135.546 -271.93 lineto closepath fill
28.115 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.116 +-389.604 -136.361 moveto
28.117 +-327.15 -226.083 -321.098 -234.777 -269.576 -308.795 curveto stroke
28.118 +newpath -262.72 -318.644 moveto -272.859 -311.081 lineto -266.293 -306.51 lineto closepath fill
28.119 +2 setlinewidth 1 0 0 setrgbcolor newpath
28.120 +5.84406 175.322 moveto
28.121 +-76.0754 267.926 -83.1051 275.873 -152.172 353.948 curveto stroke
28.122 +newpath -160.122 362.936 moveto -149.176 356.598 lineto -155.168 351.298 lineto closepath fill
28.123 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.124 +169.478 311.683 moveto
28.125 +96.8003 251.119 88.6819 244.353 30.4273 195.808 curveto stroke
28.126 +newpath 21.2086 188.126 moveto 27.8666 198.881 lineto 32.988 192.735 lineto closepath fill
28.127 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.128 +342.851 111.037 moveto
28.129 +263.766 202.563 256.831 210.589 190.4 287.47 curveto stroke
28.130 +newpath 182.554 296.55 moveto 193.427 290.085 lineto 187.373 284.855 lineto closepath fill
28.131 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.132 +5.84406 175.322 moveto
28.133 +163.16 145.314 173.605 143.321 311.418 117.033 curveto stroke
28.134 +newpath 323.205 114.784 moveto 310.668 113.104 lineto 312.167 120.962 lineto closepath fill
28.135 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.136 +342.851 111.037 moveto
28.137 +497.255 2.58683 505.964 -3.53033 643.932 -100.436 curveto stroke
28.138 +newpath 653.752 -107.334 moveto 641.633 -103.71 lineto 646.231 -97.163 lineto closepath fill
28.139 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.140 +364.28 -222.074 moveto
28.141 +354.298 -66.9063 353.616 -56.2971 344.905 79.1029 curveto stroke
28.142 +newpath 344.135 91.0781 moveto 348.897 79.3597 lineto 340.914 78.8461 lineto closepath fill
28.143 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.144 +670.118 -118.829 moveto
28.145 +528.037 -166.793 517.967 -170.192 394.599 -211.839 curveto stroke
28.146 +newpath 383.229 -215.677 moveto 393.32 -208.049 lineto 395.878 -215.629 lineto closepath fill
28.147 +2 setlinewidth 1 0 0 setrgbcolor newpath
28.148 +-105.193 -261.035 moveto
28.149 +118.401 -242.479 129.015 -241.598 332.39 -224.721 curveto stroke
28.150 +newpath 344.348 -223.728 moveto 332.72 -228.707 lineto 332.059 -220.734 lineto closepath fill
28.151 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.152 +-105.193 -261.035 moveto
28.153 +-160.867 -161.176 -166.028 -151.918 -212.336 -68.858 curveto stroke
28.154 +newpath -218.179 -58.3769 moveto -208.842 -66.9102 lineto -215.829 -70.8058 lineto closepath fill
28.155 +2 setlinewidth 0 0 1 setrgbcolor newpath
28.156 +-227.918 -40.9084 moveto
28.157 +-298.35 -82.4884 -307.42 -87.8432 -362.048 -120.093 curveto stroke
28.158 +newpath -372.381 -126.193 moveto -364.081 -116.648 lineto -360.014 -123.537 lineto closepath fill
28.159 +grestore
28.160 +%Nodes:
28.161 +gsave
28.162 +-389.604 -136.361 20 0 1 0 nc
28.163 +-227.918 -40.9084 20 0 1 0 nc
28.164 +-105.193 -261.035 20 0 1 0 nc
28.165 +364.28 -222.074 20 1 1 0 nc
28.166 +670.118 -118.829 20 1 1 0 nc
28.167 +342.851 111.037 20 1 1 0 nc
28.168 +5.84406 175.322 20 1 1 0 nc
28.169 +169.478 311.683 20 1 1 0 nc
28.170 +-173.374 377.916 20 1 0 1 nc
28.171 +-251.294 -335.059 20 0 1 0 nc
28.172 +-266.879 114.933 20 0 0 0 nc
28.173 +-368.176 331.163 20 0 0 0 nc
28.174 +-490.901 120.777 20 0 0 0 nc
28.175 +-574.666 -153.893 20 1 0 0 nc
28.176 +-675.963 -3.89604 20 1 0 0 nc
28.177 +-465.576 -42.8564 20 1 0 0 nc
28.178 +44.8044 15.5841 20 0 0 1 nc
28.179 +157.79 -130.517 20 0 0 1 nc
28.180 +218.178 27.2723 20 0 0 1 nc
28.181 +grestore
28.182 +grestore
28.183 +showpage
29.1 --- a/doc/mainpage.dox Mon Jan 12 23:11:39 2009 +0100
29.2 +++ b/doc/mainpage.dox Thu Nov 05 15:48:01 2009 +0100
29.3 @@ -21,15 +21,11 @@
29.4
29.5 \section intro Introduction
29.6
29.7 -\subsection whatis What is LEMON
29.8 -
29.9 -LEMON stands for
29.10 -<b>L</b>ibrary of <b>E</b>fficient <b>M</b>odels
29.11 -and <b>O</b>ptimization in <b>N</b>etworks.
29.12 -It is a C++ template
29.13 -library aimed at combinatorial optimization tasks which
29.14 -often involve in working
29.15 -with graphs.
29.16 +<b>LEMON</b> stands for <i><b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
29.17 +and <b>O</b>ptimization in <b>N</b>etworks</i>.
29.18 +It is a C++ template library providing efficient implementation of common
29.19 +data structures and algorithms with focus on combinatorial optimization
29.20 +problems in graphs and networks.
29.21
29.22 <b>
29.23 LEMON is an <a class="el" href="http://opensource.org/">open source</a>
29.24 @@ -39,22 +35,22 @@
29.25 \ref license "license terms".
29.26 </b>
29.27
29.28 -\subsection howtoread How to read the documentation
29.29 +The project is maintained by the
29.30 +<a href="http://www.cs.elte.hu/egres/">Egerváry Research Group on
29.31 +Combinatorial Optimization</a> \ref egres
29.32 +at the Operations Research Department of the
29.33 +<a href="http://www.elte.hu/">Eötvös Loránd University,
29.34 +Budapest</a>, Hungary.
29.35 +LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
29.36 +initiative \ref coinor.
29.37
29.38 -If you want to get a quick start and see the most important features then
29.39 -take a look at our \ref quicktour
29.40 -"Quick Tour to LEMON" which will guide you along.
29.41 +\section howtoread How to Read the Documentation
29.42
29.43 -If you already feel like using our library, see the page that tells you
29.44 -\ref getstart "How to start using LEMON".
29.45 +If you would like to get to know the library, see
29.46 +<a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
29.47
29.48 -If you
29.49 -want to see how LEMON works, see
29.50 -some \ref demoprograms "demo programs".
29.51 -
29.52 -If you know what you are looking for then try to find it under the
29.53 -<a class="el" href="modules.html">Modules</a>
29.54 -section.
29.55 +If you know what you are looking for, then try to find it under the
29.56 +<a class="el" href="modules.html">Modules</a> section.
29.57
29.58 If you are a user of the old (0.x) series of LEMON, please check out the
29.59 \ref migration "Migration Guide" for the backward incompatibilities.
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/doc/min_cost_flow.dox Thu Nov 05 15:48:01 2009 +0100
30.3 @@ -0,0 +1,153 @@
30.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
30.5 + *
30.6 + * This file is a part of LEMON, a generic C++ optimization library.
30.7 + *
30.8 + * Copyright (C) 2003-2009
30.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
30.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
30.11 + *
30.12 + * Permission to use, modify and distribute this software is granted
30.13 + * provided that this copyright notice appears in all copies. For
30.14 + * precise terms see the accompanying LICENSE file.
30.15 + *
30.16 + * This software is provided "AS IS" with no warranty of any kind,
30.17 + * express or implied, and with no claim as to its suitability for any
30.18 + * purpose.
30.19 + *
30.20 + */
30.21 +
30.22 +namespace lemon {
30.23 +
30.24 +/**
30.25 +\page min_cost_flow Minimum Cost Flow Problem
30.26 +
30.27 +\section mcf_def Definition (GEQ form)
30.28 +
30.29 +The \e minimum \e cost \e flow \e problem is to find a feasible flow of
30.30 +minimum total cost from a set of supply nodes to a set of demand nodes
30.31 +in a network with capacity constraints (lower and upper bounds)
30.32 +and arc costs \ref amo93networkflows.
30.33 +
30.34 +Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
30.35 +\f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
30.36 +upper bounds for the flow values on the arcs, for which
30.37 +\f$lower(uv) \leq upper(uv)\f$ must hold for all \f$uv\in A\f$,
30.38 +\f$cost: A\rightarrow\mathbf{R}\f$ denotes the cost per unit flow
30.39 +on the arcs and \f$sup: V\rightarrow\mathbf{R}\f$ denotes the
30.40 +signed supply values of the nodes.
30.41 +If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
30.42 +supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
30.43 +\f$-sup(u)\f$ demand.
30.44 +A minimum cost flow is an \f$f: A\rightarrow\mathbf{R}\f$ solution
30.45 +of the following optimization problem.
30.46 +
30.47 +\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
30.48 +\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \geq
30.49 + sup(u) \quad \forall u\in V \f]
30.50 +\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
30.51 +
30.52 +The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
30.53 +zero or negative in order to have a feasible solution (since the sum
30.54 +of the expressions on the left-hand side of the inequalities is zero).
30.55 +It means that the total demand must be greater or equal to the total
30.56 +supply and all the supplies have to be carried out from the supply nodes,
30.57 +but there could be demands that are not satisfied.
30.58 +If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
30.59 +constraints have to be satisfied with equality, i.e. all demands
30.60 +have to be satisfied and all supplies have to be used.
30.61 +
30.62 +
30.63 +\section mcf_algs Algorithms
30.64 +
30.65 +LEMON contains several algorithms for solving this problem, for more
30.66 +information see \ref min_cost_flow_algs "Minimum Cost Flow Algorithms".
30.67 +
30.68 +A feasible solution for this problem can be found using \ref Circulation.
30.69 +
30.70 +
30.71 +\section mcf_dual Dual Solution
30.72 +
30.73 +The dual solution of the minimum cost flow problem is represented by
30.74 +node potentials \f$\pi: V\rightarrow\mathbf{R}\f$.
30.75 +An \f$f: A\rightarrow\mathbf{R}\f$ primal feasible solution is optimal
30.76 +if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$ node potentials
30.77 +the following \e complementary \e slackness optimality conditions hold.
30.78 +
30.79 + - For all \f$uv\in A\f$ arcs:
30.80 + - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
30.81 + - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
30.82 + - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
30.83 + - For all \f$u\in V\f$ nodes:
30.84 + - \f$\pi(u)<=0\f$;
30.85 + - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
30.86 + then \f$\pi(u)=0\f$.
30.87 +
30.88 +Here \f$cost^\pi(uv)\f$ denotes the \e reduced \e cost of the arc
30.89 +\f$uv\in A\f$ with respect to the potential function \f$\pi\f$, i.e.
30.90 +\f[ cost^\pi(uv) = cost(uv) + \pi(u) - \pi(v).\f]
30.91 +
30.92 +All algorithms provide dual solution (node potentials), as well,
30.93 +if an optimal flow is found.
30.94 +
30.95 +
30.96 +\section mcf_eq Equality Form
30.97 +
30.98 +The above \ref mcf_def "definition" is actually more general than the
30.99 +usual formulation of the minimum cost flow problem, in which strict
30.100 +equalities are required in the supply/demand contraints.
30.101 +
30.102 +\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
30.103 +\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) =
30.104 + sup(u) \quad \forall u\in V \f]
30.105 +\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
30.106 +
30.107 +However if the sum of the supply values is zero, then these two problems
30.108 +are equivalent.
30.109 +The \ref min_cost_flow_algs "algorithms" in LEMON support the general
30.110 +form, so if you need the equality form, you have to ensure this additional
30.111 +contraint manually.
30.112 +
30.113 +
30.114 +\section mcf_leq Opposite Inequalites (LEQ Form)
30.115 +
30.116 +Another possible definition of the minimum cost flow problem is
30.117 +when there are <em>"less or equal"</em> (LEQ) supply/demand constraints,
30.118 +instead of the <em>"greater or equal"</em> (GEQ) constraints.
30.119 +
30.120 +\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
30.121 +\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \leq
30.122 + sup(u) \quad \forall u\in V \f]
30.123 +\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
30.124 +
30.125 +It means that the total demand must be less or equal to the
30.126 +total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
30.127 +positive) and all the demands have to be satisfied, but there
30.128 +could be supplies that are not carried out from the supply
30.129 +nodes.
30.130 +The equality form is also a special case of this form, of course.
30.131 +
30.132 +You could easily transform this case to the \ref mcf_def "GEQ form"
30.133 +of the problem by reversing the direction of the arcs and taking the
30.134 +negative of the supply values (e.g. using \ref ReverseDigraph and
30.135 +\ref NegMap adaptors).
30.136 +However \ref NetworkSimplex algorithm also supports this form directly
30.137 +for the sake of convenience.
30.138 +
30.139 +Note that the optimality conditions for this supply constraint type are
30.140 +slightly differ from the conditions that are discussed for the GEQ form,
30.141 +namely the potentials have to be non-negative instead of non-positive.
30.142 +An \f$f: A\rightarrow\mathbf{R}\f$ feasible solution of this problem
30.143 +is optimal if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$
30.144 +node potentials the following conditions hold.
30.145 +
30.146 + - For all \f$uv\in A\f$ arcs:
30.147 + - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
30.148 + - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
30.149 + - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
30.150 + - For all \f$u\in V\f$ nodes:
30.151 + - \f$\pi(u)>=0\f$;
30.152 + - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
30.153 + then \f$\pi(u)=0\f$.
30.154 +
30.155 +*/
30.156 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/doc/references.bib Thu Nov 05 15:48:01 2009 +0100
31.3 @@ -0,0 +1,301 @@
31.4 +%%%%% Defining LEMON %%%%%
31.5 +
31.6 +@misc{lemon,
31.7 + key = {LEMON},
31.8 + title = {{LEMON} -- {L}ibrary for {E}fficient {M}odeling and
31.9 + {O}ptimization in {N}etworks},
31.10 + howpublished = {\url{http://lemon.cs.elte.hu/}},
31.11 + year = 2009
31.12 +}
31.13 +
31.14 +@misc{egres,
31.15 + key = {EGRES},
31.16 + title = {{EGRES} -- {E}gerv{\'a}ry {R}esearch {G}roup on
31.17 + {C}ombinatorial {O}ptimization},
31.18 + url = {http://www.cs.elte.hu/egres/}
31.19 +}
31.20 +
31.21 +@misc{coinor,
31.22 + key = {COIN-OR},
31.23 + title = {{COIN-OR} -- {C}omputational {I}nfrastructure for
31.24 + {O}perations {R}esearch},
31.25 + url = {http://www.coin-or.org/}
31.26 +}
31.27 +
31.28 +
31.29 +%%%%% Other libraries %%%%%%
31.30 +
31.31 +@misc{boost,
31.32 + key = {Boost},
31.33 + title = {{B}oost {C++} {L}ibraries},
31.34 + url = {http://www.boost.org/}
31.35 +}
31.36 +
31.37 +@book{bglbook,
31.38 + author = {Jeremy G. Siek and Lee-Quan Lee and Andrew
31.39 + Lumsdaine},
31.40 + title = {The Boost Graph Library: User Guide and Reference
31.41 + Manual},
31.42 + publisher = {Addison-Wesley},
31.43 + year = 2002
31.44 +}
31.45 +
31.46 +@misc{leda,
31.47 + key = {LEDA},
31.48 + title = {{LEDA} -- {L}ibrary of {E}fficient {D}ata {T}ypes and
31.49 + {A}lgorithms},
31.50 + url = {http://www.algorithmic-solutions.com/}
31.51 +}
31.52 +
31.53 +@book{ledabook,
31.54 + author = {Kurt Mehlhorn and Stefan N{\"a}her},
31.55 + title = {{LEDA}: {A} platform for combinatorial and geometric
31.56 + computing},
31.57 + isbn = {0-521-56329-1},
31.58 + publisher = {Cambridge University Press},
31.59 + address = {New York, NY, USA},
31.60 + year = 1999
31.61 +}
31.62 +
31.63 +
31.64 +%%%%% Tools that LEMON depends on %%%%%
31.65 +
31.66 +@misc{cmake,
31.67 + key = {CMake},
31.68 + title = {{CMake} -- {C}ross {P}latform {M}ake},
31.69 + url = {http://www.cmake.org/}
31.70 +}
31.71 +
31.72 +@misc{doxygen,
31.73 + key = {Doxygen},
31.74 + title = {{Doxygen} -- {S}ource code documentation generator
31.75 + tool},
31.76 + url = {http://www.doxygen.org/}
31.77 +}
31.78 +
31.79 +
31.80 +%%%%% LP/MIP libraries %%%%%
31.81 +
31.82 +@misc{glpk,
31.83 + key = {GLPK},
31.84 + title = {{GLPK} -- {GNU} {L}inear {P}rogramming {K}it},
31.85 + url = {http://www.gnu.org/software/glpk/}
31.86 +}
31.87 +
31.88 +@misc{clp,
31.89 + key = {Clp},
31.90 + title = {{Clp} -- {Coin-Or} {L}inear {P}rogramming},
31.91 + url = {http://projects.coin-or.org/Clp/}
31.92 +}
31.93 +
31.94 +@misc{cbc,
31.95 + key = {Cbc},
31.96 + title = {{Cbc} -- {Coin-Or} {B}ranch and {C}ut},
31.97 + url = {http://projects.coin-or.org/Cbc/}
31.98 +}
31.99 +
31.100 +@misc{cplex,
31.101 + key = {CPLEX},
31.102 + title = {{ILOG} {CPLEX}},
31.103 + url = {http://www.ilog.com/}
31.104 +}
31.105 +
31.106 +@misc{soplex,
31.107 + key = {SoPlex},
31.108 + title = {{SoPlex} -- {T}he {S}equential {O}bject-{O}riented
31.109 + {S}implex},
31.110 + url = {http://soplex.zib.de/}
31.111 +}
31.112 +
31.113 +
31.114 +%%%%% General books %%%%%
31.115 +
31.116 +@book{amo93networkflows,
31.117 + author = {Ravindra K. Ahuja and Thomas L. Magnanti and James
31.118 + B. Orlin},
31.119 + title = {Network Flows: Theory, Algorithms, and Applications},
31.120 + publisher = {Prentice-Hall, Inc.},
31.121 + year = 1993,
31.122 + month = feb,
31.123 + isbn = {978-0136175490}
31.124 +}
31.125 +
31.126 +@book{schrijver03combinatorial,
31.127 + author = {Alexander Schrijver},
31.128 + title = {Combinatorial Optimization: Polyhedra and Efficiency},
31.129 + publisher = {Springer-Verlag},
31.130 + year = 2003,
31.131 + isbn = {978-3540443896}
31.132 +}
31.133 +
31.134 +@book{clrs01algorithms,
31.135 + author = {Thomas H. Cormen and Charles E. Leiserson and Ronald
31.136 + L. Rivest and Clifford Stein},
31.137 + title = {Introduction to Algorithms},
31.138 + publisher = {The MIT Press},
31.139 + year = 2001,
31.140 + edition = {2nd}
31.141 +}
31.142 +
31.143 +@book{stroustrup00cpp,
31.144 + author = {Bjarne Stroustrup},
31.145 + title = {The C++ Programming Language},
31.146 + edition = {3rd},
31.147 + publisher = {Addison-Wesley Professional},
31.148 + isbn = 0201700735,
31.149 + month = {February},
31.150 + year = 2000
31.151 +}
31.152 +
31.153 +
31.154 +%%%%% Maximum flow algorithms %%%%%
31.155 +
31.156 +@article{edmondskarp72theoretical,
31.157 + author = {Jack Edmonds and Richard M. Karp},
31.158 + title = {Theoretical improvements in algorithmic efficiency
31.159 + for network flow problems},
31.160 + journal = {Journal of the ACM},
31.161 + year = 1972,
31.162 + volume = 19,
31.163 + number = 2,
31.164 + pages = {248-264}
31.165 +}
31.166 +
31.167 +@article{goldberg88newapproach,
31.168 + author = {Andrew V. Goldberg and Robert E. Tarjan},
31.169 + title = {A new approach to the maximum flow problem},
31.170 + journal = {Journal of the ACM},
31.171 + year = 1988,
31.172 + volume = 35,
31.173 + number = 4,
31.174 + pages = {921-940}
31.175 +}
31.176 +
31.177 +@article{dinic70algorithm,
31.178 + author = {E. A. Dinic},
31.179 + title = {Algorithm for solution of a problem of maximum flow
31.180 + in a network with power estimation},
31.181 + journal = {Soviet Math. Doklady},
31.182 + year = 1970,
31.183 + volume = 11,
31.184 + pages = {1277-1280}
31.185 +}
31.186 +
31.187 +@article{goldberg08partial,
31.188 + author = {Andrew V. Goldberg},
31.189 + title = {The Partial Augment-Relabel Algorithm for the
31.190 + Maximum Flow Problem},
31.191 + journal = {16th Annual European Symposium on Algorithms},
31.192 + year = 2008,
31.193 + pages = {466-477}
31.194 +}
31.195 +
31.196 +@article{sleator83dynamic,
31.197 + author = {Daniel D. Sleator and Robert E. Tarjan},
31.198 + title = {A data structure for dynamic trees},
31.199 + journal = {Journal of Computer and System Sciences},
31.200 + year = 1983,
31.201 + volume = 26,
31.202 + number = 3,
31.203 + pages = {362-391}
31.204 +}
31.205 +
31.206 +
31.207 +%%%%% Minimum mean cycle algorithms %%%%%
31.208 +
31.209 +@article{karp78characterization,
31.210 + author = {Richard M. Karp},
31.211 + title = {A characterization of the minimum cycle mean in a
31.212 + digraph},
31.213 + journal = {Discrete Math.},
31.214 + year = 1978,
31.215 + volume = 23,
31.216 + pages = {309-311}
31.217 +}
31.218 +
31.219 +@article{dasdan98minmeancycle,
31.220 + author = {Ali Dasdan and Rajesh K. Gupta},
31.221 + title = {Faster Maximum and Minimum Mean Cycle Alogrithms for
31.222 + System Performance Analysis},
31.223 + journal = {IEEE Transactions on Computer-Aided Design of
31.224 + Integrated Circuits and Systems},
31.225 + year = 1998,
31.226 + volume = 17,
31.227 + number = 10,
31.228 + pages = {889-899}
31.229 +}
31.230 +
31.231 +
31.232 +%%%%% Minimum cost flow algorithms %%%%%
31.233 +
31.234 +@article{klein67primal,
31.235 + author = {Morton Klein},
31.236 + title = {A primal method for minimal cost flows with
31.237 + applications to the assignment and transportation
31.238 + problems},
31.239 + journal = {Management Science},
31.240 + year = 1967,
31.241 + volume = 14,
31.242 + pages = {205-220}
31.243 +}
31.244 +
31.245 +@article{goldberg89cyclecanceling,
31.246 + author = {Andrew V. Goldberg and Robert E. Tarjan},
31.247 + title = {Finding minimum-cost circulations by canceling
31.248 + negative cycles},
31.249 + journal = {Journal of the ACM},
31.250 + year = 1989,
31.251 + volume = 36,
31.252 + number = 4,
31.253 + pages = {873-886}
31.254 +}
31.255 +
31.256 +@article{goldberg90approximation,
31.257 + author = {Andrew V. Goldberg and Robert E. Tarjan},
31.258 + title = {Finding Minimum-Cost Circulations by Successive
31.259 + Approximation},
31.260 + journal = {Mathematics of Operations Research},
31.261 + year = 1990,
31.262 + volume = 15,
31.263 + number = 3,
31.264 + pages = {430-466}
31.265 +}
31.266 +
31.267 +@article{goldberg97efficient,
31.268 + author = {Andrew V. Goldberg},
31.269 + title = {An Efficient Implementation of a Scaling
31.270 + Minimum-Cost Flow Algorithm},
31.271 + journal = {Journal of Algorithms},
31.272 + year = 1997,
31.273 + volume = 22,
31.274 + number = 1,
31.275 + pages = {1-29}
31.276 +}
31.277 +
31.278 +@article{bunnagel98efficient,
31.279 + author = {Ursula B{\"u}nnagel and Bernhard Korte and Jens
31.280 + Vygen},
31.281 + title = {Efficient implementation of the {G}oldberg-{T}arjan
31.282 + minimum-cost flow algorithm},
31.283 + journal = {Optimization Methods and Software},
31.284 + year = 1998,
31.285 + volume = 10,
31.286 + pages = {157-174}
31.287 +}
31.288 +
31.289 +@book{dantzig63linearprog,
31.290 + author = {George B. Dantzig},
31.291 + title = {Linear Programming and Extensions},
31.292 + publisher = {Princeton University Press},
31.293 + year = 1963
31.294 +}
31.295 +
31.296 +@mastersthesis{kellyoneill91netsimplex,
31.297 + author = {Damian J. Kelly and Garrett M. O'Neill},
31.298 + title = {The Minimum Cost Flow Problem and The Network
31.299 + Simplex Method},
31.300 + school = {University College},
31.301 + address = {Dublin, Ireland},
31.302 + year = 1991,
31.303 + month = sep,
31.304 +}
32.1 --- a/lemon/CMakeLists.txt Mon Jan 12 23:11:39 2009 +0100
32.2 +++ b/lemon/CMakeLists.txt Thu Nov 05 15:48:01 2009 +0100
32.3 @@ -1,18 +1,68 @@
32.4 -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
32.5 +INCLUDE_DIRECTORIES(
32.6 + ${PROJECT_SOURCE_DIR}
32.7 + ${PROJECT_BINARY_DIR}
32.8 +)
32.9
32.10 -ADD_LIBRARY(lemon
32.11 +CONFIGURE_FILE(
32.12 + ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
32.13 + ${CMAKE_CURRENT_BINARY_DIR}/config.h
32.14 +)
32.15 +
32.16 +SET(LEMON_SOURCES
32.17 arg_parser.cc
32.18 base.cc
32.19 color.cc
32.20 - random.cc)
32.21 + lp_base.cc
32.22 + lp_skeleton.cc
32.23 + random.cc
32.24 + bits/windows.cc
32.25 +)
32.26 +
32.27 +IF(LEMON_HAVE_GLPK)
32.28 + SET(LEMON_SOURCES ${LEMON_SOURCES} glpk.cc)
32.29 + INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIRS})
32.30 + IF(WIN32)
32.31 + INSTALL(FILES ${GLPK_BIN_DIR}/glpk.dll DESTINATION bin)
32.32 + INSTALL(FILES ${GLPK_BIN_DIR}/libltdl3.dll DESTINATION bin)
32.33 + INSTALL(FILES ${GLPK_BIN_DIR}/zlib1.dll DESTINATION bin)
32.34 + ENDIF()
32.35 +ENDIF()
32.36 +
32.37 +IF(LEMON_HAVE_CPLEX)
32.38 + SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc)
32.39 + INCLUDE_DIRECTORIES(${CPLEX_INCLUDE_DIRS})
32.40 +ENDIF()
32.41 +
32.42 +IF(LEMON_HAVE_CLP)
32.43 + SET(LEMON_SOURCES ${LEMON_SOURCES} clp.cc)
32.44 + INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
32.45 +ENDIF()
32.46 +
32.47 +IF(LEMON_HAVE_CBC)
32.48 + SET(LEMON_SOURCES ${LEMON_SOURCES} cbc.cc)
32.49 + INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
32.50 +ENDIF()
32.51 +
32.52 +ADD_LIBRARY(lemon ${LEMON_SOURCES})
32.53 +IF(UNIX)
32.54 + SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon)
32.55 +ENDIF()
32.56
32.57 INSTALL(
32.58 TARGETS lemon
32.59 ARCHIVE DESTINATION lib
32.60 - COMPONENT library)
32.61 + COMPONENT library
32.62 +)
32.63
32.64 INSTALL(
32.65 DIRECTORY . bits concepts
32.66 DESTINATION include/lemon
32.67 COMPONENT headers
32.68 - FILES_MATCHING PATTERN "*.h")
32.69 + FILES_MATCHING PATTERN "*.h"
32.70 +)
32.71 +
32.72 +INSTALL(
32.73 + FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h
32.74 + DESTINATION include/lemon
32.75 + COMPONENT headers
32.76 +)
33.1 --- a/lemon/Makefile.am Mon Jan 12 23:11:39 2009 +0100
33.2 +++ b/lemon/Makefile.am Thu Nov 05 15:48:01 2009 +0100
33.3 @@ -1,6 +1,7 @@
33.4 EXTRA_DIST += \
33.5 lemon/lemon.pc.in \
33.6 - lemon/CMakeLists.txt
33.7 + lemon/CMakeLists.txt \
33.8 + lemon/config.h.cmake
33.9
33.10 pkgconfig_DATA += lemon/lemon.pc
33.11
33.12 @@ -12,20 +13,25 @@
33.13 lemon/color.cc \
33.14 lemon/lp_base.cc \
33.15 lemon/lp_skeleton.cc \
33.16 - lemon/random.cc
33.17 + lemon/random.cc \
33.18 + lemon/bits/windows.cc
33.19
33.20 +nodist_lemon_HEADERS = lemon/config.h
33.21
33.22 lemon_libemon_la_CXXFLAGS = \
33.23 + $(AM_CXXFLAGS) \
33.24 $(GLPK_CFLAGS) \
33.25 $(CPLEX_CFLAGS) \
33.26 $(SOPLEX_CXXFLAGS) \
33.27 - $(CLP_CXXFLAGS)
33.28 + $(CLP_CXXFLAGS) \
33.29 + $(CBC_CXXFLAGS)
33.30
33.31 lemon_libemon_la_LDFLAGS = \
33.32 $(GLPK_LIBS) \
33.33 $(CPLEX_LIBS) \
33.34 $(SOPLEX_LIBS) \
33.35 - $(CLP_LIBS)
33.36 + $(CLP_LIBS) \
33.37 + $(CBC_LIBS)
33.38
33.39 if HAVE_GLPK
33.40 lemon_libemon_la_SOURCES += lemon/glpk.cc
33.41 @@ -43,16 +49,25 @@
33.42 lemon_libemon_la_SOURCES += lemon/clp.cc
33.43 endif
33.44
33.45 +if HAVE_CBC
33.46 +lemon_libemon_la_SOURCES += lemon/cbc.cc
33.47 +endif
33.48 +
33.49 lemon_HEADERS += \
33.50 lemon/adaptors.h \
33.51 lemon/arg_parser.h \
33.52 lemon/assert.h \
33.53 + lemon/bellman_ford.h \
33.54 lemon/bfs.h \
33.55 lemon/bin_heap.h \
33.56 + lemon/binom_heap.h \
33.57 + lemon/bucket_heap.h \
33.58 + lemon/cbc.h \
33.59 lemon/circulation.h \
33.60 lemon/clp.h \
33.61 lemon/color.h \
33.62 lemon/concept_check.h \
33.63 + lemon/connectivity.h \
33.64 lemon/counter.h \
33.65 lemon/core.h \
33.66 lemon/cplex.h \
33.67 @@ -63,11 +78,19 @@
33.68 lemon/edge_set.h \
33.69 lemon/elevator.h \
33.70 lemon/error.h \
33.71 + lemon/euler.h \
33.72 + lemon/fib_heap.h \
33.73 + lemon/fourary_heap.h \
33.74 lemon/full_graph.h \
33.75 lemon/glpk.h \
33.76 + lemon/gomory_hu.h \
33.77 lemon/graph_to_eps.h \
33.78 lemon/grid_graph.h \
33.79 + lemon/hartmann_orlin.h \
33.80 + lemon/howard.h \
33.81 lemon/hypercube_graph.h \
33.82 + lemon/karp.h \
33.83 + lemon/kary_heap.h \
33.84 lemon/kruskal.h \
33.85 lemon/hao_orlin.h \
33.86 lemon/lgf_reader.h \
33.87 @@ -76,26 +99,30 @@
33.88 lemon/lp.h \
33.89 lemon/lp_base.h \
33.90 lemon/lp_skeleton.h \
33.91 - lemon/list_graph.h \
33.92 lemon/maps.h \
33.93 + lemon/matching.h \
33.94 lemon/math.h \
33.95 - lemon/max_matching.h \
33.96 + lemon/min_cost_arborescence.h \
33.97 lemon/nauty_reader.h \
33.98 + lemon/network_simplex.h \
33.99 + lemon/pairing_heap.h \
33.100 lemon/path.h \
33.101 lemon/preflow.h \
33.102 + lemon/radix_heap.h \
33.103 lemon/radix_sort.h \
33.104 lemon/random.h \
33.105 lemon/smart_graph.h \
33.106 lemon/soplex.h \
33.107 + lemon/static_graph.h \
33.108 lemon/suurballe.h \
33.109 lemon/time_measure.h \
33.110 lemon/tolerance.h \
33.111 - lemon/unionfind.h
33.112 + lemon/unionfind.h \
33.113 + lemon/bits/windows.h
33.114
33.115 bits_HEADERS += \
33.116 lemon/bits/alteration_notifier.h \
33.117 lemon/bits/array_map.h \
33.118 - lemon/bits/base_extender.h \
33.119 lemon/bits/bezier.h \
33.120 lemon/bits/default_map.h \
33.121 lemon/bits/edge_set_extender.h \
34.1 --- a/lemon/adaptors.h Mon Jan 12 23:11:39 2009 +0100
34.2 +++ b/lemon/adaptors.h Thu Nov 05 15:48:01 2009 +0100
34.3 @@ -30,29 +30,35 @@
34.4 #include <lemon/bits/variant.h>
34.5
34.6 #include <lemon/bits/graph_adaptor_extender.h>
34.7 +#include <lemon/bits/map_extender.h>
34.8 #include <lemon/tolerance.h>
34.9
34.10 #include <algorithm>
34.11
34.12 namespace lemon {
34.13
34.14 - template<typename _Digraph>
34.15 +#ifdef _MSC_VER
34.16 +#define LEMON_SCOPE_FIX(OUTER, NESTED) OUTER::NESTED
34.17 +#else
34.18 +#define LEMON_SCOPE_FIX(OUTER, NESTED) typename OUTER::template NESTED
34.19 +#endif
34.20 +
34.21 + template<typename DGR>
34.22 class DigraphAdaptorBase {
34.23 public:
34.24 - typedef _Digraph Digraph;
34.25 + typedef DGR Digraph;
34.26 typedef DigraphAdaptorBase Adaptor;
34.27 - typedef Digraph ParentDigraph;
34.28
34.29 protected:
34.30 - Digraph* _digraph;
34.31 + DGR* _digraph;
34.32 DigraphAdaptorBase() : _digraph(0) { }
34.33 - void setDigraph(Digraph& digraph) { _digraph = &digraph; }
34.34 + void initialize(DGR& digraph) { _digraph = &digraph; }
34.35
34.36 public:
34.37 - DigraphAdaptorBase(Digraph& digraph) : _digraph(&digraph) { }
34.38 -
34.39 - typedef typename Digraph::Node Node;
34.40 - typedef typename Digraph::Arc Arc;
34.41 + DigraphAdaptorBase(DGR& digraph) : _digraph(&digraph) { }
34.42 +
34.43 + typedef typename DGR::Node Node;
34.44 + typedef typename DGR::Arc Arc;
34.45
34.46 void first(Node& i) const { _digraph->first(i); }
34.47 void first(Arc& i) const { _digraph->first(i); }
34.48 @@ -67,13 +73,13 @@
34.49 Node source(const Arc& a) const { return _digraph->source(a); }
34.50 Node target(const Arc& a) const { return _digraph->target(a); }
34.51
34.52 - typedef NodeNumTagIndicator<Digraph> NodeNumTag;
34.53 + typedef NodeNumTagIndicator<DGR> NodeNumTag;
34.54 int nodeNum() const { return _digraph->nodeNum(); }
34.55
34.56 - typedef ArcNumTagIndicator<Digraph> ArcNumTag;
34.57 + typedef ArcNumTagIndicator<DGR> ArcNumTag;
34.58 int arcNum() const { return _digraph->arcNum(); }
34.59
34.60 - typedef FindArcTagIndicator<Digraph> FindArcTag;
34.61 + typedef FindArcTagIndicator<DGR> FindArcTag;
34.62 Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) const {
34.63 return _digraph->findArc(u, v, prev);
34.64 }
34.65 @@ -95,22 +101,20 @@
34.66 int maxNodeId() const { return _digraph->maxNodeId(); }
34.67 int maxArcId() const { return _digraph->maxArcId(); }
34.68
34.69 - typedef typename ItemSetTraits<Digraph, Node>::ItemNotifier NodeNotifier;
34.70 + typedef typename ItemSetTraits<DGR, Node>::ItemNotifier NodeNotifier;
34.71 NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
34.72
34.73 - typedef typename ItemSetTraits<Digraph, Arc>::ItemNotifier ArcNotifier;
34.74 + typedef typename ItemSetTraits<DGR, Arc>::ItemNotifier ArcNotifier;
34.75 ArcNotifier& notifier(Arc) const { return _digraph->notifier(Arc()); }
34.76
34.77 - template <typename _Value>
34.78 - class NodeMap : public Digraph::template NodeMap<_Value> {
34.79 + template <typename V>
34.80 + class NodeMap : public DGR::template NodeMap<V> {
34.81 + typedef typename DGR::template NodeMap<V> Parent;
34.82 +
34.83 public:
34.84 -
34.85 - typedef typename Digraph::template NodeMap<_Value> Parent;
34.86 -
34.87 explicit NodeMap(const Adaptor& adaptor)
34.88 : Parent(*adaptor._digraph) {}
34.89 -
34.90 - NodeMap(const Adaptor& adaptor, const _Value& value)
34.91 + NodeMap(const Adaptor& adaptor, const V& value)
34.92 : Parent(*adaptor._digraph, value) { }
34.93
34.94 private:
34.95 @@ -126,16 +130,14 @@
34.96
34.97 };
34.98
34.99 - template <typename _Value>
34.100 - class ArcMap : public Digraph::template ArcMap<_Value> {
34.101 + template <typename V>
34.102 + class ArcMap : public DGR::template ArcMap<V> {
34.103 + typedef typename DGR::template ArcMap<V> Parent;
34.104 +
34.105 public:
34.106 -
34.107 - typedef typename Digraph::template ArcMap<_Value> Parent;
34.108 -
34.109 - explicit ArcMap(const Adaptor& adaptor)
34.110 + explicit ArcMap(const DigraphAdaptorBase<DGR>& adaptor)
34.111 : Parent(*adaptor._digraph) {}
34.112 -
34.113 - ArcMap(const Adaptor& adaptor, const _Value& value)
34.114 + ArcMap(const DigraphAdaptorBase<DGR>& adaptor, const V& value)
34.115 : Parent(*adaptor._digraph, value) {}
34.116
34.117 private:
34.118 @@ -153,25 +155,24 @@
34.119
34.120 };
34.121
34.122 - template<typename _Graph>
34.123 + template<typename GR>
34.124 class GraphAdaptorBase {
34.125 public:
34.126 - typedef _Graph Graph;
34.127 - typedef Graph ParentGraph;
34.128 + typedef GR Graph;
34.129
34.130 protected:
34.131 - Graph* _graph;
34.132 + GR* _graph;
34.133
34.134 GraphAdaptorBase() : _graph(0) {}
34.135
34.136 - void setGraph(Graph& graph) { _graph = &graph; }
34.137 + void initialize(GR& graph) { _graph = &graph; }
34.138
34.139 public:
34.140 - GraphAdaptorBase(Graph& graph) : _graph(&graph) {}
34.141 -
34.142 - typedef typename Graph::Node Node;
34.143 - typedef typename Graph::Arc Arc;
34.144 - typedef typename Graph::Edge Edge;
34.145 + GraphAdaptorBase(GR& graph) : _graph(&graph) {}
34.146 +
34.147 + typedef typename GR::Node Node;
34.148 + typedef typename GR::Arc Arc;
34.149 + typedef typename GR::Edge Edge;
34.150
34.151 void first(Node& i) const { _graph->first(i); }
34.152 void first(Arc& i) const { _graph->first(i); }
34.153 @@ -239,22 +240,23 @@
34.154 int maxArcId() const { return _graph->maxArcId(); }
34.155 int maxEdgeId() const { return _graph->maxEdgeId(); }
34.156
34.157 - typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
34.158 + typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
34.159 NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
34.160
34.161 - typedef typename ItemSetTraits<Graph, Arc>::ItemNotifier ArcNotifier;
34.162 + typedef typename ItemSetTraits<GR, Arc>::ItemNotifier ArcNotifier;
34.163 ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
34.164
34.165 - typedef typename ItemSetTraits<Graph, Edge>::ItemNotifier EdgeNotifier;
34.166 + typedef typename ItemSetTraits<GR, Edge>::ItemNotifier EdgeNotifier;
34.167 EdgeNotifier& notifier(Edge) const { return _graph->notifier(Edge()); }
34.168
34.169 - template <typename _Value>
34.170 - class NodeMap : public Graph::template NodeMap<_Value> {
34.171 + template <typename V>
34.172 + class NodeMap : public GR::template NodeMap<V> {
34.173 + typedef typename GR::template NodeMap<V> Parent;
34.174 +
34.175 public:
34.176 - typedef typename Graph::template NodeMap<_Value> Parent;
34.177 - explicit NodeMap(const GraphAdaptorBase<Graph>& adapter)
34.178 + explicit NodeMap(const GraphAdaptorBase<GR>& adapter)
34.179 : Parent(*adapter._graph) {}
34.180 - NodeMap(const GraphAdaptorBase<Graph>& adapter, const _Value& value)
34.181 + NodeMap(const GraphAdaptorBase<GR>& adapter, const V& value)
34.182 : Parent(*adapter._graph, value) {}
34.183
34.184 private:
34.185 @@ -270,13 +272,14 @@
34.186
34.187 };
34.188
34.189 - template <typename _Value>
34.190 - class ArcMap : public Graph::template ArcMap<_Value> {
34.191 + template <typename V>
34.192 + class ArcMap : public GR::template ArcMap<V> {
34.193 + typedef typename GR::template ArcMap<V> Parent;
34.194 +
34.195 public:
34.196 - typedef typename Graph::template ArcMap<_Value> Parent;
34.197 - explicit ArcMap(const GraphAdaptorBase<Graph>& adapter)
34.198 + explicit ArcMap(const GraphAdaptorBase<GR>& adapter)
34.199 : Parent(*adapter._graph) {}
34.200 - ArcMap(const GraphAdaptorBase<Graph>& adapter, const _Value& value)
34.201 + ArcMap(const GraphAdaptorBase<GR>& adapter, const V& value)
34.202 : Parent(*adapter._graph, value) {}
34.203
34.204 private:
34.205 @@ -291,13 +294,14 @@
34.206 }
34.207 };
34.208
34.209 - template <typename _Value>
34.210 - class EdgeMap : public Graph::template EdgeMap<_Value> {
34.211 + template <typename V>
34.212 + class EdgeMap : public GR::template EdgeMap<V> {
34.213 + typedef typename GR::template EdgeMap<V> Parent;
34.214 +
34.215 public:
34.216 - typedef typename Graph::template EdgeMap<_Value> Parent;
34.217 - explicit EdgeMap(const GraphAdaptorBase<Graph>& adapter)
34.218 + explicit EdgeMap(const GraphAdaptorBase<GR>& adapter)
34.219 : Parent(*adapter._graph) {}
34.220 - EdgeMap(const GraphAdaptorBase<Graph>& adapter, const _Value& value)
34.221 + EdgeMap(const GraphAdaptorBase<GR>& adapter, const V& value)
34.222 : Parent(*adapter._graph, value) {}
34.223
34.224 private:
34.225 @@ -314,11 +318,11 @@
34.226
34.227 };
34.228
34.229 - template <typename _Digraph>
34.230 - class ReverseDigraphBase : public DigraphAdaptorBase<_Digraph> {
34.231 + template <typename DGR>
34.232 + class ReverseDigraphBase : public DigraphAdaptorBase<DGR> {
34.233 + typedef DigraphAdaptorBase<DGR> Parent;
34.234 public:
34.235 - typedef _Digraph Digraph;
34.236 - typedef DigraphAdaptorBase<_Digraph> Parent;
34.237 + typedef DGR Digraph;
34.238 protected:
34.239 ReverseDigraphBase() : Parent() { }
34.240 public:
34.241 @@ -336,7 +340,7 @@
34.242
34.243 Arc addArc(const Node& u, const Node& v) { return Parent::addArc(v, u); }
34.244
34.245 - typedef FindArcTagIndicator<Digraph> FindArcTag;
34.246 + typedef FindArcTagIndicator<DGR> FindArcTag;
34.247 Arc findArc(const Node& u, const Node& v,
34.248 const Arc& prev = INVALID) const {
34.249 return Parent::findArc(v, u, prev);
34.250 @@ -356,23 +360,23 @@
34.251 /// by adding or removing nodes or arcs, unless the \c GR template
34.252 /// parameter is set to be \c const.
34.253 ///
34.254 - /// \tparam GR The type of the adapted digraph.
34.255 + /// \tparam DGR The type of the adapted digraph.
34.256 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
34.257 /// It can also be specified to be \c const.
34.258 ///
34.259 /// \note The \c Node and \c Arc types of this adaptor and the adapted
34.260 /// digraph are convertible to each other.
34.261 - template<typename GR>
34.262 + template<typename DGR>
34.263 #ifdef DOXYGEN
34.264 class ReverseDigraph {
34.265 #else
34.266 class ReverseDigraph :
34.267 - public DigraphAdaptorExtender<ReverseDigraphBase<GR> > {
34.268 + public DigraphAdaptorExtender<ReverseDigraphBase<DGR> > {
34.269 #endif
34.270 + typedef DigraphAdaptorExtender<ReverseDigraphBase<DGR> > Parent;
34.271 public:
34.272 /// The type of the adapted digraph.
34.273 - typedef GR Digraph;
34.274 - typedef DigraphAdaptorExtender<ReverseDigraphBase<GR> > Parent;
34.275 + typedef DGR Digraph;
34.276 protected:
34.277 ReverseDigraph() { }
34.278 public:
34.279 @@ -380,8 +384,8 @@
34.280 /// \brief Constructor
34.281 ///
34.282 /// Creates a reverse digraph adaptor for the given digraph.
34.283 - explicit ReverseDigraph(Digraph& digraph) {
34.284 - Parent::setDigraph(digraph);
34.285 + explicit ReverseDigraph(DGR& digraph) {
34.286 + Parent::initialize(digraph);
34.287 }
34.288 };
34.289
34.290 @@ -390,33 +394,31 @@
34.291 /// This function just returns a read-only \ref ReverseDigraph adaptor.
34.292 /// \ingroup graph_adaptors
34.293 /// \relates ReverseDigraph
34.294 - template<typename GR>
34.295 - ReverseDigraph<const GR> reverseDigraph(const GR& digraph) {
34.296 - return ReverseDigraph<const GR>(digraph);
34.297 + template<typename DGR>
34.298 + ReverseDigraph<const DGR> reverseDigraph(const DGR& digraph) {
34.299 + return ReverseDigraph<const DGR>(digraph);
34.300 }
34.301
34.302
34.303 - template <typename _Digraph, typename _NodeFilterMap,
34.304 - typename _ArcFilterMap, bool _checked = true>
34.305 - class SubDigraphBase : public DigraphAdaptorBase<_Digraph> {
34.306 + template <typename DGR, typename NF, typename AF, bool ch = true>
34.307 + class SubDigraphBase : public DigraphAdaptorBase<DGR> {
34.308 + typedef DigraphAdaptorBase<DGR> Parent;
34.309 public:
34.310 - typedef _Digraph Digraph;
34.311 - typedef _NodeFilterMap NodeFilterMap;
34.312 - typedef _ArcFilterMap ArcFilterMap;
34.313 + typedef DGR Digraph;
34.314 + typedef NF NodeFilterMap;
34.315 + typedef AF ArcFilterMap;
34.316
34.317 typedef SubDigraphBase Adaptor;
34.318 - typedef DigraphAdaptorBase<_Digraph> Parent;
34.319 protected:
34.320 - NodeFilterMap* _node_filter;
34.321 - ArcFilterMap* _arc_filter;
34.322 + NF* _node_filter;
34.323 + AF* _arc_filter;
34.324 SubDigraphBase()
34.325 : Parent(), _node_filter(0), _arc_filter(0) { }
34.326
34.327 - void setNodeFilterMap(NodeFilterMap& node_filter) {
34.328 + void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
34.329 + Parent::initialize(digraph);
34.330 _node_filter = &node_filter;
34.331 - }
34.332 - void setArcFilterMap(ArcFilterMap& arc_filter) {
34.333 - _arc_filter = &arc_filter;
34.334 + _arc_filter = &arc_filter;
34.335 }
34.336
34.337 public:
34.338 @@ -487,7 +489,7 @@
34.339 typedef False NodeNumTag;
34.340 typedef False ArcNumTag;
34.341
34.342 - typedef FindArcTagIndicator<Digraph> FindArcTag;
34.343 + typedef FindArcTagIndicator<DGR> FindArcTag;
34.344 Arc findArc(const Node& source, const Node& target,
34.345 const Arc& prev = INVALID) const {
34.346 if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
34.347 @@ -500,18 +502,22 @@
34.348 return arc;
34.349 }
34.350
34.351 - template <typename _Value>
34.352 - class NodeMap : public SubMapExtender<Adaptor,
34.353 - typename Parent::template NodeMap<_Value> > {
34.354 + public:
34.355 +
34.356 + template <typename V>
34.357 + class NodeMap
34.358 + : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
34.359 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
34.360 + typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
34.361 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
34.362 +
34.363 public:
34.364 - typedef _Value Value;
34.365 - typedef SubMapExtender<Adaptor, typename Parent::
34.366 - template NodeMap<Value> > MapParent;
34.367 -
34.368 - NodeMap(const Adaptor& adaptor)
34.369 - : MapParent(adaptor) {}
34.370 - NodeMap(const Adaptor& adaptor, const Value& value)
34.371 - : MapParent(adaptor, value) {}
34.372 + typedef V Value;
34.373 +
34.374 + NodeMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
34.375 + : Parent(adaptor) {}
34.376 + NodeMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor, const V& value)
34.377 + : Parent(adaptor, value) {}
34.378
34.379 private:
34.380 NodeMap& operator=(const NodeMap& cmap) {
34.381 @@ -520,23 +526,25 @@
34.382
34.383 template <typename CMap>
34.384 NodeMap& operator=(const CMap& cmap) {
34.385 - MapParent::operator=(cmap);
34.386 + Parent::operator=(cmap);
34.387 return *this;
34.388 }
34.389 };
34.390
34.391 - template <typename _Value>
34.392 - class ArcMap : public SubMapExtender<Adaptor,
34.393 - typename Parent::template ArcMap<_Value> > {
34.394 + template <typename V>
34.395 + class ArcMap
34.396 + : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
34.397 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
34.398 + typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
34.399 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
34.400 +
34.401 public:
34.402 - typedef _Value Value;
34.403 - typedef SubMapExtender<Adaptor, typename Parent::
34.404 - template ArcMap<Value> > MapParent;
34.405 -
34.406 - ArcMap(const Adaptor& adaptor)
34.407 - : MapParent(adaptor) {}
34.408 - ArcMap(const Adaptor& adaptor, const Value& value)
34.409 - : MapParent(adaptor, value) {}
34.410 + typedef V Value;
34.411 +
34.412 + ArcMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
34.413 + : Parent(adaptor) {}
34.414 + ArcMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor, const V& value)
34.415 + : Parent(adaptor, value) {}
34.416
34.417 private:
34.418 ArcMap& operator=(const ArcMap& cmap) {
34.419 @@ -545,34 +553,33 @@
34.420
34.421 template <typename CMap>
34.422 ArcMap& operator=(const CMap& cmap) {
34.423 - MapParent::operator=(cmap);
34.424 + Parent::operator=(cmap);
34.425 return *this;
34.426 }
34.427 };
34.428
34.429 };
34.430
34.431 - template <typename _Digraph, typename _NodeFilterMap, typename _ArcFilterMap>
34.432 - class SubDigraphBase<_Digraph, _NodeFilterMap, _ArcFilterMap, false>
34.433 - : public DigraphAdaptorBase<_Digraph> {
34.434 + template <typename DGR, typename NF, typename AF>
34.435 + class SubDigraphBase<DGR, NF, AF, false>
34.436 + : public DigraphAdaptorBase<DGR> {
34.437 + typedef DigraphAdaptorBase<DGR> Parent;
34.438 public:
34.439 - typedef _Digraph Digraph;
34.440 - typedef _NodeFilterMap NodeFilterMap;
34.441 - typedef _ArcFilterMap ArcFilterMap;
34.442 + typedef DGR Digraph;
34.443 + typedef NF NodeFilterMap;
34.444 + typedef AF ArcFilterMap;
34.445
34.446 typedef SubDigraphBase Adaptor;
34.447 - typedef DigraphAdaptorBase<Digraph> Parent;
34.448 protected:
34.449 - NodeFilterMap* _node_filter;
34.450 - ArcFilterMap* _arc_filter;
34.451 + NF* _node_filter;
34.452 + AF* _arc_filter;
34.453 SubDigraphBase()
34.454 : Parent(), _node_filter(0), _arc_filter(0) { }
34.455
34.456 - void setNodeFilterMap(NodeFilterMap& node_filter) {
34.457 + void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
34.458 + Parent::initialize(digraph);
34.459 _node_filter = &node_filter;
34.460 - }
34.461 - void setArcFilterMap(ArcFilterMap& arc_filter) {
34.462 - _arc_filter = &arc_filter;
34.463 + _arc_filter = &arc_filter;
34.464 }
34.465
34.466 public:
34.467 @@ -627,7 +634,7 @@
34.468 typedef False NodeNumTag;
34.469 typedef False ArcNumTag;
34.470
34.471 - typedef FindArcTagIndicator<Digraph> FindArcTag;
34.472 + typedef FindArcTagIndicator<DGR> FindArcTag;
34.473 Arc findArc(const Node& source, const Node& target,
34.474 const Arc& prev = INVALID) const {
34.475 if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
34.476 @@ -640,18 +647,20 @@
34.477 return arc;
34.478 }
34.479
34.480 - template <typename _Value>
34.481 - class NodeMap : public SubMapExtender<Adaptor,
34.482 - typename Parent::template NodeMap<_Value> > {
34.483 + template <typename V>
34.484 + class NodeMap
34.485 + : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
34.486 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
34.487 + typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
34.488 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
34.489 +
34.490 public:
34.491 - typedef _Value Value;
34.492 - typedef SubMapExtender<Adaptor, typename Parent::
34.493 - template NodeMap<Value> > MapParent;
34.494 -
34.495 - NodeMap(const Adaptor& adaptor)
34.496 - : MapParent(adaptor) {}
34.497 - NodeMap(const Adaptor& adaptor, const Value& value)
34.498 - : MapParent(adaptor, value) {}
34.499 + typedef V Value;
34.500 +
34.501 + NodeMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
34.502 + : Parent(adaptor) {}
34.503 + NodeMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor, const V& value)
34.504 + : Parent(adaptor, value) {}
34.505
34.506 private:
34.507 NodeMap& operator=(const NodeMap& cmap) {
34.508 @@ -660,23 +669,25 @@
34.509
34.510 template <typename CMap>
34.511 NodeMap& operator=(const CMap& cmap) {
34.512 - MapParent::operator=(cmap);
34.513 + Parent::operator=(cmap);
34.514 return *this;
34.515 }
34.516 };
34.517
34.518 - template <typename _Value>
34.519 - class ArcMap : public SubMapExtender<Adaptor,
34.520 - typename Parent::template ArcMap<_Value> > {
34.521 + template <typename V>
34.522 + class ArcMap
34.523 + : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
34.524 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
34.525 + typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
34.526 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
34.527 +
34.528 public:
34.529 - typedef _Value Value;
34.530 - typedef SubMapExtender<Adaptor, typename Parent::
34.531 - template ArcMap<Value> > MapParent;
34.532 -
34.533 - ArcMap(const Adaptor& adaptor)
34.534 - : MapParent(adaptor) {}
34.535 - ArcMap(const Adaptor& adaptor, const Value& value)
34.536 - : MapParent(adaptor, value) {}
34.537 + typedef V Value;
34.538 +
34.539 + ArcMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
34.540 + : Parent(adaptor) {}
34.541 + ArcMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor, const V& value)
34.542 + : Parent(adaptor, value) {}
34.543
34.544 private:
34.545 ArcMap& operator=(const ArcMap& cmap) {
34.546 @@ -685,7 +696,7 @@
34.547
34.548 template <typename CMap>
34.549 ArcMap& operator=(const CMap& cmap) {
34.550 - MapParent::operator=(cmap);
34.551 + Parent::operator=(cmap);
34.552 return *this;
34.553 }
34.554 };
34.555 @@ -708,17 +719,17 @@
34.556 /// by adding or removing nodes or arcs, unless the \c GR template
34.557 /// parameter is set to be \c const.
34.558 ///
34.559 - /// \tparam GR The type of the adapted digraph.
34.560 + /// \tparam DGR The type of the adapted digraph.
34.561 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
34.562 /// It can also be specified to be \c const.
34.563 /// \tparam NF The type of the node filter map.
34.564 /// It must be a \c bool (or convertible) node map of the
34.565 /// adapted digraph. The default type is
34.566 - /// \ref concepts::Digraph::NodeMap "GR::NodeMap<bool>".
34.567 + /// \ref concepts::Digraph::NodeMap "DGR::NodeMap<bool>".
34.568 /// \tparam AF The type of the arc filter map.
34.569 /// It must be \c bool (or convertible) arc map of the
34.570 /// adapted digraph. The default type is
34.571 - /// \ref concepts::Digraph::ArcMap "GR::ArcMap<bool>".
34.572 + /// \ref concepts::Digraph::ArcMap "DGR::ArcMap<bool>".
34.573 ///
34.574 /// \note The \c Node and \c Arc types of this adaptor and the adapted
34.575 /// digraph are convertible to each other.
34.576 @@ -726,24 +737,24 @@
34.577 /// \see FilterNodes
34.578 /// \see FilterArcs
34.579 #ifdef DOXYGEN
34.580 - template<typename GR, typename NF, typename AF>
34.581 + template<typename DGR, typename NF, typename AF>
34.582 class SubDigraph {
34.583 #else
34.584 - template<typename GR,
34.585 - typename NF = typename GR::template NodeMap<bool>,
34.586 - typename AF = typename GR::template ArcMap<bool> >
34.587 + template<typename DGR,
34.588 + typename NF = typename DGR::template NodeMap<bool>,
34.589 + typename AF = typename DGR::template ArcMap<bool> >
34.590 class SubDigraph :
34.591 - public DigraphAdaptorExtender<SubDigraphBase<GR, NF, AF, true> > {
34.592 + public DigraphAdaptorExtender<SubDigraphBase<DGR, NF, AF, true> > {
34.593 #endif
34.594 public:
34.595 /// The type of the adapted digraph.
34.596 - typedef GR Digraph;
34.597 + typedef DGR Digraph;
34.598 /// The type of the node filter map.
34.599 typedef NF NodeFilterMap;
34.600 /// The type of the arc filter map.
34.601 typedef AF ArcFilterMap;
34.602
34.603 - typedef DigraphAdaptorExtender<SubDigraphBase<GR, NF, AF, true> >
34.604 + typedef DigraphAdaptorExtender<SubDigraphBase<DGR, NF, AF, true> >
34.605 Parent;
34.606
34.607 typedef typename Parent::Node Node;
34.608 @@ -757,11 +768,8 @@
34.609 ///
34.610 /// Creates a subdigraph for the given digraph with the
34.611 /// given node and arc filter maps.
34.612 - SubDigraph(Digraph& digraph, NodeFilterMap& node_filter,
34.613 - ArcFilterMap& arc_filter) {
34.614 - setDigraph(digraph);
34.615 - setNodeFilterMap(node_filter);
34.616 - setArcFilterMap(arc_filter);
34.617 + SubDigraph(DGR& digraph, NF& node_filter, AF& arc_filter) {
34.618 + Parent::initialize(digraph, node_filter, arc_filter);
34.619 }
34.620
34.621 /// \brief Sets the status of the given node
34.622 @@ -823,62 +831,60 @@
34.623 /// This function just returns a read-only \ref SubDigraph adaptor.
34.624 /// \ingroup graph_adaptors
34.625 /// \relates SubDigraph
34.626 - template<typename GR, typename NF, typename AF>
34.627 - SubDigraph<const GR, NF, AF>
34.628 - subDigraph(const GR& digraph,
34.629 - NF& node_filter_map, AF& arc_filter_map) {
34.630 - return SubDigraph<const GR, NF, AF>
34.631 - (digraph, node_filter_map, arc_filter_map);
34.632 + template<typename DGR, typename NF, typename AF>
34.633 + SubDigraph<const DGR, NF, AF>
34.634 + subDigraph(const DGR& digraph,
34.635 + NF& node_filter, AF& arc_filter) {
34.636 + return SubDigraph<const DGR, NF, AF>
34.637 + (digraph, node_filter, arc_filter);
34.638 }
34.639
34.640 - template<typename GR, typename NF, typename AF>
34.641 - SubDigraph<const GR, const NF, AF>
34.642 - subDigraph(const GR& digraph,
34.643 - const NF& node_filter_map, AF& arc_filter_map) {
34.644 - return SubDigraph<const GR, const NF, AF>
34.645 - (digraph, node_filter_map, arc_filter_map);
34.646 + template<typename DGR, typename NF, typename AF>
34.647 + SubDigraph<const DGR, const NF, AF>
34.648 + subDigraph(const DGR& digraph,
34.649 + const NF& node_filter, AF& arc_filter) {
34.650 + return SubDigraph<const DGR, const NF, AF>
34.651 + (digraph, node_filter, arc_filter);
34.652 }
34.653
34.654 - template<typename GR, typename NF, typename AF>
34.655 - SubDigraph<const GR, NF, const AF>
34.656 - subDigraph(const GR& digraph,
34.657 - NF& node_filter_map, const AF& arc_filter_map) {
34.658 - return SubDigraph<const GR, NF, const AF>
34.659 - (digraph, node_filter_map, arc_filter_map);
34.660 + template<typename DGR, typename NF, typename AF>
34.661 + SubDigraph<const DGR, NF, const AF>
34.662 + subDigraph(const DGR& digraph,
34.663 + NF& node_filter, const AF& arc_filter) {
34.664 + return SubDigraph<const DGR, NF, const AF>
34.665 + (digraph, node_filter, arc_filter);
34.666 }
34.667
34.668 - template<typename GR, typename NF, typename AF>
34.669 - SubDigraph<const GR, const NF, const AF>
34.670 - subDigraph(const GR& digraph,
34.671 - const NF& node_filter_map, const AF& arc_filter_map) {
34.672 - return SubDigraph<const GR, const NF, const AF>
34.673 - (digraph, node_filter_map, arc_filter_map);
34.674 + template<typename DGR, typename NF, typename AF>
34.675 + SubDigraph<const DGR, const NF, const AF>
34.676 + subDigraph(const DGR& digraph,
34.677 + const NF& node_filter, const AF& arc_filter) {
34.678 + return SubDigraph<const DGR, const NF, const AF>
34.679 + (digraph, node_filter, arc_filter);
34.680 }
34.681
34.682
34.683 - template <typename _Graph, typename _NodeFilterMap,
34.684 - typename _EdgeFilterMap, bool _checked = true>
34.685 - class SubGraphBase : public GraphAdaptorBase<_Graph> {
34.686 + template <typename GR, typename NF, typename EF, bool ch = true>
34.687 + class SubGraphBase : public GraphAdaptorBase<GR> {
34.688 + typedef GraphAdaptorBase<GR> Parent;
34.689 public:
34.690 - typedef _Graph Graph;
34.691 - typedef _NodeFilterMap NodeFilterMap;
34.692 - typedef _EdgeFilterMap EdgeFilterMap;
34.693 + typedef GR Graph;
34.694 + typedef NF NodeFilterMap;
34.695 + typedef EF EdgeFilterMap;
34.696
34.697 typedef SubGraphBase Adaptor;
34.698 - typedef GraphAdaptorBase<_Graph> Parent;
34.699 protected:
34.700
34.701 - NodeFilterMap* _node_filter_map;
34.702 - EdgeFilterMap* _edge_filter_map;
34.703 + NF* _node_filter;
34.704 + EF* _edge_filter;
34.705
34.706 SubGraphBase()
34.707 - : Parent(), _node_filter_map(0), _edge_filter_map(0) { }
34.708 -
34.709 - void setNodeFilterMap(NodeFilterMap& node_filter_map) {
34.710 - _node_filter_map=&node_filter_map;
34.711 - }
34.712 - void setEdgeFilterMap(EdgeFilterMap& edge_filter_map) {
34.713 - _edge_filter_map=&edge_filter_map;
34.714 + : Parent(), _node_filter(0), _edge_filter(0) { }
34.715 +
34.716 + void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
34.717 + Parent::initialize(graph);
34.718 + _node_filter = &node_filter;
34.719 + _edge_filter = &edge_filter;
34.720 }
34.721
34.722 public:
34.723 @@ -889,95 +895,95 @@
34.724
34.725 void first(Node& i) const {
34.726 Parent::first(i);
34.727 - while (i!=INVALID && !(*_node_filter_map)[i]) Parent::next(i);
34.728 + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
34.729 }
34.730
34.731 void first(Arc& i) const {
34.732 Parent::first(i);
34.733 - while (i!=INVALID && (!(*_edge_filter_map)[i]
34.734 - || !(*_node_filter_map)[Parent::source(i)]
34.735 - || !(*_node_filter_map)[Parent::target(i)]))
34.736 + while (i!=INVALID && (!(*_edge_filter)[i]
34.737 + || !(*_node_filter)[Parent::source(i)]
34.738 + || !(*_node_filter)[Parent::target(i)]))
34.739 Parent::next(i);
34.740 }
34.741
34.742 void first(Edge& i) const {
34.743 Parent::first(i);
34.744 - while (i!=INVALID && (!(*_edge_filter_map)[i]
34.745 - || !(*_node_filter_map)[Parent::u(i)]
34.746 - || !(*_node_filter_map)[Parent::v(i)]))
34.747 + while (i!=INVALID && (!(*_edge_filter)[i]
34.748 + || !(*_node_filter)[Parent::u(i)]
34.749 + || !(*_node_filter)[Parent::v(i)]))
34.750 Parent::next(i);
34.751 }
34.752
34.753 void firstIn(Arc& i, const Node& n) const {
34.754 Parent::firstIn(i, n);
34.755 - while (i!=INVALID && (!(*_edge_filter_map)[i]
34.756 - || !(*_node_filter_map)[Parent::source(i)]))
34.757 + while (i!=INVALID && (!(*_edge_filter)[i]
34.758 + || !(*_node_filter)[Parent::source(i)]))
34.759 Parent::nextIn(i);
34.760 }
34.761
34.762 void firstOut(Arc& i, const Node& n) const {
34.763 Parent::firstOut(i, n);
34.764 - while (i!=INVALID && (!(*_edge_filter_map)[i]
34.765 - || !(*_node_filter_map)[Parent::target(i)]))
34.766 + while (i!=INVALID && (!(*_edge_filter)[i]
34.767 + || !(*_node_filter)[Parent::target(i)]))
34.768 Parent::nextOut(i);
34.769 }
34.770
34.771 void firstInc(Edge& i, bool& d, const Node& n) const {
34.772 Parent::firstInc(i, d, n);
34.773 - while (i!=INVALID && (!(*_edge_filter_map)[i]
34.774 - || !(*_node_filter_map)[Parent::u(i)]
34.775 - || !(*_node_filter_map)[Parent::v(i)]))
34.776 + while (i!=INVALID && (!(*_edge_filter)[i]
34.777 + || !(*_node_filter)[Parent::u(i)]
34.778 + || !(*_node_filter)[Parent::v(i)]))
34.779 Parent::nextInc(i, d);
34.780 }
34.781
34.782 void next(Node& i) const {
34.783 Parent::next(i);
34.784 - while (i!=INVALID && !(*_node_filter_map)[i]) Parent::next(i);
34.785 + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
34.786 }
34.787
34.788 void next(Arc& i) const {
34.789 Parent::next(i);
34.790 - while (i!=INVALID && (!(*_edge_filter_map)[i]
34.791 - || !(*_node_filter_map)[Parent::source(i)]
34.792 - || !(*_node_filter_map)[Parent::target(i)]))
34.793 + while (i!=INVALID && (!(*_edge_filter)[i]
34.794 + || !(*_node_filter)[Parent::source(i)]
34.795 + || !(*_node_filter)[Parent::target(i)]))
34.796 Parent::next(i);
34.797 }
34.798
34.799 void next(Edge& i) const {
34.800 Parent::next(i);
34.801 - while (i!=INVALID && (!(*_edge_filter_map)[i]
34.802 - || !(*_node_filter_map)[Parent::u(i)]
34.803 - || !(*_node_filter_map)[Parent::v(i)]))
34.804 + while (i!=INVALID && (!(*_edge_filter)[i]
34.805 + || !(*_node_filter)[Parent::u(i)]
34.806 + || !(*_node_filter)[Parent::v(i)]))
34.807 Parent::next(i);
34.808 }
34.809
34.810 void nextIn(Arc& i) const {
34.811 Parent::nextIn(i);
34.812 - while (i!=INVALID && (!(*_edge_filter_map)[i]
34.813 - || !(*_node_filter_map)[Parent::source(i)]))
34.814 + while (i!=INVALID && (!(*_edge_filter)[i]
34.815 + || !(*_node_filter)[Parent::source(i)]))
34.816 Parent::nextIn(i);
34.817 }
34.818
34.819 void nextOut(Arc& i) const {
34.820 Parent::nextOut(i);
34.821 - while (i!=INVALID && (!(*_edge_filter_map)[i]
34.822 - || !(*_node_filter_map)[Parent::target(i)]))
34.823 + while (i!=INVALID && (!(*_edge_filter)[i]
34.824 + || !(*_node_filter)[Parent::target(i)]))
34.825 Parent::nextOut(i);
34.826 }
34.827
34.828 void nextInc(Edge& i, bool& d) const {
34.829 Parent::nextInc(i, d);
34.830 - while (i!=INVALID && (!(*_edge_filter_map)[i]
34.831 - || !(*_node_filter_map)[Parent::u(i)]
34.832 - || !(*_node_filter_map)[Parent::v(i)]))
34.833 + while (i!=INVALID && (!(*_edge_filter)[i]
34.834 + || !(*_node_filter)[Parent::u(i)]
34.835 + || !(*_node_filter)[Parent::v(i)]))
34.836 Parent::nextInc(i, d);
34.837 }
34.838
34.839 - void status(const Node& n, bool v) const { _node_filter_map->set(n, v); }
34.840 - void status(const Edge& e, bool v) const { _edge_filter_map->set(e, v); }
34.841 -
34.842 - bool status(const Node& n) const { return (*_node_filter_map)[n]; }
34.843 - bool status(const Edge& e) const { return (*_edge_filter_map)[e]; }
34.844 + void status(const Node& n, bool v) const { _node_filter->set(n, v); }
34.845 + void status(const Edge& e, bool v) const { _edge_filter->set(e, v); }
34.846 +
34.847 + bool status(const Node& n) const { return (*_node_filter)[n]; }
34.848 + bool status(const Edge& e) const { return (*_edge_filter)[e]; }
34.849
34.850 typedef False NodeNumTag;
34.851 typedef False ArcNumTag;
34.852 @@ -986,11 +992,11 @@
34.853 typedef FindArcTagIndicator<Graph> FindArcTag;
34.854 Arc findArc(const Node& u, const Node& v,
34.855 const Arc& prev = INVALID) const {
34.856 - if (!(*_node_filter_map)[u] || !(*_node_filter_map)[v]) {
34.857 + if (!(*_node_filter)[u] || !(*_node_filter)[v]) {
34.858 return INVALID;
34.859 }
34.860 Arc arc = Parent::findArc(u, v, prev);
34.861 - while (arc != INVALID && !(*_edge_filter_map)[arc]) {
34.862 + while (arc != INVALID && !(*_edge_filter)[arc]) {
34.863 arc = Parent::findArc(u, v, arc);
34.864 }
34.865 return arc;
34.866 @@ -999,28 +1005,30 @@
34.867 typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
34.868 Edge findEdge(const Node& u, const Node& v,
34.869 const Edge& prev = INVALID) const {
34.870 - if (!(*_node_filter_map)[u] || !(*_node_filter_map)[v]) {
34.871 + if (!(*_node_filter)[u] || !(*_node_filter)[v]) {
34.872 return INVALID;
34.873 }
34.874 Edge edge = Parent::findEdge(u, v, prev);
34.875 - while (edge != INVALID && !(*_edge_filter_map)[edge]) {
34.876 + while (edge != INVALID && !(*_edge_filter)[edge]) {
34.877 edge = Parent::findEdge(u, v, edge);
34.878 }
34.879 return edge;
34.880 }
34.881
34.882 - template <typename _Value>
34.883 - class NodeMap : public SubMapExtender<Adaptor,
34.884 - typename Parent::template NodeMap<_Value> > {
34.885 + template <typename V>
34.886 + class NodeMap
34.887 + : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
34.888 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
34.889 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
34.890 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
34.891 +
34.892 public:
34.893 - typedef _Value Value;
34.894 - typedef SubMapExtender<Adaptor, typename Parent::
34.895 - template NodeMap<Value> > MapParent;
34.896 -
34.897 - NodeMap(const Adaptor& adaptor)
34.898 - : MapParent(adaptor) {}
34.899 - NodeMap(const Adaptor& adaptor, const Value& value)
34.900 - : MapParent(adaptor, value) {}
34.901 + typedef V Value;
34.902 +
34.903 + NodeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
34.904 + : Parent(adaptor) {}
34.905 + NodeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
34.906 + : Parent(adaptor, value) {}
34.907
34.908 private:
34.909 NodeMap& operator=(const NodeMap& cmap) {
34.910 @@ -1029,23 +1037,25 @@
34.911
34.912 template <typename CMap>
34.913 NodeMap& operator=(const CMap& cmap) {
34.914 - MapParent::operator=(cmap);
34.915 + Parent::operator=(cmap);
34.916 return *this;
34.917 }
34.918 };
34.919
34.920 - template <typename _Value>
34.921 - class ArcMap : public SubMapExtender<Adaptor,
34.922 - typename Parent::template ArcMap<_Value> > {
34.923 + template <typename V>
34.924 + class ArcMap
34.925 + : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
34.926 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
34.927 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
34.928 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
34.929 +
34.930 public:
34.931 - typedef _Value Value;
34.932 - typedef SubMapExtender<Adaptor, typename Parent::
34.933 - template ArcMap<Value> > MapParent;
34.934 -
34.935 - ArcMap(const Adaptor& adaptor)
34.936 - : MapParent(adaptor) {}
34.937 - ArcMap(const Adaptor& adaptor, const Value& value)
34.938 - : MapParent(adaptor, value) {}
34.939 + typedef V Value;
34.940 +
34.941 + ArcMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
34.942 + : Parent(adaptor) {}
34.943 + ArcMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
34.944 + : Parent(adaptor, value) {}
34.945
34.946 private:
34.947 ArcMap& operator=(const ArcMap& cmap) {
34.948 @@ -1054,24 +1064,26 @@
34.949
34.950 template <typename CMap>
34.951 ArcMap& operator=(const CMap& cmap) {
34.952 - MapParent::operator=(cmap);
34.953 + Parent::operator=(cmap);
34.954 return *this;
34.955 }
34.956 };
34.957
34.958 - template <typename _Value>
34.959 - class EdgeMap : public SubMapExtender<Adaptor,
34.960 - typename Parent::template EdgeMap<_Value> > {
34.961 + template <typename V>
34.962 + class EdgeMap
34.963 + : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
34.964 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
34.965 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
34.966 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
34.967 +
34.968 public:
34.969 - typedef _Value Value;
34.970 - typedef SubMapExtender<Adaptor, typename Parent::
34.971 - template EdgeMap<Value> > MapParent;
34.972 -
34.973 - EdgeMap(const Adaptor& adaptor)
34.974 - : MapParent(adaptor) {}
34.975 -
34.976 - EdgeMap(const Adaptor& adaptor, const Value& value)
34.977 - : MapParent(adaptor, value) {}
34.978 + typedef V Value;
34.979 +
34.980 + EdgeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
34.981 + : Parent(adaptor) {}
34.982 +
34.983 + EdgeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
34.984 + : Parent(adaptor, value) {}
34.985
34.986 private:
34.987 EdgeMap& operator=(const EdgeMap& cmap) {
34.988 @@ -1080,34 +1092,33 @@
34.989
34.990 template <typename CMap>
34.991 EdgeMap& operator=(const CMap& cmap) {
34.992 - MapParent::operator=(cmap);
34.993 + Parent::operator=(cmap);
34.994 return *this;
34.995 }
34.996 };
34.997
34.998 };
34.999
34.1000 - template <typename _Graph, typename _NodeFilterMap, typename _EdgeFilterMap>
34.1001 - class SubGraphBase<_Graph, _NodeFilterMap, _EdgeFilterMap, false>
34.1002 - : public GraphAdaptorBase<_Graph> {
34.1003 + template <typename GR, typename NF, typename EF>
34.1004 + class SubGraphBase<GR, NF, EF, false>
34.1005 + : public GraphAdaptorBase<GR> {
34.1006 + typedef GraphAdaptorBase<GR> Parent;
34.1007 public:
34.1008 - typedef _Graph Graph;
34.1009 - typedef _NodeFilterMap NodeFilterMap;
34.1010 - typedef _EdgeFilterMap EdgeFilterMap;
34.1011 + typedef GR Graph;
34.1012 + typedef NF NodeFilterMap;
34.1013 + typedef EF EdgeFilterMap;
34.1014
34.1015 typedef SubGraphBase Adaptor;
34.1016 - typedef GraphAdaptorBase<_Graph> Parent;
34.1017 protected:
34.1018 - NodeFilterMap* _node_filter_map;
34.1019 - EdgeFilterMap* _edge_filter_map;
34.1020 - SubGraphBase() : Parent(),
34.1021 - _node_filter_map(0), _edge_filter_map(0) { }
34.1022 -
34.1023 - void setNodeFilterMap(NodeFilterMap& node_filter_map) {
34.1024 - _node_filter_map=&node_filter_map;
34.1025 - }
34.1026 - void setEdgeFilterMap(EdgeFilterMap& edge_filter_map) {
34.1027 - _edge_filter_map=&edge_filter_map;
34.1028 + NF* _node_filter;
34.1029 + EF* _edge_filter;
34.1030 + SubGraphBase()
34.1031 + : Parent(), _node_filter(0), _edge_filter(0) { }
34.1032 +
34.1033 + void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
34.1034 + Parent::initialize(graph);
34.1035 + _node_filter = &node_filter;
34.1036 + _edge_filter = &edge_filter;
34.1037 }
34.1038
34.1039 public:
34.1040 @@ -1118,65 +1129,65 @@
34.1041
34.1042 void first(Node& i) const {
34.1043 Parent::first(i);
34.1044 - while (i!=INVALID && !(*_node_filter_map)[i]) Parent::next(i);
34.1045 + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
34.1046 }
34.1047
34.1048 void first(Arc& i) const {
34.1049 Parent::first(i);
34.1050 - while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::next(i);
34.1051 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
34.1052 }
34.1053
34.1054 void first(Edge& i) const {
34.1055 Parent::first(i);
34.1056 - while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::next(i);
34.1057 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
34.1058 }
34.1059
34.1060 void firstIn(Arc& i, const Node& n) const {
34.1061 Parent::firstIn(i, n);
34.1062 - while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::nextIn(i);
34.1063 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextIn(i);
34.1064 }
34.1065
34.1066 void firstOut(Arc& i, const Node& n) const {
34.1067 Parent::firstOut(i, n);
34.1068 - while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::nextOut(i);
34.1069 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextOut(i);
34.1070 }
34.1071
34.1072 void firstInc(Edge& i, bool& d, const Node& n) const {
34.1073 Parent::firstInc(i, d, n);
34.1074 - while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::nextInc(i, d);
34.1075 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextInc(i, d);
34.1076 }
34.1077
34.1078 void next(Node& i) const {
34.1079 Parent::next(i);
34.1080 - while (i!=INVALID && !(*_node_filter_map)[i]) Parent::next(i);
34.1081 + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
34.1082 }
34.1083 void next(Arc& i) const {
34.1084 Parent::next(i);
34.1085 - while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::next(i);
34.1086 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
34.1087 }
34.1088 void next(Edge& i) const {
34.1089 Parent::next(i);
34.1090 - while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::next(i);
34.1091 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
34.1092 }
34.1093 void nextIn(Arc& i) const {
34.1094 Parent::nextIn(i);
34.1095 - while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::nextIn(i);
34.1096 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextIn(i);
34.1097 }
34.1098
34.1099 void nextOut(Arc& i) const {
34.1100 Parent::nextOut(i);
34.1101 - while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::nextOut(i);
34.1102 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextOut(i);
34.1103 }
34.1104 void nextInc(Edge& i, bool& d) const {
34.1105 Parent::nextInc(i, d);
34.1106 - while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::nextInc(i, d);
34.1107 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextInc(i, d);
34.1108 }
34.1109
34.1110 - void status(const Node& n, bool v) const { _node_filter_map->set(n, v); }
34.1111 - void status(const Edge& e, bool v) const { _edge_filter_map->set(e, v); }
34.1112 -
34.1113 - bool status(const Node& n) const { return (*_node_filter_map)[n]; }
34.1114 - bool status(const Edge& e) const { return (*_edge_filter_map)[e]; }
34.1115 + void status(const Node& n, bool v) const { _node_filter->set(n, v); }
34.1116 + void status(const Edge& e, bool v) const { _edge_filter->set(e, v); }
34.1117 +
34.1118 + bool status(const Node& n) const { return (*_node_filter)[n]; }
34.1119 + bool status(const Edge& e) const { return (*_edge_filter)[e]; }
34.1120
34.1121 typedef False NodeNumTag;
34.1122 typedef False ArcNumTag;
34.1123 @@ -1186,7 +1197,7 @@
34.1124 Arc findArc(const Node& u, const Node& v,
34.1125 const Arc& prev = INVALID) const {
34.1126 Arc arc = Parent::findArc(u, v, prev);
34.1127 - while (arc != INVALID && !(*_edge_filter_map)[arc]) {
34.1128 + while (arc != INVALID && !(*_edge_filter)[arc]) {
34.1129 arc = Parent::findArc(u, v, arc);
34.1130 }
34.1131 return arc;
34.1132 @@ -1196,24 +1207,26 @@
34.1133 Edge findEdge(const Node& u, const Node& v,
34.1134 const Edge& prev = INVALID) const {
34.1135 Edge edge = Parent::findEdge(u, v, prev);
34.1136 - while (edge != INVALID && !(*_edge_filter_map)[edge]) {
34.1137 + while (edge != INVALID && !(*_edge_filter)[edge]) {
34.1138 edge = Parent::findEdge(u, v, edge);
34.1139 }
34.1140 return edge;
34.1141 }
34.1142
34.1143 - template <typename _Value>
34.1144 - class NodeMap : public SubMapExtender<Adaptor,
34.1145 - typename Parent::template NodeMap<_Value> > {
34.1146 + template <typename V>
34.1147 + class NodeMap
34.1148 + : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
34.1149 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
34.1150 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
34.1151 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
34.1152 +
34.1153 public:
34.1154 - typedef _Value Value;
34.1155 - typedef SubMapExtender<Adaptor, typename Parent::
34.1156 - template NodeMap<Value> > MapParent;
34.1157 -
34.1158 - NodeMap(const Adaptor& adaptor)
34.1159 - : MapParent(adaptor) {}
34.1160 - NodeMap(const Adaptor& adaptor, const Value& value)
34.1161 - : MapParent(adaptor, value) {}
34.1162 + typedef V Value;
34.1163 +
34.1164 + NodeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
34.1165 + : Parent(adaptor) {}
34.1166 + NodeMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
34.1167 + : Parent(adaptor, value) {}
34.1168
34.1169 private:
34.1170 NodeMap& operator=(const NodeMap& cmap) {
34.1171 @@ -1222,23 +1235,25 @@
34.1172
34.1173 template <typename CMap>
34.1174 NodeMap& operator=(const CMap& cmap) {
34.1175 - MapParent::operator=(cmap);
34.1176 + Parent::operator=(cmap);
34.1177 return *this;
34.1178 }
34.1179 };
34.1180
34.1181 - template <typename _Value>
34.1182 - class ArcMap : public SubMapExtender<Adaptor,
34.1183 - typename Parent::template ArcMap<_Value> > {
34.1184 + template <typename V>
34.1185 + class ArcMap
34.1186 + : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
34.1187 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
34.1188 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
34.1189 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
34.1190 +
34.1191 public:
34.1192 - typedef _Value Value;
34.1193 - typedef SubMapExtender<Adaptor, typename Parent::
34.1194 - template ArcMap<Value> > MapParent;
34.1195 -
34.1196 - ArcMap(const Adaptor& adaptor)
34.1197 - : MapParent(adaptor) {}
34.1198 - ArcMap(const Adaptor& adaptor, const Value& value)
34.1199 - : MapParent(adaptor, value) {}
34.1200 + typedef V Value;
34.1201 +
34.1202 + ArcMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
34.1203 + : Parent(adaptor) {}
34.1204 + ArcMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
34.1205 + : Parent(adaptor, value) {}
34.1206
34.1207 private:
34.1208 ArcMap& operator=(const ArcMap& cmap) {
34.1209 @@ -1247,24 +1262,26 @@
34.1210
34.1211 template <typename CMap>
34.1212 ArcMap& operator=(const CMap& cmap) {
34.1213 - MapParent::operator=(cmap);
34.1214 + Parent::operator=(cmap);
34.1215 return *this;
34.1216 }
34.1217 };
34.1218
34.1219 - template <typename _Value>
34.1220 - class EdgeMap : public SubMapExtender<Adaptor,
34.1221 - typename Parent::template EdgeMap<_Value> > {
34.1222 + template <typename V>
34.1223 + class EdgeMap
34.1224 + : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
34.1225 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
34.1226 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
34.1227 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
34.1228 +
34.1229 public:
34.1230 - typedef _Value Value;
34.1231 - typedef SubMapExtender<Adaptor, typename Parent::
34.1232 - template EdgeMap<Value> > MapParent;
34.1233 -
34.1234 - EdgeMap(const Adaptor& adaptor)
34.1235 - : MapParent(adaptor) {}
34.1236 -
34.1237 - EdgeMap(const Adaptor& adaptor, const _Value& value)
34.1238 - : MapParent(adaptor, value) {}
34.1239 + typedef V Value;
34.1240 +
34.1241 + EdgeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
34.1242 + : Parent(adaptor) {}
34.1243 +
34.1244 + EdgeMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
34.1245 + : Parent(adaptor, value) {}
34.1246
34.1247 private:
34.1248 EdgeMap& operator=(const EdgeMap& cmap) {
34.1249 @@ -1273,7 +1290,7 @@
34.1250
34.1251 template <typename CMap>
34.1252 EdgeMap& operator=(const CMap& cmap) {
34.1253 - MapParent::operator=(cmap);
34.1254 + Parent::operator=(cmap);
34.1255 return *this;
34.1256 }
34.1257 };
34.1258 @@ -1332,7 +1349,7 @@
34.1259 /// The type of the edge filter map.
34.1260 typedef EF EdgeFilterMap;
34.1261
34.1262 - typedef GraphAdaptorExtender< SubGraphBase<GR, NF, EF, true> >
34.1263 + typedef GraphAdaptorExtender<SubGraphBase<GR, NF, EF, true> >
34.1264 Parent;
34.1265
34.1266 typedef typename Parent::Node Node;
34.1267 @@ -1346,11 +1363,8 @@
34.1268 ///
34.1269 /// Creates a subgraph for the given graph with the given node
34.1270 /// and edge filter maps.
34.1271 - SubGraph(Graph& graph, NodeFilterMap& node_filter_map,
34.1272 - EdgeFilterMap& edge_filter_map) {
34.1273 - setGraph(graph);
34.1274 - setNodeFilterMap(node_filter_map);
34.1275 - setEdgeFilterMap(edge_filter_map);
34.1276 + SubGraph(GR& graph, NF& node_filter, EF& edge_filter) {
34.1277 + initialize(graph, node_filter, edge_filter);
34.1278 }
34.1279
34.1280 /// \brief Sets the status of the given node
34.1281 @@ -1414,34 +1428,30 @@
34.1282 /// \relates SubGraph
34.1283 template<typename GR, typename NF, typename EF>
34.1284 SubGraph<const GR, NF, EF>
34.1285 - subGraph(const GR& graph,
34.1286 - NF& node_filter_map, EF& edge_filter_map) {
34.1287 + subGraph(const GR& graph, NF& node_filter, EF& edge_filter) {
34.1288 return SubGraph<const GR, NF, EF>
34.1289 - (graph, node_filter_map, edge_filter_map);
34.1290 + (graph, node_filter, edge_filter);
34.1291 }
34.1292
34.1293 template<typename GR, typename NF, typename EF>
34.1294 SubGraph<const GR, const NF, EF>
34.1295 - subGraph(const GR& graph,
34.1296 - const NF& node_filter_map, EF& edge_filter_map) {
34.1297 + subGraph(const GR& graph, const NF& node_filter, EF& edge_filter) {
34.1298 return SubGraph<const GR, const NF, EF>
34.1299 - (graph, node_filter_map, edge_filter_map);
34.1300 + (graph, node_filter, edge_filter);
34.1301 }
34.1302
34.1303 template<typename GR, typename NF, typename EF>
34.1304 SubGraph<const GR, NF, const EF>
34.1305 - subGraph(const GR& graph,
34.1306 - NF& node_filter_map, const EF& edge_filter_map) {
34.1307 + subGraph(const GR& graph, NF& node_filter, const EF& edge_filter) {
34.1308 return SubGraph<const GR, NF, const EF>
34.1309 - (graph, node_filter_map, edge_filter_map);
34.1310 + (graph, node_filter, edge_filter);
34.1311 }
34.1312
34.1313 template<typename GR, typename NF, typename EF>
34.1314 SubGraph<const GR, const NF, const EF>
34.1315 - subGraph(const GR& graph,
34.1316 - const NF& node_filter_map, const EF& edge_filter_map) {
34.1317 + subGraph(const GR& graph, const NF& node_filter, const EF& edge_filter) {
34.1318 return SubGraph<const GR, const NF, const EF>
34.1319 - (graph, node_filter_map, edge_filter_map);
34.1320 + (graph, node_filter, edge_filter);
34.1321 }
34.1322
34.1323
34.1324 @@ -1481,25 +1491,24 @@
34.1325 typename Enable = void>
34.1326 class FilterNodes :
34.1327 public DigraphAdaptorExtender<
34.1328 - SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, bool>, true> > {
34.1329 + SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >,
34.1330 + true> > {
34.1331 #endif
34.1332 + typedef DigraphAdaptorExtender<
34.1333 + SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >,
34.1334 + true> > Parent;
34.1335 +
34.1336 public:
34.1337
34.1338 typedef GR Digraph;
34.1339 typedef NF NodeFilterMap;
34.1340
34.1341 - typedef DigraphAdaptorExtender<
34.1342 - SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, bool>, true> >
34.1343 - Parent;
34.1344 -
34.1345 typedef typename Parent::Node Node;
34.1346
34.1347 protected:
34.1348 - ConstMap<typename Digraph::Arc, bool> const_true_map;
34.1349 -
34.1350 - FilterNodes() : const_true_map(true) {
34.1351 - Parent::setArcFilterMap(const_true_map);
34.1352 - }
34.1353 + ConstMap<typename Digraph::Arc, Const<bool, true> > const_true_map;
34.1354 +
34.1355 + FilterNodes() : const_true_map() {}
34.1356
34.1357 public:
34.1358
34.1359 @@ -1507,12 +1516,10 @@
34.1360 ///
34.1361 /// Creates a subgraph for the given digraph or graph with the
34.1362 /// given node filter map.
34.1363 - FilterNodes(GR& graph, NodeFilterMap& node_filter) :
34.1364 - Parent(), const_true_map(true)
34.1365 + FilterNodes(GR& graph, NF& node_filter)
34.1366 + : Parent(), const_true_map()
34.1367 {
34.1368 - Parent::setDigraph(graph);
34.1369 - Parent::setNodeFilterMap(node_filter);
34.1370 - Parent::setArcFilterMap(const_true_map);
34.1371 + Parent::initialize(graph, node_filter, const_true_map);
34.1372 }
34.1373
34.1374 /// \brief Sets the status of the given node
34.1375 @@ -1547,30 +1554,30 @@
34.1376 class FilterNodes<GR, NF,
34.1377 typename enable_if<UndirectedTagIndicator<GR> >::type> :
34.1378 public GraphAdaptorExtender<
34.1379 - SubGraphBase<GR, NF, ConstMap<typename GR::Edge, bool>, true> > {
34.1380 + SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
34.1381 + true> > {
34.1382 +
34.1383 + typedef GraphAdaptorExtender<
34.1384 + SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
34.1385 + true> > Parent;
34.1386
34.1387 public:
34.1388 +
34.1389 typedef GR Graph;
34.1390 typedef NF NodeFilterMap;
34.1391 - typedef GraphAdaptorExtender<
34.1392 - SubGraphBase<GR, NF, ConstMap<typename GR::Edge, bool>, true> >
34.1393 - Parent;
34.1394
34.1395 typedef typename Parent::Node Node;
34.1396 +
34.1397 protected:
34.1398 - ConstMap<typename Graph::Edge, bool> const_true_map;
34.1399 -
34.1400 - FilterNodes() : const_true_map(true) {
34.1401 - Parent::setEdgeFilterMap(const_true_map);
34.1402 - }
34.1403 + ConstMap<typename GR::Edge, Const<bool, true> > const_true_map;
34.1404 +
34.1405 + FilterNodes() : const_true_map() {}
34.1406
34.1407 public:
34.1408
34.1409 - FilterNodes(Graph& _graph, NodeFilterMap& node_filter_map) :
34.1410 - Parent(), const_true_map(true) {
34.1411 - Parent::setGraph(_graph);
34.1412 - Parent::setNodeFilterMap(node_filter_map);
34.1413 - Parent::setEdgeFilterMap(const_true_map);
34.1414 + FilterNodes(GR& graph, NodeFilterMap& node_filter) :
34.1415 + Parent(), const_true_map() {
34.1416 + Parent::initialize(graph, node_filter, const_true_map);
34.1417 }
34.1418
34.1419 void status(const Node& n, bool v) const { Parent::status(n, v); }
34.1420 @@ -1588,14 +1595,14 @@
34.1421 /// \relates FilterNodes
34.1422 template<typename GR, typename NF>
34.1423 FilterNodes<const GR, NF>
34.1424 - filterNodes(const GR& graph, NF& node_filter_map) {
34.1425 - return FilterNodes<const GR, NF>(graph, node_filter_map);
34.1426 + filterNodes(const GR& graph, NF& node_filter) {
34.1427 + return FilterNodes<const GR, NF>(graph, node_filter);
34.1428 }
34.1429
34.1430 template<typename GR, typename NF>
34.1431 FilterNodes<const GR, const NF>
34.1432 - filterNodes(const GR& graph, const NF& node_filter_map) {
34.1433 - return FilterNodes<const GR, const NF>(graph, node_filter_map);
34.1434 + filterNodes(const GR& graph, const NF& node_filter) {
34.1435 + return FilterNodes<const GR, const NF>(graph, node_filter);
34.1436 }
34.1437
34.1438 /// \ingroup graph_adaptors
34.1439 @@ -1612,45 +1619,45 @@
34.1440 /// by adding or removing nodes or arcs, unless the \c GR template
34.1441 /// parameter is set to be \c const.
34.1442 ///
34.1443 - /// \tparam GR The type of the adapted digraph.
34.1444 + /// \tparam DGR The type of the adapted digraph.
34.1445 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
34.1446 /// It can also be specified to be \c const.
34.1447 /// \tparam AF The type of the arc filter map.
34.1448 /// It must be a \c bool (or convertible) arc map of the
34.1449 /// adapted digraph. The default type is
34.1450 - /// \ref concepts::Digraph::ArcMap "GR::ArcMap<bool>".
34.1451 + /// \ref concepts::Digraph::ArcMap "DGR::ArcMap<bool>".
34.1452 ///
34.1453 /// \note The \c Node and \c Arc types of this adaptor and the adapted
34.1454 /// digraph are convertible to each other.
34.1455 #ifdef DOXYGEN
34.1456 - template<typename GR,
34.1457 + template<typename DGR,
34.1458 typename AF>
34.1459 class FilterArcs {
34.1460 #else
34.1461 - template<typename GR,
34.1462 - typename AF = typename GR::template ArcMap<bool> >
34.1463 + template<typename DGR,
34.1464 + typename AF = typename DGR::template ArcMap<bool> >
34.1465 class FilterArcs :
34.1466 public DigraphAdaptorExtender<
34.1467 - SubDigraphBase<GR, ConstMap<typename GR::Node, bool>, AF, false> > {
34.1468 + SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
34.1469 + AF, false> > {
34.1470 #endif
34.1471 + typedef DigraphAdaptorExtender<
34.1472 + SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
34.1473 + AF, false> > Parent;
34.1474 +
34.1475 public:
34.1476 +
34.1477 /// The type of the adapted digraph.
34.1478 - typedef GR Digraph;
34.1479 + typedef DGR Digraph;
34.1480 /// The type of the arc filter map.
34.1481 typedef AF ArcFilterMap;
34.1482
34.1483 - typedef DigraphAdaptorExtender<
34.1484 - SubDigraphBase<GR, ConstMap<typename GR::Node, bool>, AF, false> >
34.1485 - Parent;
34.1486 -
34.1487 typedef typename Parent::Arc Arc;
34.1488
34.1489 protected:
34.1490 - ConstMap<typename Digraph::Node, bool> const_true_map;
34.1491 -
34.1492 - FilterArcs() : const_true_map(true) {
34.1493 - Parent::setNodeFilterMap(const_true_map);
34.1494 - }
34.1495 + ConstMap<typename DGR::Node, Const<bool, true> > const_true_map;
34.1496 +
34.1497 + FilterArcs() : const_true_map() {}
34.1498
34.1499 public:
34.1500
34.1501 @@ -1658,11 +1665,9 @@
34.1502 ///
34.1503 /// Creates a subdigraph for the given digraph with the given arc
34.1504 /// filter map.
34.1505 - FilterArcs(Digraph& digraph, ArcFilterMap& arc_filter)
34.1506 - : Parent(), const_true_map(true) {
34.1507 - Parent::setDigraph(digraph);
34.1508 - Parent::setNodeFilterMap(const_true_map);
34.1509 - Parent::setArcFilterMap(arc_filter);
34.1510 + FilterArcs(DGR& digraph, ArcFilterMap& arc_filter)
34.1511 + : Parent(), const_true_map() {
34.1512 + Parent::initialize(digraph, const_true_map, arc_filter);
34.1513 }
34.1514
34.1515 /// \brief Sets the status of the given arc
34.1516 @@ -1698,16 +1703,16 @@
34.1517 /// This function just returns a read-only \ref FilterArcs adaptor.
34.1518 /// \ingroup graph_adaptors
34.1519 /// \relates FilterArcs
34.1520 - template<typename GR, typename AF>
34.1521 - FilterArcs<const GR, AF>
34.1522 - filterArcs(const GR& digraph, AF& arc_filter_map) {
34.1523 - return FilterArcs<const GR, AF>(digraph, arc_filter_map);
34.1524 + template<typename DGR, typename AF>
34.1525 + FilterArcs<const DGR, AF>
34.1526 + filterArcs(const DGR& digraph, AF& arc_filter) {
34.1527 + return FilterArcs<const DGR, AF>(digraph, arc_filter);
34.1528 }
34.1529
34.1530 - template<typename GR, typename AF>
34.1531 - FilterArcs<const GR, const AF>
34.1532 - filterArcs(const GR& digraph, const AF& arc_filter_map) {
34.1533 - return FilterArcs<const GR, const AF>(digraph, arc_filter_map);
34.1534 + template<typename DGR, typename AF>
34.1535 + FilterArcs<const DGR, const AF>
34.1536 + filterArcs(const DGR& digraph, const AF& arc_filter) {
34.1537 + return FilterArcs<const DGR, const AF>(digraph, arc_filter);
34.1538 }
34.1539
34.1540 /// \ingroup graph_adaptors
34.1541 @@ -1743,22 +1748,24 @@
34.1542 typename EF = typename GR::template EdgeMap<bool> >
34.1543 class FilterEdges :
34.1544 public GraphAdaptorExtender<
34.1545 - SubGraphBase<GR, ConstMap<typename GR::Node,bool>, EF, false> > {
34.1546 + SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >,
34.1547 + EF, false> > {
34.1548 #endif
34.1549 + typedef GraphAdaptorExtender<
34.1550 + SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >,
34.1551 + EF, false> > Parent;
34.1552 +
34.1553 public:
34.1554 +
34.1555 /// The type of the adapted graph.
34.1556 typedef GR Graph;
34.1557 /// The type of the edge filter map.
34.1558 typedef EF EdgeFilterMap;
34.1559
34.1560 - typedef GraphAdaptorExtender<
34.1561 - SubGraphBase<GR, ConstMap<typename GR::Node,bool>, EF, false> >
34.1562 - Parent;
34.1563 -
34.1564 typedef typename Parent::Edge Edge;
34.1565
34.1566 protected:
34.1567 - ConstMap<typename Graph::Node, bool> const_true_map;
34.1568 + ConstMap<typename GR::Node, Const<bool, true> > const_true_map;
34.1569
34.1570 FilterEdges() : const_true_map(true) {
34.1571 Parent::setNodeFilterMap(const_true_map);
34.1572 @@ -1770,11 +1777,9 @@
34.1573 ///
34.1574 /// Creates a subgraph for the given graph with the given edge
34.1575 /// filter map.
34.1576 - FilterEdges(Graph& graph, EdgeFilterMap& edge_filter_map) :
34.1577 - Parent(), const_true_map(true) {
34.1578 - Parent::setGraph(graph);
34.1579 - Parent::setNodeFilterMap(const_true_map);
34.1580 - Parent::setEdgeFilterMap(edge_filter_map);
34.1581 + FilterEdges(GR& graph, EF& edge_filter)
34.1582 + : Parent(), const_true_map() {
34.1583 + Parent::initialize(graph, const_true_map, edge_filter);
34.1584 }
34.1585
34.1586 /// \brief Sets the status of the given edge
34.1587 @@ -1812,21 +1817,21 @@
34.1588 /// \relates FilterEdges
34.1589 template<typename GR, typename EF>
34.1590 FilterEdges<const GR, EF>
34.1591 - filterEdges(const GR& graph, EF& edge_filter_map) {
34.1592 - return FilterEdges<const GR, EF>(graph, edge_filter_map);
34.1593 + filterEdges(const GR& graph, EF& edge_filter) {
34.1594 + return FilterEdges<const GR, EF>(graph, edge_filter);
34.1595 }
34.1596
34.1597 template<typename GR, typename EF>
34.1598 FilterEdges<const GR, const EF>
34.1599 - filterEdges(const GR& graph, const EF& edge_filter_map) {
34.1600 - return FilterEdges<const GR, const EF>(graph, edge_filter_map);
34.1601 + filterEdges(const GR& graph, const EF& edge_filter) {
34.1602 + return FilterEdges<const GR, const EF>(graph, edge_filter);
34.1603 }
34.1604
34.1605
34.1606 - template <typename _Digraph>
34.1607 + template <typename DGR>
34.1608 class UndirectorBase {
34.1609 public:
34.1610 - typedef _Digraph Digraph;
34.1611 + typedef DGR Digraph;
34.1612 typedef UndirectorBase Adaptor;
34.1613
34.1614 typedef True UndirectedTag;
34.1615 @@ -1834,31 +1839,31 @@
34.1616 typedef typename Digraph::Arc Edge;
34.1617 typedef typename Digraph::Node Node;
34.1618
34.1619 - class Arc : public Edge {
34.1620 + class Arc {
34.1621 friend class UndirectorBase;
34.1622 protected:
34.1623 + Edge _edge;
34.1624 bool _forward;
34.1625
34.1626 - Arc(const Edge& edge, bool forward) :
34.1627 - Edge(edge), _forward(forward) {}
34.1628 + Arc(const Edge& edge, bool forward)
34.1629 + : _edge(edge), _forward(forward) {}
34.1630
34.1631 public:
34.1632 Arc() {}
34.1633
34.1634 - Arc(Invalid) : Edge(INVALID), _forward(true) {}
34.1635 + Arc(Invalid) : _edge(INVALID), _forward(true) {}
34.1636 +
34.1637 + operator const Edge&() const { return _edge; }
34.1638
34.1639 bool operator==(const Arc &other) const {
34.1640 - return _forward == other._forward &&
34.1641 - static_cast<const Edge&>(*this) == static_cast<const Edge&>(other);
34.1642 + return _forward == other._forward && _edge == other._edge;
34.1643 }
34.1644 bool operator!=(const Arc &other) const {
34.1645 - return _forward != other._forward ||
34.1646 - static_cast<const Edge&>(*this) != static_cast<const Edge&>(other);
34.1647 + return _forward != other._forward || _edge != other._edge;
34.1648 }
34.1649 bool operator<(const Arc &other) const {
34.1650 return _forward < other._forward ||
34.1651 - (_forward == other._forward &&
34.1652 - static_cast<const Edge&>(*this) < static_cast<const Edge&>(other));
34.1653 + (_forward == other._forward && _edge < other._edge);
34.1654 }
34.1655 };
34.1656
34.1657 @@ -1871,7 +1876,7 @@
34.1658 }
34.1659
34.1660 void first(Arc& a) const {
34.1661 - _digraph->first(a);
34.1662 + _digraph->first(a._edge);
34.1663 a._forward = true;
34.1664 }
34.1665
34.1666 @@ -1879,7 +1884,7 @@
34.1667 if (a._forward) {
34.1668 a._forward = false;
34.1669 } else {
34.1670 - _digraph->next(a);
34.1671 + _digraph->next(a._edge);
34.1672 a._forward = true;
34.1673 }
34.1674 }
34.1675 @@ -1893,48 +1898,48 @@
34.1676 }
34.1677
34.1678 void firstOut(Arc& a, const Node& n) const {
34.1679 - _digraph->firstIn(a, n);
34.1680 - if( static_cast<const Edge&>(a) != INVALID ) {
34.1681 + _digraph->firstIn(a._edge, n);
34.1682 + if (a._edge != INVALID ) {
34.1683 a._forward = false;
34.1684 } else {
34.1685 - _digraph->firstOut(a, n);
34.1686 + _digraph->firstOut(a._edge, n);
34.1687 a._forward = true;
34.1688 }
34.1689 }
34.1690 void nextOut(Arc &a) const {
34.1691 if (!a._forward) {
34.1692 - Node n = _digraph->target(a);
34.1693 - _digraph->nextIn(a);
34.1694 - if (static_cast<const Edge&>(a) == INVALID ) {
34.1695 - _digraph->firstOut(a, n);
34.1696 + Node n = _digraph->target(a._edge);
34.1697 + _digraph->nextIn(a._edge);
34.1698 + if (a._edge == INVALID) {
34.1699 + _digraph->firstOut(a._edge, n);
34.1700 a._forward = true;
34.1701 }
34.1702 }
34.1703 else {
34.1704 - _digraph->nextOut(a);
34.1705 + _digraph->nextOut(a._edge);
34.1706 }
34.1707 }
34.1708
34.1709 void firstIn(Arc &a, const Node &n) const {
34.1710 - _digraph->firstOut(a, n);
34.1711 - if (static_cast<const Edge&>(a) != INVALID ) {
34.1712 + _digraph->firstOut(a._edge, n);
34.1713 + if (a._edge != INVALID ) {
34.1714 a._forward = false;
34.1715 } else {
34.1716 - _digraph->firstIn(a, n);
34.1717 + _digraph->firstIn(a._edge, n);
34.1718 a._forward = true;
34.1719 }
34.1720 }
34.1721 void nextIn(Arc &a) const {
34.1722 if (!a._forward) {
34.1723 - Node n = _digraph->source(a);
34.1724 - _digraph->nextOut(a);
34.1725 - if( static_cast<const Edge&>(a) == INVALID ) {
34.1726 - _digraph->firstIn(a, n);
34.1727 + Node n = _digraph->source(a._edge);
34.1728 + _digraph->nextOut(a._edge);
34.1729 + if (a._edge == INVALID ) {
34.1730 + _digraph->firstIn(a._edge, n);
34.1731 a._forward = true;
34.1732 }
34.1733 }
34.1734 else {
34.1735 - _digraph->nextIn(a);
34.1736 + _digraph->nextIn(a._edge);
34.1737 }
34.1738 }
34.1739
34.1740 @@ -1967,19 +1972,16 @@
34.1741 }
34.1742
34.1743 Node source(const Arc &a) const {
34.1744 - return a._forward ? _digraph->source(a) : _digraph->target(a);
34.1745 + return a._forward ? _digraph->source(a._edge) : _digraph->target(a._edge);
34.1746 }
34.1747
34.1748 Node target(const Arc &a) const {
34.1749 - return a._forward ? _digraph->target(a) : _digraph->source(a);
34.1750 + return a._forward ? _digraph->target(a._edge) : _digraph->source(a._edge);
34.1751 }
34.1752
34.1753 static Arc direct(const Edge &e, bool d) {
34.1754 return Arc(e, d);
34.1755 }
34.1756 - Arc direct(const Edge &e, const Node& n) const {
34.1757 - return Arc(e, _digraph->source(e) == n);
34.1758 - }
34.1759
34.1760 static bool direction(const Arc &a) { return a._forward; }
34.1761
34.1762 @@ -2062,34 +2064,35 @@
34.1763
34.1764 private:
34.1765
34.1766 - template <typename _Value>
34.1767 + template <typename V>
34.1768 class ArcMapBase {
34.1769 private:
34.1770
34.1771 - typedef typename Digraph::template ArcMap<_Value> MapImpl;
34.1772 + typedef typename DGR::template ArcMap<V> MapImpl;
34.1773
34.1774 public:
34.1775
34.1776 typedef typename MapTraits<MapImpl>::ReferenceMapTag ReferenceMapTag;
34.1777
34.1778 - typedef _Value Value;
34.1779 + typedef V Value;
34.1780 typedef Arc Key;
34.1781 typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReturnValue;
34.1782 typedef typename MapTraits<MapImpl>::ReturnValue ReturnValue;
34.1783 typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReference;
34.1784 typedef typename MapTraits<MapImpl>::ReturnValue Reference;
34.1785
34.1786 - ArcMapBase(const Adaptor& adaptor) :
34.1787 + ArcMapBase(const UndirectorBase<DGR>& adaptor) :
34.1788 _forward(*adaptor._digraph), _backward(*adaptor._digraph) {}
34.1789
34.1790 - ArcMapBase(const Adaptor& adaptor, const Value& v)
34.1791 - : _forward(*adaptor._digraph, v), _backward(*adaptor._digraph, v) {}
34.1792 -
34.1793 - void set(const Arc& a, const Value& v) {
34.1794 + ArcMapBase(const UndirectorBase<DGR>& adaptor, const V& value)
34.1795 + : _forward(*adaptor._digraph, value),
34.1796 + _backward(*adaptor._digraph, value) {}
34.1797 +
34.1798 + void set(const Arc& a, const V& value) {
34.1799 if (direction(a)) {
34.1800 - _forward.set(a, v);
34.1801 + _forward.set(a, value);
34.1802 } else {
34.1803 - _backward.set(a, v);
34.1804 + _backward.set(a, value);
34.1805 }
34.1806 }
34.1807
34.1808 @@ -2117,17 +2120,17 @@
34.1809
34.1810 public:
34.1811
34.1812 - template <typename _Value>
34.1813 - class NodeMap : public Digraph::template NodeMap<_Value> {
34.1814 + template <typename V>
34.1815 + class NodeMap : public DGR::template NodeMap<V> {
34.1816 + typedef typename DGR::template NodeMap<V> Parent;
34.1817 +
34.1818 public:
34.1819 -
34.1820 - typedef _Value Value;
34.1821 - typedef typename Digraph::template NodeMap<Value> Parent;
34.1822 -
34.1823 - explicit NodeMap(const Adaptor& adaptor)
34.1824 + typedef V Value;
34.1825 +
34.1826 + explicit NodeMap(const UndirectorBase<DGR>& adaptor)
34.1827 : Parent(*adaptor._digraph) {}
34.1828
34.1829 - NodeMap(const Adaptor& adaptor, const _Value& value)
34.1830 + NodeMap(const UndirectorBase<DGR>& adaptor, const V& value)
34.1831 : Parent(*adaptor._digraph, value) { }
34.1832
34.1833 private:
34.1834 @@ -2143,18 +2146,18 @@
34.1835
34.1836 };
34.1837
34.1838 - template <typename _Value>
34.1839 + template <typename V>
34.1840 class ArcMap
34.1841 - : public SubMapExtender<Adaptor, ArcMapBase<_Value> >
34.1842 - {
34.1843 + : public SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> > {
34.1844 + typedef SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> > Parent;
34.1845 +
34.1846 public:
34.1847 - typedef _Value Value;
34.1848 - typedef SubMapExtender<Adaptor, ArcMapBase<Value> > Parent;
34.1849 -
34.1850 - explicit ArcMap(const Adaptor& adaptor)
34.1851 + typedef V Value;
34.1852 +
34.1853 + explicit ArcMap(const UndirectorBase<DGR>& adaptor)
34.1854 : Parent(adaptor) {}
34.1855
34.1856 - ArcMap(const Adaptor& adaptor, const Value& value)
34.1857 + ArcMap(const UndirectorBase<DGR>& adaptor, const V& value)
34.1858 : Parent(adaptor, value) {}
34.1859
34.1860 private:
34.1861 @@ -2169,17 +2172,17 @@
34.1862 }
34.1863 };
34.1864
34.1865 - template <typename _Value>
34.1866 - class EdgeMap : public Digraph::template ArcMap<_Value> {
34.1867 + template <typename V>
34.1868 + class EdgeMap : public Digraph::template ArcMap<V> {
34.1869 + typedef typename Digraph::template ArcMap<V> Parent;
34.1870 +
34.1871 public:
34.1872 -
34.1873 - typedef _Value Value;
34.1874 - typedef typename Digraph::template ArcMap<Value> Parent;
34.1875 -
34.1876 - explicit EdgeMap(const Adaptor& adaptor)
34.1877 + typedef V Value;
34.1878 +
34.1879 + explicit EdgeMap(const UndirectorBase<DGR>& adaptor)
34.1880 : Parent(*adaptor._digraph) {}
34.1881
34.1882 - EdgeMap(const Adaptor& adaptor, const Value& value)
34.1883 + EdgeMap(const UndirectorBase<DGR>& adaptor, const V& value)
34.1884 : Parent(*adaptor._digraph, value) {}
34.1885
34.1886 private:
34.1887 @@ -2195,19 +2198,22 @@
34.1888
34.1889 };
34.1890
34.1891 - typedef typename ItemSetTraits<Digraph, Node>::ItemNotifier NodeNotifier;
34.1892 + typedef typename ItemSetTraits<DGR, Node>::ItemNotifier NodeNotifier;
34.1893 NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
34.1894
34.1895 - typedef typename ItemSetTraits<Digraph, Edge>::ItemNotifier EdgeNotifier;
34.1896 + typedef typename ItemSetTraits<DGR, Edge>::ItemNotifier EdgeNotifier;
34.1897 EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); }
34.1898 +
34.1899 + typedef EdgeNotifier ArcNotifier;
34.1900 + ArcNotifier& notifier(Arc) const { return _digraph->notifier(Edge()); }
34.1901
34.1902 protected:
34.1903
34.1904 UndirectorBase() : _digraph(0) {}
34.1905
34.1906 - Digraph* _digraph;
34.1907 -
34.1908 - void setDigraph(Digraph& digraph) {
34.1909 + DGR* _digraph;
34.1910 +
34.1911 + void initialize(DGR& digraph) {
34.1912 _digraph = &digraph;
34.1913 }
34.1914
34.1915 @@ -2226,7 +2232,7 @@
34.1916 /// by adding or removing nodes or edges, unless the \c GR template
34.1917 /// parameter is set to be \c const.
34.1918 ///
34.1919 - /// \tparam GR The type of the adapted digraph.
34.1920 + /// \tparam DGR The type of the adapted digraph.
34.1921 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
34.1922 /// It can also be specified to be \c const.
34.1923 ///
34.1924 @@ -2236,17 +2242,17 @@
34.1925 /// each other.
34.1926 /// (Thus the \c Arc type of the adaptor is convertible to the \c Arc type
34.1927 /// of the adapted digraph.)
34.1928 - template<typename GR>
34.1929 + template<typename DGR>
34.1930 #ifdef DOXYGEN
34.1931 class Undirector {
34.1932 #else
34.1933 class Undirector :
34.1934 - public GraphAdaptorExtender<UndirectorBase<GR> > {
34.1935 + public GraphAdaptorExtender<UndirectorBase<DGR> > {
34.1936 #endif
34.1937 + typedef GraphAdaptorExtender<UndirectorBase<DGR> > Parent;
34.1938 public:
34.1939 /// The type of the adapted digraph.
34.1940 - typedef GR Digraph;
34.1941 - typedef GraphAdaptorExtender<UndirectorBase<GR> > Parent;
34.1942 + typedef DGR Digraph;
34.1943 protected:
34.1944 Undirector() { }
34.1945 public:
34.1946 @@ -2254,34 +2260,35 @@
34.1947 /// \brief Constructor
34.1948 ///
34.1949 /// Creates an undirected graph from the given digraph.
34.1950 - Undirector(Digraph& digraph) {
34.1951 - setDigraph(digraph);
34.1952 + Undirector(DGR& digraph) {
34.1953 + initialize(digraph);
34.1954 }
34.1955
34.1956 /// \brief Arc map combined from two original arc maps
34.1957 ///
34.1958 /// This map adaptor class adapts two arc maps of the underlying
34.1959 /// digraph to get an arc map of the undirected graph.
34.1960 - /// Its value type is inherited from the first arc map type
34.1961 - /// (\c %ForwardMap).
34.1962 - template <typename ForwardMap, typename BackwardMap>
34.1963 + /// Its value type is inherited from the first arc map type (\c FW).
34.1964 + /// \tparam FW The type of the "foward" arc map.
34.1965 + /// \tparam BK The type of the "backward" arc map.
34.1966 + template <typename FW, typename BK>
34.1967 class CombinedArcMap {
34.1968 public:
34.1969
34.1970 /// The key type of the map
34.1971 typedef typename Parent::Arc Key;
34.1972 /// The value type of the map
34.1973 - typedef typename ForwardMap::Value Value;
34.1974 -
34.1975 - typedef typename MapTraits<ForwardMap>::ReferenceMapTag ReferenceMapTag;
34.1976 -
34.1977 - typedef typename MapTraits<ForwardMap>::ReturnValue ReturnValue;
34.1978 - typedef typename MapTraits<ForwardMap>::ConstReturnValue ConstReturnValue;
34.1979 - typedef typename MapTraits<ForwardMap>::ReturnValue Reference;
34.1980 - typedef typename MapTraits<ForwardMap>::ConstReturnValue ConstReference;
34.1981 + typedef typename FW::Value Value;
34.1982 +
34.1983 + typedef typename MapTraits<FW>::ReferenceMapTag ReferenceMapTag;
34.1984 +
34.1985 + typedef typename MapTraits<FW>::ReturnValue ReturnValue;
34.1986 + typedef typename MapTraits<FW>::ConstReturnValue ConstReturnValue;
34.1987 + typedef typename MapTraits<FW>::ReturnValue Reference;
34.1988 + typedef typename MapTraits<FW>::ConstReturnValue ConstReference;
34.1989
34.1990 /// Constructor
34.1991 - CombinedArcMap(ForwardMap& forward, BackwardMap& backward)
34.1992 + CombinedArcMap(FW& forward, BK& backward)
34.1993 : _forward(&forward), _backward(&backward) {}
34.1994
34.1995 /// Sets the value associated with the given key.
34.1996 @@ -2313,39 +2320,36 @@
34.1997
34.1998 protected:
34.1999
34.2000 - ForwardMap* _forward;
34.2001 - BackwardMap* _backward;
34.2002 + FW* _forward;
34.2003 + BK* _backward;
34.2004
34.2005 };
34.2006
34.2007 /// \brief Returns a combined arc map
34.2008 ///
34.2009 /// This function just returns a combined arc map.
34.2010 - template <typename ForwardMap, typename BackwardMap>
34.2011 - static CombinedArcMap<ForwardMap, BackwardMap>
34.2012 - combinedArcMap(ForwardMap& forward, BackwardMap& backward) {
34.2013 - return CombinedArcMap<ForwardMap, BackwardMap>(forward, backward);
34.2014 + template <typename FW, typename BK>
34.2015 + static CombinedArcMap<FW, BK>
34.2016 + combinedArcMap(FW& forward, BK& backward) {
34.2017 + return CombinedArcMap<FW, BK>(forward, backward);
34.2018 }
34.2019
34.2020 - template <typename ForwardMap, typename BackwardMap>
34.2021 - static CombinedArcMap<const ForwardMap, BackwardMap>
34.2022 - combinedArcMap(const ForwardMap& forward, BackwardMap& backward) {
34.2023 - return CombinedArcMap<const ForwardMap,
34.2024 - BackwardMap>(forward, backward);
34.2025 + template <typename FW, typename BK>
34.2026 + static CombinedArcMap<const FW, BK>
34.2027 + combinedArcMap(const FW& forward, BK& backward) {
34.2028 + return CombinedArcMap<const FW, BK>(forward, backward);
34.2029 }
34.2030
34.2031 - template <typename ForwardMap, typename BackwardMap>
34.2032 - static CombinedArcMap<ForwardMap, const BackwardMap>
34.2033 - combinedArcMap(ForwardMap& forward, const BackwardMap& backward) {
34.2034 - return CombinedArcMap<ForwardMap,
34.2035 - const BackwardMap>(forward, backward);
34.2036 + template <typename FW, typename BK>
34.2037 + static CombinedArcMap<FW, const BK>
34.2038 + combinedArcMap(FW& forward, const BK& backward) {
34.2039 + return CombinedArcMap<FW, const BK>(forward, backward);
34.2040 }
34.2041
34.2042 - template <typename ForwardMap, typename BackwardMap>
34.2043 - static CombinedArcMap<const ForwardMap, const BackwardMap>
34.2044 - combinedArcMap(const ForwardMap& forward, const BackwardMap& backward) {
34.2045 - return CombinedArcMap<const ForwardMap,
34.2046 - const BackwardMap>(forward, backward);
34.2047 + template <typename FW, typename BK>
34.2048 + static CombinedArcMap<const FW, const BK>
34.2049 + combinedArcMap(const FW& forward, const BK& backward) {
34.2050 + return CombinedArcMap<const FW, const BK>(forward, backward);
34.2051 }
34.2052
34.2053 };
34.2054 @@ -2355,21 +2359,21 @@
34.2055 /// This function just returns a read-only \ref Undirector adaptor.
34.2056 /// \ingroup graph_adaptors
34.2057 /// \relates Undirector
34.2058 - template<typename GR>
34.2059 - Undirector<const GR> undirector(const GR& digraph) {
34.2060 - return Undirector<const GR>(digraph);
34.2061 + template<typename DGR>
34.2062 + Undirector<const DGR> undirector(const DGR& digraph) {
34.2063 + return Undirector<const DGR>(digraph);
34.2064 }
34.2065
34.2066
34.2067 - template <typename _Graph, typename _DirectionMap>
34.2068 + template <typename GR, typename DM>
34.2069 class OrienterBase {
34.2070 public:
34.2071
34.2072 - typedef _Graph Graph;
34.2073 - typedef _DirectionMap DirectionMap;
34.2074 -
34.2075 - typedef typename Graph::Node Node;
34.2076 - typedef typename Graph::Edge Arc;
34.2077 + typedef GR Graph;
34.2078 + typedef DM DirectionMap;
34.2079 +
34.2080 + typedef typename GR::Node Node;
34.2081 + typedef typename GR::Edge Arc;
34.2082
34.2083 void reverseArc(const Arc& arc) {
34.2084 _direction->set(arc, !(*_direction)[arc]);
34.2085 @@ -2448,22 +2452,22 @@
34.2086 int maxNodeId() const { return _graph->maxNodeId(); }
34.2087 int maxArcId() const { return _graph->maxEdgeId(); }
34.2088
34.2089 - typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
34.2090 + typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
34.2091 NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
34.2092
34.2093 - typedef typename ItemSetTraits<Graph, Arc>::ItemNotifier ArcNotifier;
34.2094 + typedef typename ItemSetTraits<GR, Arc>::ItemNotifier ArcNotifier;
34.2095 ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
34.2096
34.2097 - template <typename _Value>
34.2098 - class NodeMap : public _Graph::template NodeMap<_Value> {
34.2099 + template <typename V>
34.2100 + class NodeMap : public GR::template NodeMap<V> {
34.2101 + typedef typename GR::template NodeMap<V> Parent;
34.2102 +
34.2103 public:
34.2104
34.2105 - typedef typename _Graph::template NodeMap<_Value> Parent;
34.2106 -
34.2107 - explicit NodeMap(const OrienterBase& adapter)
34.2108 + explicit NodeMap(const OrienterBase<GR, DM>& adapter)
34.2109 : Parent(*adapter._graph) {}
34.2110
34.2111 - NodeMap(const OrienterBase& adapter, const _Value& value)
34.2112 + NodeMap(const OrienterBase<GR, DM>& adapter, const V& value)
34.2113 : Parent(*adapter._graph, value) {}
34.2114
34.2115 private:
34.2116 @@ -2479,16 +2483,16 @@
34.2117
34.2118 };
34.2119
34.2120 - template <typename _Value>
34.2121 - class ArcMap : public _Graph::template EdgeMap<_Value> {
34.2122 + template <typename V>
34.2123 + class ArcMap : public GR::template EdgeMap<V> {
34.2124 + typedef typename Graph::template EdgeMap<V> Parent;
34.2125 +
34.2126 public:
34.2127
34.2128 - typedef typename Graph::template EdgeMap<_Value> Parent;
34.2129 -
34.2130 - explicit ArcMap(const OrienterBase& adapter)
34.2131 + explicit ArcMap(const OrienterBase<GR, DM>& adapter)
34.2132 : Parent(*adapter._graph) { }
34.2133
34.2134 - ArcMap(const OrienterBase& adapter, const _Value& value)
34.2135 + ArcMap(const OrienterBase<GR, DM>& adapter, const V& value)
34.2136 : Parent(*adapter._graph, value) { }
34.2137
34.2138 private:
34.2139 @@ -2507,16 +2511,13 @@
34.2140
34.2141 protected:
34.2142 Graph* _graph;
34.2143 - DirectionMap* _direction;
34.2144 -
34.2145 - void setDirectionMap(DirectionMap& direction) {
34.2146 + DM* _direction;
34.2147 +
34.2148 + void initialize(GR& graph, DM& direction) {
34.2149 + _graph = &graph;
34.2150 _direction = &direction;
34.2151 }
34.2152
34.2153 - void setGraph(Graph& graph) {
34.2154 - _graph = &graph;
34.2155 - }
34.2156 -
34.2157 };
34.2158
34.2159 /// \ingroup graph_adaptors
34.2160 @@ -2556,6 +2557,7 @@
34.2161 class Orienter :
34.2162 public DigraphAdaptorExtender<OrienterBase<GR, DM> > {
34.2163 #endif
34.2164 + typedef DigraphAdaptorExtender<OrienterBase<GR, DM> > Parent;
34.2165 public:
34.2166
34.2167 /// The type of the adapted graph.
34.2168 @@ -2563,18 +2565,18 @@
34.2169 /// The type of the direction edge map.
34.2170 typedef DM DirectionMap;
34.2171
34.2172 - typedef DigraphAdaptorExtender<OrienterBase<GR, DM> > Parent;
34.2173 typedef typename Parent::Arc Arc;
34.2174 +
34.2175 protected:
34.2176 Orienter() { }
34.2177 +
34.2178 public:
34.2179
34.2180 /// \brief Constructor
34.2181 ///
34.2182 /// Constructor of the adaptor.
34.2183 - Orienter(Graph& graph, DirectionMap& direction) {
34.2184 - setGraph(graph);
34.2185 - setDirectionMap(direction);
34.2186 + Orienter(GR& graph, DM& direction) {
34.2187 + Parent::initialize(graph, direction);
34.2188 }
34.2189
34.2190 /// \brief Reverses the given arc
34.2191 @@ -2594,67 +2596,62 @@
34.2192 /// \relates Orienter
34.2193 template<typename GR, typename DM>
34.2194 Orienter<const GR, DM>
34.2195 - orienter(const GR& graph, DM& direction_map) {
34.2196 - return Orienter<const GR, DM>(graph, direction_map);
34.2197 + orienter(const GR& graph, DM& direction) {
34.2198 + return Orienter<const GR, DM>(graph, direction);
34.2199 }
34.2200
34.2201 template<typename GR, typename DM>
34.2202 Orienter<const GR, const DM>
34.2203 - orienter(const GR& graph, const DM& direction_map) {
34.2204 - return Orienter<const GR, const DM>(graph, direction_map);
34.2205 + orienter(const GR& graph, const DM& direction) {
34.2206 + return Orienter<const GR, const DM>(graph, direction);
34.2207 }
34.2208
34.2209 namespace _adaptor_bits {
34.2210
34.2211 - template<typename Digraph,
34.2212 - typename CapacityMap,
34.2213 - typename FlowMap,
34.2214 - typename Tolerance>
34.2215 + template <typename DGR, typename CM, typename FM, typename TL>
34.2216 class ResForwardFilter {
34.2217 public:
34.2218
34.2219 - typedef typename Digraph::Arc Key;
34.2220 + typedef typename DGR::Arc Key;
34.2221 typedef bool Value;
34.2222
34.2223 private:
34.2224
34.2225 - const CapacityMap* _capacity;
34.2226 - const FlowMap* _flow;
34.2227 - Tolerance _tolerance;
34.2228 + const CM* _capacity;
34.2229 + const FM* _flow;
34.2230 + TL _tolerance;
34.2231 +
34.2232 public:
34.2233
34.2234 - ResForwardFilter(const CapacityMap& capacity, const FlowMap& flow,
34.2235 - const Tolerance& tolerance = Tolerance())
34.2236 + ResForwardFilter(const CM& capacity, const FM& flow,
34.2237 + const TL& tolerance = TL())
34.2238 : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
34.2239
34.2240 - bool operator[](const typename Digraph::Arc& a) const {
34.2241 + bool operator[](const typename DGR::Arc& a) const {
34.2242 return _tolerance.positive((*_capacity)[a] - (*_flow)[a]);
34.2243 }
34.2244 };
34.2245
34.2246 - template<typename Digraph,
34.2247 - typename CapacityMap,
34.2248 - typename FlowMap,
34.2249 - typename Tolerance>
34.2250 + template<typename DGR,typename CM, typename FM, typename TL>
34.2251 class ResBackwardFilter {
34.2252 public:
34.2253
34.2254 - typedef typename Digraph::Arc Key;
34.2255 + typedef typename DGR::Arc Key;
34.2256 typedef bool Value;
34.2257
34.2258 private:
34.2259
34.2260 - const CapacityMap* _capacity;
34.2261 - const FlowMap* _flow;
34.2262 - Tolerance _tolerance;
34.2263 + const CM* _capacity;
34.2264 + const FM* _flow;
34.2265 + TL _tolerance;
34.2266
34.2267 public:
34.2268
34.2269 - ResBackwardFilter(const CapacityMap& capacity, const FlowMap& flow,
34.2270 - const Tolerance& tolerance = Tolerance())
34.2271 + ResBackwardFilter(const CM& capacity, const FM& flow,
34.2272 + const TL& tolerance = TL())
34.2273 : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
34.2274
34.2275 - bool operator[](const typename Digraph::Arc& a) const {
34.2276 + bool operator[](const typename DGR::Arc& a) const {
34.2277 return _tolerance.positive((*_flow)[a]);
34.2278 }
34.2279 };
34.2280 @@ -2681,7 +2678,7 @@
34.2281 /// arcs).
34.2282 /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
34.2283 ///
34.2284 - /// \tparam GR The type of the adapted digraph.
34.2285 + /// \tparam DGR The type of the adapted digraph.
34.2286 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
34.2287 /// It is implicitly \c const.
34.2288 /// \tparam CM The type of the capacity map.
34.2289 @@ -2703,25 +2700,26 @@
34.2290 /// convertible to each other, moreover the \c Arc type of the adaptor
34.2291 /// is convertible to the \c Arc type of the adapted digraph.
34.2292 #ifdef DOXYGEN
34.2293 - template<typename GR, typename CM, typename FM, typename TL>
34.2294 + template<typename DGR, typename CM, typename FM, typename TL>
34.2295 class ResidualDigraph
34.2296 #else
34.2297 - template<typename GR,
34.2298 - typename CM = typename GR::template ArcMap<int>,
34.2299 + template<typename DGR,
34.2300 + typename CM = typename DGR::template ArcMap<int>,
34.2301 typename FM = CM,
34.2302 typename TL = Tolerance<typename CM::Value> >
34.2303 - class ResidualDigraph :
34.2304 - public FilterArcs<
34.2305 - Undirector<const GR>,
34.2306 - typename Undirector<const GR>::template CombinedArcMap<
34.2307 - _adaptor_bits::ResForwardFilter<const GR, CM, FM, TL>,
34.2308 - _adaptor_bits::ResBackwardFilter<const GR, CM, FM, TL> > >
34.2309 + class ResidualDigraph
34.2310 + : public SubDigraph<
34.2311 + Undirector<const DGR>,
34.2312 + ConstMap<typename DGR::Node, Const<bool, true> >,
34.2313 + typename Undirector<const DGR>::template CombinedArcMap<
34.2314 + _adaptor_bits::ResForwardFilter<const DGR, CM, FM, TL>,
34.2315 + _adaptor_bits::ResBackwardFilter<const DGR, CM, FM, TL> > >
34.2316 #endif
34.2317 {
34.2318 public:
34.2319
34.2320 /// The type of the underlying digraph.
34.2321 - typedef GR Digraph;
34.2322 + typedef DGR Digraph;
34.2323 /// The type of the capacity map.
34.2324 typedef CM CapacityMap;
34.2325 /// The type of the flow map.
34.2326 @@ -2736,21 +2734,24 @@
34.2327
34.2328 typedef Undirector<const Digraph> Undirected;
34.2329
34.2330 - typedef _adaptor_bits::ResForwardFilter<const Digraph, CapacityMap,
34.2331 - FlowMap, Tolerance> ForwardFilter;
34.2332 -
34.2333 - typedef _adaptor_bits::ResBackwardFilter<const Digraph, CapacityMap,
34.2334 - FlowMap, Tolerance> BackwardFilter;
34.2335 + typedef ConstMap<typename DGR::Node, Const<bool, true> > NodeFilter;
34.2336 +
34.2337 + typedef _adaptor_bits::ResForwardFilter<const DGR, CM,
34.2338 + FM, TL> ForwardFilter;
34.2339 +
34.2340 + typedef _adaptor_bits::ResBackwardFilter<const DGR, CM,
34.2341 + FM, TL> BackwardFilter;
34.2342
34.2343 typedef typename Undirected::
34.2344 template CombinedArcMap<ForwardFilter, BackwardFilter> ArcFilter;
34.2345
34.2346 - typedef FilterArcs<Undirected, ArcFilter> Parent;
34.2347 + typedef SubDigraph<Undirected, NodeFilter, ArcFilter> Parent;
34.2348
34.2349 const CapacityMap* _capacity;
34.2350 FlowMap* _flow;
34.2351
34.2352 Undirected _graph;
34.2353 + NodeFilter _node_filter;
34.2354 ForwardFilter _forward_filter;
34.2355 BackwardFilter _backward_filter;
34.2356 ArcFilter _arc_filter;
34.2357 @@ -2761,15 +2762,15 @@
34.2358 ///
34.2359 /// Constructor of the residual digraph adaptor. The parameters are the
34.2360 /// digraph, the capacity map, the flow map, and a tolerance object.
34.2361 - ResidualDigraph(const Digraph& digraph, const CapacityMap& capacity,
34.2362 - FlowMap& flow, const Tolerance& tolerance = Tolerance())
34.2363 - : Parent(), _capacity(&capacity), _flow(&flow), _graph(digraph),
34.2364 + ResidualDigraph(const DGR& digraph, const CM& capacity,
34.2365 + FM& flow, const TL& tolerance = Tolerance())
34.2366 + : Parent(), _capacity(&capacity), _flow(&flow),
34.2367 + _graph(digraph), _node_filter(),
34.2368 _forward_filter(capacity, flow, tolerance),
34.2369 _backward_filter(capacity, flow, tolerance),
34.2370 _arc_filter(_forward_filter, _backward_filter)
34.2371 {
34.2372 - Parent::setDigraph(_graph);
34.2373 - Parent::setArcFilterMap(_arc_filter);
34.2374 + Parent::initialize(_graph, _node_filter, _arc_filter);
34.2375 }
34.2376
34.2377 typedef typename Parent::Arc Arc;
34.2378 @@ -2845,7 +2846,8 @@
34.2379 typedef typename CapacityMap::Value Value;
34.2380
34.2381 /// Constructor
34.2382 - ResidualCapacity(const Adaptor& adaptor) : _adaptor(&adaptor) {}
34.2383 + ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor)
34.2384 + : _adaptor(&adaptor) {}
34.2385
34.2386 /// Returns the value associated with the given residual arc
34.2387 Value operator[](const Arc& a) const {
34.2388 @@ -2865,26 +2867,27 @@
34.2389
34.2390 /// \brief Returns a (read-only) Residual adaptor
34.2391 ///
34.2392 - /// This function just returns a (read-only) \ref Residual adaptor.
34.2393 + /// This function just returns a (read-only) \ref ResidualDigraph adaptor.
34.2394 /// \ingroup graph_adaptors
34.2395 - /// \relates Residual
34.2396 - template<typename GR, typename CM, typename FM>
34.2397 - ResidualDigraph<GR, CM, FM>
34.2398 - residualDigraph(const GR& digraph, const CM& capacity_map, FM& flow_map) {
34.2399 - return ResidualDigraph<GR, CM, FM> (digraph, capacity_map, flow_map);
34.2400 + /// \relates ResidualDigraph
34.2401 + template<typename DGR, typename CM, typename FM>
34.2402 + ResidualDigraph<DGR, CM, FM>
34.2403 + residualDigraph(const DGR& digraph, const CM& capacity_map, FM& flow_map) {
34.2404 + return ResidualDigraph<DGR, CM, FM> (digraph, capacity_map, flow_map);
34.2405 }
34.2406
34.2407
34.2408 - template <typename _Digraph>
34.2409 + template <typename DGR>
34.2410 class SplitNodesBase {
34.2411 + typedef DigraphAdaptorBase<const DGR> Parent;
34.2412 +
34.2413 public:
34.2414
34.2415 - typedef _Digraph Digraph;
34.2416 - typedef DigraphAdaptorBase<const _Digraph> Parent;
34.2417 + typedef DGR Digraph;
34.2418 typedef SplitNodesBase Adaptor;
34.2419
34.2420 - typedef typename Digraph::Node DigraphNode;
34.2421 - typedef typename Digraph::Arc DigraphArc;
34.2422 + typedef typename DGR::Node DigraphNode;
34.2423 + typedef typename DGR::Arc DigraphArc;
34.2424
34.2425 class Node;
34.2426 class Arc;
34.2427 @@ -3148,32 +3151,32 @@
34.2428
34.2429 private:
34.2430
34.2431 - template <typename _Value>
34.2432 + template <typename V>
34.2433 class NodeMapBase
34.2434 - : public MapTraits<typename Parent::template NodeMap<_Value> > {
34.2435 - typedef typename Parent::template NodeMap<_Value> NodeImpl;
34.2436 + : public MapTraits<typename Parent::template NodeMap<V> > {
34.2437 + typedef typename Parent::template NodeMap<V> NodeImpl;
34.2438 public:
34.2439 typedef Node Key;
34.2440 - typedef _Value Value;
34.2441 + typedef V Value;
34.2442 typedef typename MapTraits<NodeImpl>::ReferenceMapTag ReferenceMapTag;
34.2443 typedef typename MapTraits<NodeImpl>::ReturnValue ReturnValue;
34.2444 typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReturnValue;
34.2445 typedef typename MapTraits<NodeImpl>::ReturnValue Reference;
34.2446 typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReference;
34.2447
34.2448 - NodeMapBase(const Adaptor& adaptor)
34.2449 + NodeMapBase(const SplitNodesBase<DGR>& adaptor)
34.2450 : _in_map(*adaptor._digraph), _out_map(*adaptor._digraph) {}
34.2451 - NodeMapBase(const Adaptor& adaptor, const Value& value)
34.2452 + NodeMapBase(const SplitNodesBase<DGR>& adaptor, const V& value)
34.2453 : _in_map(*adaptor._digraph, value),
34.2454 _out_map(*adaptor._digraph, value) {}
34.2455
34.2456 - void set(const Node& key, const Value& val) {
34.2457 - if (Adaptor::inNode(key)) { _in_map.set(key, val); }
34.2458 + void set(const Node& key, const V& val) {
34.2459 + if (SplitNodesBase<DGR>::inNode(key)) { _in_map.set(key, val); }
34.2460 else {_out_map.set(key, val); }
34.2461 }
34.2462
34.2463 ReturnValue operator[](const Node& key) {
34.2464 - if (Adaptor::inNode(key)) { return _in_map[key]; }
34.2465 + if (SplitNodesBase<DGR>::inNode(key)) { return _in_map[key]; }
34.2466 else { return _out_map[key]; }
34.2467 }
34.2468
34.2469 @@ -3186,47 +3189,47 @@
34.2470 NodeImpl _in_map, _out_map;
34.2471 };
34.2472
34.2473 - template <typename _Value>
34.2474 + template <typename V>
34.2475 class ArcMapBase
34.2476 - : public MapTraits<typename Parent::template ArcMap<_Value> > {
34.2477 - typedef typename Parent::template ArcMap<_Value> ArcImpl;
34.2478 - typedef typename Parent::template NodeMap<_Value> NodeImpl;
34.2479 + : public MapTraits<typename Parent::template ArcMap<V> > {
34.2480 + typedef typename Parent::template ArcMap<V> ArcImpl;
34.2481 + typedef typename Parent::template NodeMap<V> NodeImpl;
34.2482 public:
34.2483 typedef Arc Key;
34.2484 - typedef _Value Value;
34.2485 + typedef V Value;
34.2486 typedef typename MapTraits<ArcImpl>::ReferenceMapTag ReferenceMapTag;
34.2487 typedef typename MapTraits<ArcImpl>::ReturnValue ReturnValue;
34.2488 typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReturnValue;
34.2489 typedef typename MapTraits<ArcImpl>::ReturnValue Reference;
34.2490 typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReference;
34.2491
34.2492 - ArcMapBase(const Adaptor& adaptor)
34.2493 + ArcMapBase(const SplitNodesBase<DGR>& adaptor)
34.2494 : _arc_map(*adaptor._digraph), _node_map(*adaptor._digraph) {}
34.2495 - ArcMapBase(const Adaptor& adaptor, const Value& value)
34.2496 + ArcMapBase(const SplitNodesBase<DGR>& adaptor, const V& value)
34.2497 : _arc_map(*adaptor._digraph, value),
34.2498 _node_map(*adaptor._digraph, value) {}
34.2499
34.2500 - void set(const Arc& key, const Value& val) {
34.2501 - if (Adaptor::origArc(key)) {
34.2502 - _arc_map.set(key._item.first(), val);
34.2503 + void set(const Arc& key, const V& val) {
34.2504 + if (SplitNodesBase<DGR>::origArc(key)) {
34.2505 + _arc_map.set(static_cast<const DigraphArc&>(key), val);
34.2506 } else {
34.2507 - _node_map.set(key._item.second(), val);
34.2508 + _node_map.set(static_cast<const DigraphNode&>(key), val);
34.2509 }
34.2510 }
34.2511
34.2512 ReturnValue operator[](const Arc& key) {
34.2513 - if (Adaptor::origArc(key)) {
34.2514 - return _arc_map[key._item.first()];
34.2515 + if (SplitNodesBase<DGR>::origArc(key)) {
34.2516 + return _arc_map[static_cast<const DigraphArc&>(key)];
34.2517 } else {
34.2518 - return _node_map[key._item.second()];
34.2519 + return _node_map[static_cast<const DigraphNode&>(key)];
34.2520 }
34.2521 }
34.2522
34.2523 ConstReturnValue operator[](const Arc& key) const {
34.2524 - if (Adaptor::origArc(key)) {
34.2525 - return _arc_map[key._item.first()];
34.2526 + if (SplitNodesBase<DGR>::origArc(key)) {
34.2527 + return _arc_map[static_cast<const DigraphArc&>(key)];
34.2528 } else {
34.2529 - return _node_map[key._item.second()];
34.2530 + return _node_map[static_cast<const DigraphNode&>(key)];
34.2531 }
34.2532 }
34.2533
34.2534 @@ -3237,18 +3240,18 @@
34.2535
34.2536 public:
34.2537
34.2538 - template <typename _Value>
34.2539 + template <typename V>
34.2540 class NodeMap
34.2541 - : public SubMapExtender<Adaptor, NodeMapBase<_Value> >
34.2542 - {
34.2543 + : public SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> > {
34.2544 + typedef SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> > Parent;
34.2545 +
34.2546 public:
34.2547 - typedef _Value Value;
34.2548 - typedef SubMapExtender<Adaptor, NodeMapBase<Value> > Parent;
34.2549 -
34.2550 - NodeMap(const Adaptor& adaptor)
34.2551 + typedef V Value;
34.2552 +
34.2553 + NodeMap(const SplitNodesBase<DGR>& adaptor)
34.2554 : Parent(adaptor) {}
34.2555
34.2556 - NodeMap(const Adaptor& adaptor, const Value& value)
34.2557 + NodeMap(const SplitNodesBase<DGR>& adaptor, const V& value)
34.2558 : Parent(adaptor, value) {}
34.2559
34.2560 private:
34.2561 @@ -3263,18 +3266,18 @@
34.2562 }
34.2563 };
34.2564
34.2565 - template <typename _Value>
34.2566 + template <typename V>
34.2567 class ArcMap
34.2568 - : public SubMapExtender<Adaptor, ArcMapBase<_Value> >
34.2569 - {
34.2570 + : public SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> > {
34.2571 + typedef SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> > Parent;
34.2572 +
34.2573 public:
34.2574 - typedef _Value Value;
34.2575 - typedef SubMapExtender<Adaptor, ArcMapBase<Value> > Parent;
34.2576 -
34.2577 - ArcMap(const Adaptor& adaptor)
34.2578 + typedef V Value;
34.2579 +
34.2580 + ArcMap(const SplitNodesBase<DGR>& adaptor)
34.2581 : Parent(adaptor) {}
34.2582
34.2583 - ArcMap(const Adaptor& adaptor, const Value& value)
34.2584 + ArcMap(const SplitNodesBase<DGR>& adaptor, const V& value)
34.2585 : Parent(adaptor, value) {}
34.2586
34.2587 private:
34.2588 @@ -3293,9 +3296,9 @@
34.2589
34.2590 SplitNodesBase() : _digraph(0) {}
34.2591
34.2592 - Digraph* _digraph;
34.2593 -
34.2594 - void setDigraph(Digraph& digraph) {
34.2595 + DGR* _digraph;
34.2596 +
34.2597 + void initialize(Digraph& digraph) {
34.2598 _digraph = &digraph;
34.2599 }
34.2600
34.2601 @@ -3322,25 +3325,26 @@
34.2602 /// costs/capacities of the original digraph to the \e bind \e arcs
34.2603 /// in the adaptor.
34.2604 ///
34.2605 - /// \tparam GR The type of the adapted digraph.
34.2606 + /// \tparam DGR The type of the adapted digraph.
34.2607 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
34.2608 /// It is implicitly \c const.
34.2609 ///
34.2610 /// \note The \c Node type of this adaptor is converible to the \c Node
34.2611 /// type of the adapted digraph.
34.2612 - template <typename GR>
34.2613 + template <typename DGR>
34.2614 #ifdef DOXYGEN
34.2615 class SplitNodes {
34.2616 #else
34.2617 class SplitNodes
34.2618 - : public DigraphAdaptorExtender<SplitNodesBase<const GR> > {
34.2619 + : public DigraphAdaptorExtender<SplitNodesBase<const DGR> > {
34.2620 #endif
34.2621 + typedef DigraphAdaptorExtender<SplitNodesBase<const DGR> > Parent;
34.2622 +
34.2623 public:
34.2624 - typedef GR Digraph;
34.2625 - typedef DigraphAdaptorExtender<SplitNodesBase<const GR> > Parent;
34.2626 -
34.2627 - typedef typename Digraph::Node DigraphNode;
34.2628 - typedef typename Digraph::Arc DigraphArc;
34.2629 + typedef DGR Digraph;
34.2630 +
34.2631 + typedef typename DGR::Node DigraphNode;
34.2632 + typedef typename DGR::Arc DigraphArc;
34.2633
34.2634 typedef typename Parent::Node Node;
34.2635 typedef typename Parent::Arc Arc;
34.2636 @@ -3348,8 +3352,8 @@
34.2637 /// \brief Constructor
34.2638 ///
34.2639 /// Constructor of the adaptor.
34.2640 - SplitNodes(const Digraph& g) {
34.2641 - Parent::setDigraph(g);
34.2642 + SplitNodes(const DGR& g) {
34.2643 + Parent::initialize(g);
34.2644 }
34.2645
34.2646 /// \brief Returns \c true if the given node is an in-node.
34.2647 @@ -3418,30 +3422,31 @@
34.2648 ///
34.2649 /// This map adaptor class adapts two node maps of the original digraph
34.2650 /// to get a node map of the split digraph.
34.2651 - /// Its value type is inherited from the first node map type
34.2652 - /// (\c InNodeMap).
34.2653 - template <typename InNodeMap, typename OutNodeMap>
34.2654 + /// Its value type is inherited from the first node map type (\c IN).
34.2655 + /// \tparam IN The type of the node map for the in-nodes.
34.2656 + /// \tparam OUT The type of the node map for the out-nodes.
34.2657 + template <typename IN, typename OUT>
34.2658 class CombinedNodeMap {
34.2659 public:
34.2660
34.2661 /// The key type of the map
34.2662 typedef Node Key;
34.2663 /// The value type of the map
34.2664 - typedef typename InNodeMap::Value Value;
34.2665 -
34.2666 - typedef typename MapTraits<InNodeMap>::ReferenceMapTag ReferenceMapTag;
34.2667 - typedef typename MapTraits<InNodeMap>::ReturnValue ReturnValue;
34.2668 - typedef typename MapTraits<InNodeMap>::ConstReturnValue ConstReturnValue;
34.2669 - typedef typename MapTraits<InNodeMap>::ReturnValue Reference;
34.2670 - typedef typename MapTraits<InNodeMap>::ConstReturnValue ConstReference;
34.2671 + typedef typename IN::Value Value;
34.2672 +
34.2673 + typedef typename MapTraits<IN>::ReferenceMapTag ReferenceMapTag;
34.2674 + typedef typename MapTraits<IN>::ReturnValue ReturnValue;
34.2675 + typedef typename MapTraits<IN>::ConstReturnValue ConstReturnValue;
34.2676 + typedef typename MapTraits<IN>::ReturnValue Reference;
34.2677 + typedef typename MapTraits<IN>::ConstReturnValue ConstReference;
34.2678
34.2679 /// Constructor
34.2680 - CombinedNodeMap(InNodeMap& in_map, OutNodeMap& out_map)
34.2681 + CombinedNodeMap(IN& in_map, OUT& out_map)
34.2682 : _in_map(in_map), _out_map(out_map) {}
34.2683
34.2684 /// Returns the value associated with the given key.
34.2685 Value operator[](const Key& key) const {
34.2686 - if (Parent::inNode(key)) {
34.2687 + if (SplitNodesBase<const DGR>::inNode(key)) {
34.2688 return _in_map[key];
34.2689 } else {
34.2690 return _out_map[key];
34.2691 @@ -3450,7 +3455,7 @@
34.2692
34.2693 /// Returns a reference to the value associated with the given key.
34.2694 Value& operator[](const Key& key) {
34.2695 - if (Parent::inNode(key)) {
34.2696 + if (SplitNodesBase<const DGR>::inNode(key)) {
34.2697 return _in_map[key];
34.2698 } else {
34.2699 return _out_map[key];
34.2700 @@ -3459,7 +3464,7 @@
34.2701
34.2702 /// Sets the value associated with the given key.
34.2703 void set(const Key& key, const Value& value) {
34.2704 - if (Parent::inNode(key)) {
34.2705 + if (SplitNodesBase<const DGR>::inNode(key)) {
34.2706 _in_map.set(key, value);
34.2707 } else {
34.2708 _out_map.set(key, value);
34.2709 @@ -3468,8 +3473,8 @@
34.2710
34.2711 private:
34.2712
34.2713 - InNodeMap& _in_map;
34.2714 - OutNodeMap& _out_map;
34.2715 + IN& _in_map;
34.2716 + OUT& _out_map;
34.2717
34.2718 };
34.2719
34.2720 @@ -3477,29 +3482,28 @@
34.2721 /// \brief Returns a combined node map
34.2722 ///
34.2723 /// This function just returns a combined node map.
34.2724 - template <typename InNodeMap, typename OutNodeMap>
34.2725 - static CombinedNodeMap<InNodeMap, OutNodeMap>
34.2726 - combinedNodeMap(InNodeMap& in_map, OutNodeMap& out_map) {
34.2727 - return CombinedNodeMap<InNodeMap, OutNodeMap>(in_map, out_map);
34.2728 + template <typename IN, typename OUT>
34.2729 + static CombinedNodeMap<IN, OUT>
34.2730 + combinedNodeMap(IN& in_map, OUT& out_map) {
34.2731 + return CombinedNodeMap<IN, OUT>(in_map, out_map);
34.2732 }
34.2733
34.2734 - template <typename InNodeMap, typename OutNodeMap>
34.2735 - static CombinedNodeMap<const InNodeMap, OutNodeMap>
34.2736 - combinedNodeMap(const InNodeMap& in_map, OutNodeMap& out_map) {
34.2737 - return CombinedNodeMap<const InNodeMap, OutNodeMap>(in_map, out_map);
34.2738 + template <typename IN, typename OUT>
34.2739 + static CombinedNodeMap<const IN, OUT>
34.2740 + combinedNodeMap(const IN& in_map, OUT& out_map) {
34.2741 + return CombinedNodeMap<const IN, OUT>(in_map, out_map);
34.2742 }
34.2743
34.2744 - template <typename InNodeMap, typename OutNodeMap>
34.2745 - static CombinedNodeMap<InNodeMap, const OutNodeMap>
34.2746 - combinedNodeMap(InNodeMap& in_map, const OutNodeMap& out_map) {
34.2747 - return CombinedNodeMap<InNodeMap, const OutNodeMap>(in_map, out_map);
34.2748 + template <typename IN, typename OUT>
34.2749 + static CombinedNodeMap<IN, const OUT>
34.2750 + combinedNodeMap(IN& in_map, const OUT& out_map) {
34.2751 + return CombinedNodeMap<IN, const OUT>(in_map, out_map);
34.2752 }
34.2753
34.2754 - template <typename InNodeMap, typename OutNodeMap>
34.2755 - static CombinedNodeMap<const InNodeMap, const OutNodeMap>
34.2756 - combinedNodeMap(const InNodeMap& in_map, const OutNodeMap& out_map) {
34.2757 - return CombinedNodeMap<const InNodeMap,
34.2758 - const OutNodeMap>(in_map, out_map);
34.2759 + template <typename IN, typename OUT>
34.2760 + static CombinedNodeMap<const IN, const OUT>
34.2761 + combinedNodeMap(const IN& in_map, const OUT& out_map) {
34.2762 + return CombinedNodeMap<const IN, const OUT>(in_map, out_map);
34.2763 }
34.2764
34.2765 /// \brief Arc map combined from an arc map and a node map of the
34.2766 @@ -3507,30 +3511,31 @@
34.2767 ///
34.2768 /// This map adaptor class adapts an arc map and a node map of the
34.2769 /// original digraph to get an arc map of the split digraph.
34.2770 - /// Its value type is inherited from the original arc map type
34.2771 - /// (\c ArcMap).
34.2772 - template <typename ArcMap, typename NodeMap>
34.2773 + /// Its value type is inherited from the original arc map type (\c AM).
34.2774 + /// \tparam AM The type of the arc map.
34.2775 + /// \tparam NM the type of the node map.
34.2776 + template <typename AM, typename NM>
34.2777 class CombinedArcMap {
34.2778 public:
34.2779
34.2780 /// The key type of the map
34.2781 typedef Arc Key;
34.2782 /// The value type of the map
34.2783 - typedef typename ArcMap::Value Value;
34.2784 -
34.2785 - typedef typename MapTraits<ArcMap>::ReferenceMapTag ReferenceMapTag;
34.2786 - typedef typename MapTraits<ArcMap>::ReturnValue ReturnValue;
34.2787 - typedef typename MapTraits<ArcMap>::ConstReturnValue ConstReturnValue;
34.2788 - typedef typename MapTraits<ArcMap>::ReturnValue Reference;
34.2789 - typedef typename MapTraits<ArcMap>::ConstReturnValue ConstReference;
34.2790 + typedef typename AM::Value Value;
34.2791 +
34.2792 + typedef typename MapTraits<AM>::ReferenceMapTag ReferenceMapTag;
34.2793 + typedef typename MapTraits<AM>::ReturnValue ReturnValue;
34.2794 + typedef typename MapTraits<AM>::ConstReturnValue ConstReturnValue;
34.2795 + typedef typename MapTraits<AM>::ReturnValue Reference;
34.2796 + typedef typename MapTraits<AM>::ConstReturnValue ConstReference;
34.2797
34.2798 /// Constructor
34.2799 - CombinedArcMap(ArcMap& arc_map, NodeMap& node_map)
34.2800 + CombinedArcMap(AM& arc_map, NM& node_map)
34.2801 : _arc_map(arc_map), _node_map(node_map) {}
34.2802
34.2803 /// Returns the value associated with the given key.
34.2804 Value operator[](const Key& arc) const {
34.2805 - if (Parent::origArc(arc)) {
34.2806 + if (SplitNodesBase<const DGR>::origArc(arc)) {
34.2807 return _arc_map[arc];
34.2808 } else {
34.2809 return _node_map[arc];
34.2810 @@ -3539,7 +3544,7 @@
34.2811
34.2812 /// Returns a reference to the value associated with the given key.
34.2813 Value& operator[](const Key& arc) {
34.2814 - if (Parent::origArc(arc)) {
34.2815 + if (SplitNodesBase<const DGR>::origArc(arc)) {
34.2816 return _arc_map[arc];
34.2817 } else {
34.2818 return _node_map[arc];
34.2819 @@ -3548,7 +3553,7 @@
34.2820
34.2821 /// Sets the value associated with the given key.
34.2822 void set(const Arc& arc, const Value& val) {
34.2823 - if (Parent::origArc(arc)) {
34.2824 + if (SplitNodesBase<const DGR>::origArc(arc)) {
34.2825 _arc_map.set(arc, val);
34.2826 } else {
34.2827 _node_map.set(arc, val);
34.2828 @@ -3556,8 +3561,10 @@
34.2829 }
34.2830
34.2831 private:
34.2832 - ArcMap& _arc_map;
34.2833 - NodeMap& _node_map;
34.2834 +
34.2835 + AM& _arc_map;
34.2836 + NM& _node_map;
34.2837 +
34.2838 };
34.2839
34.2840 /// \brief Returns a combined arc map
34.2841 @@ -3594,12 +3601,14 @@
34.2842 /// This function just returns a (read-only) \ref SplitNodes adaptor.
34.2843 /// \ingroup graph_adaptors
34.2844 /// \relates SplitNodes
34.2845 - template<typename GR>
34.2846 - SplitNodes<GR>
34.2847 - splitNodes(const GR& digraph) {
34.2848 - return SplitNodes<GR>(digraph);
34.2849 + template<typename DGR>
34.2850 + SplitNodes<DGR>
34.2851 + splitNodes(const DGR& digraph) {
34.2852 + return SplitNodes<DGR>(digraph);
34.2853 }
34.2854
34.2855 +#undef LEMON_SCOPE_FIX
34.2856 +
34.2857 } //namespace lemon
34.2858
34.2859 #endif //LEMON_ADAPTORS_H
35.1 --- a/lemon/base.cc Mon Jan 12 23:11:39 2009 +0100
35.2 +++ b/lemon/base.cc Thu Nov 05 15:48:01 2009 +0100
35.3 @@ -23,7 +23,7 @@
35.4 #include<lemon/core.h>
35.5 namespace lemon {
35.6
35.7 - float Tolerance<float>::def_epsilon = 1e-4;
35.8 + float Tolerance<float>::def_epsilon = static_cast<float>(1e-4);
35.9 double Tolerance<double>::def_epsilon = 1e-10;
35.10 long double Tolerance<long double>::def_epsilon = 1e-14;
35.11
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/lemon/bellman_ford.h Thu Nov 05 15:48:01 2009 +0100
36.3 @@ -0,0 +1,1101 @@
36.4 +/* -*- C++ -*-
36.5 + *
36.6 + * This file is a part of LEMON, a generic C++ optimization library
36.7 + *
36.8 + * Copyright (C) 2003-2008
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 +#ifndef LEMON_BELLMAN_FORD_H
36.23 +#define LEMON_BELLMAN_FORD_H
36.24 +
36.25 +/// \ingroup shortest_path
36.26 +/// \file
36.27 +/// \brief Bellman-Ford algorithm.
36.28 +
36.29 +#include <lemon/list_graph.h>
36.30 +#include <lemon/bits/path_dump.h>
36.31 +#include <lemon/core.h>
36.32 +#include <lemon/error.h>
36.33 +#include <lemon/maps.h>
36.34 +#include <lemon/path.h>
36.35 +
36.36 +#include <limits>
36.37 +
36.38 +namespace lemon {
36.39 +
36.40 + /// \brief Default OperationTraits for the BellmanFord algorithm class.
36.41 + ///
36.42 + /// This operation traits class defines all computational operations
36.43 + /// and constants that are used in the Bellman-Ford algorithm.
36.44 + /// The default implementation is based on the \c numeric_limits class.
36.45 + /// If the numeric type does not have infinity value, then the maximum
36.46 + /// value is used as extremal infinity value.
36.47 + template <
36.48 + typename V,
36.49 + bool has_inf = std::numeric_limits<V>::has_infinity>
36.50 + struct BellmanFordDefaultOperationTraits {
36.51 + /// \e
36.52 + typedef V Value;
36.53 + /// \brief Gives back the zero value of the type.
36.54 + static Value zero() {
36.55 + return static_cast<Value>(0);
36.56 + }
36.57 + /// \brief Gives back the positive infinity value of the type.
36.58 + static Value infinity() {
36.59 + return std::numeric_limits<Value>::infinity();
36.60 + }
36.61 + /// \brief Gives back the sum of the given two elements.
36.62 + static Value plus(const Value& left, const Value& right) {
36.63 + return left + right;
36.64 + }
36.65 + /// \brief Gives back \c true only if the first value is less than
36.66 + /// the second.
36.67 + static bool less(const Value& left, const Value& right) {
36.68 + return left < right;
36.69 + }
36.70 + };
36.71 +
36.72 + template <typename V>
36.73 + struct BellmanFordDefaultOperationTraits<V, false> {
36.74 + typedef V Value;
36.75 + static Value zero() {
36.76 + return static_cast<Value>(0);
36.77 + }
36.78 + static Value infinity() {
36.79 + return std::numeric_limits<Value>::max();
36.80 + }
36.81 + static Value plus(const Value& left, const Value& right) {
36.82 + if (left == infinity() || right == infinity()) return infinity();
36.83 + return left + right;
36.84 + }
36.85 + static bool less(const Value& left, const Value& right) {
36.86 + return left < right;
36.87 + }
36.88 + };
36.89 +
36.90 + /// \brief Default traits class of BellmanFord class.
36.91 + ///
36.92 + /// Default traits class of BellmanFord class.
36.93 + /// \param GR The type of the digraph.
36.94 + /// \param LEN The type of the length map.
36.95 + template<typename GR, typename LEN>
36.96 + struct BellmanFordDefaultTraits {
36.97 + /// The type of the digraph the algorithm runs on.
36.98 + typedef GR Digraph;
36.99 +
36.100 + /// \brief The type of the map that stores the arc lengths.
36.101 + ///
36.102 + /// The type of the map that stores the arc lengths.
36.103 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
36.104 + typedef LEN LengthMap;
36.105 +
36.106 + /// The type of the arc lengths.
36.107 + typedef typename LEN::Value Value;
36.108 +
36.109 + /// \brief Operation traits for Bellman-Ford algorithm.
36.110 + ///
36.111 + /// It defines the used operations and the infinity value for the
36.112 + /// given \c Value type.
36.113 + /// \see BellmanFordDefaultOperationTraits
36.114 + typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
36.115 +
36.116 + /// \brief The type of the map that stores the last arcs of the
36.117 + /// shortest paths.
36.118 + ///
36.119 + /// The type of the map that stores the last
36.120 + /// arcs of the shortest paths.
36.121 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
36.122 + typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
36.123 +
36.124 + /// \brief Instantiates a \c PredMap.
36.125 + ///
36.126 + /// This function instantiates a \ref PredMap.
36.127 + /// \param g is the digraph to which we would like to define the
36.128 + /// \ref PredMap.
36.129 + static PredMap *createPredMap(const GR& g) {
36.130 + return new PredMap(g);
36.131 + }
36.132 +
36.133 + /// \brief The type of the map that stores the distances of the nodes.
36.134 + ///
36.135 + /// The type of the map that stores the distances of the nodes.
36.136 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
36.137 + typedef typename GR::template NodeMap<typename LEN::Value> DistMap;
36.138 +
36.139 + /// \brief Instantiates a \c DistMap.
36.140 + ///
36.141 + /// This function instantiates a \ref DistMap.
36.142 + /// \param g is the digraph to which we would like to define the
36.143 + /// \ref DistMap.
36.144 + static DistMap *createDistMap(const GR& g) {
36.145 + return new DistMap(g);
36.146 + }
36.147 +
36.148 + };
36.149 +
36.150 + /// \brief %BellmanFord algorithm class.
36.151 + ///
36.152 + /// \ingroup shortest_path
36.153 + /// This class provides an efficient implementation of the Bellman-Ford
36.154 + /// algorithm. The maximum time complexity of the algorithm is
36.155 + /// <tt>O(ne)</tt>.
36.156 + ///
36.157 + /// The Bellman-Ford algorithm solves the single-source shortest path
36.158 + /// problem when the arcs can have negative lengths, but the digraph
36.159 + /// should not contain directed cycles with negative total length.
36.160 + /// If all arc costs are non-negative, consider to use the Dijkstra
36.161 + /// algorithm instead, since it is more efficient.
36.162 + ///
36.163 + /// The arc lengths are passed to the algorithm using a
36.164 + /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
36.165 + /// kind of length. The type of the length values is determined by the
36.166 + /// \ref concepts::ReadMap::Value "Value" type of the length map.
36.167 + ///
36.168 + /// There is also a \ref bellmanFord() "function-type interface" for the
36.169 + /// Bellman-Ford algorithm, which is convenient in the simplier cases and
36.170 + /// it can be used easier.
36.171 + ///
36.172 + /// \tparam GR The type of the digraph the algorithm runs on.
36.173 + /// The default type is \ref ListDigraph.
36.174 + /// \tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
36.175 + /// the lengths of the arcs. The default map type is
36.176 + /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
36.177 +#ifdef DOXYGEN
36.178 + template <typename GR, typename LEN, typename TR>
36.179 +#else
36.180 + template <typename GR=ListDigraph,
36.181 + typename LEN=typename GR::template ArcMap<int>,
36.182 + typename TR=BellmanFordDefaultTraits<GR,LEN> >
36.183 +#endif
36.184 + class BellmanFord {
36.185 + public:
36.186 +
36.187 + ///The type of the underlying digraph.
36.188 + typedef typename TR::Digraph Digraph;
36.189 +
36.190 + /// \brief The type of the arc lengths.
36.191 + typedef typename TR::LengthMap::Value Value;
36.192 + /// \brief The type of the map that stores the arc lengths.
36.193 + typedef typename TR::LengthMap LengthMap;
36.194 + /// \brief The type of the map that stores the last
36.195 + /// arcs of the shortest paths.
36.196 + typedef typename TR::PredMap PredMap;
36.197 + /// \brief The type of the map that stores the distances of the nodes.
36.198 + typedef typename TR::DistMap DistMap;
36.199 + /// The type of the paths.
36.200 + typedef PredMapPath<Digraph, PredMap> Path;
36.201 + ///\brief The \ref BellmanFordDefaultOperationTraits
36.202 + /// "operation traits class" of the algorithm.
36.203 + typedef typename TR::OperationTraits OperationTraits;
36.204 +
36.205 + ///The \ref BellmanFordDefaultTraits "traits class" of the algorithm.
36.206 + typedef TR Traits;
36.207 +
36.208 + private:
36.209 +
36.210 + typedef typename Digraph::Node Node;
36.211 + typedef typename Digraph::NodeIt NodeIt;
36.212 + typedef typename Digraph::Arc Arc;
36.213 + typedef typename Digraph::OutArcIt OutArcIt;
36.214 +
36.215 + // Pointer to the underlying digraph.
36.216 + const Digraph *_gr;
36.217 + // Pointer to the length map
36.218 + const LengthMap *_length;
36.219 + // Pointer to the map of predecessors arcs.
36.220 + PredMap *_pred;
36.221 + // Indicates if _pred is locally allocated (true) or not.
36.222 + bool _local_pred;
36.223 + // Pointer to the map of distances.
36.224 + DistMap *_dist;
36.225 + // Indicates if _dist is locally allocated (true) or not.
36.226 + bool _local_dist;
36.227 +
36.228 + typedef typename Digraph::template NodeMap<bool> MaskMap;
36.229 + MaskMap *_mask;
36.230 +
36.231 + std::vector<Node> _process;
36.232 +
36.233 + // Creates the maps if necessary.
36.234 + void create_maps() {
36.235 + if(!_pred) {
36.236 + _local_pred = true;
36.237 + _pred = Traits::createPredMap(*_gr);
36.238 + }
36.239 + if(!_dist) {
36.240 + _local_dist = true;
36.241 + _dist = Traits::createDistMap(*_gr);
36.242 + }
36.243 + _mask = new MaskMap(*_gr, false);
36.244 + }
36.245 +
36.246 + public :
36.247 +
36.248 + typedef BellmanFord Create;
36.249 +
36.250 + /// \name Named Template Parameters
36.251 +
36.252 + ///@{
36.253 +
36.254 + template <class T>
36.255 + struct SetPredMapTraits : public Traits {
36.256 + typedef T PredMap;
36.257 + static PredMap *createPredMap(const Digraph&) {
36.258 + LEMON_ASSERT(false, "PredMap is not initialized");
36.259 + return 0; // ignore warnings
36.260 + }
36.261 + };
36.262 +
36.263 + /// \brief \ref named-templ-param "Named parameter" for setting
36.264 + /// \c PredMap type.
36.265 + ///
36.266 + /// \ref named-templ-param "Named parameter" for setting
36.267 + /// \c PredMap type.
36.268 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
36.269 + template <class T>
36.270 + struct SetPredMap
36.271 + : public BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > {
36.272 + typedef BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > Create;
36.273 + };
36.274 +
36.275 + template <class T>
36.276 + struct SetDistMapTraits : public Traits {
36.277 + typedef T DistMap;
36.278 + static DistMap *createDistMap(const Digraph&) {
36.279 + LEMON_ASSERT(false, "DistMap is not initialized");
36.280 + return 0; // ignore warnings
36.281 + }
36.282 + };
36.283 +
36.284 + /// \brief \ref named-templ-param "Named parameter" for setting
36.285 + /// \c DistMap type.
36.286 + ///
36.287 + /// \ref named-templ-param "Named parameter" for setting
36.288 + /// \c DistMap type.
36.289 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
36.290 + template <class T>
36.291 + struct SetDistMap
36.292 + : public BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > {
36.293 + typedef BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > Create;
36.294 + };
36.295 +
36.296 + template <class T>
36.297 + struct SetOperationTraitsTraits : public Traits {
36.298 + typedef T OperationTraits;
36.299 + };
36.300 +
36.301 + /// \brief \ref named-templ-param "Named parameter" for setting
36.302 + /// \c OperationTraits type.
36.303 + ///
36.304 + /// \ref named-templ-param "Named parameter" for setting
36.305 + /// \c OperationTraits type.
36.306 + /// For more information see \ref BellmanFordDefaultOperationTraits.
36.307 + template <class T>
36.308 + struct SetOperationTraits
36.309 + : public BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> > {
36.310 + typedef BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> >
36.311 + Create;
36.312 + };
36.313 +
36.314 + ///@}
36.315 +
36.316 + protected:
36.317 +
36.318 + BellmanFord() {}
36.319 +
36.320 + public:
36.321 +
36.322 + /// \brief Constructor.
36.323 + ///
36.324 + /// Constructor.
36.325 + /// \param g The digraph the algorithm runs on.
36.326 + /// \param length The length map used by the algorithm.
36.327 + BellmanFord(const Digraph& g, const LengthMap& length) :
36.328 + _gr(&g), _length(&length),
36.329 + _pred(0), _local_pred(false),
36.330 + _dist(0), _local_dist(false), _mask(0) {}
36.331 +
36.332 + ///Destructor.
36.333 + ~BellmanFord() {
36.334 + if(_local_pred) delete _pred;
36.335 + if(_local_dist) delete _dist;
36.336 + if(_mask) delete _mask;
36.337 + }
36.338 +
36.339 + /// \brief Sets the length map.
36.340 + ///
36.341 + /// Sets the length map.
36.342 + /// \return <tt>(*this)</tt>
36.343 + BellmanFord &lengthMap(const LengthMap &map) {
36.344 + _length = ↦
36.345 + return *this;
36.346 + }
36.347 +
36.348 + /// \brief Sets the map that stores the predecessor arcs.
36.349 + ///
36.350 + /// Sets the map that stores the predecessor arcs.
36.351 + /// If you don't use this function before calling \ref run()
36.352 + /// or \ref init(), an instance will be allocated automatically.
36.353 + /// The destructor deallocates this automatically allocated map,
36.354 + /// of course.
36.355 + /// \return <tt>(*this)</tt>
36.356 + BellmanFord &predMap(PredMap &map) {
36.357 + if(_local_pred) {
36.358 + delete _pred;
36.359 + _local_pred=false;
36.360 + }
36.361 + _pred = ↦
36.362 + return *this;
36.363 + }
36.364 +
36.365 + /// \brief Sets the map that stores the distances of the nodes.
36.366 + ///
36.367 + /// Sets the map that stores the distances of the nodes calculated
36.368 + /// by the algorithm.
36.369 + /// If you don't use this function before calling \ref run()
36.370 + /// or \ref init(), an instance will be allocated automatically.
36.371 + /// The destructor deallocates this automatically allocated map,
36.372 + /// of course.
36.373 + /// \return <tt>(*this)</tt>
36.374 + BellmanFord &distMap(DistMap &map) {
36.375 + if(_local_dist) {
36.376 + delete _dist;
36.377 + _local_dist=false;
36.378 + }
36.379 + _dist = ↦
36.380 + return *this;
36.381 + }
36.382 +
36.383 + /// \name Execution Control
36.384 + /// The simplest way to execute the Bellman-Ford algorithm is to use
36.385 + /// one of the member functions called \ref run().\n
36.386 + /// If you need better control on the execution, you have to call
36.387 + /// \ref init() first, then you can add several source nodes
36.388 + /// with \ref addSource(). Finally the actual path computation can be
36.389 + /// performed with \ref start(), \ref checkedStart() or
36.390 + /// \ref limitedStart().
36.391 +
36.392 + ///@{
36.393 +
36.394 + /// \brief Initializes the internal data structures.
36.395 + ///
36.396 + /// Initializes the internal data structures. The optional parameter
36.397 + /// is the initial distance of each node.
36.398 + void init(const Value value = OperationTraits::infinity()) {
36.399 + create_maps();
36.400 + for (NodeIt it(*_gr); it != INVALID; ++it) {
36.401 + _pred->set(it, INVALID);
36.402 + _dist->set(it, value);
36.403 + }
36.404 + _process.clear();
36.405 + if (OperationTraits::less(value, OperationTraits::infinity())) {
36.406 + for (NodeIt it(*_gr); it != INVALID; ++it) {
36.407 + _process.push_back(it);
36.408 + _mask->set(it, true);
36.409 + }
36.410 + }
36.411 + }
36.412 +
36.413 + /// \brief Adds a new source node.
36.414 + ///
36.415 + /// This function adds a new source node. The optional second parameter
36.416 + /// is the initial distance of the node.
36.417 + void addSource(Node source, Value dst = OperationTraits::zero()) {
36.418 + _dist->set(source, dst);
36.419 + if (!(*_mask)[source]) {
36.420 + _process.push_back(source);
36.421 + _mask->set(source, true);
36.422 + }
36.423 + }
36.424 +
36.425 + /// \brief Executes one round from the Bellman-Ford algorithm.
36.426 + ///
36.427 + /// If the algoritm calculated the distances in the previous round
36.428 + /// exactly for the paths of at most \c k arcs, then this function
36.429 + /// will calculate the distances exactly for the paths of at most
36.430 + /// <tt>k+1</tt> arcs. Performing \c k iterations using this function
36.431 + /// calculates the shortest path distances exactly for the paths
36.432 + /// consisting of at most \c k arcs.
36.433 + ///
36.434 + /// \warning The paths with limited arc number cannot be retrieved
36.435 + /// easily with \ref path() or \ref predArc() functions. If you also
36.436 + /// need the shortest paths and not only the distances, you should
36.437 + /// store the \ref predMap() "predecessor map" after each iteration
36.438 + /// and build the path manually.
36.439 + ///
36.440 + /// \return \c true when the algorithm have not found more shorter
36.441 + /// paths.
36.442 + ///
36.443 + /// \see ActiveIt
36.444 + bool processNextRound() {
36.445 + for (int i = 0; i < int(_process.size()); ++i) {
36.446 + _mask->set(_process[i], false);
36.447 + }
36.448 + std::vector<Node> nextProcess;
36.449 + std::vector<Value> values(_process.size());
36.450 + for (int i = 0; i < int(_process.size()); ++i) {
36.451 + values[i] = (*_dist)[_process[i]];
36.452 + }
36.453 + for (int i = 0; i < int(_process.size()); ++i) {
36.454 + for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
36.455 + Node target = _gr->target(it);
36.456 + Value relaxed = OperationTraits::plus(values[i], (*_length)[it]);
36.457 + if (OperationTraits::less(relaxed, (*_dist)[target])) {
36.458 + _pred->set(target, it);
36.459 + _dist->set(target, relaxed);
36.460 + if (!(*_mask)[target]) {
36.461 + _mask->set(target, true);
36.462 + nextProcess.push_back(target);
36.463 + }
36.464 + }
36.465 + }
36.466 + }
36.467 + _process.swap(nextProcess);
36.468 + return _process.empty();
36.469 + }
36.470 +
36.471 + /// \brief Executes one weak round from the Bellman-Ford algorithm.
36.472 + ///
36.473 + /// If the algorithm calculated the distances in the previous round
36.474 + /// at least for the paths of at most \c k arcs, then this function
36.475 + /// will calculate the distances at least for the paths of at most
36.476 + /// <tt>k+1</tt> arcs.
36.477 + /// This function does not make it possible to calculate the shortest
36.478 + /// path distances exactly for paths consisting of at most \c k arcs,
36.479 + /// this is why it is called weak round.
36.480 + ///
36.481 + /// \return \c true when the algorithm have not found more shorter
36.482 + /// paths.
36.483 + ///
36.484 + /// \see ActiveIt
36.485 + bool processNextWeakRound() {
36.486 + for (int i = 0; i < int(_process.size()); ++i) {
36.487 + _mask->set(_process[i], false);
36.488 + }
36.489 + std::vector<Node> nextProcess;
36.490 + for (int i = 0; i < int(_process.size()); ++i) {
36.491 + for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
36.492 + Node target = _gr->target(it);
36.493 + Value relaxed =
36.494 + OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]);
36.495 + if (OperationTraits::less(relaxed, (*_dist)[target])) {
36.496 + _pred->set(target, it);
36.497 + _dist->set(target, relaxed);
36.498 + if (!(*_mask)[target]) {
36.499 + _mask->set(target, true);
36.500 + nextProcess.push_back(target);
36.501 + }
36.502 + }
36.503 + }
36.504 + }
36.505 + _process.swap(nextProcess);
36.506 + return _process.empty();
36.507 + }
36.508 +
36.509 + /// \brief Executes the algorithm.
36.510 + ///
36.511 + /// Executes the algorithm.
36.512 + ///
36.513 + /// This method runs the Bellman-Ford algorithm from the root node(s)
36.514 + /// in order to compute the shortest path to each node.
36.515 + ///
36.516 + /// The algorithm computes
36.517 + /// - the shortest path tree (forest),
36.518 + /// - the distance of each node from the root(s).
36.519 + ///
36.520 + /// \pre init() must be called and at least one root node should be
36.521 + /// added with addSource() before using this function.
36.522 + void start() {
36.523 + int num = countNodes(*_gr) - 1;
36.524 + for (int i = 0; i < num; ++i) {
36.525 + if (processNextWeakRound()) break;
36.526 + }
36.527 + }
36.528 +
36.529 + /// \brief Executes the algorithm and checks the negative cycles.
36.530 + ///
36.531 + /// Executes the algorithm and checks the negative cycles.
36.532 + ///
36.533 + /// This method runs the Bellman-Ford algorithm from the root node(s)
36.534 + /// in order to compute the shortest path to each node and also checks
36.535 + /// if the digraph contains cycles with negative total length.
36.536 + ///
36.537 + /// The algorithm computes
36.538 + /// - the shortest path tree (forest),
36.539 + /// - the distance of each node from the root(s).
36.540 + ///
36.541 + /// \return \c false if there is a negative cycle in the digraph.
36.542 + ///
36.543 + /// \pre init() must be called and at least one root node should be
36.544 + /// added with addSource() before using this function.
36.545 + bool checkedStart() {
36.546 + int num = countNodes(*_gr);
36.547 + for (int i = 0; i < num; ++i) {
36.548 + if (processNextWeakRound()) return true;
36.549 + }
36.550 + return _process.empty();
36.551 + }
36.552 +
36.553 + /// \brief Executes the algorithm with arc number limit.
36.554 + ///
36.555 + /// Executes the algorithm with arc number limit.
36.556 + ///
36.557 + /// This method runs the Bellman-Ford algorithm from the root node(s)
36.558 + /// in order to compute the shortest path distance for each node
36.559 + /// using only the paths consisting of at most \c num arcs.
36.560 + ///
36.561 + /// The algorithm computes
36.562 + /// - the limited distance of each node from the root(s),
36.563 + /// - the predecessor arc for each node.
36.564 + ///
36.565 + /// \warning The paths with limited arc number cannot be retrieved
36.566 + /// easily with \ref path() or \ref predArc() functions. If you also
36.567 + /// need the shortest paths and not only the distances, you should
36.568 + /// store the \ref predMap() "predecessor map" after each iteration
36.569 + /// and build the path manually.
36.570 + ///
36.571 + /// \pre init() must be called and at least one root node should be
36.572 + /// added with addSource() before using this function.
36.573 + void limitedStart(int num) {
36.574 + for (int i = 0; i < num; ++i) {
36.575 + if (processNextRound()) break;
36.576 + }
36.577 + }
36.578 +
36.579 + /// \brief Runs the algorithm from the given root node.
36.580 + ///
36.581 + /// This method runs the Bellman-Ford algorithm from the given root
36.582 + /// node \c s in order to compute the shortest path to each node.
36.583 + ///
36.584 + /// The algorithm computes
36.585 + /// - the shortest path tree (forest),
36.586 + /// - the distance of each node from the root(s).
36.587 + ///
36.588 + /// \note bf.run(s) is just a shortcut of the following code.
36.589 + /// \code
36.590 + /// bf.init();
36.591 + /// bf.addSource(s);
36.592 + /// bf.start();
36.593 + /// \endcode
36.594 + void run(Node s) {
36.595 + init();
36.596 + addSource(s);
36.597 + start();
36.598 + }
36.599 +
36.600 + /// \brief Runs the algorithm from the given root node with arc
36.601 + /// number limit.
36.602 + ///
36.603 + /// This method runs the Bellman-Ford algorithm from the given root
36.604 + /// node \c s in order to compute the shortest path distance for each
36.605 + /// node using only the paths consisting of at most \c num arcs.
36.606 + ///
36.607 + /// The algorithm computes
36.608 + /// - the limited distance of each node from the root(s),
36.609 + /// - the predecessor arc for each node.
36.610 + ///
36.611 + /// \warning The paths with limited arc number cannot be retrieved
36.612 + /// easily with \ref path() or \ref predArc() functions. If you also
36.613 + /// need the shortest paths and not only the distances, you should
36.614 + /// store the \ref predMap() "predecessor map" after each iteration
36.615 + /// and build the path manually.
36.616 + ///
36.617 + /// \note bf.run(s, num) is just a shortcut of the following code.
36.618 + /// \code
36.619 + /// bf.init();
36.620 + /// bf.addSource(s);
36.621 + /// bf.limitedStart(num);
36.622 + /// \endcode
36.623 + void run(Node s, int num) {
36.624 + init();
36.625 + addSource(s);
36.626 + limitedStart(num);
36.627 + }
36.628 +
36.629 + ///@}
36.630 +
36.631 + /// \brief LEMON iterator for getting the active nodes.
36.632 + ///
36.633 + /// This class provides a common style LEMON iterator that traverses
36.634 + /// the active nodes of the Bellman-Ford algorithm after the last
36.635 + /// phase. These nodes should be checked in the next phase to
36.636 + /// find augmenting arcs outgoing from them.
36.637 + class ActiveIt {
36.638 + public:
36.639 +
36.640 + /// \brief Constructor.
36.641 + ///
36.642 + /// Constructor for getting the active nodes of the given BellmanFord
36.643 + /// instance.
36.644 + ActiveIt(const BellmanFord& algorithm) : _algorithm(&algorithm)
36.645 + {
36.646 + _index = _algorithm->_process.size() - 1;
36.647 + }
36.648 +
36.649 + /// \brief Invalid constructor.
36.650 + ///
36.651 + /// Invalid constructor.
36.652 + ActiveIt(Invalid) : _algorithm(0), _index(-1) {}
36.653 +
36.654 + /// \brief Conversion to \c Node.
36.655 + ///
36.656 + /// Conversion to \c Node.
36.657 + operator Node() const {
36.658 + return _index >= 0 ? _algorithm->_process[_index] : INVALID;
36.659 + }
36.660 +
36.661 + /// \brief Increment operator.
36.662 + ///
36.663 + /// Increment operator.
36.664 + ActiveIt& operator++() {
36.665 + --_index;
36.666 + return *this;
36.667 + }
36.668 +
36.669 + bool operator==(const ActiveIt& it) const {
36.670 + return static_cast<Node>(*this) == static_cast<Node>(it);
36.671 + }
36.672 + bool operator!=(const ActiveIt& it) const {
36.673 + return static_cast<Node>(*this) != static_cast<Node>(it);
36.674 + }
36.675 + bool operator<(const ActiveIt& it) const {
36.676 + return static_cast<Node>(*this) < static_cast<Node>(it);
36.677 + }
36.678 +
36.679 + private:
36.680 + const BellmanFord* _algorithm;
36.681 + int _index;
36.682 + };
36.683 +
36.684 + /// \name Query Functions
36.685 + /// The result of the Bellman-Ford algorithm can be obtained using these
36.686 + /// functions.\n
36.687 + /// Either \ref run() or \ref init() should be called before using them.
36.688 +
36.689 + ///@{
36.690 +
36.691 + /// \brief The shortest path to the given node.
36.692 + ///
36.693 + /// Gives back the shortest path to the given node from the root(s).
36.694 + ///
36.695 + /// \warning \c t should be reached from the root(s).
36.696 + ///
36.697 + /// \pre Either \ref run() or \ref init() must be called before
36.698 + /// using this function.
36.699 + Path path(Node t) const
36.700 + {
36.701 + return Path(*_gr, *_pred, t);
36.702 + }
36.703 +
36.704 + /// \brief The distance of the given node from the root(s).
36.705 + ///
36.706 + /// Returns the distance of the given node from the root(s).
36.707 + ///
36.708 + /// \warning If node \c v is not reached from the root(s), then
36.709 + /// the return value of this function is undefined.
36.710 + ///
36.711 + /// \pre Either \ref run() or \ref init() must be called before
36.712 + /// using this function.
36.713 + Value dist(Node v) const { return (*_dist)[v]; }
36.714 +
36.715 + /// \brief Returns the 'previous arc' of the shortest path tree for
36.716 + /// the given node.
36.717 + ///
36.718 + /// This function returns the 'previous arc' of the shortest path
36.719 + /// tree for node \c v, i.e. it returns the last arc of a
36.720 + /// shortest path from a root to \c v. It is \c INVALID if \c v
36.721 + /// is not reached from the root(s) or if \c v is a root.
36.722 + ///
36.723 + /// The shortest path tree used here is equal to the shortest path
36.724 + /// tree used in \ref predNode() and \predMap().
36.725 + ///
36.726 + /// \pre Either \ref run() or \ref init() must be called before
36.727 + /// using this function.
36.728 + Arc predArc(Node v) const { return (*_pred)[v]; }
36.729 +
36.730 + /// \brief Returns the 'previous node' of the shortest path tree for
36.731 + /// the given node.
36.732 + ///
36.733 + /// This function returns the 'previous node' of the shortest path
36.734 + /// tree for node \c v, i.e. it returns the last but one node of
36.735 + /// a shortest path from a root to \c v. It is \c INVALID if \c v
36.736 + /// is not reached from the root(s) or if \c v is a root.
36.737 + ///
36.738 + /// The shortest path tree used here is equal to the shortest path
36.739 + /// tree used in \ref predArc() and \predMap().
36.740 + ///
36.741 + /// \pre Either \ref run() or \ref init() must be called before
36.742 + /// using this function.
36.743 + Node predNode(Node v) const {
36.744 + return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]);
36.745 + }
36.746 +
36.747 + /// \brief Returns a const reference to the node map that stores the
36.748 + /// distances of the nodes.
36.749 + ///
36.750 + /// Returns a const reference to the node map that stores the distances
36.751 + /// of the nodes calculated by the algorithm.
36.752 + ///
36.753 + /// \pre Either \ref run() or \ref init() must be called before
36.754 + /// using this function.
36.755 + const DistMap &distMap() const { return *_dist;}
36.756 +
36.757 + /// \brief Returns a const reference to the node map that stores the
36.758 + /// predecessor arcs.
36.759 + ///
36.760 + /// Returns a const reference to the node map that stores the predecessor
36.761 + /// arcs, which form the shortest path tree (forest).
36.762 + ///
36.763 + /// \pre Either \ref run() or \ref init() must be called before
36.764 + /// using this function.
36.765 + const PredMap &predMap() const { return *_pred; }
36.766 +
36.767 + /// \brief Checks if a node is reached from the root(s).
36.768 + ///
36.769 + /// Returns \c true if \c v is reached from the root(s).
36.770 + ///
36.771 + /// \pre Either \ref run() or \ref init() must be called before
36.772 + /// using this function.
36.773 + bool reached(Node v) const {
36.774 + return (*_dist)[v] != OperationTraits::infinity();
36.775 + }
36.776 +
36.777 + /// \brief Gives back a negative cycle.
36.778 + ///
36.779 + /// This function gives back a directed cycle with negative total
36.780 + /// length if the algorithm has already found one.
36.781 + /// Otherwise it gives back an empty path.
36.782 + lemon::Path<Digraph> negativeCycle() const {
36.783 + typename Digraph::template NodeMap<int> state(*_gr, -1);
36.784 + lemon::Path<Digraph> cycle;
36.785 + for (int i = 0; i < int(_process.size()); ++i) {
36.786 + if (state[_process[i]] != -1) continue;
36.787 + for (Node v = _process[i]; (*_pred)[v] != INVALID;
36.788 + v = _gr->source((*_pred)[v])) {
36.789 + if (state[v] == i) {
36.790 + cycle.addFront((*_pred)[v]);
36.791 + for (Node u = _gr->source((*_pred)[v]); u != v;
36.792 + u = _gr->source((*_pred)[u])) {
36.793 + cycle.addFront((*_pred)[u]);
36.794 + }
36.795 + return cycle;
36.796 + }
36.797 + else if (state[v] >= 0) {
36.798 + break;
36.799 + }
36.800 + state[v] = i;
36.801 + }
36.802 + }
36.803 + return cycle;
36.804 + }
36.805 +
36.806 + ///@}
36.807 + };
36.808 +
36.809 + /// \brief Default traits class of bellmanFord() function.
36.810 + ///
36.811 + /// Default traits class of bellmanFord() function.
36.812 + /// \tparam GR The type of the digraph.
36.813 + /// \tparam LEN The type of the length map.
36.814 + template <typename GR, typename LEN>
36.815 + struct BellmanFordWizardDefaultTraits {
36.816 + /// The type of the digraph the algorithm runs on.
36.817 + typedef GR Digraph;
36.818 +
36.819 + /// \brief The type of the map that stores the arc lengths.
36.820 + ///
36.821 + /// The type of the map that stores the arc lengths.
36.822 + /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
36.823 + typedef LEN LengthMap;
36.824 +
36.825 + /// The type of the arc lengths.
36.826 + typedef typename LEN::Value Value;
36.827 +
36.828 + /// \brief Operation traits for Bellman-Ford algorithm.
36.829 + ///
36.830 + /// It defines the used operations and the infinity value for the
36.831 + /// given \c Value type.
36.832 + /// \see BellmanFordDefaultOperationTraits
36.833 + typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
36.834 +
36.835 + /// \brief The type of the map that stores the last
36.836 + /// arcs of the shortest paths.
36.837 + ///
36.838 + /// The type of the map that stores the last arcs of the shortest paths.
36.839 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
36.840 + typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
36.841 +
36.842 + /// \brief Instantiates a \c PredMap.
36.843 + ///
36.844 + /// This function instantiates a \ref PredMap.
36.845 + /// \param g is the digraph to which we would like to define the
36.846 + /// \ref PredMap.
36.847 + static PredMap *createPredMap(const GR &g) {
36.848 + return new PredMap(g);
36.849 + }
36.850 +
36.851 + /// \brief The type of the map that stores the distances of the nodes.
36.852 + ///
36.853 + /// The type of the map that stores the distances of the nodes.
36.854 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
36.855 + typedef typename GR::template NodeMap<Value> DistMap;
36.856 +
36.857 + /// \brief Instantiates a \c DistMap.
36.858 + ///
36.859 + /// This function instantiates a \ref DistMap.
36.860 + /// \param g is the digraph to which we would like to define the
36.861 + /// \ref DistMap.
36.862 + static DistMap *createDistMap(const GR &g) {
36.863 + return new DistMap(g);
36.864 + }
36.865 +
36.866 + ///The type of the shortest paths.
36.867 +
36.868 + ///The type of the shortest paths.
36.869 + ///It must meet the \ref concepts::Path "Path" concept.
36.870 + typedef lemon::Path<Digraph> Path;
36.871 + };
36.872 +
36.873 + /// \brief Default traits class used by BellmanFordWizard.
36.874 + ///
36.875 + /// Default traits class used by BellmanFordWizard.
36.876 + /// \tparam GR The type of the digraph.
36.877 + /// \tparam LEN The type of the length map.
36.878 + template <typename GR, typename LEN>
36.879 + class BellmanFordWizardBase
36.880 + : public BellmanFordWizardDefaultTraits<GR, LEN> {
36.881 +
36.882 + typedef BellmanFordWizardDefaultTraits<GR, LEN> Base;
36.883 + protected:
36.884 + // Type of the nodes in the digraph.
36.885 + typedef typename Base::Digraph::Node Node;
36.886 +
36.887 + // Pointer to the underlying digraph.
36.888 + void *_graph;
36.889 + // Pointer to the length map
36.890 + void *_length;
36.891 + // Pointer to the map of predecessors arcs.
36.892 + void *_pred;
36.893 + // Pointer to the map of distances.
36.894 + void *_dist;
36.895 + //Pointer to the shortest path to the target node.
36.896 + void *_path;
36.897 + //Pointer to the distance of the target node.
36.898 + void *_di;
36.899 +
36.900 + public:
36.901 + /// Constructor.
36.902 +
36.903 + /// This constructor does not require parameters, it initiates
36.904 + /// all of the attributes to default values \c 0.
36.905 + BellmanFordWizardBase() :
36.906 + _graph(0), _length(0), _pred(0), _dist(0), _path(0), _di(0) {}
36.907 +
36.908 + /// Constructor.
36.909 +
36.910 + /// This constructor requires two parameters,
36.911 + /// others are initiated to \c 0.
36.912 + /// \param gr The digraph the algorithm runs on.
36.913 + /// \param len The length map.
36.914 + BellmanFordWizardBase(const GR& gr,
36.915 + const LEN& len) :
36.916 + _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))),
36.917 + _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))),
36.918 + _pred(0), _dist(0), _path(0), _di(0) {}
36.919 +
36.920 + };
36.921 +
36.922 + /// \brief Auxiliary class for the function-type interface of the
36.923 + /// \ref BellmanFord "Bellman-Ford" algorithm.
36.924 + ///
36.925 + /// This auxiliary class is created to implement the
36.926 + /// \ref bellmanFord() "function-type interface" of the
36.927 + /// \ref BellmanFord "Bellman-Ford" algorithm.
36.928 + /// It does not have own \ref run() method, it uses the
36.929 + /// functions and features of the plain \ref BellmanFord.
36.930 + ///
36.931 + /// This class should only be used through the \ref bellmanFord()
36.932 + /// function, which makes it easier to use the algorithm.
36.933 + template<class TR>
36.934 + class BellmanFordWizard : public TR {
36.935 + typedef TR Base;
36.936 +
36.937 + typedef typename TR::Digraph Digraph;
36.938 +
36.939 + typedef typename Digraph::Node Node;
36.940 + typedef typename Digraph::NodeIt NodeIt;
36.941 + typedef typename Digraph::Arc Arc;
36.942 + typedef typename Digraph::OutArcIt ArcIt;
36.943 +
36.944 + typedef typename TR::LengthMap LengthMap;
36.945 + typedef typename LengthMap::Value Value;
36.946 + typedef typename TR::PredMap PredMap;
36.947 + typedef typename TR::DistMap DistMap;
36.948 + typedef typename TR::Path Path;
36.949 +
36.950 + public:
36.951 + /// Constructor.
36.952 + BellmanFordWizard() : TR() {}
36.953 +
36.954 + /// \brief Constructor that requires parameters.
36.955 + ///
36.956 + /// Constructor that requires parameters.
36.957 + /// These parameters will be the default values for the traits class.
36.958 + /// \param gr The digraph the algorithm runs on.
36.959 + /// \param len The length map.
36.960 + BellmanFordWizard(const Digraph& gr, const LengthMap& len)
36.961 + : TR(gr, len) {}
36.962 +
36.963 + /// \brief Copy constructor
36.964 + BellmanFordWizard(const TR &b) : TR(b) {}
36.965 +
36.966 + ~BellmanFordWizard() {}
36.967 +
36.968 + /// \brief Runs the Bellman-Ford algorithm from the given source node.
36.969 + ///
36.970 + /// This method runs the Bellman-Ford algorithm from the given source
36.971 + /// node in order to compute the shortest path to each node.
36.972 + void run(Node s) {
36.973 + BellmanFord<Digraph,LengthMap,TR>
36.974 + bf(*reinterpret_cast<const Digraph*>(Base::_graph),
36.975 + *reinterpret_cast<const LengthMap*>(Base::_length));
36.976 + if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
36.977 + if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
36.978 + bf.run(s);
36.979 + }
36.980 +
36.981 + /// \brief Runs the Bellman-Ford algorithm to find the shortest path
36.982 + /// between \c s and \c t.
36.983 + ///
36.984 + /// This method runs the Bellman-Ford algorithm from node \c s
36.985 + /// in order to compute the shortest path to node \c t.
36.986 + /// Actually, it computes the shortest path to each node, but using
36.987 + /// this function you can retrieve the distance and the shortest path
36.988 + /// for a single target node easier.
36.989 + ///
36.990 + /// \return \c true if \c t is reachable form \c s.
36.991 + bool run(Node s, Node t) {
36.992 + BellmanFord<Digraph,LengthMap,TR>
36.993 + bf(*reinterpret_cast<const Digraph*>(Base::_graph),
36.994 + *reinterpret_cast<const LengthMap*>(Base::_length));
36.995 + if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
36.996 + if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
36.997 + bf.run(s);
36.998 + if (Base::_path) *reinterpret_cast<Path*>(Base::_path) = bf.path(t);
36.999 + if (Base::_di) *reinterpret_cast<Value*>(Base::_di) = bf.dist(t);
36.1000 + return bf.reached(t);
36.1001 + }
36.1002 +
36.1003 + template<class T>
36.1004 + struct SetPredMapBase : public Base {
36.1005 + typedef T PredMap;
36.1006 + static PredMap *createPredMap(const Digraph &) { return 0; };
36.1007 + SetPredMapBase(const TR &b) : TR(b) {}
36.1008 + };
36.1009 +
36.1010 + /// \brief \ref named-templ-param "Named parameter" for setting
36.1011 + /// the predecessor map.
36.1012 + ///
36.1013 + /// \ref named-templ-param "Named parameter" for setting
36.1014 + /// the map that stores the predecessor arcs of the nodes.
36.1015 + template<class T>
36.1016 + BellmanFordWizard<SetPredMapBase<T> > predMap(const T &t) {
36.1017 + Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
36.1018 + return BellmanFordWizard<SetPredMapBase<T> >(*this);
36.1019 + }
36.1020 +
36.1021 + template<class T>
36.1022 + struct SetDistMapBase : public Base {
36.1023 + typedef T DistMap;
36.1024 + static DistMap *createDistMap(const Digraph &) { return 0; };
36.1025 + SetDistMapBase(const TR &b) : TR(b) {}
36.1026 + };
36.1027 +
36.1028 + /// \brief \ref named-templ-param "Named parameter" for setting
36.1029 + /// the distance map.
36.1030 + ///
36.1031 + /// \ref named-templ-param "Named parameter" for setting
36.1032 + /// the map that stores the distances of the nodes calculated
36.1033 + /// by the algorithm.
36.1034 + template<class T>
36.1035 + BellmanFordWizard<SetDistMapBase<T> > distMap(const T &t) {
36.1036 + Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
36.1037 + return BellmanFordWizard<SetDistMapBase<T> >(*this);
36.1038 + }
36.1039 +
36.1040 + template<class T>
36.1041 + struct SetPathBase : public Base {
36.1042 + typedef T Path;
36.1043 + SetPathBase(const TR &b) : TR(b) {}
36.1044 + };
36.1045 +
36.1046 + /// \brief \ref named-func-param "Named parameter" for getting
36.1047 + /// the shortest path to the target node.
36.1048 + ///
36.1049 + /// \ref named-func-param "Named parameter" for getting
36.1050 + /// the shortest path to the target node.
36.1051 + template<class T>
36.1052 + BellmanFordWizard<SetPathBase<T> > path(const T &t)
36.1053 + {
36.1054 + Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
36.1055 + return BellmanFordWizard<SetPathBase<T> >(*this);
36.1056 + }
36.1057 +
36.1058 + /// \brief \ref named-func-param "Named parameter" for getting
36.1059 + /// the distance of the target node.
36.1060 + ///
36.1061 + /// \ref named-func-param "Named parameter" for getting
36.1062 + /// the distance of the target node.
36.1063 + BellmanFordWizard dist(const Value &d)
36.1064 + {
36.1065 + Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
36.1066 + return *this;
36.1067 + }
36.1068 +
36.1069 + };
36.1070 +
36.1071 + /// \brief Function type interface for the \ref BellmanFord "Bellman-Ford"
36.1072 + /// algorithm.
36.1073 + ///
36.1074 + /// \ingroup shortest_path
36.1075 + /// Function type interface for the \ref BellmanFord "Bellman-Ford"
36.1076 + /// algorithm.
36.1077 + ///
36.1078 + /// This function also has several \ref named-templ-func-param
36.1079 + /// "named parameters", they are declared as the members of class
36.1080 + /// \ref BellmanFordWizard.
36.1081 + /// The following examples show how to use these parameters.
36.1082 + /// \code
36.1083 + /// // Compute shortest path from node s to each node
36.1084 + /// bellmanFord(g,length).predMap(preds).distMap(dists).run(s);
36.1085 + ///
36.1086 + /// // Compute shortest path from s to t
36.1087 + /// bool reached = bellmanFord(g,length).path(p).dist(d).run(s,t);
36.1088 + /// \endcode
36.1089 + /// \warning Don't forget to put the \ref BellmanFordWizard::run() "run()"
36.1090 + /// to the end of the parameter list.
36.1091 + /// \sa BellmanFordWizard
36.1092 + /// \sa BellmanFord
36.1093 + template<typename GR, typename LEN>
36.1094 + BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >
36.1095 + bellmanFord(const GR& digraph,
36.1096 + const LEN& length)
36.1097 + {
36.1098 + return BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >(digraph, length);
36.1099 + }
36.1100 +
36.1101 +} //END OF NAMESPACE LEMON
36.1102 +
36.1103 +#endif
36.1104 +
37.1 --- a/lemon/bfs.h Mon Jan 12 23:11:39 2009 +0100
37.2 +++ b/lemon/bfs.h Thu Nov 05 15:48:01 2009 +0100
37.3 @@ -47,13 +47,13 @@
37.4 ///
37.5 ///The type of the map that stores the predecessor
37.6 ///arcs of the shortest paths.
37.7 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
37.8 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
37.9 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
37.10 - ///Instantiates a PredMap.
37.11 + ///Instantiates a \c PredMap.
37.12
37.13 - ///This function instantiates a PredMap.
37.14 + ///This function instantiates a \ref PredMap.
37.15 ///\param g is the digraph, to which we would like to define the
37.16 - ///PredMap.
37.17 + ///\ref PredMap.
37.18 static PredMap *createPredMap(const Digraph &g)
37.19 {
37.20 return new PredMap(g);
37.21 @@ -62,13 +62,14 @@
37.22 ///The type of the map that indicates which nodes are processed.
37.23
37.24 ///The type of the map that indicates which nodes are processed.
37.25 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
37.26 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
37.27 + ///By default it is a NullMap.
37.28 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
37.29 - ///Instantiates a ProcessedMap.
37.30 + ///Instantiates a \c ProcessedMap.
37.31
37.32 - ///This function instantiates a ProcessedMap.
37.33 + ///This function instantiates a \ref ProcessedMap.
37.34 ///\param g is the digraph, to which
37.35 - ///we would like to define the ProcessedMap
37.36 + ///we would like to define the \ref ProcessedMap
37.37 #ifdef DOXYGEN
37.38 static ProcessedMap *createProcessedMap(const Digraph &g)
37.39 #else
37.40 @@ -81,13 +82,13 @@
37.41 ///The type of the map that indicates which nodes are reached.
37.42
37.43 ///The type of the map that indicates which nodes are reached.
37.44 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
37.45 + ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
37.46 typedef typename Digraph::template NodeMap<bool> ReachedMap;
37.47 - ///Instantiates a ReachedMap.
37.48 + ///Instantiates a \c ReachedMap.
37.49
37.50 - ///This function instantiates a ReachedMap.
37.51 + ///This function instantiates a \ref ReachedMap.
37.52 ///\param g is the digraph, to which
37.53 - ///we would like to define the ReachedMap.
37.54 + ///we would like to define the \ref ReachedMap.
37.55 static ReachedMap *createReachedMap(const Digraph &g)
37.56 {
37.57 return new ReachedMap(g);
37.58 @@ -96,13 +97,13 @@
37.59 ///The type of the map that stores the distances of the nodes.
37.60
37.61 ///The type of the map that stores the distances of the nodes.
37.62 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
37.63 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
37.64 typedef typename Digraph::template NodeMap<int> DistMap;
37.65 - ///Instantiates a DistMap.
37.66 + ///Instantiates a \c DistMap.
37.67
37.68 - ///This function instantiates a DistMap.
37.69 + ///This function instantiates a \ref DistMap.
37.70 ///\param g is the digraph, to which we would like to define the
37.71 - ///DistMap.
37.72 + ///\ref DistMap.
37.73 static DistMap *createDistMap(const Digraph &g)
37.74 {
37.75 return new DistMap(g);
37.76 @@ -221,11 +222,11 @@
37.77 }
37.78 };
37.79 ///\brief \ref named-templ-param "Named parameter" for setting
37.80 - ///PredMap type.
37.81 + ///\c PredMap type.
37.82 ///
37.83 ///\ref named-templ-param "Named parameter" for setting
37.84 - ///PredMap type.
37.85 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
37.86 + ///\c PredMap type.
37.87 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
37.88 template <class T>
37.89 struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
37.90 typedef Bfs< Digraph, SetPredMapTraits<T> > Create;
37.91 @@ -241,11 +242,11 @@
37.92 }
37.93 };
37.94 ///\brief \ref named-templ-param "Named parameter" for setting
37.95 - ///DistMap type.
37.96 + ///\c DistMap type.
37.97 ///
37.98 ///\ref named-templ-param "Named parameter" for setting
37.99 - ///DistMap type.
37.100 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
37.101 + ///\c DistMap type.
37.102 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
37.103 template <class T>
37.104 struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
37.105 typedef Bfs< Digraph, SetDistMapTraits<T> > Create;
37.106 @@ -261,11 +262,11 @@
37.107 }
37.108 };
37.109 ///\brief \ref named-templ-param "Named parameter" for setting
37.110 - ///ReachedMap type.
37.111 + ///\c ReachedMap type.
37.112 ///
37.113 ///\ref named-templ-param "Named parameter" for setting
37.114 - ///ReachedMap type.
37.115 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
37.116 + ///\c ReachedMap type.
37.117 + ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
37.118 template <class T>
37.119 struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
37.120 typedef Bfs< Digraph, SetReachedMapTraits<T> > Create;
37.121 @@ -281,11 +282,11 @@
37.122 }
37.123 };
37.124 ///\brief \ref named-templ-param "Named parameter" for setting
37.125 - ///ProcessedMap type.
37.126 + ///\c ProcessedMap type.
37.127 ///
37.128 ///\ref named-templ-param "Named parameter" for setting
37.129 - ///ProcessedMap type.
37.130 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
37.131 + ///\c ProcessedMap type.
37.132 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
37.133 template <class T>
37.134 struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
37.135 typedef Bfs< Digraph, SetProcessedMapTraits<T> > Create;
37.136 @@ -300,10 +301,10 @@
37.137 }
37.138 };
37.139 ///\brief \ref named-templ-param "Named parameter" for setting
37.140 - ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
37.141 + ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
37.142 ///
37.143 ///\ref named-templ-param "Named parameter" for setting
37.144 - ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
37.145 + ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
37.146 ///If you don't set it explicitly, it will be automatically allocated.
37.147 struct SetStandardProcessedMap :
37.148 public Bfs< Digraph, SetStandardProcessedMapTraits > {
37.149 @@ -413,8 +414,8 @@
37.150 ///\name Execution Control
37.151 ///The simplest way to execute the BFS algorithm is to use one of the
37.152 ///member functions called \ref run(Node) "run()".\n
37.153 - ///If you need more control on the execution, first you have to call
37.154 - ///\ref init(), then you can add several source nodes with
37.155 + ///If you need better control on the execution, you have to call
37.156 + ///\ref init() first, then you can add several source nodes with
37.157 ///\ref addSource(). Finally the actual path computation can be
37.158 ///performed with one of the \ref start() functions.
37.159
37.160 @@ -737,9 +738,9 @@
37.161
37.162 ///@{
37.163
37.164 - ///The shortest path to a node.
37.165 + ///The shortest path to the given node.
37.166
37.167 - ///Returns the shortest path to a node.
37.168 + ///Returns the shortest path to the given node from the root(s).
37.169 ///
37.170 ///\warning \c t should be reached from the root(s).
37.171 ///
37.172 @@ -747,9 +748,9 @@
37.173 ///must be called before using this function.
37.174 Path path(Node t) const { return Path(*G, *_pred, t); }
37.175
37.176 - ///The distance of a node from the root(s).
37.177 + ///The distance of the given node from the root(s).
37.178
37.179 - ///Returns the distance of a node from the root(s).
37.180 + ///Returns the distance of the given node from the root(s).
37.181 ///
37.182 ///\warning If node \c v is not reached from the root(s), then
37.183 ///the return value of this function is undefined.
37.184 @@ -758,29 +759,31 @@
37.185 ///must be called before using this function.
37.186 int dist(Node v) const { return (*_dist)[v]; }
37.187
37.188 - ///Returns the 'previous arc' of the shortest path tree for a node.
37.189 -
37.190 + ///\brief Returns the 'previous arc' of the shortest path tree for
37.191 + ///the given node.
37.192 + ///
37.193 ///This function returns the 'previous arc' of the shortest path
37.194 ///tree for the node \c v, i.e. it returns the last arc of a
37.195 ///shortest path from a root to \c v. It is \c INVALID if \c v
37.196 ///is not reached from the root(s) or if \c v is a root.
37.197 ///
37.198 ///The shortest path tree used here is equal to the shortest path
37.199 - ///tree used in \ref predNode().
37.200 + ///tree used in \ref predNode() and \ref predMap().
37.201 ///
37.202 ///\pre Either \ref run(Node) "run()" or \ref init()
37.203 ///must be called before using this function.
37.204 Arc predArc(Node v) const { return (*_pred)[v];}
37.205
37.206 - ///Returns the 'previous node' of the shortest path tree for a node.
37.207 -
37.208 + ///\brief Returns the 'previous node' of the shortest path tree for
37.209 + ///the given node.
37.210 + ///
37.211 ///This function returns the 'previous node' of the shortest path
37.212 ///tree for the node \c v, i.e. it returns the last but one node
37.213 - ///from a shortest path from a root to \c v. It is \c INVALID
37.214 + ///of a shortest path from a root to \c v. It is \c INVALID
37.215 ///if \c v is not reached from the root(s) or if \c v is a root.
37.216 ///
37.217 ///The shortest path tree used here is equal to the shortest path
37.218 - ///tree used in \ref predArc().
37.219 + ///tree used in \ref predArc() and \ref predMap().
37.220 ///
37.221 ///\pre Either \ref run(Node) "run()" or \ref init()
37.222 ///must be called before using this function.
37.223 @@ -801,13 +804,13 @@
37.224 ///predecessor arcs.
37.225 ///
37.226 ///Returns a const reference to the node map that stores the predecessor
37.227 - ///arcs, which form the shortest path tree.
37.228 + ///arcs, which form the shortest path tree (forest).
37.229 ///
37.230 ///\pre Either \ref run(Node) "run()" or \ref init()
37.231 ///must be called before using this function.
37.232 const PredMap &predMap() const { return *_pred;}
37.233
37.234 - ///Checks if a node is reached from the root(s).
37.235 + ///Checks if the given node is reached from the root(s).
37.236
37.237 ///Returns \c true if \c v is reached from the root(s).
37.238 ///
37.239 @@ -833,7 +836,7 @@
37.240 ///
37.241 ///The type of the map that stores the predecessor
37.242 ///arcs of the shortest paths.
37.243 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
37.244 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
37.245 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
37.246 ///Instantiates a PredMap.
37.247
37.248 @@ -848,7 +851,7 @@
37.249 ///The type of the map that indicates which nodes are processed.
37.250
37.251 ///The type of the map that indicates which nodes are processed.
37.252 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
37.253 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
37.254 ///By default it is a NullMap.
37.255 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
37.256 ///Instantiates a ProcessedMap.
37.257 @@ -868,7 +871,7 @@
37.258 ///The type of the map that indicates which nodes are reached.
37.259
37.260 ///The type of the map that indicates which nodes are reached.
37.261 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
37.262 + ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
37.263 typedef typename Digraph::template NodeMap<bool> ReachedMap;
37.264 ///Instantiates a ReachedMap.
37.265
37.266 @@ -883,7 +886,7 @@
37.267 ///The type of the map that stores the distances of the nodes.
37.268
37.269 ///The type of the map that stores the distances of the nodes.
37.270 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
37.271 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
37.272 typedef typename Digraph::template NodeMap<int> DistMap;
37.273 ///Instantiates a DistMap.
37.274
37.275 @@ -898,18 +901,14 @@
37.276 ///The type of the shortest paths.
37.277
37.278 ///The type of the shortest paths.
37.279 - ///It must meet the \ref concepts::Path "Path" concept.
37.280 + ///It must conform to the \ref concepts::Path "Path" concept.
37.281 typedef lemon::Path<Digraph> Path;
37.282 };
37.283
37.284 /// Default traits class used by BfsWizard
37.285
37.286 - /// To make it easier to use Bfs algorithm
37.287 - /// we have created a wizard class.
37.288 - /// This \ref BfsWizard class needs default traits,
37.289 - /// as well as the \ref Bfs class.
37.290 - /// The \ref BfsWizardBase is a class to be the default traits of the
37.291 - /// \ref BfsWizard class.
37.292 + /// Default traits class used by BfsWizard.
37.293 + /// \tparam GR The type of the digraph.
37.294 template<class GR>
37.295 class BfsWizardBase : public BfsWizardDefaultTraits<GR>
37.296 {
37.297 @@ -937,7 +936,7 @@
37.298 public:
37.299 /// Constructor.
37.300
37.301 - /// This constructor does not require parameters, therefore it initiates
37.302 + /// This constructor does not require parameters, it initiates
37.303 /// all of the attributes to \c 0.
37.304 BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
37.305 _dist(0), _path(0), _di(0) {}
37.306 @@ -967,7 +966,6 @@
37.307 {
37.308 typedef TR Base;
37.309
37.310 - ///The type of the digraph the algorithm runs on.
37.311 typedef typename TR::Digraph Digraph;
37.312
37.313 typedef typename Digraph::Node Node;
37.314 @@ -975,16 +973,10 @@
37.315 typedef typename Digraph::Arc Arc;
37.316 typedef typename Digraph::OutArcIt OutArcIt;
37.317
37.318 - ///\brief The type of the map that stores the predecessor
37.319 - ///arcs of the shortest paths.
37.320 typedef typename TR::PredMap PredMap;
37.321 - ///\brief The type of the map that stores the distances of the nodes.
37.322 typedef typename TR::DistMap DistMap;
37.323 - ///\brief The type of the map that indicates which nodes are reached.
37.324 typedef typename TR::ReachedMap ReachedMap;
37.325 - ///\brief The type of the map that indicates which nodes are processed.
37.326 typedef typename TR::ProcessedMap ProcessedMap;
37.327 - ///The type of the shortest paths
37.328 typedef typename TR::Path Path;
37.329
37.330 public:
37.331 @@ -1067,11 +1059,12 @@
37.332 static PredMap *createPredMap(const Digraph &) { return 0; };
37.333 SetPredMapBase(const TR &b) : TR(b) {}
37.334 };
37.335 - ///\brief \ref named-func-param "Named parameter"
37.336 - ///for setting PredMap object.
37.337 +
37.338 + ///\brief \ref named-templ-param "Named parameter" for setting
37.339 + ///the predecessor map.
37.340 ///
37.341 - ///\ref named-func-param "Named parameter"
37.342 - ///for setting PredMap object.
37.343 + ///\ref named-templ-param "Named parameter" function for setting
37.344 + ///the map that stores the predecessor arcs of the nodes.
37.345 template<class T>
37.346 BfsWizard<SetPredMapBase<T> > predMap(const T &t)
37.347 {
37.348 @@ -1085,11 +1078,12 @@
37.349 static ReachedMap *createReachedMap(const Digraph &) { return 0; };
37.350 SetReachedMapBase(const TR &b) : TR(b) {}
37.351 };
37.352 - ///\brief \ref named-func-param "Named parameter"
37.353 - ///for setting ReachedMap object.
37.354 +
37.355 + ///\brief \ref named-templ-param "Named parameter" for setting
37.356 + ///the reached map.
37.357 ///
37.358 - /// \ref named-func-param "Named parameter"
37.359 - ///for setting ReachedMap object.
37.360 + ///\ref named-templ-param "Named parameter" function for setting
37.361 + ///the map that indicates which nodes are reached.
37.362 template<class T>
37.363 BfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
37.364 {
37.365 @@ -1103,11 +1097,13 @@
37.366 static DistMap *createDistMap(const Digraph &) { return 0; };
37.367 SetDistMapBase(const TR &b) : TR(b) {}
37.368 };
37.369 - ///\brief \ref named-func-param "Named parameter"
37.370 - ///for setting DistMap object.
37.371 +
37.372 + ///\brief \ref named-templ-param "Named parameter" for setting
37.373 + ///the distance map.
37.374 ///
37.375 - /// \ref named-func-param "Named parameter"
37.376 - ///for setting DistMap object.
37.377 + ///\ref named-templ-param "Named parameter" function for setting
37.378 + ///the map that stores the distances of the nodes calculated
37.379 + ///by the algorithm.
37.380 template<class T>
37.381 BfsWizard<SetDistMapBase<T> > distMap(const T &t)
37.382 {
37.383 @@ -1121,11 +1117,12 @@
37.384 static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
37.385 SetProcessedMapBase(const TR &b) : TR(b) {}
37.386 };
37.387 - ///\brief \ref named-func-param "Named parameter"
37.388 - ///for setting ProcessedMap object.
37.389 +
37.390 + ///\brief \ref named-func-param "Named parameter" for setting
37.391 + ///the processed map.
37.392 ///
37.393 - /// \ref named-func-param "Named parameter"
37.394 - ///for setting ProcessedMap object.
37.395 + ///\ref named-templ-param "Named parameter" function for setting
37.396 + ///the map that indicates which nodes are processed.
37.397 template<class T>
37.398 BfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
37.399 {
37.400 @@ -1194,9 +1191,9 @@
37.401 ///
37.402 /// This class defines the interface of the BfsVisit events, and
37.403 /// it could be the base of a real visitor class.
37.404 - template <typename _Digraph>
37.405 + template <typename GR>
37.406 struct BfsVisitor {
37.407 - typedef _Digraph Digraph;
37.408 + typedef GR Digraph;
37.409 typedef typename Digraph::Arc Arc;
37.410 typedef typename Digraph::Node Node;
37.411 /// \brief Called for the source node(s) of the BFS.
37.412 @@ -1224,9 +1221,9 @@
37.413 void examine(const Arc& arc) {}
37.414 };
37.415 #else
37.416 - template <typename _Digraph>
37.417 + template <typename GR>
37.418 struct BfsVisitor {
37.419 - typedef _Digraph Digraph;
37.420 + typedef GR Digraph;
37.421 typedef typename Digraph::Arc Arc;
37.422 typedef typename Digraph::Node Node;
37.423 void start(const Node&) {}
37.424 @@ -1254,17 +1251,17 @@
37.425 /// \brief Default traits class of BfsVisit class.
37.426 ///
37.427 /// Default traits class of BfsVisit class.
37.428 - /// \tparam _Digraph The type of the digraph the algorithm runs on.
37.429 - template<class _Digraph>
37.430 + /// \tparam GR The type of the digraph the algorithm runs on.
37.431 + template<class GR>
37.432 struct BfsVisitDefaultTraits {
37.433
37.434 /// \brief The type of the digraph the algorithm runs on.
37.435 - typedef _Digraph Digraph;
37.436 + typedef GR Digraph;
37.437
37.438 /// \brief The type of the map that indicates which nodes are reached.
37.439 ///
37.440 /// The type of the map that indicates which nodes are reached.
37.441 - /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
37.442 + /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
37.443 typedef typename Digraph::template NodeMap<bool> ReachedMap;
37.444
37.445 /// \brief Instantiates a ReachedMap.
37.446 @@ -1280,12 +1277,12 @@
37.447
37.448 /// \ingroup search
37.449 ///
37.450 - /// \brief %BFS algorithm class with visitor interface.
37.451 + /// \brief BFS algorithm class with visitor interface.
37.452 ///
37.453 - /// This class provides an efficient implementation of the %BFS algorithm
37.454 + /// This class provides an efficient implementation of the BFS algorithm
37.455 /// with visitor interface.
37.456 ///
37.457 - /// The %BfsVisit class provides an alternative interface to the Bfs
37.458 + /// The BfsVisit class provides an alternative interface to the Bfs
37.459 /// class. It works with callback mechanism, the BfsVisit object calls
37.460 /// the member functions of the \c Visitor class on every BFS event.
37.461 ///
37.462 @@ -1294,37 +1291,37 @@
37.463 /// events of the BFS algorithm. Otherwise consider to use Bfs or bfs()
37.464 /// instead.
37.465 ///
37.466 - /// \tparam _Digraph The type of the digraph the algorithm runs on.
37.467 - /// The default value is
37.468 - /// \ref ListDigraph. The value of _Digraph is not used directly by
37.469 - /// \ref BfsVisit, it is only passed to \ref BfsVisitDefaultTraits.
37.470 - /// \tparam _Visitor The Visitor type that is used by the algorithm.
37.471 - /// \ref BfsVisitor "BfsVisitor<_Digraph>" is an empty visitor, which
37.472 + /// \tparam GR The type of the digraph the algorithm runs on.
37.473 + /// The default type is \ref ListDigraph.
37.474 + /// The value of GR is not used directly by \ref BfsVisit,
37.475 + /// it is only passed to \ref BfsVisitDefaultTraits.
37.476 + /// \tparam VS The Visitor type that is used by the algorithm.
37.477 + /// \ref BfsVisitor "BfsVisitor<GR>" is an empty visitor, which
37.478 /// does not observe the BFS events. If you want to observe the BFS
37.479 /// events, you should implement your own visitor class.
37.480 - /// \tparam _Traits Traits class to set various data types used by the
37.481 + /// \tparam TR Traits class to set various data types used by the
37.482 /// algorithm. The default traits class is
37.483 - /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<_Digraph>".
37.484 + /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<GR>".
37.485 /// See \ref BfsVisitDefaultTraits for the documentation of
37.486 /// a BFS visit traits class.
37.487 #ifdef DOXYGEN
37.488 - template <typename _Digraph, typename _Visitor, typename _Traits>
37.489 + template <typename GR, typename VS, typename TR>
37.490 #else
37.491 - template <typename _Digraph = ListDigraph,
37.492 - typename _Visitor = BfsVisitor<_Digraph>,
37.493 - typename _Traits = BfsVisitDefaultTraits<_Digraph> >
37.494 + template <typename GR = ListDigraph,
37.495 + typename VS = BfsVisitor<GR>,
37.496 + typename TR = BfsVisitDefaultTraits<GR> >
37.497 #endif
37.498 class BfsVisit {
37.499 public:
37.500
37.501 ///The traits class.
37.502 - typedef _Traits Traits;
37.503 + typedef TR Traits;
37.504
37.505 ///The type of the digraph the algorithm runs on.
37.506 typedef typename Traits::Digraph Digraph;
37.507
37.508 ///The visitor type used by the algorithm.
37.509 - typedef _Visitor Visitor;
37.510 + typedef VS Visitor;
37.511
37.512 ///The type of the map that indicates which nodes are reached.
37.513 typedef typename Traits::ReachedMap ReachedMap;
37.514 @@ -1425,8 +1422,8 @@
37.515 /// \name Execution Control
37.516 /// The simplest way to execute the BFS algorithm is to use one of the
37.517 /// member functions called \ref run(Node) "run()".\n
37.518 - /// If you need more control on the execution, first you have to call
37.519 - /// \ref init(), then you can add several source nodes with
37.520 + /// If you need better control on the execution, you have to call
37.521 + /// \ref init() first, then you can add several source nodes with
37.522 /// \ref addSource(). Finally the actual path computation can be
37.523 /// performed with one of the \ref start() functions.
37.524
37.525 @@ -1735,7 +1732,7 @@
37.526
37.527 ///@{
37.528
37.529 - /// \brief Checks if a node is reached from the root(s).
37.530 + /// \brief Checks if the given node is reached from the root(s).
37.531 ///
37.532 /// Returns \c true if \c v is reached from the root(s).
37.533 ///
38.1 --- a/lemon/bin_heap.h Mon Jan 12 23:11:39 2009 +0100
38.2 +++ b/lemon/bin_heap.h Thu Nov 05 15:48:01 2009 +0100
38.3 @@ -19,9 +19,9 @@
38.4 #ifndef LEMON_BIN_HEAP_H
38.5 #define LEMON_BIN_HEAP_H
38.6
38.7 -///\ingroup auxdat
38.8 +///\ingroup heaps
38.9 ///\file
38.10 -///\brief Binary Heap implementation.
38.11 +///\brief Binary heap implementation.
38.12
38.13 #include <vector>
38.14 #include <utility>
38.15 @@ -29,112 +29,110 @@
38.16
38.17 namespace lemon {
38.18
38.19 - ///\ingroup auxdat
38.20 + /// \ingroup heaps
38.21 ///
38.22 - ///\brief A Binary Heap implementation.
38.23 + /// \brief Binary heap data structure.
38.24 ///
38.25 - ///This class implements the \e binary \e heap data structure. A \e heap
38.26 - ///is a data structure for storing items with specified values called \e
38.27 - ///priorities in such a way that finding the item with minimum priority is
38.28 - ///efficient. \c Compare specifies the ordering of the priorities. In a heap
38.29 - ///one can change the priority of an item, add or erase an item, etc.
38.30 + /// This class implements the \e binary \e heap data structure.
38.31 + /// It fully conforms to the \ref concepts::Heap "heap concept".
38.32 ///
38.33 - ///\tparam _Prio Type of the priority of the items.
38.34 - ///\tparam _ItemIntMap A read and writable Item int map, used internally
38.35 - ///to handle the cross references.
38.36 - ///\tparam _Compare A class for the ordering of the priorities. The
38.37 - ///default is \c std::less<_Prio>.
38.38 - ///
38.39 - ///\sa FibHeap
38.40 - ///\sa Dijkstra
38.41 - template <typename _Prio, typename _ItemIntMap,
38.42 - typename _Compare = std::less<_Prio> >
38.43 + /// \tparam PR Type of the priorities of the items.
38.44 + /// \tparam IM A read-writable item map with \c int values, used
38.45 + /// internally to handle the cross references.
38.46 + /// \tparam CMP A functor class for comparing the priorities.
38.47 + /// The default is \c std::less<PR>.
38.48 +#ifdef DOXYGEN
38.49 + template <typename PR, typename IM, typename CMP>
38.50 +#else
38.51 + template <typename PR, typename IM, typename CMP = std::less<PR> >
38.52 +#endif
38.53 class BinHeap {
38.54 + public:
38.55
38.56 - public:
38.57 - ///\e
38.58 - typedef _ItemIntMap ItemIntMap;
38.59 - ///\e
38.60 - typedef _Prio Prio;
38.61 - ///\e
38.62 + /// Type of the item-int map.
38.63 + typedef IM ItemIntMap;
38.64 + /// Type of the priorities.
38.65 + typedef PR Prio;
38.66 + /// Type of the items stored in the heap.
38.67 typedef typename ItemIntMap::Key Item;
38.68 - ///\e
38.69 + /// Type of the item-priority pairs.
38.70 typedef std::pair<Item,Prio> Pair;
38.71 - ///\e
38.72 - typedef _Compare Compare;
38.73 + /// Functor type for comparing the priorities.
38.74 + typedef CMP Compare;
38.75
38.76 - /// \brief Type to represent the items states.
38.77 + /// \brief Type to represent the states of the items.
38.78 ///
38.79 - /// Each Item element have a state associated to it. It may be "in heap",
38.80 - /// "pre heap" or "post heap". The latter two are indifferent from the
38.81 + /// Each item has a state associated to it. It can be "in heap",
38.82 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
38.83 /// heap's point of view, but may be useful to the user.
38.84 ///
38.85 - /// The ItemIntMap \e should be initialized in such way that it maps
38.86 - /// PRE_HEAP (-1) to any element to be put in the heap...
38.87 + /// The item-int map must be initialized in such way that it assigns
38.88 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
38.89 enum State {
38.90 - IN_HEAP = 0,
38.91 - PRE_HEAP = -1,
38.92 - POST_HEAP = -2
38.93 + IN_HEAP = 0, ///< = 0.
38.94 + PRE_HEAP = -1, ///< = -1.
38.95 + POST_HEAP = -2 ///< = -2.
38.96 };
38.97
38.98 private:
38.99 - std::vector<Pair> data;
38.100 - Compare comp;
38.101 - ItemIntMap &iim;
38.102 + std::vector<Pair> _data;
38.103 + Compare _comp;
38.104 + ItemIntMap &_iim;
38.105
38.106 public:
38.107 - /// \brief The constructor.
38.108 +
38.109 + /// \brief Constructor.
38.110 ///
38.111 - /// The constructor.
38.112 - /// \param _iim should be given to the constructor, since it is used
38.113 - /// internally to handle the cross references. The value of the map
38.114 - /// should be PRE_HEAP (-1) for each element.
38.115 - explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {}
38.116 + /// Constructor.
38.117 + /// \param map A map that assigns \c int values to the items.
38.118 + /// It is used internally to handle the cross references.
38.119 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
38.120 + explicit BinHeap(ItemIntMap &map) : _iim(map) {}
38.121
38.122 - /// \brief The constructor.
38.123 + /// \brief Constructor.
38.124 ///
38.125 - /// The constructor.
38.126 - /// \param _iim should be given to the constructor, since it is used
38.127 - /// internally to handle the cross references. The value of the map
38.128 - /// should be PRE_HEAP (-1) for each element.
38.129 + /// Constructor.
38.130 + /// \param map A map that assigns \c int values to the items.
38.131 + /// It is used internally to handle the cross references.
38.132 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
38.133 + /// \param comp The function object used for comparing the priorities.
38.134 + BinHeap(ItemIntMap &map, const Compare &comp)
38.135 + : _iim(map), _comp(comp) {}
38.136 +
38.137 +
38.138 + /// \brief The number of items stored in the heap.
38.139 ///
38.140 - /// \param _comp The comparator function object.
38.141 - BinHeap(ItemIntMap &_iim, const Compare &_comp)
38.142 - : iim(_iim), comp(_comp) {}
38.143 + /// This function returns the number of items stored in the heap.
38.144 + int size() const { return _data.size(); }
38.145
38.146 + /// \brief Check if the heap is empty.
38.147 + ///
38.148 + /// This function returns \c true if the heap is empty.
38.149 + bool empty() const { return _data.empty(); }
38.150
38.151 - /// The number of items stored in the heap.
38.152 + /// \brief Make the heap empty.
38.153 ///
38.154 - /// \brief Returns the number of items stored in the heap.
38.155 - int size() const { return data.size(); }
38.156 -
38.157 - /// \brief Checks if the heap stores no items.
38.158 - ///
38.159 - /// Returns \c true if and only if the heap stores no items.
38.160 - bool empty() const { return data.empty(); }
38.161 -
38.162 - /// \brief Make empty this heap.
38.163 - ///
38.164 - /// Make empty this heap. It does not change the cross reference map.
38.165 - /// If you want to reuse what is not surely empty you should first clear
38.166 - /// the heap and after that you should set the cross reference map for
38.167 - /// each item to \c PRE_HEAP.
38.168 + /// This functon makes the heap empty.
38.169 + /// It does not change the cross reference map. If you want to reuse
38.170 + /// a heap that is not surely empty, you should first clear it and
38.171 + /// then you should set the cross reference map to \c PRE_HEAP
38.172 + /// for each item.
38.173 void clear() {
38.174 - data.clear();
38.175 + _data.clear();
38.176 }
38.177
38.178 private:
38.179 static int parent(int i) { return (i-1)/2; }
38.180
38.181 - static int second_child(int i) { return 2*i+2; }
38.182 + static int secondChild(int i) { return 2*i+2; }
38.183 bool less(const Pair &p1, const Pair &p2) const {
38.184 - return comp(p1.second, p2.second);
38.185 + return _comp(p1.second, p2.second);
38.186 }
38.187
38.188 - int bubble_up(int hole, Pair p) {
38.189 + int bubbleUp(int hole, Pair p) {
38.190 int par = parent(hole);
38.191 - while( hole>0 && less(p,data[par]) ) {
38.192 - move(data[par],hole);
38.193 + while( hole>0 && less(p,_data[par]) ) {
38.194 + move(_data[par],hole);
38.195 hole = par;
38.196 par = parent(hole);
38.197 }
38.198 @@ -142,21 +140,21 @@
38.199 return hole;
38.200 }
38.201
38.202 - int bubble_down(int hole, Pair p, int length) {
38.203 - int child = second_child(hole);
38.204 + int bubbleDown(int hole, Pair p, int length) {
38.205 + int child = secondChild(hole);
38.206 while(child < length) {
38.207 - if( less(data[child-1], data[child]) ) {
38.208 + if( less(_data[child-1], _data[child]) ) {
38.209 --child;
38.210 }
38.211 - if( !less(data[child], p) )
38.212 + if( !less(_data[child], p) )
38.213 goto ok;
38.214 - move(data[child], hole);
38.215 + move(_data[child], hole);
38.216 hole = child;
38.217 - child = second_child(hole);
38.218 + child = secondChild(hole);
38.219 }
38.220 child--;
38.221 - if( child<length && less(data[child], p) ) {
38.222 - move(data[child], hole);
38.223 + if( child<length && less(_data[child], p) ) {
38.224 + move(_data[child], hole);
38.225 hole=child;
38.226 }
38.227 ok:
38.228 @@ -165,151 +163,153 @@
38.229 }
38.230
38.231 void move(const Pair &p, int i) {
38.232 - data[i] = p;
38.233 - iim.set(p.first, i);
38.234 + _data[i] = p;
38.235 + _iim.set(p.first, i);
38.236 }
38.237
38.238 public:
38.239 +
38.240 /// \brief Insert a pair of item and priority into the heap.
38.241 ///
38.242 - /// Adds \c p.first to the heap with priority \c p.second.
38.243 + /// This function inserts \c p.first to the heap with priority
38.244 + /// \c p.second.
38.245 /// \param p The pair to insert.
38.246 + /// \pre \c p.first must not be stored in the heap.
38.247 void push(const Pair &p) {
38.248 - int n = data.size();
38.249 - data.resize(n+1);
38.250 - bubble_up(n, p);
38.251 + int n = _data.size();
38.252 + _data.resize(n+1);
38.253 + bubbleUp(n, p);
38.254 }
38.255
38.256 - /// \brief Insert an item into the heap with the given heap.
38.257 + /// \brief Insert an item into the heap with the given priority.
38.258 ///
38.259 - /// Adds \c i to the heap with priority \c p.
38.260 + /// This function inserts the given item into the heap with the
38.261 + /// given priority.
38.262 /// \param i The item to insert.
38.263 /// \param p The priority of the item.
38.264 + /// \pre \e i must not be stored in the heap.
38.265 void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
38.266
38.267 - /// \brief Returns the item with minimum priority relative to \c Compare.
38.268 + /// \brief Return the item having minimum priority.
38.269 ///
38.270 - /// This method returns the item with minimum priority relative to \c
38.271 - /// Compare.
38.272 - /// \pre The heap must be nonempty.
38.273 + /// This function returns the item having minimum priority.
38.274 + /// \pre The heap must be non-empty.
38.275 Item top() const {
38.276 - return data[0].first;
38.277 + return _data[0].first;
38.278 }
38.279
38.280 - /// \brief Returns the minimum priority relative to \c Compare.
38.281 + /// \brief The minimum priority.
38.282 ///
38.283 - /// It returns the minimum priority relative to \c Compare.
38.284 - /// \pre The heap must be nonempty.
38.285 + /// This function returns the minimum priority.
38.286 + /// \pre The heap must be non-empty.
38.287 Prio prio() const {
38.288 - return data[0].second;
38.289 + return _data[0].second;
38.290 }
38.291
38.292 - /// \brief Deletes the item with minimum priority relative to \c Compare.
38.293 + /// \brief Remove the item having minimum priority.
38.294 ///
38.295 - /// This method deletes the item with minimum priority relative to \c
38.296 - /// Compare from the heap.
38.297 + /// This function removes the item having minimum priority.
38.298 /// \pre The heap must be non-empty.
38.299 void pop() {
38.300 - int n = data.size()-1;
38.301 - iim.set(data[0].first, POST_HEAP);
38.302 + int n = _data.size()-1;
38.303 + _iim.set(_data[0].first, POST_HEAP);
38.304 if (n > 0) {
38.305 - bubble_down(0, data[n], n);
38.306 + bubbleDown(0, _data[n], n);
38.307 }
38.308 - data.pop_back();
38.309 + _data.pop_back();
38.310 }
38.311
38.312 - /// \brief Deletes \c i from the heap.
38.313 + /// \brief Remove the given item from the heap.
38.314 ///
38.315 - /// This method deletes item \c i from the heap.
38.316 - /// \param i The item to erase.
38.317 - /// \pre The item should be in the heap.
38.318 + /// This function removes the given item from the heap if it is
38.319 + /// already stored.
38.320 + /// \param i The item to delete.
38.321 + /// \pre \e i must be in the heap.
38.322 void erase(const Item &i) {
38.323 - int h = iim[i];
38.324 - int n = data.size()-1;
38.325 - iim.set(data[h].first, POST_HEAP);
38.326 + int h = _iim[i];
38.327 + int n = _data.size()-1;
38.328 + _iim.set(_data[h].first, POST_HEAP);
38.329 if( h < n ) {
38.330 - if ( bubble_up(h, data[n]) == h) {
38.331 - bubble_down(h, data[n], n);
38.332 + if ( bubbleUp(h, _data[n]) == h) {
38.333 + bubbleDown(h, _data[n], n);
38.334 }
38.335 }
38.336 - data.pop_back();
38.337 + _data.pop_back();
38.338 }
38.339
38.340 -
38.341 - /// \brief Returns the priority of \c i.
38.342 + /// \brief The priority of the given item.
38.343 ///
38.344 - /// This function returns the priority of item \c i.
38.345 - /// \pre \c i must be in the heap.
38.346 + /// This function returns the priority of the given item.
38.347 /// \param i The item.
38.348 + /// \pre \e i must be in the heap.
38.349 Prio operator[](const Item &i) const {
38.350 - int idx = iim[i];
38.351 - return data[idx].second;
38.352 + int idx = _iim[i];
38.353 + return _data[idx].second;
38.354 }
38.355
38.356 - /// \brief \c i gets to the heap with priority \c p independently
38.357 - /// if \c i was already there.
38.358 + /// \brief Set the priority of an item or insert it, if it is
38.359 + /// not stored in the heap.
38.360 ///
38.361 - /// This method calls \ref push(\c i, \c p) if \c i is not stored
38.362 - /// in the heap and sets the priority of \c i to \c p otherwise.
38.363 + /// This method sets the priority of the given item if it is
38.364 + /// already stored in the heap. Otherwise it inserts the given
38.365 + /// item into the heap with the given priority.
38.366 /// \param i The item.
38.367 /// \param p The priority.
38.368 void set(const Item &i, const Prio &p) {
38.369 - int idx = iim[i];
38.370 + int idx = _iim[i];
38.371 if( idx < 0 ) {
38.372 push(i,p);
38.373 }
38.374 - else if( comp(p, data[idx].second) ) {
38.375 - bubble_up(idx, Pair(i,p));
38.376 + else if( _comp(p, _data[idx].second) ) {
38.377 + bubbleUp(idx, Pair(i,p));
38.378 }
38.379 else {
38.380 - bubble_down(idx, Pair(i,p), data.size());
38.381 + bubbleDown(idx, Pair(i,p), _data.size());
38.382 }
38.383 }
38.384
38.385 - /// \brief Decreases the priority of \c i to \c p.
38.386 + /// \brief Decrease the priority of an item to the given value.
38.387 ///
38.388 - /// This method decreases the priority of item \c i to \c p.
38.389 - /// \pre \c i must be stored in the heap with priority at least \c
38.390 - /// p relative to \c Compare.
38.391 + /// This function decreases the priority of an item to the given value.
38.392 /// \param i The item.
38.393 /// \param p The priority.
38.394 + /// \pre \e i must be stored in the heap with priority at least \e p.
38.395 void decrease(const Item &i, const Prio &p) {
38.396 - int idx = iim[i];
38.397 - bubble_up(idx, Pair(i,p));
38.398 + int idx = _iim[i];
38.399 + bubbleUp(idx, Pair(i,p));
38.400 }
38.401
38.402 - /// \brief Increases the priority of \c i to \c p.
38.403 + /// \brief Increase the priority of an item to the given value.
38.404 ///
38.405 - /// This method sets the priority of item \c i to \c p.
38.406 - /// \pre \c i must be stored in the heap with priority at most \c
38.407 - /// p relative to \c Compare.
38.408 + /// This function increases the priority of an item to the given value.
38.409 /// \param i The item.
38.410 /// \param p The priority.
38.411 + /// \pre \e i must be stored in the heap with priority at most \e p.
38.412 void increase(const Item &i, const Prio &p) {
38.413 - int idx = iim[i];
38.414 - bubble_down(idx, Pair(i,p), data.size());
38.415 + int idx = _iim[i];
38.416 + bubbleDown(idx, Pair(i,p), _data.size());
38.417 }
38.418
38.419 - /// \brief Returns if \c item is in, has already been in, or has
38.420 - /// never been in the heap.
38.421 + /// \brief Return the state of an item.
38.422 ///
38.423 - /// This method returns PRE_HEAP if \c item has never been in the
38.424 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
38.425 - /// otherwise. In the latter case it is possible that \c item will
38.426 - /// get back to the heap again.
38.427 + /// This method returns \c PRE_HEAP if the given item has never
38.428 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
38.429 + /// and \c POST_HEAP otherwise.
38.430 + /// In the latter case it is possible that the item will get back
38.431 + /// to the heap again.
38.432 /// \param i The item.
38.433 State state(const Item &i) const {
38.434 - int s = iim[i];
38.435 + int s = _iim[i];
38.436 if( s>=0 )
38.437 s=0;
38.438 return State(s);
38.439 }
38.440
38.441 - /// \brief Sets the state of the \c item in the heap.
38.442 + /// \brief Set the state of an item in the heap.
38.443 ///
38.444 - /// Sets the state of the \c item in the heap. It can be used to
38.445 - /// manually clear the heap when it is important to achive the
38.446 - /// better time complexity.
38.447 + /// This function sets the state of the given item in the heap.
38.448 + /// It can be used to manually clear the heap when it is important
38.449 + /// to achive better time complexity.
38.450 /// \param i The item.
38.451 /// \param st The state. It should not be \c IN_HEAP.
38.452 void state(const Item& i, State st) {
38.453 @@ -319,24 +319,25 @@
38.454 if (state(i) == IN_HEAP) {
38.455 erase(i);
38.456 }
38.457 - iim[i] = st;
38.458 + _iim[i] = st;
38.459 break;
38.460 case IN_HEAP:
38.461 break;
38.462 }
38.463 }
38.464
38.465 - /// \brief Replaces an item in the heap.
38.466 + /// \brief Replace an item in the heap.
38.467 ///
38.468 - /// The \c i item is replaced with \c j item. The \c i item should
38.469 - /// be in the heap, while the \c j should be out of the heap. The
38.470 - /// \c i item will out of the heap and \c j will be in the heap
38.471 - /// with the same prioriority as prevoiusly the \c i item.
38.472 + /// This function replaces item \c i with item \c j.
38.473 + /// Item \c i must be in the heap, while \c j must be out of the heap.
38.474 + /// After calling this method, item \c i will be out of the
38.475 + /// heap and \c j will be in the heap with the same prioriority
38.476 + /// as item \c i had before.
38.477 void replace(const Item& i, const Item& j) {
38.478 - int idx = iim[i];
38.479 - iim.set(i, iim[j]);
38.480 - iim.set(j, idx);
38.481 - data[idx].first = j;
38.482 + int idx = _iim[i];
38.483 + _iim.set(i, _iim[j]);
38.484 + _iim.set(j, idx);
38.485 + _data[idx].first = j;
38.486 }
38.487
38.488 }; // class BinHeap
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/lemon/binom_heap.h Thu Nov 05 15:48:01 2009 +0100
39.3 @@ -0,0 +1,445 @@
39.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
39.5 + *
39.6 + * This file is a part of LEMON, a generic C++ optimization library.
39.7 + *
39.8 + * Copyright (C) 2003-2009
39.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
39.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
39.11 + *
39.12 + * Permission to use, modify and distribute this software is granted
39.13 + * provided that this copyright notice appears in all copies. For
39.14 + * precise terms see the accompanying LICENSE file.
39.15 + *
39.16 + * This software is provided "AS IS" with no warranty of any kind,
39.17 + * express or implied, and with no claim as to its suitability for any
39.18 + * purpose.
39.19 + *
39.20 + */
39.21 +
39.22 +#ifndef LEMON_BINOM_HEAP_H
39.23 +#define LEMON_BINOM_HEAP_H
39.24 +
39.25 +///\file
39.26 +///\ingroup heaps
39.27 +///\brief Binomial Heap implementation.
39.28 +
39.29 +#include <vector>
39.30 +#include <utility>
39.31 +#include <functional>
39.32 +#include <lemon/math.h>
39.33 +#include <lemon/counter.h>
39.34 +
39.35 +namespace lemon {
39.36 +
39.37 + /// \ingroup heaps
39.38 + ///
39.39 + ///\brief Binomial heap data structure.
39.40 + ///
39.41 + /// This class implements the \e binomial \e heap data structure.
39.42 + /// It fully conforms to the \ref concepts::Heap "heap concept".
39.43 + ///
39.44 + /// The methods \ref increase() and \ref erase() are not efficient
39.45 + /// in a binomial heap. In case of many calls of these operations,
39.46 + /// it is better to use other heap structure, e.g. \ref BinHeap
39.47 + /// "binary heap".
39.48 + ///
39.49 + /// \tparam PR Type of the priorities of the items.
39.50 + /// \tparam IM A read-writable item map with \c int values, used
39.51 + /// internally to handle the cross references.
39.52 + /// \tparam CMP A functor class for comparing the priorities.
39.53 + /// The default is \c std::less<PR>.
39.54 +#ifdef DOXYGEN
39.55 + template <typename PR, typename IM, typename CMP>
39.56 +#else
39.57 + template <typename PR, typename IM, typename CMP = std::less<PR> >
39.58 +#endif
39.59 + class BinomHeap {
39.60 + public:
39.61 + /// Type of the item-int map.
39.62 + typedef IM ItemIntMap;
39.63 + /// Type of the priorities.
39.64 + typedef PR Prio;
39.65 + /// Type of the items stored in the heap.
39.66 + typedef typename ItemIntMap::Key Item;
39.67 + /// Functor type for comparing the priorities.
39.68 + typedef CMP Compare;
39.69 +
39.70 + /// \brief Type to represent the states of the items.
39.71 + ///
39.72 + /// Each item has a state associated to it. It can be "in heap",
39.73 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
39.74 + /// heap's point of view, but may be useful to the user.
39.75 + ///
39.76 + /// The item-int map must be initialized in such way that it assigns
39.77 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
39.78 + enum State {
39.79 + IN_HEAP = 0, ///< = 0.
39.80 + PRE_HEAP = -1, ///< = -1.
39.81 + POST_HEAP = -2 ///< = -2.
39.82 + };
39.83 +
39.84 + private:
39.85 + class Store;
39.86 +
39.87 + std::vector<Store> _data;
39.88 + int _min, _head;
39.89 + ItemIntMap &_iim;
39.90 + Compare _comp;
39.91 + int _num_items;
39.92 +
39.93 + public:
39.94 + /// \brief Constructor.
39.95 + ///
39.96 + /// Constructor.
39.97 + /// \param map A map that assigns \c int values to the items.
39.98 + /// It is used internally to handle the cross references.
39.99 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
39.100 + explicit BinomHeap(ItemIntMap &map)
39.101 + : _min(0), _head(-1), _iim(map), _num_items(0) {}
39.102 +
39.103 + /// \brief Constructor.
39.104 + ///
39.105 + /// Constructor.
39.106 + /// \param map A map that assigns \c int values to the items.
39.107 + /// It is used internally to handle the cross references.
39.108 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
39.109 + /// \param comp The function object used for comparing the priorities.
39.110 + BinomHeap(ItemIntMap &map, const Compare &comp)
39.111 + : _min(0), _head(-1), _iim(map), _comp(comp), _num_items(0) {}
39.112 +
39.113 + /// \brief The number of items stored in the heap.
39.114 + ///
39.115 + /// This function returns the number of items stored in the heap.
39.116 + int size() const { return _num_items; }
39.117 +
39.118 + /// \brief Check if the heap is empty.
39.119 + ///
39.120 + /// This function returns \c true if the heap is empty.
39.121 + bool empty() const { return _num_items==0; }
39.122 +
39.123 + /// \brief Make the heap empty.
39.124 + ///
39.125 + /// This functon makes the heap empty.
39.126 + /// It does not change the cross reference map. If you want to reuse
39.127 + /// a heap that is not surely empty, you should first clear it and
39.128 + /// then you should set the cross reference map to \c PRE_HEAP
39.129 + /// for each item.
39.130 + void clear() {
39.131 + _data.clear(); _min=0; _num_items=0; _head=-1;
39.132 + }
39.133 +
39.134 + /// \brief Set the priority of an item or insert it, if it is
39.135 + /// not stored in the heap.
39.136 + ///
39.137 + /// This method sets the priority of the given item if it is
39.138 + /// already stored in the heap. Otherwise it inserts the given
39.139 + /// item into the heap with the given priority.
39.140 + /// \param item The item.
39.141 + /// \param value The priority.
39.142 + void set (const Item& item, const Prio& value) {
39.143 + int i=_iim[item];
39.144 + if ( i >= 0 && _data[i].in ) {
39.145 + if ( _comp(value, _data[i].prio) ) decrease(item, value);
39.146 + if ( _comp(_data[i].prio, value) ) increase(item, value);
39.147 + } else push(item, value);
39.148 + }
39.149 +
39.150 + /// \brief Insert an item into the heap with the given priority.
39.151 + ///
39.152 + /// This function inserts the given item into the heap with the
39.153 + /// given priority.
39.154 + /// \param item The item to insert.
39.155 + /// \param value The priority of the item.
39.156 + /// \pre \e item must not be stored in the heap.
39.157 + void push (const Item& item, const Prio& value) {
39.158 + int i=_iim[item];
39.159 + if ( i<0 ) {
39.160 + int s=_data.size();
39.161 + _iim.set( item,s );
39.162 + Store st;
39.163 + st.name=item;
39.164 + st.prio=value;
39.165 + _data.push_back(st);
39.166 + i=s;
39.167 + }
39.168 + else {
39.169 + _data[i].parent=_data[i].right_neighbor=_data[i].child=-1;
39.170 + _data[i].degree=0;
39.171 + _data[i].in=true;
39.172 + _data[i].prio=value;
39.173 + }
39.174 +
39.175 + if( 0==_num_items ) {
39.176 + _head=i;
39.177 + _min=i;
39.178 + } else {
39.179 + merge(i);
39.180 + if( _comp(_data[i].prio, _data[_min].prio) ) _min=i;
39.181 + }
39.182 + ++_num_items;
39.183 + }
39.184 +
39.185 + /// \brief Return the item having minimum priority.
39.186 + ///
39.187 + /// This function returns the item having minimum priority.
39.188 + /// \pre The heap must be non-empty.
39.189 + Item top() const { return _data[_min].name; }
39.190 +
39.191 + /// \brief The minimum priority.
39.192 + ///
39.193 + /// This function returns the minimum priority.
39.194 + /// \pre The heap must be non-empty.
39.195 + Prio prio() const { return _data[_min].prio; }
39.196 +
39.197 + /// \brief The priority of the given item.
39.198 + ///
39.199 + /// This function returns the priority of the given item.
39.200 + /// \param item The item.
39.201 + /// \pre \e item must be in the heap.
39.202 + const Prio& operator[](const Item& item) const {
39.203 + return _data[_iim[item]].prio;
39.204 + }
39.205 +
39.206 + /// \brief Remove the item having minimum priority.
39.207 + ///
39.208 + /// This function removes the item having minimum priority.
39.209 + /// \pre The heap must be non-empty.
39.210 + void pop() {
39.211 + _data[_min].in=false;
39.212 +
39.213 + int head_child=-1;
39.214 + if ( _data[_min].child!=-1 ) {
39.215 + int child=_data[_min].child;
39.216 + int neighb;
39.217 + while( child!=-1 ) {
39.218 + neighb=_data[child].right_neighbor;
39.219 + _data[child].parent=-1;
39.220 + _data[child].right_neighbor=head_child;
39.221 + head_child=child;
39.222 + child=neighb;
39.223 + }
39.224 + }
39.225 +
39.226 + if ( _data[_head].right_neighbor==-1 ) {
39.227 + // there was only one root
39.228 + _head=head_child;
39.229 + }
39.230 + else {
39.231 + // there were more roots
39.232 + if( _head!=_min ) { unlace(_min); }
39.233 + else { _head=_data[_head].right_neighbor; }
39.234 + merge(head_child);
39.235 + }
39.236 + _min=findMin();
39.237 + --_num_items;
39.238 + }
39.239 +
39.240 + /// \brief Remove the given item from the heap.
39.241 + ///
39.242 + /// This function removes the given item from the heap if it is
39.243 + /// already stored.
39.244 + /// \param item The item to delete.
39.245 + /// \pre \e item must be in the heap.
39.246 + void erase (const Item& item) {
39.247 + int i=_iim[item];
39.248 + if ( i >= 0 && _data[i].in ) {
39.249 + decrease( item, _data[_min].prio-1 );
39.250 + pop();
39.251 + }
39.252 + }
39.253 +
39.254 + /// \brief Decrease the priority of an item to the given value.
39.255 + ///
39.256 + /// This function decreases the priority of an item to the given value.
39.257 + /// \param item The item.
39.258 + /// \param value The priority.
39.259 + /// \pre \e item must be stored in the heap with priority at least \e value.
39.260 + void decrease (Item item, const Prio& value) {
39.261 + int i=_iim[item];
39.262 + int p=_data[i].parent;
39.263 + _data[i].prio=value;
39.264 +
39.265 + while( p!=-1 && _comp(value, _data[p].prio) ) {
39.266 + _data[i].name=_data[p].name;
39.267 + _data[i].prio=_data[p].prio;
39.268 + _data[p].name=item;
39.269 + _data[p].prio=value;
39.270 + _iim[_data[i].name]=i;
39.271 + i=p;
39.272 + p=_data[p].parent;
39.273 + }
39.274 + _iim[item]=i;
39.275 + if ( _comp(value, _data[_min].prio) ) _min=i;
39.276 + }
39.277 +
39.278 + /// \brief Increase the priority of an item to the given value.
39.279 + ///
39.280 + /// This function increases the priority of an item to the given value.
39.281 + /// \param item The item.
39.282 + /// \param value The priority.
39.283 + /// \pre \e item must be stored in the heap with priority at most \e value.
39.284 + void increase (Item item, const Prio& value) {
39.285 + erase(item);
39.286 + push(item, value);
39.287 + }
39.288 +
39.289 + /// \brief Return the state of an item.
39.290 + ///
39.291 + /// This method returns \c PRE_HEAP if the given item has never
39.292 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
39.293 + /// and \c POST_HEAP otherwise.
39.294 + /// In the latter case it is possible that the item will get back
39.295 + /// to the heap again.
39.296 + /// \param item The item.
39.297 + State state(const Item &item) const {
39.298 + int i=_iim[item];
39.299 + if( i>=0 ) {
39.300 + if ( _data[i].in ) i=0;
39.301 + else i=-2;
39.302 + }
39.303 + return State(i);
39.304 + }
39.305 +
39.306 + /// \brief Set the state of an item in the heap.
39.307 + ///
39.308 + /// This function sets the state of the given item in the heap.
39.309 + /// It can be used to manually clear the heap when it is important
39.310 + /// to achive better time complexity.
39.311 + /// \param i The item.
39.312 + /// \param st The state. It should not be \c IN_HEAP.
39.313 + void state(const Item& i, State st) {
39.314 + switch (st) {
39.315 + case POST_HEAP:
39.316 + case PRE_HEAP:
39.317 + if (state(i) == IN_HEAP) {
39.318 + erase(i);
39.319 + }
39.320 + _iim[i] = st;
39.321 + break;
39.322 + case IN_HEAP:
39.323 + break;
39.324 + }
39.325 + }
39.326 +
39.327 + private:
39.328 +
39.329 + // Find the minimum of the roots
39.330 + int findMin() {
39.331 + if( _head!=-1 ) {
39.332 + int min_loc=_head, min_val=_data[_head].prio;
39.333 + for( int x=_data[_head].right_neighbor; x!=-1;
39.334 + x=_data[x].right_neighbor ) {
39.335 + if( _comp( _data[x].prio,min_val ) ) {
39.336 + min_val=_data[x].prio;
39.337 + min_loc=x;
39.338 + }
39.339 + }
39.340 + return min_loc;
39.341 + }
39.342 + else return -1;
39.343 + }
39.344 +
39.345 + // Merge the heap with another heap starting at the given position
39.346 + void merge(int a) {
39.347 + if( _head==-1 || a==-1 ) return;
39.348 + if( _data[a].right_neighbor==-1 &&
39.349 + _data[a].degree<=_data[_head].degree ) {
39.350 + _data[a].right_neighbor=_head;
39.351 + _head=a;
39.352 + } else {
39.353 + interleave(a);
39.354 + }
39.355 + if( _data[_head].right_neighbor==-1 ) return;
39.356 +
39.357 + int x=_head;
39.358 + int x_prev=-1, x_next=_data[x].right_neighbor;
39.359 + while( x_next!=-1 ) {
39.360 + if( _data[x].degree!=_data[x_next].degree ||
39.361 + ( _data[x_next].right_neighbor!=-1 &&
39.362 + _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
39.363 + x_prev=x;
39.364 + x=x_next;
39.365 + }
39.366 + else {
39.367 + if( _comp(_data[x_next].prio,_data[x].prio) ) {
39.368 + if( x_prev==-1 ) {
39.369 + _head=x_next;
39.370 + } else {
39.371 + _data[x_prev].right_neighbor=x_next;
39.372 + }
39.373 + fuse(x,x_next);
39.374 + x=x_next;
39.375 + }
39.376 + else {
39.377 + _data[x].right_neighbor=_data[x_next].right_neighbor;
39.378 + fuse(x_next,x);
39.379 + }
39.380 + }
39.381 + x_next=_data[x].right_neighbor;
39.382 + }
39.383 + }
39.384 +
39.385 + // Interleave the elements of the given list into the list of the roots
39.386 + void interleave(int a) {
39.387 + int p=_head, q=a;
39.388 + int curr=_data.size();
39.389 + _data.push_back(Store());
39.390 +
39.391 + while( p!=-1 || q!=-1 ) {
39.392 + if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
39.393 + _data[curr].right_neighbor=p;
39.394 + curr=p;
39.395 + p=_data[p].right_neighbor;
39.396 + }
39.397 + else {
39.398 + _data[curr].right_neighbor=q;
39.399 + curr=q;
39.400 + q=_data[q].right_neighbor;
39.401 + }
39.402 + }
39.403 +
39.404 + _head=_data.back().right_neighbor;
39.405 + _data.pop_back();
39.406 + }
39.407 +
39.408 + // Lace node a under node b
39.409 + void fuse(int a, int b) {
39.410 + _data[a].parent=b;
39.411 + _data[a].right_neighbor=_data[b].child;
39.412 + _data[b].child=a;
39.413 +
39.414 + ++_data[b].degree;
39.415 + }
39.416 +
39.417 + // Unlace node a (if it has siblings)
39.418 + void unlace(int a) {
39.419 + int neighb=_data[a].right_neighbor;
39.420 + int other=_head;
39.421 +
39.422 + while( _data[other].right_neighbor!=a )
39.423 + other=_data[other].right_neighbor;
39.424 + _data[other].right_neighbor=neighb;
39.425 + }
39.426 +
39.427 + private:
39.428 +
39.429 + class Store {
39.430 + friend class BinomHeap;
39.431 +
39.432 + Item name;
39.433 + int parent;
39.434 + int right_neighbor;
39.435 + int child;
39.436 + int degree;
39.437 + bool in;
39.438 + Prio prio;
39.439 +
39.440 + Store() : parent(-1), right_neighbor(-1), child(-1), degree(0),
39.441 + in(true) {}
39.442 + };
39.443 + };
39.444 +
39.445 +} //namespace lemon
39.446 +
39.447 +#endif //LEMON_BINOM_HEAP_H
39.448 +
40.1 --- a/lemon/bits/array_map.h Mon Jan 12 23:11:39 2009 +0100
40.2 +++ b/lemon/bits/array_map.h Thu Nov 05 15:48:01 2009 +0100
40.3 @@ -47,7 +47,7 @@
40.4 : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
40.5 public:
40.6 // The graph type.
40.7 - typedef _Graph Graph;
40.8 + typedef _Graph GraphType;
40.9 // The item type.
40.10 typedef _Item Item;
40.11 // The reference map tag.
40.12 @@ -63,13 +63,17 @@
40.13 // The reference type of the map.
40.14 typedef _Value& Reference;
40.15
40.16 + // The map type.
40.17 + typedef ArrayMap Map;
40.18 +
40.19 // The notifier type.
40.20 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
40.21
40.22 + private:
40.23 +
40.24 // The MapBase of the Map which imlements the core regisitry function.
40.25 typedef typename Notifier::ObserverBase Parent;
40.26
40.27 - private:
40.28 typedef std::allocator<Value> Allocator;
40.29
40.30 public:
40.31 @@ -77,7 +81,7 @@
40.32 // \brief Graph initialized map constructor.
40.33 //
40.34 // Graph initialized map constructor.
40.35 - explicit ArrayMap(const Graph& graph) {
40.36 + explicit ArrayMap(const GraphType& graph) {
40.37 Parent::attach(graph.notifier(Item()));
40.38 allocate_memory();
40.39 Notifier* nf = Parent::notifier();
40.40 @@ -91,7 +95,7 @@
40.41 // \brief Constructor to use default value to initialize the map.
40.42 //
40.43 // It constructs a map and initialize all of the the map.
40.44 - ArrayMap(const Graph& graph, const Value& value) {
40.45 + ArrayMap(const GraphType& graph, const Value& value) {
40.46 Parent::attach(graph.notifier(Item()));
40.47 allocate_memory();
40.48 Notifier* nf = Parent::notifier();
40.49 @@ -135,7 +139,7 @@
40.50
40.51 // \brief Template assign operator.
40.52 //
40.53 - // The given parameter should be conform to the ReadMap
40.54 + // The given parameter should conform to the ReadMap
40.55 // concecpt and could be indiced by the current item set of
40.56 // the NodeMap. In this case the value for each item
40.57 // is assigned by the value of the given ReadMap.
41.1 --- a/lemon/bits/base_extender.h Mon Jan 12 23:11:39 2009 +0100
41.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
41.3 @@ -1,494 +0,0 @@
41.4 -/* -*- mode: C++; indent-tabs-mode: nil; -*-
41.5 - *
41.6 - * This file is a part of LEMON, a generic C++ optimization library.
41.7 - *
41.8 - * Copyright (C) 2003-2009
41.9 - * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
41.10 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
41.11 - *
41.12 - * Permission to use, modify and distribute this software is granted
41.13 - * provided that this copyright notice appears in all copies. For
41.14 - * precise terms see the accompanying LICENSE file.
41.15 - *
41.16 - * This software is provided "AS IS" with no warranty of any kind,
41.17 - * express or implied, and with no claim as to its suitability for any
41.18 - * purpose.
41.19 - *
41.20 - */
41.21 -
41.22 -#ifndef LEMON_BITS_BASE_EXTENDER_H
41.23 -#define LEMON_BITS_BASE_EXTENDER_H
41.24 -
41.25 -#include <lemon/core.h>
41.26 -#include <lemon/error.h>
41.27 -
41.28 -#include <lemon/bits/map_extender.h>
41.29 -#include <lemon/bits/default_map.h>
41.30 -
41.31 -#include <lemon/concept_check.h>
41.32 -#include <lemon/concepts/maps.h>
41.33 -
41.34 -//\ingroup digraphbits
41.35 -//\file
41.36 -//\brief Extenders for the graph types
41.37 -namespace lemon {
41.38 -
41.39 - // \ingroup digraphbits
41.40 - //
41.41 - // \brief BaseDigraph to BaseGraph extender
41.42 - template <typename Base>
41.43 - class UndirDigraphExtender : public Base {
41.44 -
41.45 - public:
41.46 -
41.47 - typedef Base Parent;
41.48 - typedef typename Parent::Arc Edge;
41.49 - typedef typename Parent::Node Node;
41.50 -
41.51 - typedef True UndirectedTag;
41.52 -
41.53 - class Arc : public Edge {
41.54 - friend class UndirDigraphExtender;
41.55 -
41.56 - protected:
41.57 - bool forward;
41.58 -
41.59 - Arc(const Edge &ue, bool _forward) :
41.60 - Edge(ue), forward(_forward) {}
41.61 -
41.62 - public:
41.63 - Arc() {}
41.64 -
41.65 - // Invalid arc constructor
41.66 - Arc(Invalid i) : Edge(i), forward(true) {}
41.67 -
41.68 - bool operator==(const Arc &that) const {
41.69 - return forward==that.forward && Edge(*this)==Edge(that);
41.70 - }
41.71 - bool operator!=(const Arc &that) const {
41.72 - return forward!=that.forward || Edge(*this)!=Edge(that);
41.73 - }
41.74 - bool operator<(const Arc &that) const {
41.75 - return forward<that.forward ||
41.76 - (!(that.forward<forward) && Edge(*this)<Edge(that));
41.77 - }
41.78 - };
41.79 -
41.80 - // First node of the edge
41.81 - Node u(const Edge &e) const {
41.82 - return Parent::source(e);
41.83 - }
41.84 -
41.85 - // Source of the given arc
41.86 - Node source(const Arc &e) const {
41.87 - return e.forward ? Parent::source(e) : Parent::target(e);
41.88 - }
41.89 -
41.90 - // Second node of the edge
41.91 - Node v(const Edge &e) const {
41.92 - return Parent::target(e);
41.93 - }
41.94 -
41.95 - // Target of the given arc
41.96 - Node target(const Arc &e) const {
41.97 - return e.forward ? Parent::target(e) : Parent::source(e);
41.98 - }
41.99 -
41.100 - // \brief Directed arc from an edge.
41.101 - //
41.102 - // Returns a directed arc corresponding to the specified edge.
41.103 - // If the given bool is true, the first node of the given edge and
41.104 - // the source node of the returned arc are the same.
41.105 - static Arc direct(const Edge &e, bool d) {
41.106 - return Arc(e, d);
41.107 - }
41.108 -
41.109 - // Returns whether the given directed arc has the same orientation
41.110 - // as the corresponding edge.
41.111 - static bool direction(const Arc &a) { return a.forward; }
41.112 -
41.113 - using Parent::first;
41.114 - using Parent::next;
41.115 -
41.116 - void first(Arc &e) const {
41.117 - Parent::first(e);
41.118 - e.forward=true;
41.119 - }
41.120 -
41.121 - void next(Arc &e) const {
41.122 - if( e.forward ) {
41.123 - e.forward = false;
41.124 - }
41.125 - else {
41.126 - Parent::next(e);
41.127 - e.forward = true;
41.128 - }
41.129 - }
41.130 -
41.131 - void firstOut(Arc &e, const Node &n) const {
41.132 - Parent::firstIn(e,n);
41.133 - if( Edge(e) != INVALID ) {
41.134 - e.forward = false;
41.135 - }
41.136 - else {
41.137 - Parent::firstOut(e,n);
41.138 - e.forward = true;
41.139 - }
41.140 - }
41.141 - void nextOut(Arc &e) const {
41.142 - if( ! e.forward ) {
41.143 - Node n = Parent::target(e);
41.144 - Parent::nextIn(e);
41.145 - if( Edge(e) == INVALID ) {
41.146 - Parent::firstOut(e, n);
41.147 - e.forward = true;
41.148 - }
41.149 - }
41.150 - else {
41.151 - Parent::nextOut(e);
41.152 - }
41.153 - }
41.154 -
41.155 - void firstIn(Arc &e, const Node &n) const {
41.156 - Parent::firstOut(e,n);
41.157 - if( Edge(e) != INVALID ) {
41.158 - e.forward = false;
41.159 - }
41.160 - else {
41.161 - Parent::firstIn(e,n);
41.162 - e.forward = true;
41.163 - }
41.164 - }
41.165 - void nextIn(Arc &e) const {
41.166 - if( ! e.forward ) {
41.167 - Node n = Parent::source(e);
41.168 - Parent::nextOut(e);
41.169 - if( Edge(e) == INVALID ) {
41.170 - Parent::firstIn(e, n);
41.171 - e.forward = true;
41.172 - }
41.173 - }
41.174 - else {
41.175 - Parent::nextIn(e);
41.176 - }
41.177 - }
41.178 -
41.179 - void firstInc(Edge &e, bool &d, const Node &n) const {
41.180 - d = true;
41.181 - Parent::firstOut(e, n);
41.182 - if (e != INVALID) return;
41.183 - d = false;
41.184 - Parent::firstIn(e, n);
41.185 - }
41.186 -
41.187 - void nextInc(Edge &e, bool &d) const {
41.188 - if (d) {
41.189 - Node s = Parent::source(e);
41.190 - Parent::nextOut(e);
41.191 - if (e != INVALID) return;
41.192 - d = false;
41.193 - Parent::firstIn(e, s);
41.194 - } else {
41.195 - Parent::nextIn(e);
41.196 - }
41.197 - }
41.198 -
41.199 - Node nodeFromId(int ix) const {
41.200 - return Parent::nodeFromId(ix);
41.201 - }
41.202 -
41.203 - Arc arcFromId(int ix) const {
41.204 - return direct(Parent::arcFromId(ix >> 1), bool(ix & 1));
41.205 - }
41.206 -
41.207 - Edge edgeFromId(int ix) const {
41.208 - return Parent::arcFromId(ix);
41.209 - }
41.210 -
41.211 - int id(const Node &n) const {
41.212 - return Parent::id(n);
41.213 - }
41.214 -
41.215 - int id(const Edge &e) const {
41.216 - return Parent::id(e);
41.217 - }
41.218 -
41.219 - int id(const Arc &e) const {
41.220 - return 2 * Parent::id(e) + int(e.forward);
41.221 - }
41.222 -
41.223 - int maxNodeId() const {
41.224 - return Parent::maxNodeId();
41.225 - }
41.226 -
41.227 - int maxArcId() const {
41.228 - return 2 * Parent::maxArcId() + 1;
41.229 - }
41.230 -
41.231 - int maxEdgeId() const {
41.232 - return Parent::maxArcId();
41.233 - }
41.234 -
41.235 - int arcNum() const {
41.236 - return 2 * Parent::arcNum();
41.237 - }
41.238 -
41.239 - int edgeNum() const {
41.240 - return Parent::arcNum();
41.241 - }
41.242 -
41.243 - Arc findArc(Node s, Node t, Arc p = INVALID) const {
41.244 - if (p == INVALID) {
41.245 - Edge arc = Parent::findArc(s, t);
41.246 - if (arc != INVALID) return direct(arc, true);
41.247 - arc = Parent::findArc(t, s);
41.248 - if (arc != INVALID) return direct(arc, false);
41.249 - } else if (direction(p)) {
41.250 - Edge arc = Parent::findArc(s, t, p);
41.251 - if (arc != INVALID) return direct(arc, true);
41.252 - arc = Parent::findArc(t, s);
41.253 - if (arc != INVALID) return direct(arc, false);
41.254 - } else {
41.255 - Edge arc = Parent::findArc(t, s, p);
41.256 - if (arc != INVALID) return direct(arc, false);
41.257 - }
41.258 - return INVALID;
41.259 - }
41.260 -
41.261 - Edge findEdge(Node s, Node t, Edge p = INVALID) const {
41.262 - if (s != t) {
41.263 - if (p == INVALID) {
41.264 - Edge arc = Parent::findArc(s, t);
41.265 - if (arc != INVALID) return arc;
41.266 - arc = Parent::findArc(t, s);
41.267 - if (arc != INVALID) return arc;
41.268 - } else if (Parent::s(p) == s) {
41.269 - Edge arc = Parent::findArc(s, t, p);
41.270 - if (arc != INVALID) return arc;
41.271 - arc = Parent::findArc(t, s);
41.272 - if (arc != INVALID) return arc;
41.273 - } else {
41.274 - Edge arc = Parent::findArc(t, s, p);
41.275 - if (arc != INVALID) return arc;
41.276 - }
41.277 - } else {
41.278 - return Parent::findArc(s, t, p);
41.279 - }
41.280 - return INVALID;
41.281 - }
41.282 - };
41.283 -
41.284 - template <typename Base>
41.285 - class BidirBpGraphExtender : public Base {
41.286 - public:
41.287 - typedef Base Parent;
41.288 - typedef BidirBpGraphExtender Digraph;
41.289 -
41.290 - typedef typename Parent::Node Node;
41.291 - typedef typename Parent::Edge Edge;
41.292 -
41.293 -
41.294 - using Parent::first;
41.295 - using Parent::next;
41.296 -
41.297 - using Parent::id;
41.298 -
41.299 - class Red : public Node {
41.300 - friend class BidirBpGraphExtender;
41.301 - public:
41.302 - Red() {}
41.303 - Red(const Node& node) : Node(node) {
41.304 - LEMON_DEBUG(Parent::red(node) || node == INVALID,
41.305 - typename Parent::NodeSetError());
41.306 - }
41.307 - Red& operator=(const Node& node) {
41.308 - LEMON_DEBUG(Parent::red(node) || node == INVALID,
41.309 - typename Parent::NodeSetError());
41.310 - Node::operator=(node);
41.311 - return *this;
41.312 - }
41.313 - Red(Invalid) : Node(INVALID) {}
41.314 - Red& operator=(Invalid) {
41.315 - Node::operator=(INVALID);
41.316 - return *this;
41.317 - }
41.318 - };
41.319 -
41.320 - void first(Red& node) const {
41.321 - Parent::firstRed(static_cast<Node&>(node));
41.322 - }
41.323 - void next(Red& node) const {
41.324 - Parent::nextRed(static_cast<Node&>(node));
41.325 - }
41.326 -
41.327 - int id(const Red& node) const {
41.328 - return Parent::redId(node);
41.329 - }
41.330 -
41.331 - class Blue : public Node {
41.332 - friend class BidirBpGraphExtender;
41.333 - public:
41.334 - Blue() {}
41.335 - Blue(const Node& node) : Node(node) {
41.336 - LEMON_DEBUG(Parent::blue(node) || node == INVALID,
41.337 - typename Parent::NodeSetError());
41.338 - }
41.339 - Blue& operator=(const Node& node) {
41.340 - LEMON_DEBUG(Parent::blue(node) || node == INVALID,
41.341 - typename Parent::NodeSetError());
41.342 - Node::operator=(node);
41.343 - return *this;
41.344 - }
41.345 - Blue(Invalid) : Node(INVALID) {}
41.346 - Blue& operator=(Invalid) {
41.347 - Node::operator=(INVALID);
41.348 - return *this;
41.349 - }
41.350 - };
41.351 -
41.352 - void first(Blue& node) const {
41.353 - Parent::firstBlue(static_cast<Node&>(node));
41.354 - }
41.355 - void next(Blue& node) const {
41.356 - Parent::nextBlue(static_cast<Node&>(node));
41.357 - }
41.358 -
41.359 - int id(const Blue& node) const {
41.360 - return Parent::redId(node);
41.361 - }
41.362 -
41.363 - Node source(const Edge& arc) const {
41.364 - return red(arc);
41.365 - }
41.366 - Node target(const Edge& arc) const {
41.367 - return blue(arc);
41.368 - }
41.369 -
41.370 - void firstInc(Edge& arc, bool& dir, const Node& node) const {
41.371 - if (Parent::red(node)) {
41.372 - Parent::firstFromRed(arc, node);
41.373 - dir = true;
41.374 - } else {
41.375 - Parent::firstFromBlue(arc, node);
41.376 - dir = static_cast<Edge&>(arc) == INVALID;
41.377 - }
41.378 - }
41.379 - void nextInc(Edge& arc, bool& dir) const {
41.380 - if (dir) {
41.381 - Parent::nextFromRed(arc);
41.382 - } else {
41.383 - Parent::nextFromBlue(arc);
41.384 - if (arc == INVALID) dir = true;
41.385 - }
41.386 - }
41.387 -
41.388 - class Arc : public Edge {
41.389 - friend class BidirBpGraphExtender;
41.390 - protected:
41.391 - bool forward;
41.392 -
41.393 - Arc(const Edge& arc, bool _forward)
41.394 - : Edge(arc), forward(_forward) {}
41.395 -
41.396 - public:
41.397 - Arc() {}
41.398 - Arc (Invalid) : Edge(INVALID), forward(true) {}
41.399 - bool operator==(const Arc& i) const {
41.400 - return Edge::operator==(i) && forward == i.forward;
41.401 - }
41.402 - bool operator!=(const Arc& i) const {
41.403 - return Edge::operator!=(i) || forward != i.forward;
41.404 - }
41.405 - bool operator<(const Arc& i) const {
41.406 - return Edge::operator<(i) ||
41.407 - (!(i.forward<forward) && Edge(*this)<Edge(i));
41.408 - }
41.409 - };
41.410 -
41.411 - void first(Arc& arc) const {
41.412 - Parent::first(static_cast<Edge&>(arc));
41.413 - arc.forward = true;
41.414 - }
41.415 -
41.416 - void next(Arc& arc) const {
41.417 - if (!arc.forward) {
41.418 - Parent::next(static_cast<Edge&>(arc));
41.419 - }
41.420 - arc.forward = !arc.forward;
41.421 - }
41.422 -
41.423 - void firstOut(Arc& arc, const Node& node) const {
41.424 - if (Parent::red(node)) {
41.425 - Parent::firstFromRed(arc, node);
41.426 - arc.forward = true;
41.427 - } else {
41.428 - Parent::firstFromBlue(arc, node);
41.429 - arc.forward = static_cast<Edge&>(arc) == INVALID;
41.430 - }
41.431 - }
41.432 - void nextOut(Arc& arc) const {
41.433 - if (arc.forward) {
41.434 - Parent::nextFromRed(arc);
41.435 - } else {
41.436 - Parent::nextFromBlue(arc);
41.437 - arc.forward = static_cast<Edge&>(arc) == INVALID;
41.438 - }
41.439 - }
41.440 -
41.441 - void firstIn(Arc& arc, const Node& node) const {
41.442 - if (Parent::blue(node)) {
41.443 - Parent::firstFromBlue(arc, node);
41.444 - arc.forward = true;
41.445 - } else {
41.446 - Parent::firstFromRed(arc, node);
41.447 - arc.forward = static_cast<Edge&>(arc) == INVALID;
41.448 - }
41.449 - }
41.450 - void nextIn(Arc& arc) const {
41.451 - if (arc.forward) {
41.452 - Parent::nextFromBlue(arc);
41.453 - } else {
41.454 - Parent::nextFromRed(arc);
41.455 - arc.forward = static_cast<Edge&>(arc) == INVALID;
41.456 - }
41.457 - }
41.458 -
41.459 - Node source(const Arc& arc) const {
41.460 - return arc.forward ? Parent::red(arc) : Parent::blue(arc);
41.461 - }
41.462 - Node target(const Arc& arc) const {
41.463 - return arc.forward ? Parent::blue(arc) : Parent::red(arc);
41.464 - }
41.465 -
41.466 - int id(const Arc& arc) const {
41.467 - return (Parent::id(static_cast<const Edge&>(arc)) << 1) +
41.468 - (arc.forward ? 0 : 1);
41.469 - }
41.470 - Arc arcFromId(int ix) const {
41.471 - return Arc(Parent::fromEdgeId(ix >> 1), (ix & 1) == 0);
41.472 - }
41.473 - int maxArcId() const {
41.474 - return (Parent::maxEdgeId() << 1) + 1;
41.475 - }
41.476 -
41.477 - bool direction(const Arc& arc) const {
41.478 - return arc.forward;
41.479 - }
41.480 -
41.481 - Arc direct(const Edge& arc, bool dir) const {
41.482 - return Arc(arc, dir);
41.483 - }
41.484 -
41.485 - int arcNum() const {
41.486 - return 2 * Parent::edgeNum();
41.487 - }
41.488 -
41.489 - int edgeNum() const {
41.490 - return Parent::edgeNum();
41.491 - }
41.492 -
41.493 -
41.494 - };
41.495 -}
41.496 -
41.497 -#endif
42.1 --- a/lemon/bits/default_map.h Mon Jan 12 23:11:39 2009 +0100
42.2 +++ b/lemon/bits/default_map.h Thu Nov 05 15:48:01 2009 +0100
42.3 @@ -19,6 +19,7 @@
42.4 #ifndef LEMON_BITS_DEFAULT_MAP_H
42.5 #define LEMON_BITS_DEFAULT_MAP_H
42.6
42.7 +#include <lemon/config.h>
42.8 #include <lemon/bits/array_map.h>
42.9 #include <lemon/bits/vector_map.h>
42.10 //#include <lemon/bits/debug_map.h>
42.11 @@ -96,7 +97,7 @@
42.12 };
42.13
42.14
42.15 -#if defined __GNUC__ && !defined __STRICT_ANSI__
42.16 +#if defined LEMON_HAVE_LONG_LONG
42.17
42.18 // long long
42.19 template <typename _Graph, typename _Item>
42.20 @@ -152,15 +153,16 @@
42.21 template <typename _Graph, typename _Item, typename _Value>
42.22 class DefaultMap
42.23 : public DefaultMapSelector<_Graph, _Item, _Value>::Map {
42.24 + typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
42.25 +
42.26 public:
42.27 - typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
42.28 typedef DefaultMap<_Graph, _Item, _Value> Map;
42.29 -
42.30 - typedef typename Parent::Graph Graph;
42.31 +
42.32 + typedef typename Parent::GraphType GraphType;
42.33 typedef typename Parent::Value Value;
42.34
42.35 - explicit DefaultMap(const Graph& graph) : Parent(graph) {}
42.36 - DefaultMap(const Graph& graph, const Value& value)
42.37 + explicit DefaultMap(const GraphType& graph) : Parent(graph) {}
42.38 + DefaultMap(const GraphType& graph, const Value& value)
42.39 : Parent(graph, value) {}
42.40
42.41 DefaultMap& operator=(const DefaultMap& cmap) {
43.1 --- a/lemon/bits/edge_set_extender.h Mon Jan 12 23:11:39 2009 +0100
43.2 +++ b/lemon/bits/edge_set_extender.h Thu Nov 05 15:48:01 2009 +0100
43.3 @@ -19,22 +19,25 @@
43.4 #ifndef LEMON_BITS_EDGE_SET_EXTENDER_H
43.5 #define LEMON_BITS_EDGE_SET_EXTENDER_H
43.6
43.7 +#include <lemon/core.h>
43.8 #include <lemon/error.h>
43.9 #include <lemon/bits/default_map.h>
43.10 +#include <lemon/bits/map_extender.h>
43.11
43.12 -///\ingroup digraphbits
43.13 -///\file
43.14 -///\brief Extenders for the arc set types
43.15 +//\ingroup digraphbits
43.16 +//\file
43.17 +//\brief Extenders for the arc set types
43.18 namespace lemon {
43.19
43.20 - /// \ingroup digraphbits
43.21 - ///
43.22 - /// \brief Extender for the ArcSets
43.23 + // \ingroup digraphbits
43.24 + //
43.25 + // \brief Extender for the ArcSets
43.26 template <typename Base>
43.27 class ArcSetExtender : public Base {
43.28 + typedef Base Parent;
43.29 +
43.30 public:
43.31
43.32 - typedef Base Parent;
43.33 typedef ArcSetExtender Digraph;
43.34
43.35 // Base extensions
43.36 @@ -70,7 +73,7 @@
43.37
43.38 // Alteration notifier extensions
43.39
43.40 - /// The arc observer registry.
43.41 + // The arc observer registry.
43.42 typedef AlterationNotifier<ArcSetExtender, Arc> ArcNotifier;
43.43
43.44 protected:
43.45 @@ -81,9 +84,7 @@
43.46
43.47 using Parent::notifier;
43.48
43.49 - /// \brief Gives back the arc alteration notifier.
43.50 - ///
43.51 - /// Gives back the arc alteration notifier.
43.52 + // Gives back the arc alteration notifier.
43.53 ArcNotifier& notifier(Arc) const {
43.54 return arc_notifier;
43.55 }
43.56 @@ -183,30 +184,30 @@
43.57
43.58 };
43.59
43.60 - /// \brief Base node of the iterator
43.61 - ///
43.62 - /// Returns the base node (ie. the source in this case) of the iterator
43.63 + // \brief Base node of the iterator
43.64 + //
43.65 + // Returns the base node (ie. the source in this case) of the iterator
43.66 Node baseNode(const OutArcIt &e) const {
43.67 return Parent::source(static_cast<const Arc&>(e));
43.68 }
43.69 - /// \brief Running node of the iterator
43.70 - ///
43.71 - /// Returns the running node (ie. the target in this case) of the
43.72 - /// iterator
43.73 + // \brief Running node of the iterator
43.74 + //
43.75 + // Returns the running node (ie. the target in this case) of the
43.76 + // iterator
43.77 Node runningNode(const OutArcIt &e) const {
43.78 return Parent::target(static_cast<const Arc&>(e));
43.79 }
43.80
43.81 - /// \brief Base node of the iterator
43.82 - ///
43.83 - /// Returns the base node (ie. the target in this case) of the iterator
43.84 + // \brief Base node of the iterator
43.85 + //
43.86 + // Returns the base node (ie. the target in this case) of the iterator
43.87 Node baseNode(const InArcIt &e) const {
43.88 return Parent::target(static_cast<const Arc&>(e));
43.89 }
43.90 - /// \brief Running node of the iterator
43.91 - ///
43.92 - /// Returns the running node (ie. the source in this case) of the
43.93 - /// iterator
43.94 + // \brief Running node of the iterator
43.95 + //
43.96 + // Returns the running node (ie. the source in this case) of the
43.97 + // iterator
43.98 Node runningNode(const InArcIt &e) const {
43.99 return Parent::source(static_cast<const Arc&>(e));
43.100 }
43.101 @@ -218,10 +219,9 @@
43.102 template <typename _Value>
43.103 class ArcMap
43.104 : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
43.105 - public:
43.106 - typedef ArcSetExtender Digraph;
43.107 typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
43.108
43.109 + public:
43.110 explicit ArcMap(const Digraph& _g)
43.111 : Parent(_g) {}
43.112 ArcMap(const Digraph& _g, const _Value& _v)
43.113 @@ -269,22 +269,21 @@
43.114 };
43.115
43.116
43.117 - /// \ingroup digraphbits
43.118 - ///
43.119 - /// \brief Extender for the EdgeSets
43.120 + // \ingroup digraphbits
43.121 + //
43.122 + // \brief Extender for the EdgeSets
43.123 template <typename Base>
43.124 class EdgeSetExtender : public Base {
43.125 + typedef Base Parent;
43.126
43.127 public:
43.128
43.129 - typedef Base Parent;
43.130 - typedef EdgeSetExtender Digraph;
43.131 + typedef EdgeSetExtender Graph;
43.132
43.133 typedef typename Parent::Node Node;
43.134 typedef typename Parent::Arc Arc;
43.135 typedef typename Parent::Edge Edge;
43.136
43.137 -
43.138 int maxId(Node) const {
43.139 return Parent::maxNodeId();
43.140 }
43.141 @@ -350,22 +349,22 @@
43.142
43.143
43.144 class NodeIt : public Node {
43.145 - const Digraph* digraph;
43.146 + const Graph* graph;
43.147 public:
43.148
43.149 NodeIt() {}
43.150
43.151 NodeIt(Invalid i) : Node(i) { }
43.152
43.153 - explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
43.154 + explicit NodeIt(const Graph& _graph) : graph(&_graph) {
43.155 _graph.first(static_cast<Node&>(*this));
43.156 }
43.157
43.158 - NodeIt(const Digraph& _graph, const Node& node)
43.159 - : Node(node), digraph(&_graph) {}
43.160 + NodeIt(const Graph& _graph, const Node& node)
43.161 + : Node(node), graph(&_graph) {}
43.162
43.163 NodeIt& operator++() {
43.164 - digraph->next(*this);
43.165 + graph->next(*this);
43.166 return *this;
43.167 }
43.168
43.169 @@ -373,22 +372,22 @@
43.170
43.171
43.172 class ArcIt : public Arc {
43.173 - const Digraph* digraph;
43.174 + const Graph* graph;
43.175 public:
43.176
43.177 ArcIt() { }
43.178
43.179 ArcIt(Invalid i) : Arc(i) { }
43.180
43.181 - explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
43.182 + explicit ArcIt(const Graph& _graph) : graph(&_graph) {
43.183 _graph.first(static_cast<Arc&>(*this));
43.184 }
43.185
43.186 - ArcIt(const Digraph& _graph, const Arc& e) :
43.187 - Arc(e), digraph(&_graph) { }
43.188 + ArcIt(const Graph& _graph, const Arc& e) :
43.189 + Arc(e), graph(&_graph) { }
43.190
43.191 ArcIt& operator++() {
43.192 - digraph->next(*this);
43.193 + graph->next(*this);
43.194 return *this;
43.195 }
43.196
43.197 @@ -396,23 +395,23 @@
43.198
43.199
43.200 class OutArcIt : public Arc {
43.201 - const Digraph* digraph;
43.202 + const Graph* graph;
43.203 public:
43.204
43.205 OutArcIt() { }
43.206
43.207 OutArcIt(Invalid i) : Arc(i) { }
43.208
43.209 - OutArcIt(const Digraph& _graph, const Node& node)
43.210 - : digraph(&_graph) {
43.211 + OutArcIt(const Graph& _graph, const Node& node)
43.212 + : graph(&_graph) {
43.213 _graph.firstOut(*this, node);
43.214 }
43.215
43.216 - OutArcIt(const Digraph& _graph, const Arc& arc)
43.217 - : Arc(arc), digraph(&_graph) {}
43.218 + OutArcIt(const Graph& _graph, const Arc& arc)
43.219 + : Arc(arc), graph(&_graph) {}
43.220
43.221 OutArcIt& operator++() {
43.222 - digraph->nextOut(*this);
43.223 + graph->nextOut(*this);
43.224 return *this;
43.225 }
43.226
43.227 @@ -420,23 +419,23 @@
43.228
43.229
43.230 class InArcIt : public Arc {
43.231 - const Digraph* digraph;
43.232 + const Graph* graph;
43.233 public:
43.234
43.235 InArcIt() { }
43.236
43.237 InArcIt(Invalid i) : Arc(i) { }
43.238
43.239 - InArcIt(const Digraph& _graph, const Node& node)
43.240 - : digraph(&_graph) {
43.241 + InArcIt(const Graph& _graph, const Node& node)
43.242 + : graph(&_graph) {
43.243 _graph.firstIn(*this, node);
43.244 }
43.245
43.246 - InArcIt(const Digraph& _graph, const Arc& arc) :
43.247 - Arc(arc), digraph(&_graph) {}
43.248 + InArcIt(const Graph& _graph, const Arc& arc) :
43.249 + Arc(arc), graph(&_graph) {}
43.250
43.251 InArcIt& operator++() {
43.252 - digraph->nextIn(*this);
43.253 + graph->nextIn(*this);
43.254 return *this;
43.255 }
43.256
43.257 @@ -444,22 +443,22 @@
43.258
43.259
43.260 class EdgeIt : public Parent::Edge {
43.261 - const Digraph* digraph;
43.262 + const Graph* graph;
43.263 public:
43.264
43.265 EdgeIt() { }
43.266
43.267 EdgeIt(Invalid i) : Edge(i) { }
43.268
43.269 - explicit EdgeIt(const Digraph& _graph) : digraph(&_graph) {
43.270 + explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
43.271 _graph.first(static_cast<Edge&>(*this));
43.272 }
43.273
43.274 - EdgeIt(const Digraph& _graph, const Edge& e) :
43.275 - Edge(e), digraph(&_graph) { }
43.276 + EdgeIt(const Graph& _graph, const Edge& e) :
43.277 + Edge(e), graph(&_graph) { }
43.278
43.279 EdgeIt& operator++() {
43.280 - digraph->next(*this);
43.281 + graph->next(*this);
43.282 return *this;
43.283 }
43.284
43.285 @@ -467,7 +466,7 @@
43.286
43.287 class IncEdgeIt : public Parent::Edge {
43.288 friend class EdgeSetExtender;
43.289 - const Digraph* digraph;
43.290 + const Graph* graph;
43.291 bool direction;
43.292 public:
43.293
43.294 @@ -475,58 +474,58 @@
43.295
43.296 IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
43.297
43.298 - IncEdgeIt(const Digraph& _graph, const Node &n) : digraph(&_graph) {
43.299 + IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
43.300 _graph.firstInc(*this, direction, n);
43.301 }
43.302
43.303 - IncEdgeIt(const Digraph& _graph, const Edge &ue, const Node &n)
43.304 - : digraph(&_graph), Edge(ue) {
43.305 + IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n)
43.306 + : graph(&_graph), Edge(ue) {
43.307 direction = (_graph.source(ue) == n);
43.308 }
43.309
43.310 IncEdgeIt& operator++() {
43.311 - digraph->nextInc(*this, direction);
43.312 + graph->nextInc(*this, direction);
43.313 return *this;
43.314 }
43.315 };
43.316
43.317 - /// \brief Base node of the iterator
43.318 - ///
43.319 - /// Returns the base node (ie. the source in this case) of the iterator
43.320 + // \brief Base node of the iterator
43.321 + //
43.322 + // Returns the base node (ie. the source in this case) of the iterator
43.323 Node baseNode(const OutArcIt &e) const {
43.324 return Parent::source(static_cast<const Arc&>(e));
43.325 }
43.326 - /// \brief Running node of the iterator
43.327 - ///
43.328 - /// Returns the running node (ie. the target in this case) of the
43.329 - /// iterator
43.330 + // \brief Running node of the iterator
43.331 + //
43.332 + // Returns the running node (ie. the target in this case) of the
43.333 + // iterator
43.334 Node runningNode(const OutArcIt &e) const {
43.335 return Parent::target(static_cast<const Arc&>(e));
43.336 }
43.337
43.338 - /// \brief Base node of the iterator
43.339 - ///
43.340 - /// Returns the base node (ie. the target in this case) of the iterator
43.341 + // \brief Base node of the iterator
43.342 + //
43.343 + // Returns the base node (ie. the target in this case) of the iterator
43.344 Node baseNode(const InArcIt &e) const {
43.345 return Parent::target(static_cast<const Arc&>(e));
43.346 }
43.347 - /// \brief Running node of the iterator
43.348 - ///
43.349 - /// Returns the running node (ie. the source in this case) of the
43.350 - /// iterator
43.351 + // \brief Running node of the iterator
43.352 + //
43.353 + // Returns the running node (ie. the source in this case) of the
43.354 + // iterator
43.355 Node runningNode(const InArcIt &e) const {
43.356 return Parent::source(static_cast<const Arc&>(e));
43.357 }
43.358
43.359 - /// Base node of the iterator
43.360 - ///
43.361 - /// Returns the base node of the iterator
43.362 + // Base node of the iterator
43.363 + //
43.364 + // Returns the base node of the iterator
43.365 Node baseNode(const IncEdgeIt &e) const {
43.366 return e.direction ? u(e) : v(e);
43.367 }
43.368 - /// Running node of the iterator
43.369 - ///
43.370 - /// Returns the running node of the iterator
43.371 + // Running node of the iterator
43.372 + //
43.373 + // Returns the running node of the iterator
43.374 Node runningNode(const IncEdgeIt &e) const {
43.375 return e.direction ? v(e) : u(e);
43.376 }
43.377 @@ -534,14 +533,13 @@
43.378
43.379 template <typename _Value>
43.380 class ArcMap
43.381 - : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
43.382 + : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
43.383 + typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
43.384 +
43.385 public:
43.386 - typedef EdgeSetExtender Digraph;
43.387 - typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
43.388 -
43.389 - ArcMap(const Digraph& _g)
43.390 + explicit ArcMap(const Graph& _g)
43.391 : Parent(_g) {}
43.392 - ArcMap(const Digraph& _g, const _Value& _v)
43.393 + ArcMap(const Graph& _g, const _Value& _v)
43.394 : Parent(_g, _v) {}
43.395
43.396 ArcMap& operator=(const ArcMap& cmap) {
43.397 @@ -559,15 +557,14 @@
43.398
43.399 template <typename _Value>
43.400 class EdgeMap
43.401 - : public MapExtender<DefaultMap<Digraph, Edge, _Value> > {
43.402 + : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
43.403 + typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
43.404 +
43.405 public:
43.406 - typedef EdgeSetExtender Digraph;
43.407 - typedef MapExtender<DefaultMap<Digraph, Edge, _Value> > Parent;
43.408 -
43.409 - EdgeMap(const Digraph& _g)
43.410 + explicit EdgeMap(const Graph& _g)
43.411 : Parent(_g) {}
43.412
43.413 - EdgeMap(const Digraph& _g, const _Value& _v)
43.414 + EdgeMap(const Graph& _g, const _Value& _v)
43.415 : Parent(_g, _v) {}
43.416
43.417 EdgeMap& operator=(const EdgeMap& cmap) {
44.1 --- a/lemon/bits/graph_adaptor_extender.h Mon Jan 12 23:11:39 2009 +0100
44.2 +++ b/lemon/bits/graph_adaptor_extender.h Thu Nov 05 15:48:01 2009 +0100
44.3 @@ -22,15 +22,14 @@
44.4 #include <lemon/core.h>
44.5 #include <lemon/error.h>
44.6
44.7 -#include <lemon/bits/default_map.h>
44.8 -
44.9 namespace lemon {
44.10
44.11 template <typename _Digraph>
44.12 class DigraphAdaptorExtender : public _Digraph {
44.13 + typedef _Digraph Parent;
44.14 +
44.15 public:
44.16
44.17 - typedef _Digraph Parent;
44.18 typedef _Digraph Digraph;
44.19 typedef DigraphAdaptorExtender Adaptor;
44.20
44.21 @@ -175,9 +174,10 @@
44.22
44.23 template <typename _Graph>
44.24 class GraphAdaptorExtender : public _Graph {
44.25 + typedef _Graph Parent;
44.26 +
44.27 public:
44.28
44.29 - typedef _Graph Parent;
44.30 typedef _Graph Graph;
44.31 typedef GraphAdaptorExtender Adaptor;
44.32
45.1 --- a/lemon/bits/graph_extender.h Mon Jan 12 23:11:39 2009 +0100
45.2 +++ b/lemon/bits/graph_extender.h Thu Nov 05 15:48:01 2009 +0100
45.3 @@ -37,9 +37,10 @@
45.4 // \brief Extender for the digraph implementations
45.5 template <typename Base>
45.6 class DigraphExtender : public Base {
45.7 + typedef Base Parent;
45.8 +
45.9 public:
45.10
45.11 - typedef Base Parent;
45.12 typedef DigraphExtender Digraph;
45.13
45.14 // Base extensions
45.15 @@ -55,11 +56,11 @@
45.16 return Parent::maxArcId();
45.17 }
45.18
45.19 - Node fromId(int id, Node) const {
45.20 + static Node fromId(int id, Node) {
45.21 return Parent::nodeFromId(id);
45.22 }
45.23
45.24 - Arc fromId(int id, Arc) const {
45.25 + static Arc fromId(int id, Arc) {
45.26 return Parent::arcFromId(id);
45.27 }
45.28
45.29 @@ -218,10 +219,9 @@
45.30 template <typename _Value>
45.31 class NodeMap
45.32 : public MapExtender<DefaultMap<Digraph, Node, _Value> > {
45.33 - public:
45.34 - typedef DigraphExtender Digraph;
45.35 typedef MapExtender<DefaultMap<Digraph, Node, _Value> > Parent;
45.36
45.37 + public:
45.38 explicit NodeMap(const Digraph& digraph)
45.39 : Parent(digraph) {}
45.40 NodeMap(const Digraph& digraph, const _Value& value)
45.41 @@ -243,10 +243,9 @@
45.42 template <typename _Value>
45.43 class ArcMap
45.44 : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
45.45 - public:
45.46 - typedef DigraphExtender Digraph;
45.47 typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
45.48
45.49 + public:
45.50 explicit ArcMap(const Digraph& digraph)
45.51 : Parent(digraph) {}
45.52 ArcMap(const Digraph& digraph, const _Value& value)
45.53 @@ -330,9 +329,10 @@
45.54 // \brief Extender for the Graphs
45.55 template <typename Base>
45.56 class GraphExtender : public Base {
45.57 + typedef Base Parent;
45.58 +
45.59 public:
45.60
45.61 - typedef Base Parent;
45.62 typedef GraphExtender Graph;
45.63
45.64 typedef True UndirectedTag;
45.65 @@ -355,15 +355,15 @@
45.66 return Parent::maxEdgeId();
45.67 }
45.68
45.69 - Node fromId(int id, Node) const {
45.70 + static Node fromId(int id, Node) {
45.71 return Parent::nodeFromId(id);
45.72 }
45.73
45.74 - Arc fromId(int id, Arc) const {
45.75 + static Arc fromId(int id, Arc) {
45.76 return Parent::arcFromId(id);
45.77 }
45.78
45.79 - Edge fromId(int id, Edge) const {
45.80 + static Edge fromId(int id, Edge) {
45.81 return Parent::edgeFromId(id);
45.82 }
45.83
45.84 @@ -601,11 +601,10 @@
45.85 template <typename _Value>
45.86 class NodeMap
45.87 : public MapExtender<DefaultMap<Graph, Node, _Value> > {
45.88 - public:
45.89 - typedef GraphExtender Graph;
45.90 typedef MapExtender<DefaultMap<Graph, Node, _Value> > Parent;
45.91
45.92 - NodeMap(const Graph& graph)
45.93 + public:
45.94 + explicit NodeMap(const Graph& graph)
45.95 : Parent(graph) {}
45.96 NodeMap(const Graph& graph, const _Value& value)
45.97 : Parent(graph, value) {}
45.98 @@ -626,11 +625,10 @@
45.99 template <typename _Value>
45.100 class ArcMap
45.101 : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
45.102 - public:
45.103 - typedef GraphExtender Graph;
45.104 typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
45.105
45.106 - ArcMap(const Graph& graph)
45.107 + public:
45.108 + explicit ArcMap(const Graph& graph)
45.109 : Parent(graph) {}
45.110 ArcMap(const Graph& graph, const _Value& value)
45.111 : Parent(graph, value) {}
45.112 @@ -651,11 +649,10 @@
45.113 template <typename _Value>
45.114 class EdgeMap
45.115 : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
45.116 - public:
45.117 - typedef GraphExtender Graph;
45.118 typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
45.119
45.120 - EdgeMap(const Graph& graph)
45.121 + public:
45.122 + explicit EdgeMap(const Graph& graph)
45.123 : Parent(graph) {}
45.124
45.125 EdgeMap(const Graph& graph, const _Value& value)
46.1 --- a/lemon/bits/map_extender.h Mon Jan 12 23:11:39 2009 +0100
46.2 +++ b/lemon/bits/map_extender.h Thu Nov 05 15:48:01 2009 +0100
46.3 @@ -36,17 +36,20 @@
46.4 // \brief Extender for maps
46.5 template <typename _Map>
46.6 class MapExtender : public _Map {
46.7 + typedef _Map Parent;
46.8 + typedef typename Parent::GraphType GraphType;
46.9 +
46.10 public:
46.11
46.12 - typedef _Map Parent;
46.13 typedef MapExtender Map;
46.14 -
46.15 -
46.16 - typedef typename Parent::Graph Graph;
46.17 typedef typename Parent::Key Item;
46.18
46.19 typedef typename Parent::Key Key;
46.20 typedef typename Parent::Value Value;
46.21 + typedef typename Parent::Reference Reference;
46.22 + typedef typename Parent::ConstReference ConstReference;
46.23 +
46.24 + typedef typename Parent::ReferenceMapTag ReferenceMapTag;
46.25
46.26 class MapIt;
46.27 class ConstMapIt;
46.28 @@ -56,10 +59,10 @@
46.29
46.30 public:
46.31
46.32 - MapExtender(const Graph& graph)
46.33 + MapExtender(const GraphType& graph)
46.34 : Parent(graph) {}
46.35
46.36 - MapExtender(const Graph& graph, const Value& value)
46.37 + MapExtender(const GraphType& graph, const Value& value)
46.38 : Parent(graph, value) {}
46.39
46.40 private:
46.41 @@ -75,9 +78,10 @@
46.42
46.43 public:
46.44 class MapIt : public Item {
46.45 + typedef Item Parent;
46.46 +
46.47 public:
46.48
46.49 - typedef Item Parent;
46.50 typedef typename Map::Value Value;
46.51
46.52 MapIt() {}
46.53 @@ -114,10 +118,10 @@
46.54 };
46.55
46.56 class ConstMapIt : public Item {
46.57 + typedef Item Parent;
46.58 +
46.59 public:
46.60
46.61 - typedef Item Parent;
46.62 -
46.63 typedef typename Map::Value Value;
46.64
46.65 ConstMapIt() {}
46.66 @@ -145,10 +149,10 @@
46.67 };
46.68
46.69 class ItemIt : public Item {
46.70 + typedef Item Parent;
46.71 +
46.72 public:
46.73
46.74 - typedef Item Parent;
46.75 -
46.76 ItemIt() {}
46.77
46.78 ItemIt(Invalid i) : Parent(i) { }
46.79 @@ -176,17 +180,20 @@
46.80 // \brief Extender for maps which use a subset of the items.
46.81 template <typename _Graph, typename _Map>
46.82 class SubMapExtender : public _Map {
46.83 + typedef _Map Parent;
46.84 + typedef _Graph GraphType;
46.85 +
46.86 public:
46.87
46.88 - typedef _Map Parent;
46.89 typedef SubMapExtender Map;
46.90 -
46.91 - typedef _Graph Graph;
46.92 -
46.93 typedef typename Parent::Key Item;
46.94
46.95 typedef typename Parent::Key Key;
46.96 typedef typename Parent::Value Value;
46.97 + typedef typename Parent::Reference Reference;
46.98 + typedef typename Parent::ConstReference ConstReference;
46.99 +
46.100 + typedef typename Parent::ReferenceMapTag ReferenceMapTag;
46.101
46.102 class MapIt;
46.103 class ConstMapIt;
46.104 @@ -196,10 +203,10 @@
46.105
46.106 public:
46.107
46.108 - SubMapExtender(const Graph& _graph)
46.109 + SubMapExtender(const GraphType& _graph)
46.110 : Parent(_graph), graph(_graph) {}
46.111
46.112 - SubMapExtender(const Graph& _graph, const Value& _value)
46.113 + SubMapExtender(const GraphType& _graph, const Value& _value)
46.114 : Parent(_graph, _value), graph(_graph) {}
46.115
46.116 private:
46.117 @@ -219,9 +226,9 @@
46.118
46.119 public:
46.120 class MapIt : public Item {
46.121 + typedef Item Parent;
46.122 +
46.123 public:
46.124 -
46.125 - typedef Item Parent;
46.126 typedef typename Map::Value Value;
46.127
46.128 MapIt() {}
46.129 @@ -258,10 +265,10 @@
46.130 };
46.131
46.132 class ConstMapIt : public Item {
46.133 + typedef Item Parent;
46.134 +
46.135 public:
46.136
46.137 - typedef Item Parent;
46.138 -
46.139 typedef typename Map::Value Value;
46.140
46.141 ConstMapIt() {}
46.142 @@ -289,10 +296,10 @@
46.143 };
46.144
46.145 class ItemIt : public Item {
46.146 + typedef Item Parent;
46.147 +
46.148 public:
46.149
46.150 - typedef Item Parent;
46.151 -
46.152 ItemIt() {}
46.153
46.154 ItemIt(Invalid i) : Parent(i) { }
46.155 @@ -316,7 +323,7 @@
46.156
46.157 private:
46.158
46.159 - const Graph& graph;
46.160 + const GraphType& graph;
46.161
46.162 };
46.163
47.1 --- a/lemon/bits/path_dump.h Mon Jan 12 23:11:39 2009 +0100
47.2 +++ b/lemon/bits/path_dump.h Thu Nov 05 15:48:01 2009 +0100
47.3 @@ -16,8 +16,11 @@
47.4 *
47.5 */
47.6
47.7 -#ifndef LEMON_BITS_PRED_MAP_PATH_H
47.8 -#define LEMON_BITS_PRED_MAP_PATH_H
47.9 +#ifndef LEMON_BITS_PATH_DUMP_H
47.10 +#define LEMON_BITS_PATH_DUMP_H
47.11 +
47.12 +#include <lemon/core.h>
47.13 +#include <lemon/concept_check.h>
47.14
47.15 namespace lemon {
47.16
48.1 --- a/lemon/bits/solver_bits.h Mon Jan 12 23:11:39 2009 +0100
48.2 +++ b/lemon/bits/solver_bits.h Thu Nov 05 15:48:01 2009 +0100
48.3 @@ -19,6 +19,8 @@
48.4 #ifndef LEMON_BITS_SOLVER_BITS_H
48.5 #define LEMON_BITS_SOLVER_BITS_H
48.6
48.7 +#include <vector>
48.8 +
48.9 namespace lemon {
48.10
48.11 namespace _solver_bits {
49.1 --- a/lemon/bits/traits.h Mon Jan 12 23:11:39 2009 +0100
49.2 +++ b/lemon/bits/traits.h Thu Nov 05 15:48:01 2009 +0100
49.3 @@ -29,117 +29,123 @@
49.4
49.5 struct InvalidType {};
49.6
49.7 - template <typename _Graph, typename _Item>
49.8 + template <typename GR, typename _Item>
49.9 class ItemSetTraits {};
49.10
49.11
49.12 - template <typename Graph, typename Enable = void>
49.13 + template <typename GR, typename Enable = void>
49.14 struct NodeNotifierIndicator {
49.15 typedef InvalidType Type;
49.16 };
49.17 - template <typename Graph>
49.18 + template <typename GR>
49.19 struct NodeNotifierIndicator<
49.20 - Graph,
49.21 - typename enable_if<typename Graph::NodeNotifier::Notifier, void>::type
49.22 + GR,
49.23 + typename enable_if<typename GR::NodeNotifier::Notifier, void>::type
49.24 > {
49.25 - typedef typename Graph::NodeNotifier Type;
49.26 + typedef typename GR::NodeNotifier Type;
49.27 };
49.28
49.29 - template <typename _Graph>
49.30 - class ItemSetTraits<_Graph, typename _Graph::Node> {
49.31 + template <typename GR>
49.32 + class ItemSetTraits<GR, typename GR::Node> {
49.33 public:
49.34
49.35 - typedef _Graph Graph;
49.36 + typedef GR Graph;
49.37 + typedef GR Digraph;
49.38
49.39 - typedef typename Graph::Node Item;
49.40 - typedef typename Graph::NodeIt ItemIt;
49.41 + typedef typename GR::Node Item;
49.42 + typedef typename GR::NodeIt ItemIt;
49.43
49.44 - typedef typename NodeNotifierIndicator<Graph>::Type ItemNotifier;
49.45 + typedef typename NodeNotifierIndicator<GR>::Type ItemNotifier;
49.46
49.47 - template <typename _Value>
49.48 - class Map : public Graph::template NodeMap<_Value> {
49.49 + template <typename V>
49.50 + class Map : public GR::template NodeMap<V> {
49.51 + typedef typename GR::template NodeMap<V> Parent;
49.52 +
49.53 public:
49.54 - typedef typename Graph::template NodeMap<_Value> Parent;
49.55 - typedef typename Graph::template NodeMap<_Value> Type;
49.56 + typedef typename GR::template NodeMap<V> Type;
49.57 typedef typename Parent::Value Value;
49.58
49.59 - Map(const Graph& _digraph) : Parent(_digraph) {}
49.60 - Map(const Graph& _digraph, const Value& _value)
49.61 + Map(const GR& _digraph) : Parent(_digraph) {}
49.62 + Map(const GR& _digraph, const Value& _value)
49.63 : Parent(_digraph, _value) {}
49.64
49.65 };
49.66
49.67 };
49.68
49.69 - template <typename Graph, typename Enable = void>
49.70 + template <typename GR, typename Enable = void>
49.71 struct ArcNotifierIndicator {
49.72 typedef InvalidType Type;
49.73 };
49.74 - template <typename Graph>
49.75 + template <typename GR>
49.76 struct ArcNotifierIndicator<
49.77 - Graph,
49.78 - typename enable_if<typename Graph::ArcNotifier::Notifier, void>::type
49.79 + GR,
49.80 + typename enable_if<typename GR::ArcNotifier::Notifier, void>::type
49.81 > {
49.82 - typedef typename Graph::ArcNotifier Type;
49.83 + typedef typename GR::ArcNotifier Type;
49.84 };
49.85
49.86 - template <typename _Graph>
49.87 - class ItemSetTraits<_Graph, typename _Graph::Arc> {
49.88 + template <typename GR>
49.89 + class ItemSetTraits<GR, typename GR::Arc> {
49.90 public:
49.91
49.92 - typedef _Graph Graph;
49.93 + typedef GR Graph;
49.94 + typedef GR Digraph;
49.95
49.96 - typedef typename Graph::Arc Item;
49.97 - typedef typename Graph::ArcIt ItemIt;
49.98 + typedef typename GR::Arc Item;
49.99 + typedef typename GR::ArcIt ItemIt;
49.100
49.101 - typedef typename ArcNotifierIndicator<Graph>::Type ItemNotifier;
49.102 + typedef typename ArcNotifierIndicator<GR>::Type ItemNotifier;
49.103
49.104 - template <typename _Value>
49.105 - class Map : public Graph::template ArcMap<_Value> {
49.106 + template <typename V>
49.107 + class Map : public GR::template ArcMap<V> {
49.108 + typedef typename GR::template ArcMap<V> Parent;
49.109 +
49.110 public:
49.111 - typedef typename Graph::template ArcMap<_Value> Parent;
49.112 - typedef typename Graph::template ArcMap<_Value> Type;
49.113 + typedef typename GR::template ArcMap<V> Type;
49.114 typedef typename Parent::Value Value;
49.115
49.116 - Map(const Graph& _digraph) : Parent(_digraph) {}
49.117 - Map(const Graph& _digraph, const Value& _value)
49.118 + Map(const GR& _digraph) : Parent(_digraph) {}
49.119 + Map(const GR& _digraph, const Value& _value)
49.120 : Parent(_digraph, _value) {}
49.121 };
49.122
49.123 };
49.124
49.125 - template <typename Graph, typename Enable = void>
49.126 + template <typename GR, typename Enable = void>
49.127 struct EdgeNotifierIndicator {
49.128 typedef InvalidType Type;
49.129 };
49.130 - template <typename Graph>
49.131 + template <typename GR>
49.132 struct EdgeNotifierIndicator<
49.133 - Graph,
49.134 - typename enable_if<typename Graph::EdgeNotifier::Notifier, void>::type
49.135 + GR,
49.136 + typename enable_if<typename GR::EdgeNotifier::Notifier, void>::type
49.137 > {
49.138 - typedef typename Graph::EdgeNotifier Type;
49.139 + typedef typename GR::EdgeNotifier Type;
49.140 };
49.141
49.142 - template <typename _Graph>
49.143 - class ItemSetTraits<_Graph, typename _Graph::Edge> {
49.144 + template <typename GR>
49.145 + class ItemSetTraits<GR, typename GR::Edge> {
49.146 public:
49.147
49.148 - typedef _Graph Graph;
49.149 + typedef GR Graph;
49.150 + typedef GR Digraph;
49.151
49.152 - typedef typename Graph::Edge Item;
49.153 - typedef typename Graph::EdgeIt ItemIt;
49.154 + typedef typename GR::Edge Item;
49.155 + typedef typename GR::EdgeIt ItemIt;
49.156
49.157 - typedef typename EdgeNotifierIndicator<Graph>::Type ItemNotifier;
49.158 + typedef typename EdgeNotifierIndicator<GR>::Type ItemNotifier;
49.159
49.160 - template <typename _Value>
49.161 - class Map : public Graph::template EdgeMap<_Value> {
49.162 + template <typename V>
49.163 + class Map : public GR::template EdgeMap<V> {
49.164 + typedef typename GR::template EdgeMap<V> Parent;
49.165 +
49.166 public:
49.167 - typedef typename Graph::template EdgeMap<_Value> Parent;
49.168 - typedef typename Graph::template EdgeMap<_Value> Type;
49.169 + typedef typename GR::template EdgeMap<V> Type;
49.170 typedef typename Parent::Value Value;
49.171
49.172 - Map(const Graph& _digraph) : Parent(_digraph) {}
49.173 - Map(const Graph& _digraph, const Value& _value)
49.174 + Map(const GR& _digraph) : Parent(_digraph) {}
49.175 + Map(const GR& _digraph, const Value& _value)
49.176 : Parent(_digraph, _value) {}
49.177 };
49.178
49.179 @@ -204,93 +210,93 @@
49.180
49.181 // Indicators for the tags
49.182
49.183 - template <typename Graph, typename Enable = void>
49.184 + template <typename GR, typename Enable = void>
49.185 struct NodeNumTagIndicator {
49.186 static const bool value = false;
49.187 };
49.188
49.189 - template <typename Graph>
49.190 + template <typename GR>
49.191 struct NodeNumTagIndicator<
49.192 - Graph,
49.193 - typename enable_if<typename Graph::NodeNumTag, void>::type
49.194 + GR,
49.195 + typename enable_if<typename GR::NodeNumTag, void>::type
49.196 > {
49.197 static const bool value = true;
49.198 };
49.199
49.200 - template <typename Graph, typename Enable = void>
49.201 + template <typename GR, typename Enable = void>
49.202 struct ArcNumTagIndicator {
49.203 static const bool value = false;
49.204 };
49.205
49.206 - template <typename Graph>
49.207 + template <typename GR>
49.208 struct ArcNumTagIndicator<
49.209 - Graph,
49.210 - typename enable_if<typename Graph::ArcNumTag, void>::type
49.211 + GR,
49.212 + typename enable_if<typename GR::ArcNumTag, void>::type
49.213 > {
49.214 static const bool value = true;
49.215 };
49.216
49.217 - template <typename Graph, typename Enable = void>
49.218 + template <typename GR, typename Enable = void>
49.219 struct EdgeNumTagIndicator {
49.220 static const bool value = false;
49.221 };
49.222
49.223 - template <typename Graph>
49.224 + template <typename GR>
49.225 struct EdgeNumTagIndicator<
49.226 - Graph,
49.227 - typename enable_if<typename Graph::EdgeNumTag, void>::type
49.228 + GR,
49.229 + typename enable_if<typename GR::EdgeNumTag, void>::type
49.230 > {
49.231 static const bool value = true;
49.232 };
49.233
49.234 - template <typename Graph, typename Enable = void>
49.235 + template <typename GR, typename Enable = void>
49.236 struct FindArcTagIndicator {
49.237 static const bool value = false;
49.238 };
49.239
49.240 - template <typename Graph>
49.241 + template <typename GR>
49.242 struct FindArcTagIndicator<
49.243 - Graph,
49.244 - typename enable_if<typename Graph::FindArcTag, void>::type
49.245 + GR,
49.246 + typename enable_if<typename GR::FindArcTag, void>::type
49.247 > {
49.248 static const bool value = true;
49.249 };
49.250
49.251 - template <typename Graph, typename Enable = void>
49.252 + template <typename GR, typename Enable = void>
49.253 struct FindEdgeTagIndicator {
49.254 static const bool value = false;
49.255 };
49.256
49.257 - template <typename Graph>
49.258 + template <typename GR>
49.259 struct FindEdgeTagIndicator<
49.260 - Graph,
49.261 - typename enable_if<typename Graph::FindEdgeTag, void>::type
49.262 + GR,
49.263 + typename enable_if<typename GR::FindEdgeTag, void>::type
49.264 > {
49.265 static const bool value = true;
49.266 };
49.267
49.268 - template <typename Graph, typename Enable = void>
49.269 + template <typename GR, typename Enable = void>
49.270 struct UndirectedTagIndicator {
49.271 static const bool value = false;
49.272 };
49.273
49.274 - template <typename Graph>
49.275 + template <typename GR>
49.276 struct UndirectedTagIndicator<
49.277 - Graph,
49.278 - typename enable_if<typename Graph::UndirectedTag, void>::type
49.279 + GR,
49.280 + typename enable_if<typename GR::UndirectedTag, void>::type
49.281 > {
49.282 static const bool value = true;
49.283 };
49.284
49.285 - template <typename Graph, typename Enable = void>
49.286 + template <typename GR, typename Enable = void>
49.287 struct BuildTagIndicator {
49.288 static const bool value = false;
49.289 };
49.290
49.291 - template <typename Graph>
49.292 + template <typename GR>
49.293 struct BuildTagIndicator<
49.294 - Graph,
49.295 - typename enable_if<typename Graph::BuildTag, void>::type
49.296 + GR,
49.297 + typename enable_if<typename GR::BuildTag, void>::type
49.298 > {
49.299 static const bool value = true;
49.300 };
50.1 --- a/lemon/bits/vector_map.h Mon Jan 12 23:11:39 2009 +0100
50.2 +++ b/lemon/bits/vector_map.h Thu Nov 05 15:48:01 2009 +0100
50.3 @@ -56,7 +56,7 @@
50.4 public:
50.5
50.6 // The graph type of the map.
50.7 - typedef _Graph Graph;
50.8 + typedef _Graph GraphType;
50.9 // The item type of the map.
50.10 typedef _Item Item;
50.11 // The reference map tag.
50.12 @@ -72,20 +72,24 @@
50.13
50.14 // The map type.
50.15 typedef VectorMap Map;
50.16 - // The base class of the map.
50.17 - typedef typename Notifier::ObserverBase Parent;
50.18
50.19 // The reference type of the map;
50.20 typedef typename Container::reference Reference;
50.21 // The const reference type of the map;
50.22 typedef typename Container::const_reference ConstReference;
50.23
50.24 + private:
50.25 +
50.26 + // The base class of the map.
50.27 + typedef typename Notifier::ObserverBase Parent;
50.28 +
50.29 + public:
50.30
50.31 // \brief Constructor to attach the new map into the notifier.
50.32 //
50.33 // It constructs a map and attachs it into the notifier.
50.34 // It adds all the items of the graph to the map.
50.35 - VectorMap(const Graph& graph) {
50.36 + VectorMap(const GraphType& graph) {
50.37 Parent::attach(graph.notifier(Item()));
50.38 container.resize(Parent::notifier()->maxId() + 1);
50.39 }
50.40 @@ -94,7 +98,7 @@
50.41 //
50.42 // It constructs a map uses a given value to initialize the map.
50.43 // It adds all the items of the graph to the map.
50.44 - VectorMap(const Graph& graph, const Value& value) {
50.45 + VectorMap(const GraphType& graph, const Value& value) {
50.46 Parent::attach(graph.notifier(Item()));
50.47 container.resize(Parent::notifier()->maxId() + 1, value);
50.48 }
50.49 @@ -124,7 +128,7 @@
50.50
50.51 // \brief Template assign operator.
50.52 //
50.53 - // The given parameter should be conform to the ReadMap
50.54 + // The given parameter should conform to the ReadMap
50.55 // concecpt and could be indiced by the current item set of
50.56 // the NodeMap. In this case the value for each item
50.57 // is assigned by the value of the given ReadMap.
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
51.2 +++ b/lemon/bits/windows.cc Thu Nov 05 15:48:01 2009 +0100
51.3 @@ -0,0 +1,132 @@
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 +///\file
51.23 +///\brief Some basic non-inline functions and static global data.
51.24 +
51.25 +#include<lemon/bits/windows.h>
51.26 +
51.27 +#ifdef WIN32
51.28 +#ifndef WIN32_LEAN_AND_MEAN
51.29 +#define WIN32_LEAN_AND_MEAN
51.30 +#endif
51.31 +#ifndef NOMINMAX
51.32 +#define NOMINMAX
51.33 +#endif
51.34 +#ifdef UNICODE
51.35 +#undef UNICODE
51.36 +#endif
51.37 +#include <windows.h>
51.38 +#ifdef LOCALE_INVARIANT
51.39 +#define MY_LOCALE LOCALE_INVARIANT
51.40 +#else
51.41 +#define MY_LOCALE LOCALE_NEUTRAL
51.42 +#endif
51.43 +#else
51.44 +#include <unistd.h>
51.45 +#include <ctime>
51.46 +#include <sys/times.h>
51.47 +#include <sys/time.h>
51.48 +#endif
51.49 +
51.50 +#include <cmath>
51.51 +#include <sstream>
51.52 +
51.53 +namespace lemon {
51.54 + namespace bits {
51.55 + void getWinProcTimes(double &rtime,
51.56 + double &utime, double &stime,
51.57 + double &cutime, double &cstime)
51.58 + {
51.59 +#ifdef WIN32
51.60 + static const double ch = 4294967296.0e-7;
51.61 + static const double cl = 1.0e-7;
51.62 +
51.63 + FILETIME system;
51.64 + GetSystemTimeAsFileTime(&system);
51.65 + rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
51.66 +
51.67 + FILETIME create, exit, kernel, user;
51.68 + if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
51.69 + utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
51.70 + stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
51.71 + cutime = 0;
51.72 + cstime = 0;
51.73 + } else {
51.74 + rtime = 0;
51.75 + utime = 0;
51.76 + stime = 0;
51.77 + cutime = 0;
51.78 + cstime = 0;
51.79 + }
51.80 +#else
51.81 + timeval tv;
51.82 + gettimeofday(&tv, 0);
51.83 + rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
51.84 +
51.85 + tms ts;
51.86 + double tck=sysconf(_SC_CLK_TCK);
51.87 + times(&ts);
51.88 + utime=ts.tms_utime/tck;
51.89 + stime=ts.tms_stime/tck;
51.90 + cutime=ts.tms_cutime/tck;
51.91 + cstime=ts.tms_cstime/tck;
51.92 +#endif
51.93 + }
51.94 +
51.95 + std::string getWinFormattedDate()
51.96 + {
51.97 + std::ostringstream os;
51.98 +#ifdef WIN32
51.99 + SYSTEMTIME time;
51.100 + GetSystemTime(&time);
51.101 + char buf1[11], buf2[9], buf3[5];
51.102 + if (GetDateFormat(MY_LOCALE, 0, &time,
51.103 + ("ddd MMM dd"), buf1, 11) &&
51.104 + GetTimeFormat(MY_LOCALE, 0, &time,
51.105 + ("HH':'mm':'ss"), buf2, 9) &&
51.106 + GetDateFormat(MY_LOCALE, 0, &time,
51.107 + ("yyyy"), buf3, 5)) {
51.108 + os << buf1 << ' ' << buf2 << ' ' << buf3;
51.109 + }
51.110 + else os << "unknown";
51.111 +#else
51.112 + timeval tv;
51.113 + gettimeofday(&tv, 0);
51.114 +
51.115 + char cbuf[26];
51.116 + ctime_r(&tv.tv_sec,cbuf);
51.117 + os << cbuf;
51.118 +#endif
51.119 + return os.str();
51.120 + }
51.121 +
51.122 + int getWinRndSeed()
51.123 + {
51.124 +#ifdef WIN32
51.125 + FILETIME time;
51.126 + GetSystemTimeAsFileTime(&time);
51.127 + return GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime;
51.128 +#else
51.129 + timeval tv;
51.130 + gettimeofday(&tv, 0);
51.131 + return getpid() + tv.tv_sec + tv.tv_usec;
51.132 +#endif
51.133 + }
51.134 + }
51.135 +}
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
52.2 +++ b/lemon/bits/windows.h Thu Nov 05 15:48:01 2009 +0100
52.3 @@ -0,0 +1,34 @@
52.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
52.5 + *
52.6 + * This file is a part of LEMON, a generic C++ optimization library.
52.7 + *
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 + * Permission to use, modify and distribute this software is granted
52.13 + * provided that this copyright notice appears in all copies. For
52.14 + * precise terms see the accompanying LICENSE file.
52.15 + *
52.16 + * This software is provided "AS IS" with no warranty of any kind,
52.17 + * express or implied, and with no claim as to its suitability for any
52.18 + * purpose.
52.19 + *
52.20 + */
52.21 +
52.22 +#ifndef LEMON_BITS_WINDOWS_H
52.23 +#define LEMON_BITS_WINDOWS_H
52.24 +
52.25 +#include <string>
52.26 +
52.27 +namespace lemon {
52.28 + namespace bits {
52.29 + void getWinProcTimes(double &rtime,
52.30 + double &utime, double &stime,
52.31 + double &cutime, double &cstime);
52.32 + std::string getWinFormattedDate();
52.33 + int getWinRndSeed();
52.34 + }
52.35 +}
52.36 +
52.37 +#endif
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
53.2 +++ b/lemon/bucket_heap.h Thu Nov 05 15:48:01 2009 +0100
53.3 @@ -0,0 +1,594 @@
53.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
53.5 + *
53.6 + * This file is a part of LEMON, a generic C++ optimization library.
53.7 + *
53.8 + * Copyright (C) 2003-2009
53.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
53.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
53.11 + *
53.12 + * Permission to use, modify and distribute this software is granted
53.13 + * provided that this copyright notice appears in all copies. For
53.14 + * precise terms see the accompanying LICENSE file.
53.15 + *
53.16 + * This software is provided "AS IS" with no warranty of any kind,
53.17 + * express or implied, and with no claim as to its suitability for any
53.18 + * purpose.
53.19 + *
53.20 + */
53.21 +
53.22 +#ifndef LEMON_BUCKET_HEAP_H
53.23 +#define LEMON_BUCKET_HEAP_H
53.24 +
53.25 +///\ingroup heaps
53.26 +///\file
53.27 +///\brief Bucket heap implementation.
53.28 +
53.29 +#include <vector>
53.30 +#include <utility>
53.31 +#include <functional>
53.32 +
53.33 +namespace lemon {
53.34 +
53.35 + namespace _bucket_heap_bits {
53.36 +
53.37 + template <bool MIN>
53.38 + struct DirectionTraits {
53.39 + static bool less(int left, int right) {
53.40 + return left < right;
53.41 + }
53.42 + static void increase(int& value) {
53.43 + ++value;
53.44 + }
53.45 + };
53.46 +
53.47 + template <>
53.48 + struct DirectionTraits<false> {
53.49 + static bool less(int left, int right) {
53.50 + return left > right;
53.51 + }
53.52 + static void increase(int& value) {
53.53 + --value;
53.54 + }
53.55 + };
53.56 +
53.57 + }
53.58 +
53.59 + /// \ingroup heaps
53.60 + ///
53.61 + /// \brief Bucket heap data structure.
53.62 + ///
53.63 + /// This class implements the \e bucket \e heap data structure.
53.64 + /// It practically conforms to the \ref concepts::Heap "heap concept",
53.65 + /// but it has some limitations.
53.66 + ///
53.67 + /// The bucket heap is a very simple structure. It can store only
53.68 + /// \c int priorities and it maintains a list of items for each priority
53.69 + /// in the range <tt>[0..C)</tt>. So it should only be used when the
53.70 + /// priorities are small. It is not intended to use as a Dijkstra heap.
53.71 + ///
53.72 + /// \tparam IM A read-writable item map with \c int values, used
53.73 + /// internally to handle the cross references.
53.74 + /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
53.75 + /// The default is \e min-heap. If this parameter is set to \c false,
53.76 + /// then the comparison is reversed, so the top(), prio() and pop()
53.77 + /// functions deal with the item having maximum priority instead of the
53.78 + /// minimum.
53.79 + ///
53.80 + /// \sa SimpleBucketHeap
53.81 + template <typename IM, bool MIN = true>
53.82 + class BucketHeap {
53.83 +
53.84 + public:
53.85 +
53.86 + /// Type of the item-int map.
53.87 + typedef IM ItemIntMap;
53.88 + /// Type of the priorities.
53.89 + typedef int Prio;
53.90 + /// Type of the items stored in the heap.
53.91 + typedef typename ItemIntMap::Key Item;
53.92 + /// Type of the item-priority pairs.
53.93 + typedef std::pair<Item,Prio> Pair;
53.94 +
53.95 + private:
53.96 +
53.97 + typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
53.98 +
53.99 + public:
53.100 +
53.101 + /// \brief Type to represent the states of the items.
53.102 + ///
53.103 + /// Each item has a state associated to it. It can be "in heap",
53.104 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
53.105 + /// heap's point of view, but may be useful to the user.
53.106 + ///
53.107 + /// The item-int map must be initialized in such way that it assigns
53.108 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
53.109 + enum State {
53.110 + IN_HEAP = 0, ///< = 0.
53.111 + PRE_HEAP = -1, ///< = -1.
53.112 + POST_HEAP = -2 ///< = -2.
53.113 + };
53.114 +
53.115 + public:
53.116 +
53.117 + /// \brief Constructor.
53.118 + ///
53.119 + /// Constructor.
53.120 + /// \param map A map that assigns \c int values to the items.
53.121 + /// It is used internally to handle the cross references.
53.122 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
53.123 + explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
53.124 +
53.125 + /// \brief The number of items stored in the heap.
53.126 + ///
53.127 + /// This function returns the number of items stored in the heap.
53.128 + int size() const { return _data.size(); }
53.129 +
53.130 + /// \brief Check if the heap is empty.
53.131 + ///
53.132 + /// This function returns \c true if the heap is empty.
53.133 + bool empty() const { return _data.empty(); }
53.134 +
53.135 + /// \brief Make the heap empty.
53.136 + ///
53.137 + /// This functon makes the heap empty.
53.138 + /// It does not change the cross reference map. If you want to reuse
53.139 + /// a heap that is not surely empty, you should first clear it and
53.140 + /// then you should set the cross reference map to \c PRE_HEAP
53.141 + /// for each item.
53.142 + void clear() {
53.143 + _data.clear(); _first.clear(); _minimum = 0;
53.144 + }
53.145 +
53.146 + private:
53.147 +
53.148 + void relocateLast(int idx) {
53.149 + if (idx + 1 < int(_data.size())) {
53.150 + _data[idx] = _data.back();
53.151 + if (_data[idx].prev != -1) {
53.152 + _data[_data[idx].prev].next = idx;
53.153 + } else {
53.154 + _first[_data[idx].value] = idx;
53.155 + }
53.156 + if (_data[idx].next != -1) {
53.157 + _data[_data[idx].next].prev = idx;
53.158 + }
53.159 + _iim[_data[idx].item] = idx;
53.160 + }
53.161 + _data.pop_back();
53.162 + }
53.163 +
53.164 + void unlace(int idx) {
53.165 + if (_data[idx].prev != -1) {
53.166 + _data[_data[idx].prev].next = _data[idx].next;
53.167 + } else {
53.168 + _first[_data[idx].value] = _data[idx].next;
53.169 + }
53.170 + if (_data[idx].next != -1) {
53.171 + _data[_data[idx].next].prev = _data[idx].prev;
53.172 + }
53.173 + }
53.174 +
53.175 + void lace(int idx) {
53.176 + if (int(_first.size()) <= _data[idx].value) {
53.177 + _first.resize(_data[idx].value + 1, -1);
53.178 + }
53.179 + _data[idx].next = _first[_data[idx].value];
53.180 + if (_data[idx].next != -1) {
53.181 + _data[_data[idx].next].prev = idx;
53.182 + }
53.183 + _first[_data[idx].value] = idx;
53.184 + _data[idx].prev = -1;
53.185 + }
53.186 +
53.187 + public:
53.188 +
53.189 + /// \brief Insert a pair of item and priority into the heap.
53.190 + ///
53.191 + /// This function inserts \c p.first to the heap with priority
53.192 + /// \c p.second.
53.193 + /// \param p The pair to insert.
53.194 + /// \pre \c p.first must not be stored in the heap.
53.195 + void push(const Pair& p) {
53.196 + push(p.first, p.second);
53.197 + }
53.198 +
53.199 + /// \brief Insert an item into the heap with the given priority.
53.200 + ///
53.201 + /// This function inserts the given item into the heap with the
53.202 + /// given priority.
53.203 + /// \param i The item to insert.
53.204 + /// \param p The priority of the item.
53.205 + /// \pre \e i must not be stored in the heap.
53.206 + void push(const Item &i, const Prio &p) {
53.207 + int idx = _data.size();
53.208 + _iim[i] = idx;
53.209 + _data.push_back(BucketItem(i, p));
53.210 + lace(idx);
53.211 + if (Direction::less(p, _minimum)) {
53.212 + _minimum = p;
53.213 + }
53.214 + }
53.215 +
53.216 + /// \brief Return the item having minimum priority.
53.217 + ///
53.218 + /// This function returns the item having minimum priority.
53.219 + /// \pre The heap must be non-empty.
53.220 + Item top() const {
53.221 + while (_first[_minimum] == -1) {
53.222 + Direction::increase(_minimum);
53.223 + }
53.224 + return _data[_first[_minimum]].item;
53.225 + }
53.226 +
53.227 + /// \brief The minimum priority.
53.228 + ///
53.229 + /// This function returns the minimum priority.
53.230 + /// \pre The heap must be non-empty.
53.231 + Prio prio() const {
53.232 + while (_first[_minimum] == -1) {
53.233 + Direction::increase(_minimum);
53.234 + }
53.235 + return _minimum;
53.236 + }
53.237 +
53.238 + /// \brief Remove the item having minimum priority.
53.239 + ///
53.240 + /// This function removes the item having minimum priority.
53.241 + /// \pre The heap must be non-empty.
53.242 + void pop() {
53.243 + while (_first[_minimum] == -1) {
53.244 + Direction::increase(_minimum);
53.245 + }
53.246 + int idx = _first[_minimum];
53.247 + _iim[_data[idx].item] = -2;
53.248 + unlace(idx);
53.249 + relocateLast(idx);
53.250 + }
53.251 +
53.252 + /// \brief Remove the given item from the heap.
53.253 + ///
53.254 + /// This function removes the given item from the heap if it is
53.255 + /// already stored.
53.256 + /// \param i The item to delete.
53.257 + /// \pre \e i must be in the heap.
53.258 + void erase(const Item &i) {
53.259 + int idx = _iim[i];
53.260 + _iim[_data[idx].item] = -2;
53.261 + unlace(idx);
53.262 + relocateLast(idx);
53.263 + }
53.264 +
53.265 + /// \brief The priority of the given item.
53.266 + ///
53.267 + /// This function returns the priority of the given item.
53.268 + /// \param i The item.
53.269 + /// \pre \e i must be in the heap.
53.270 + Prio operator[](const Item &i) const {
53.271 + int idx = _iim[i];
53.272 + return _data[idx].value;
53.273 + }
53.274 +
53.275 + /// \brief Set the priority of an item or insert it, if it is
53.276 + /// not stored in the heap.
53.277 + ///
53.278 + /// This method sets the priority of the given item if it is
53.279 + /// already stored in the heap. Otherwise it inserts the given
53.280 + /// item into the heap with the given priority.
53.281 + /// \param i The item.
53.282 + /// \param p The priority.
53.283 + void set(const Item &i, const Prio &p) {
53.284 + int idx = _iim[i];
53.285 + if (idx < 0) {
53.286 + push(i, p);
53.287 + } else if (Direction::less(p, _data[idx].value)) {
53.288 + decrease(i, p);
53.289 + } else {
53.290 + increase(i, p);
53.291 + }
53.292 + }
53.293 +
53.294 + /// \brief Decrease the priority of an item to the given value.
53.295 + ///
53.296 + /// This function decreases the priority of an item to the given value.
53.297 + /// \param i The item.
53.298 + /// \param p The priority.
53.299 + /// \pre \e i must be stored in the heap with priority at least \e p.
53.300 + void decrease(const Item &i, const Prio &p) {
53.301 + int idx = _iim[i];
53.302 + unlace(idx);
53.303 + _data[idx].value = p;
53.304 + if (Direction::less(p, _minimum)) {
53.305 + _minimum = p;
53.306 + }
53.307 + lace(idx);
53.308 + }
53.309 +
53.310 + /// \brief Increase the priority of an item to the given value.
53.311 + ///
53.312 + /// This function increases the priority of an item to the given value.
53.313 + /// \param i The item.
53.314 + /// \param p The priority.
53.315 + /// \pre \e i must be stored in the heap with priority at most \e p.
53.316 + void increase(const Item &i, const Prio &p) {
53.317 + int idx = _iim[i];
53.318 + unlace(idx);
53.319 + _data[idx].value = p;
53.320 + lace(idx);
53.321 + }
53.322 +
53.323 + /// \brief Return the state of an item.
53.324 + ///
53.325 + /// This method returns \c PRE_HEAP if the given item has never
53.326 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
53.327 + /// and \c POST_HEAP otherwise.
53.328 + /// In the latter case it is possible that the item will get back
53.329 + /// to the heap again.
53.330 + /// \param i The item.
53.331 + State state(const Item &i) const {
53.332 + int idx = _iim[i];
53.333 + if (idx >= 0) idx = 0;
53.334 + return State(idx);
53.335 + }
53.336 +
53.337 + /// \brief Set the state of an item in the heap.
53.338 + ///
53.339 + /// This function sets the state of the given item in the heap.
53.340 + /// It can be used to manually clear the heap when it is important
53.341 + /// to achive better time complexity.
53.342 + /// \param i The item.
53.343 + /// \param st The state. It should not be \c IN_HEAP.
53.344 + void state(const Item& i, State st) {
53.345 + switch (st) {
53.346 + case POST_HEAP:
53.347 + case PRE_HEAP:
53.348 + if (state(i) == IN_HEAP) {
53.349 + erase(i);
53.350 + }
53.351 + _iim[i] = st;
53.352 + break;
53.353 + case IN_HEAP:
53.354 + break;
53.355 + }
53.356 + }
53.357 +
53.358 + private:
53.359 +
53.360 + struct BucketItem {
53.361 + BucketItem(const Item& _item, int _value)
53.362 + : item(_item), value(_value) {}
53.363 +
53.364 + Item item;
53.365 + int value;
53.366 +
53.367 + int prev, next;
53.368 + };
53.369 +
53.370 + ItemIntMap& _iim;
53.371 + std::vector<int> _first;
53.372 + std::vector<BucketItem> _data;
53.373 + mutable int _minimum;
53.374 +
53.375 + }; // class BucketHeap
53.376 +
53.377 + /// \ingroup heaps
53.378 + ///
53.379 + /// \brief Simplified bucket heap data structure.
53.380 + ///
53.381 + /// This class implements a simplified \e bucket \e heap data
53.382 + /// structure. It does not provide some functionality, but it is
53.383 + /// faster and simpler than BucketHeap. The main difference is
53.384 + /// that BucketHeap stores a doubly-linked list for each key while
53.385 + /// this class stores only simply-linked lists. It supports erasing
53.386 + /// only for the item having minimum priority and it does not support
53.387 + /// key increasing and decreasing.
53.388 + ///
53.389 + /// Note that this implementation does not conform to the
53.390 + /// \ref concepts::Heap "heap concept" due to the lack of some
53.391 + /// functionality.
53.392 + ///
53.393 + /// \tparam IM A read-writable item map with \c int values, used
53.394 + /// internally to handle the cross references.
53.395 + /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
53.396 + /// The default is \e min-heap. If this parameter is set to \c false,
53.397 + /// then the comparison is reversed, so the top(), prio() and pop()
53.398 + /// functions deal with the item having maximum priority instead of the
53.399 + /// minimum.
53.400 + ///
53.401 + /// \sa BucketHeap
53.402 + template <typename IM, bool MIN = true >
53.403 + class SimpleBucketHeap {
53.404 +
53.405 + public:
53.406 +
53.407 + /// Type of the item-int map.
53.408 + typedef IM ItemIntMap;
53.409 + /// Type of the priorities.
53.410 + typedef int Prio;
53.411 + /// Type of the items stored in the heap.
53.412 + typedef typename ItemIntMap::Key Item;
53.413 + /// Type of the item-priority pairs.
53.414 + typedef std::pair<Item,Prio> Pair;
53.415 +
53.416 + private:
53.417 +
53.418 + typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
53.419 +
53.420 + public:
53.421 +
53.422 + /// \brief Type to represent the states of the items.
53.423 + ///
53.424 + /// Each item has a state associated to it. It can be "in heap",
53.425 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
53.426 + /// heap's point of view, but may be useful to the user.
53.427 + ///
53.428 + /// The item-int map must be initialized in such way that it assigns
53.429 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
53.430 + enum State {
53.431 + IN_HEAP = 0, ///< = 0.
53.432 + PRE_HEAP = -1, ///< = -1.
53.433 + POST_HEAP = -2 ///< = -2.
53.434 + };
53.435 +
53.436 + public:
53.437 +
53.438 + /// \brief Constructor.
53.439 + ///
53.440 + /// Constructor.
53.441 + /// \param map A map that assigns \c int values to the items.
53.442 + /// It is used internally to handle the cross references.
53.443 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
53.444 + explicit SimpleBucketHeap(ItemIntMap &map)
53.445 + : _iim(map), _free(-1), _num(0), _minimum(0) {}
53.446 +
53.447 + /// \brief The number of items stored in the heap.
53.448 + ///
53.449 + /// This function returns the number of items stored in the heap.
53.450 + int size() const { return _num; }
53.451 +
53.452 + /// \brief Check if the heap is empty.
53.453 + ///
53.454 + /// This function returns \c true if the heap is empty.
53.455 + bool empty() const { return _num == 0; }
53.456 +
53.457 + /// \brief Make the heap empty.
53.458 + ///
53.459 + /// This functon makes the heap empty.
53.460 + /// It does not change the cross reference map. If you want to reuse
53.461 + /// a heap that is not surely empty, you should first clear it and
53.462 + /// then you should set the cross reference map to \c PRE_HEAP
53.463 + /// for each item.
53.464 + void clear() {
53.465 + _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
53.466 + }
53.467 +
53.468 + /// \brief Insert a pair of item and priority into the heap.
53.469 + ///
53.470 + /// This function inserts \c p.first to the heap with priority
53.471 + /// \c p.second.
53.472 + /// \param p The pair to insert.
53.473 + /// \pre \c p.first must not be stored in the heap.
53.474 + void push(const Pair& p) {
53.475 + push(p.first, p.second);
53.476 + }
53.477 +
53.478 + /// \brief Insert an item into the heap with the given priority.
53.479 + ///
53.480 + /// This function inserts the given item into the heap with the
53.481 + /// given priority.
53.482 + /// \param i The item to insert.
53.483 + /// \param p The priority of the item.
53.484 + /// \pre \e i must not be stored in the heap.
53.485 + void push(const Item &i, const Prio &p) {
53.486 + int idx;
53.487 + if (_free == -1) {
53.488 + idx = _data.size();
53.489 + _data.push_back(BucketItem(i));
53.490 + } else {
53.491 + idx = _free;
53.492 + _free = _data[idx].next;
53.493 + _data[idx].item = i;
53.494 + }
53.495 + _iim[i] = idx;
53.496 + if (p >= int(_first.size())) _first.resize(p + 1, -1);
53.497 + _data[idx].next = _first[p];
53.498 + _first[p] = idx;
53.499 + if (Direction::less(p, _minimum)) {
53.500 + _minimum = p;
53.501 + }
53.502 + ++_num;
53.503 + }
53.504 +
53.505 + /// \brief Return the item having minimum priority.
53.506 + ///
53.507 + /// This function returns the item having minimum priority.
53.508 + /// \pre The heap must be non-empty.
53.509 + Item top() const {
53.510 + while (_first[_minimum] == -1) {
53.511 + Direction::increase(_minimum);
53.512 + }
53.513 + return _data[_first[_minimum]].item;
53.514 + }
53.515 +
53.516 + /// \brief The minimum priority.
53.517 + ///
53.518 + /// This function returns the minimum priority.
53.519 + /// \pre The heap must be non-empty.
53.520 + Prio prio() const {
53.521 + while (_first[_minimum] == -1) {
53.522 + Direction::increase(_minimum);
53.523 + }
53.524 + return _minimum;
53.525 + }
53.526 +
53.527 + /// \brief Remove the item having minimum priority.
53.528 + ///
53.529 + /// This function removes the item having minimum priority.
53.530 + /// \pre The heap must be non-empty.
53.531 + void pop() {
53.532 + while (_first[_minimum] == -1) {
53.533 + Direction::increase(_minimum);
53.534 + }
53.535 + int idx = _first[_minimum];
53.536 + _iim[_data[idx].item] = -2;
53.537 + _first[_minimum] = _data[idx].next;
53.538 + _data[idx].next = _free;
53.539 + _free = idx;
53.540 + --_num;
53.541 + }
53.542 +
53.543 + /// \brief The priority of the given item.
53.544 + ///
53.545 + /// This function returns the priority of the given item.
53.546 + /// \param i The item.
53.547 + /// \pre \e i must be in the heap.
53.548 + /// \warning This operator is not a constant time function because
53.549 + /// it scans the whole data structure to find the proper value.
53.550 + Prio operator[](const Item &i) const {
53.551 + for (int k = 0; k < int(_first.size()); ++k) {
53.552 + int idx = _first[k];
53.553 + while (idx != -1) {
53.554 + if (_data[idx].item == i) {
53.555 + return k;
53.556 + }
53.557 + idx = _data[idx].next;
53.558 + }
53.559 + }
53.560 + return -1;
53.561 + }
53.562 +
53.563 + /// \brief Return the state of an item.
53.564 + ///
53.565 + /// This method returns \c PRE_HEAP if the given item has never
53.566 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
53.567 + /// and \c POST_HEAP otherwise.
53.568 + /// In the latter case it is possible that the item will get back
53.569 + /// to the heap again.
53.570 + /// \param i The item.
53.571 + State state(const Item &i) const {
53.572 + int idx = _iim[i];
53.573 + if (idx >= 0) idx = 0;
53.574 + return State(idx);
53.575 + }
53.576 +
53.577 + private:
53.578 +
53.579 + struct BucketItem {
53.580 + BucketItem(const Item& _item)
53.581 + : item(_item) {}
53.582 +
53.583 + Item item;
53.584 + int next;
53.585 + };
53.586 +
53.587 + ItemIntMap& _iim;
53.588 + std::vector<int> _first;
53.589 + std::vector<BucketItem> _data;
53.590 + int _free, _num;
53.591 + mutable int _minimum;
53.592 +
53.593 + }; // class SimpleBucketHeap
53.594 +
53.595 +}
53.596 +
53.597 +#endif
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
54.2 +++ b/lemon/cbc.cc Thu Nov 05 15:48:01 2009 +0100
54.3 @@ -0,0 +1,475 @@
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-2009
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 +///\file
54.23 +///\brief Implementation of the CBC MIP solver interface.
54.24 +
54.25 +#include "cbc.h"
54.26 +
54.27 +#include <coin/CoinModel.hpp>
54.28 +#include <coin/CbcModel.hpp>
54.29 +#include <coin/OsiSolverInterface.hpp>
54.30 +
54.31 +#ifdef COIN_HAS_CLP
54.32 +#include "coin/OsiClpSolverInterface.hpp"
54.33 +#endif
54.34 +#ifdef COIN_HAS_OSL
54.35 +#include "coin/OsiOslSolverInterface.hpp"
54.36 +#endif
54.37 +
54.38 +#include "coin/CbcCutGenerator.hpp"
54.39 +#include "coin/CbcHeuristicLocal.hpp"
54.40 +#include "coin/CbcHeuristicGreedy.hpp"
54.41 +#include "coin/CbcHeuristicFPump.hpp"
54.42 +#include "coin/CbcHeuristicRINS.hpp"
54.43 +
54.44 +#include "coin/CglGomory.hpp"
54.45 +#include "coin/CglProbing.hpp"
54.46 +#include "coin/CglKnapsackCover.hpp"
54.47 +#include "coin/CglOddHole.hpp"
54.48 +#include "coin/CglClique.hpp"
54.49 +#include "coin/CglFlowCover.hpp"
54.50 +#include "coin/CglMixedIntegerRounding.hpp"
54.51 +
54.52 +#include "coin/CbcHeuristic.hpp"
54.53 +
54.54 +namespace lemon {
54.55 +
54.56 + CbcMip::CbcMip() {
54.57 + _prob = new CoinModel();
54.58 + _prob->setProblemName("LEMON");
54.59 + _osi_solver = 0;
54.60 + _cbc_model = 0;
54.61 + messageLevel(MESSAGE_NOTHING);
54.62 + }
54.63 +
54.64 + CbcMip::CbcMip(const CbcMip& other) {
54.65 + _prob = new CoinModel(*other._prob);
54.66 + _prob->setProblemName("LEMON");
54.67 + _osi_solver = 0;
54.68 + _cbc_model = 0;
54.69 + messageLevel(MESSAGE_NOTHING);
54.70 + }
54.71 +
54.72 + CbcMip::~CbcMip() {
54.73 + delete _prob;
54.74 + if (_osi_solver) delete _osi_solver;
54.75 + if (_cbc_model) delete _cbc_model;
54.76 + }
54.77 +
54.78 + const char* CbcMip::_solverName() const { return "CbcMip"; }
54.79 +
54.80 + int CbcMip::_addCol() {
54.81 + _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0, 0, false);
54.82 + return _prob->numberColumns() - 1;
54.83 + }
54.84 +
54.85 + CbcMip* CbcMip::newSolver() const {
54.86 + CbcMip* newlp = new CbcMip;
54.87 + return newlp;
54.88 + }
54.89 +
54.90 + CbcMip* CbcMip::cloneSolver() const {
54.91 + CbcMip* copylp = new CbcMip(*this);
54.92 + return copylp;
54.93 + }
54.94 +
54.95 + int CbcMip::_addRow() {
54.96 + _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
54.97 + return _prob->numberRows() - 1;
54.98 + }
54.99 +
54.100 + int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
54.101 + std::vector<int> indexes;
54.102 + std::vector<Value> values;
54.103 +
54.104 + for(ExprIterator it = b; it != e; ++it) {
54.105 + indexes.push_back(it->first);
54.106 + values.push_back(it->second);
54.107 + }
54.108 +
54.109 + _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
54.110 + return _prob->numberRows() - 1;
54.111 + }
54.112 +
54.113 + void CbcMip::_eraseCol(int i) {
54.114 + _prob->deleteColumn(i);
54.115 + }
54.116 +
54.117 + void CbcMip::_eraseRow(int i) {
54.118 + _prob->deleteRow(i);
54.119 + }
54.120 +
54.121 + void CbcMip::_eraseColId(int i) {
54.122 + cols.eraseIndex(i);
54.123 + }
54.124 +
54.125 + void CbcMip::_eraseRowId(int i) {
54.126 + rows.eraseIndex(i);
54.127 + }
54.128 +
54.129 + void CbcMip::_getColName(int c, std::string& name) const {
54.130 + name = _prob->getColumnName(c);
54.131 + }
54.132 +
54.133 + void CbcMip::_setColName(int c, const std::string& name) {
54.134 + _prob->setColumnName(c, name.c_str());
54.135 + }
54.136 +
54.137 + int CbcMip::_colByName(const std::string& name) const {
54.138 + return _prob->column(name.c_str());
54.139 + }
54.140 +
54.141 + void CbcMip::_getRowName(int r, std::string& name) const {
54.142 + name = _prob->getRowName(r);
54.143 + }
54.144 +
54.145 + void CbcMip::_setRowName(int r, const std::string& name) {
54.146 + _prob->setRowName(r, name.c_str());
54.147 + }
54.148 +
54.149 + int CbcMip::_rowByName(const std::string& name) const {
54.150 + return _prob->row(name.c_str());
54.151 + }
54.152 +
54.153 + void CbcMip::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
54.154 + for (ExprIterator it = b; it != e; ++it) {
54.155 + _prob->setElement(i, it->first, it->second);
54.156 + }
54.157 + }
54.158 +
54.159 + void CbcMip::_getRowCoeffs(int ix, InsertIterator b) const {
54.160 + int length = _prob->numberRows();
54.161 +
54.162 + std::vector<int> indices(length);
54.163 + std::vector<Value> values(length);
54.164 +
54.165 + length = _prob->getRow(ix, &indices[0], &values[0]);
54.166 +
54.167 + for (int i = 0; i < length; ++i) {
54.168 + *b = std::make_pair(indices[i], values[i]);
54.169 + ++b;
54.170 + }
54.171 + }
54.172 +
54.173 + void CbcMip::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
54.174 + for (ExprIterator it = b; it != e; ++it) {
54.175 + _prob->setElement(it->first, ix, it->second);
54.176 + }
54.177 + }
54.178 +
54.179 + void CbcMip::_getColCoeffs(int ix, InsertIterator b) const {
54.180 + int length = _prob->numberColumns();
54.181 +
54.182 + std::vector<int> indices(length);
54.183 + std::vector<Value> values(length);
54.184 +
54.185 + length = _prob->getColumn(ix, &indices[0], &values[0]);
54.186 +
54.187 + for (int i = 0; i < length; ++i) {
54.188 + *b = std::make_pair(indices[i], values[i]);
54.189 + ++b;
54.190 + }
54.191 + }
54.192 +
54.193 + void CbcMip::_setCoeff(int ix, int jx, Value value) {
54.194 + _prob->setElement(ix, jx, value);
54.195 + }
54.196 +
54.197 + CbcMip::Value CbcMip::_getCoeff(int ix, int jx) const {
54.198 + return _prob->getElement(ix, jx);
54.199 + }
54.200 +
54.201 +
54.202 + void CbcMip::_setColLowerBound(int i, Value lo) {
54.203 + LEMON_ASSERT(lo != INF, "Invalid bound");
54.204 + _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
54.205 + }
54.206 +
54.207 + CbcMip::Value CbcMip::_getColLowerBound(int i) const {
54.208 + double val = _prob->getColumnLower(i);
54.209 + return val == - COIN_DBL_MAX ? - INF : val;
54.210 + }
54.211 +
54.212 + void CbcMip::_setColUpperBound(int i, Value up) {
54.213 + LEMON_ASSERT(up != -INF, "Invalid bound");
54.214 + _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
54.215 + }
54.216 +
54.217 + CbcMip::Value CbcMip::_getColUpperBound(int i) const {
54.218 + double val = _prob->getColumnUpper(i);
54.219 + return val == COIN_DBL_MAX ? INF : val;
54.220 + }
54.221 +
54.222 + void CbcMip::_setRowLowerBound(int i, Value lo) {
54.223 + LEMON_ASSERT(lo != INF, "Invalid bound");
54.224 + _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
54.225 + }
54.226 +
54.227 + CbcMip::Value CbcMip::_getRowLowerBound(int i) const {
54.228 + double val = _prob->getRowLower(i);
54.229 + return val == - COIN_DBL_MAX ? - INF : val;
54.230 + }
54.231 +
54.232 + void CbcMip::_setRowUpperBound(int i, Value up) {
54.233 + LEMON_ASSERT(up != -INF, "Invalid bound");
54.234 + _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
54.235 + }
54.236 +
54.237 + CbcMip::Value CbcMip::_getRowUpperBound(int i) const {
54.238 + double val = _prob->getRowUpper(i);
54.239 + return val == COIN_DBL_MAX ? INF : val;
54.240 + }
54.241 +
54.242 + void CbcMip::_setObjCoeffs(ExprIterator b, ExprIterator e) {
54.243 + int num = _prob->numberColumns();
54.244 + for (int i = 0; i < num; ++i) {
54.245 + _prob->setColumnObjective(i, 0.0);
54.246 + }
54.247 + for (ExprIterator it = b; it != e; ++it) {
54.248 + _prob->setColumnObjective(it->first, it->second);
54.249 + }
54.250 + }
54.251 +
54.252 + void CbcMip::_getObjCoeffs(InsertIterator b) const {
54.253 + int num = _prob->numberColumns();
54.254 + for (int i = 0; i < num; ++i) {
54.255 + Value coef = _prob->getColumnObjective(i);
54.256 + if (coef != 0.0) {
54.257 + *b = std::make_pair(i, coef);
54.258 + ++b;
54.259 + }
54.260 + }
54.261 + }
54.262 +
54.263 + void CbcMip::_setObjCoeff(int i, Value obj_coef) {
54.264 + _prob->setColumnObjective(i, obj_coef);
54.265 + }
54.266 +
54.267 + CbcMip::Value CbcMip::_getObjCoeff(int i) const {
54.268 + return _prob->getColumnObjective(i);
54.269 + }
54.270 +
54.271 + CbcMip::SolveExitStatus CbcMip::_solve() {
54.272 +
54.273 + if (_osi_solver) {
54.274 + delete _osi_solver;
54.275 + }
54.276 +#ifdef COIN_HAS_CLP
54.277 + _osi_solver = new OsiClpSolverInterface();
54.278 +#elif COIN_HAS_OSL
54.279 + _osi_solver = new OsiOslSolverInterface();
54.280 +#else
54.281 +#error Cannot instantiate Osi solver
54.282 +#endif
54.283 +
54.284 + _osi_solver->loadFromCoinModel(*_prob);
54.285 +
54.286 + if (_cbc_model) {
54.287 + delete _cbc_model;
54.288 + }
54.289 + _cbc_model= new CbcModel(*_osi_solver);
54.290 +
54.291 + _osi_solver->messageHandler()->setLogLevel(_message_level);
54.292 + _cbc_model->setLogLevel(_message_level);
54.293 +
54.294 + _cbc_model->initialSolve();
54.295 + _cbc_model->solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
54.296 +
54.297 + if (!_cbc_model->isInitialSolveAbandoned() &&
54.298 + _cbc_model->isInitialSolveProvenOptimal() &&
54.299 + !_cbc_model->isInitialSolveProvenPrimalInfeasible() &&
54.300 + !_cbc_model->isInitialSolveProvenDualInfeasible()) {
54.301 +
54.302 + CglProbing generator1;
54.303 + generator1.setUsingObjective(true);
54.304 + generator1.setMaxPass(3);
54.305 + generator1.setMaxProbe(100);
54.306 + generator1.setMaxLook(50);
54.307 + generator1.setRowCuts(3);
54.308 + _cbc_model->addCutGenerator(&generator1, -1, "Probing");
54.309 +
54.310 + CglGomory generator2;
54.311 + generator2.setLimit(300);
54.312 + _cbc_model->addCutGenerator(&generator2, -1, "Gomory");
54.313 +
54.314 + CglKnapsackCover generator3;
54.315 + _cbc_model->addCutGenerator(&generator3, -1, "Knapsack");
54.316 +
54.317 + CglOddHole generator4;
54.318 + generator4.setMinimumViolation(0.005);
54.319 + generator4.setMinimumViolationPer(0.00002);
54.320 + generator4.setMaximumEntries(200);
54.321 + _cbc_model->addCutGenerator(&generator4, -1, "OddHole");
54.322 +
54.323 + CglClique generator5;
54.324 + generator5.setStarCliqueReport(false);
54.325 + generator5.setRowCliqueReport(false);
54.326 + _cbc_model->addCutGenerator(&generator5, -1, "Clique");
54.327 +
54.328 + CglMixedIntegerRounding mixedGen;
54.329 + _cbc_model->addCutGenerator(&mixedGen, -1, "MixedIntegerRounding");
54.330 +
54.331 + CglFlowCover flowGen;
54.332 + _cbc_model->addCutGenerator(&flowGen, -1, "FlowCover");
54.333 +
54.334 +#ifdef COIN_HAS_CLP
54.335 + OsiClpSolverInterface* osiclp =
54.336 + dynamic_cast<OsiClpSolverInterface*>(_cbc_model->solver());
54.337 + if (osiclp->getNumRows() < 300 && osiclp->getNumCols() < 500) {
54.338 + osiclp->setupForRepeatedUse(2, 0);
54.339 + }
54.340 +#endif
54.341 +
54.342 + CbcRounding heuristic1(*_cbc_model);
54.343 + heuristic1.setWhen(3);
54.344 + _cbc_model->addHeuristic(&heuristic1);
54.345 +
54.346 + CbcHeuristicLocal heuristic2(*_cbc_model);
54.347 + heuristic2.setWhen(3);
54.348 + _cbc_model->addHeuristic(&heuristic2);
54.349 +
54.350 + CbcHeuristicGreedyCover heuristic3(*_cbc_model);
54.351 + heuristic3.setAlgorithm(11);
54.352 + heuristic3.setWhen(3);
54.353 + _cbc_model->addHeuristic(&heuristic3);
54.354 +
54.355 + CbcHeuristicFPump heuristic4(*_cbc_model);
54.356 + heuristic4.setWhen(3);
54.357 + _cbc_model->addHeuristic(&heuristic4);
54.358 +
54.359 + CbcHeuristicRINS heuristic5(*_cbc_model);
54.360 + heuristic5.setWhen(3);
54.361 + _cbc_model->addHeuristic(&heuristic5);
54.362 +
54.363 + if (_cbc_model->getNumCols() < 500) {
54.364 + _cbc_model->setMaximumCutPassesAtRoot(-100);
54.365 + } else if (_cbc_model->getNumCols() < 5000) {
54.366 + _cbc_model->setMaximumCutPassesAtRoot(100);
54.367 + } else {
54.368 + _cbc_model->setMaximumCutPassesAtRoot(20);
54.369 + }
54.370 +
54.371 + if (_cbc_model->getNumCols() < 5000) {
54.372 + _cbc_model->setNumberStrong(10);
54.373 + }
54.374 +
54.375 + _cbc_model->solver()->setIntParam(OsiMaxNumIterationHotStart, 100);
54.376 + _cbc_model->branchAndBound();
54.377 + }
54.378 +
54.379 + if (_cbc_model->isAbandoned()) {
54.380 + return UNSOLVED;
54.381 + } else {
54.382 + return SOLVED;
54.383 + }
54.384 + }
54.385 +
54.386 + CbcMip::Value CbcMip::_getSol(int i) const {
54.387 + return _cbc_model->getColSolution()[i];
54.388 + }
54.389 +
54.390 + CbcMip::Value CbcMip::_getSolValue() const {
54.391 + return _cbc_model->getObjValue();
54.392 + }
54.393 +
54.394 + CbcMip::ProblemType CbcMip::_getType() const {
54.395 + if (_cbc_model->isProvenOptimal()) {
54.396 + return OPTIMAL;
54.397 + } else if (_cbc_model->isContinuousUnbounded()) {
54.398 + return UNBOUNDED;
54.399 + }
54.400 + return FEASIBLE;
54.401 + }
54.402 +
54.403 + void CbcMip::_setSense(Sense sense) {
54.404 + switch (sense) {
54.405 + case MIN:
54.406 + _prob->setOptimizationDirection(1.0);
54.407 + break;
54.408 + case MAX:
54.409 + _prob->setOptimizationDirection(- 1.0);
54.410 + break;
54.411 + }
54.412 + }
54.413 +
54.414 + CbcMip::Sense CbcMip::_getSense() const {
54.415 + if (_prob->optimizationDirection() > 0.0) {
54.416 + return MIN;
54.417 + } else if (_prob->optimizationDirection() < 0.0) {
54.418 + return MAX;
54.419 + } else {
54.420 + LEMON_ASSERT(false, "Wrong sense");
54.421 + return CbcMip::Sense();
54.422 + }
54.423 + }
54.424 +
54.425 + void CbcMip::_setColType(int i, CbcMip::ColTypes col_type) {
54.426 + switch (col_type){
54.427 + case INTEGER:
54.428 + _prob->setInteger(i);
54.429 + break;
54.430 + case REAL:
54.431 + _prob->setContinuous(i);
54.432 + break;
54.433 + default:;
54.434 + LEMON_ASSERT(false, "Wrong sense");
54.435 + }
54.436 + }
54.437 +
54.438 + CbcMip::ColTypes CbcMip::_getColType(int i) const {
54.439 + return _prob->getColumnIsInteger(i) ? INTEGER : REAL;
54.440 + }
54.441 +
54.442 + void CbcMip::_clear() {
54.443 + delete _prob;
54.444 + if (_osi_solver) {
54.445 + delete _osi_solver;
54.446 + _osi_solver = 0;
54.447 + }
54.448 + if (_cbc_model) {
54.449 + delete _cbc_model;
54.450 + _cbc_model = 0;
54.451 + }
54.452 +
54.453 + _prob = new CoinModel();
54.454 + rows.clear();
54.455 + cols.clear();
54.456 + }
54.457 +
54.458 + void CbcMip::_messageLevel(MessageLevel level) {
54.459 + switch (level) {
54.460 + case MESSAGE_NOTHING:
54.461 + _message_level = 0;
54.462 + break;
54.463 + case MESSAGE_ERROR:
54.464 + _message_level = 1;
54.465 + break;
54.466 + case MESSAGE_WARNING:
54.467 + _message_level = 1;
54.468 + break;
54.469 + case MESSAGE_NORMAL:
54.470 + _message_level = 2;
54.471 + break;
54.472 + case MESSAGE_VERBOSE:
54.473 + _message_level = 3;
54.474 + break;
54.475 + }
54.476 + }
54.477 +
54.478 +} //END OF NAMESPACE LEMON
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
55.2 +++ b/lemon/cbc.h Thu Nov 05 15:48:01 2009 +0100
55.3 @@ -0,0 +1,130 @@
55.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
55.5 + *
55.6 + * This file is a part of LEMON, a generic C++ optimization library.
55.7 + *
55.8 + * Copyright (C) 2003-2009
55.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
55.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
55.11 + *
55.12 + * Permission to use, modify and distribute this software is granted
55.13 + * provided that this copyright notice appears in all copies. For
55.14 + * precise terms see the accompanying LICENSE file.
55.15 + *
55.16 + * This software is provided "AS IS" with no warranty of any kind,
55.17 + * express or implied, and with no claim as to its suitability for any
55.18 + * purpose.
55.19 + *
55.20 + */
55.21 +
55.22 +// -*- C++ -*-
55.23 +#ifndef LEMON_CBC_H
55.24 +#define LEMON_CBC_H
55.25 +
55.26 +///\file
55.27 +///\brief Header of the LEMON-CBC mip solver interface.
55.28 +///\ingroup lp_group
55.29 +
55.30 +#include <lemon/lp_base.h>
55.31 +
55.32 +class CoinModel;
55.33 +class OsiSolverInterface;
55.34 +class CbcModel;
55.35 +
55.36 +namespace lemon {
55.37 +
55.38 + /// \brief Interface for the CBC MIP solver
55.39 + ///
55.40 + /// This class implements an interface for the CBC MIP solver.
55.41 + ///\ingroup lp_group
55.42 + class CbcMip : public MipSolver {
55.43 + protected:
55.44 +
55.45 + CoinModel *_prob;
55.46 + OsiSolverInterface *_osi_solver;
55.47 + CbcModel *_cbc_model;
55.48 +
55.49 + public:
55.50 +
55.51 + /// \e
55.52 + CbcMip();
55.53 + /// \e
55.54 + CbcMip(const CbcMip&);
55.55 + /// \e
55.56 + ~CbcMip();
55.57 + /// \e
55.58 + virtual CbcMip* newSolver() const;
55.59 + /// \e
55.60 + virtual CbcMip* cloneSolver() const;
55.61 +
55.62 + protected:
55.63 +
55.64 + virtual const char* _solverName() const;
55.65 +
55.66 + virtual int _addCol();
55.67 + virtual int _addRow();
55.68 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
55.69 +
55.70 + virtual void _eraseCol(int i);
55.71 + virtual void _eraseRow(int i);
55.72 +
55.73 + virtual void _eraseColId(int i);
55.74 + virtual void _eraseRowId(int i);
55.75 +
55.76 + virtual void _getColName(int col, std::string& name) const;
55.77 + virtual void _setColName(int col, const std::string& name);
55.78 + virtual int _colByName(const std::string& name) const;
55.79 +
55.80 + virtual void _getRowName(int row, std::string& name) const;
55.81 + virtual void _setRowName(int row, const std::string& name);
55.82 + virtual int _rowByName(const std::string& name) const;
55.83 +
55.84 + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
55.85 + virtual void _getRowCoeffs(int i, InsertIterator b) const;
55.86 +
55.87 + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
55.88 + virtual void _getColCoeffs(int i, InsertIterator b) const;
55.89 +
55.90 + virtual void _setCoeff(int row, int col, Value value);
55.91 + virtual Value _getCoeff(int row, int col) const;
55.92 +
55.93 + virtual void _setColLowerBound(int i, Value value);
55.94 + virtual Value _getColLowerBound(int i) const;
55.95 + virtual void _setColUpperBound(int i, Value value);
55.96 + virtual Value _getColUpperBound(int i) const;
55.97 +
55.98 + virtual void _setRowLowerBound(int i, Value value);
55.99 + virtual Value _getRowLowerBound(int i) const;
55.100 + virtual void _setRowUpperBound(int i, Value value);
55.101 + virtual Value _getRowUpperBound(int i) const;
55.102 +
55.103 + virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
55.104 + virtual void _getObjCoeffs(InsertIterator b) const;
55.105 +
55.106 + virtual void _setObjCoeff(int i, Value obj_coef);
55.107 + virtual Value _getObjCoeff(int i) const;
55.108 +
55.109 + virtual void _setSense(Sense sense);
55.110 + virtual Sense _getSense() const;
55.111 +
55.112 + virtual ColTypes _getColType(int col) const;
55.113 + virtual void _setColType(int col, ColTypes col_type);
55.114 +
55.115 + virtual SolveExitStatus _solve();
55.116 + virtual ProblemType _getType() const;
55.117 + virtual Value _getSol(int i) const;
55.118 + virtual Value _getSolValue() const;
55.119 +
55.120 + virtual void _clear();
55.121 +
55.122 + virtual void _messageLevel(MessageLevel level);
55.123 + void _applyMessageLevel();
55.124 +
55.125 + int _message_level;
55.126 +
55.127 +
55.128 +
55.129 + };
55.130 +
55.131 +}
55.132 +
55.133 +#endif
56.1 --- a/lemon/circulation.h Mon Jan 12 23:11:39 2009 +0100
56.2 +++ b/lemon/circulation.h Thu Nov 05 15:48:01 2009 +0100
56.3 @@ -21,6 +21,7 @@
56.4
56.5 #include <lemon/tolerance.h>
56.6 #include <lemon/elevator.h>
56.7 +#include <limits>
56.8
56.9 ///\ingroup max_flow
56.10 ///\file
56.11 @@ -31,52 +32,56 @@
56.12 /// \brief Default traits class of Circulation class.
56.13 ///
56.14 /// Default traits class of Circulation class.
56.15 - /// \tparam _Diraph Digraph type.
56.16 - /// \tparam _LCapMap Lower bound capacity map type.
56.17 - /// \tparam _UCapMap Upper bound capacity map type.
56.18 - /// \tparam _DeltaMap Delta map type.
56.19 - template <typename _Diraph, typename _LCapMap,
56.20 - typename _UCapMap, typename _DeltaMap>
56.21 + ///
56.22 + /// \tparam GR Type of the digraph the algorithm runs on.
56.23 + /// \tparam LM The type of the lower bound map.
56.24 + /// \tparam UM The type of the upper bound (capacity) map.
56.25 + /// \tparam SM The type of the supply map.
56.26 + template <typename GR, typename LM,
56.27 + typename UM, typename SM>
56.28 struct CirculationDefaultTraits {
56.29
56.30 /// \brief The type of the digraph the algorithm runs on.
56.31 - typedef _Diraph Digraph;
56.32 + typedef GR Digraph;
56.33
56.34 - /// \brief The type of the map that stores the circulation lower
56.35 - /// bound.
56.36 + /// \brief The type of the lower bound map.
56.37 ///
56.38 - /// The type of the map that stores the circulation lower bound.
56.39 - /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
56.40 - typedef _LCapMap LCapMap;
56.41 + /// The type of the map that stores the lower bounds on the arcs.
56.42 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
56.43 + typedef LM LowerMap;
56.44
56.45 - /// \brief The type of the map that stores the circulation upper
56.46 - /// bound.
56.47 + /// \brief The type of the upper bound (capacity) map.
56.48 ///
56.49 - /// The type of the map that stores the circulation upper bound.
56.50 - /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
56.51 - typedef _UCapMap UCapMap;
56.52 + /// The type of the map that stores the upper bounds (capacities)
56.53 + /// on the arcs.
56.54 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
56.55 + typedef UM UpperMap;
56.56
56.57 - /// \brief The type of the map that stores the lower bound for
56.58 - /// the supply of the nodes.
56.59 + /// \brief The type of supply map.
56.60 ///
56.61 - /// The type of the map that stores the lower bound for the supply
56.62 - /// of the nodes. It must meet the \ref concepts::ReadMap "ReadMap"
56.63 - /// concept.
56.64 - typedef _DeltaMap DeltaMap;
56.65 + /// The type of the map that stores the signed supply values of the
56.66 + /// nodes.
56.67 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
56.68 + typedef SM SupplyMap;
56.69
56.70 - /// \brief The type of the flow values.
56.71 - typedef typename DeltaMap::Value Value;
56.72 + /// \brief The type of the flow and supply values.
56.73 + typedef typename SupplyMap::Value Value;
56.74
56.75 /// \brief The type of the map that stores the flow values.
56.76 ///
56.77 /// The type of the map that stores the flow values.
56.78 - /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
56.79 + /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
56.80 + /// concept.
56.81 +#ifdef DOXYGEN
56.82 + typedef GR::ArcMap<Value> FlowMap;
56.83 +#else
56.84 typedef typename Digraph::template ArcMap<Value> FlowMap;
56.85 +#endif
56.86
56.87 /// \brief Instantiates a FlowMap.
56.88 ///
56.89 /// This function instantiates a \ref FlowMap.
56.90 - /// \param digraph The digraph, to which we would like to define
56.91 + /// \param digraph The digraph for which we would like to define
56.92 /// the flow map.
56.93 static FlowMap* createFlowMap(const Digraph& digraph) {
56.94 return new FlowMap(digraph);
56.95 @@ -86,14 +91,17 @@
56.96 ///
56.97 /// The elevator type used by the algorithm.
56.98 ///
56.99 - /// \sa Elevator
56.100 - /// \sa LinkedElevator
56.101 + /// \sa Elevator, LinkedElevator
56.102 +#ifdef DOXYGEN
56.103 + typedef lemon::Elevator<GR, GR::Node> Elevator;
56.104 +#else
56.105 typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
56.106 +#endif
56.107
56.108 /// \brief Instantiates an Elevator.
56.109 ///
56.110 /// This function instantiates an \ref Elevator.
56.111 - /// \param digraph The digraph, to which we would like to define
56.112 + /// \param digraph The digraph for which we would like to define
56.113 /// the elevator.
56.114 /// \param max_level The maximum level of the elevator.
56.115 static Elevator* createElevator(const Digraph& digraph, int max_level) {
56.116 @@ -111,73 +119,90 @@
56.117 \brief Push-relabel algorithm for the network circulation problem.
56.118
56.119 \ingroup max_flow
56.120 - This class implements a push-relabel algorithm for the network
56.121 - circulation problem.
56.122 + This class implements a push-relabel algorithm for the \e network
56.123 + \e circulation problem.
56.124 It is to find a feasible circulation when lower and upper bounds
56.125 - are given for the flow values on the arcs and lower bounds
56.126 - are given for the supply values of the nodes.
56.127 + are given for the flow values on the arcs and lower bounds are
56.128 + given for the difference between the outgoing and incoming flow
56.129 + at the nodes.
56.130
56.131 The exact formulation of this problem is the following.
56.132 - Let \f$G=(V,A)\f$ be a digraph,
56.133 - \f$lower, upper: A\rightarrow\mathbf{R}^+_0\f$,
56.134 - \f$delta: V\rightarrow\mathbf{R}\f$. Find a feasible circulation
56.135 - \f$f: A\rightarrow\mathbf{R}^+_0\f$ so that
56.136 - \f[ \sum_{a\in\delta_{out}(v)} f(a) - \sum_{a\in\delta_{in}(v)} f(a)
56.137 - \geq delta(v) \quad \forall v\in V, \f]
56.138 - \f[ lower(a)\leq f(a) \leq upper(a) \quad \forall a\in A. \f]
56.139 - \note \f$delta(v)\f$ specifies a lower bound for the supply of node
56.140 - \f$v\f$. It can be either positive or negative, however note that
56.141 - \f$\sum_{v\in V}delta(v)\f$ should be zero or negative in order to
56.142 - have a feasible solution.
56.143 + Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$
56.144 + \f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and
56.145 + upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$
56.146 + holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
56.147 + denotes the signed supply values of the nodes.
56.148 + If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
56.149 + supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
56.150 + \f$-sup(u)\f$ demand.
56.151 + A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$
56.152 + solution of the following problem.
56.153
56.154 - \note A special case of this problem is when
56.155 - \f$\sum_{v\in V}delta(v) = 0\f$. Then the supply of each node \f$v\f$
56.156 - will be \e equal \e to \f$delta(v)\f$, if a circulation can be found.
56.157 - Thus a feasible solution for the
56.158 - \ref min_cost_flow "minimum cost flow" problem can be calculated
56.159 - in this way.
56.160 + \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
56.161 + \geq sup(u) \quad \forall u\in V, \f]
56.162 + \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
56.163 +
56.164 + The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
56.165 + zero or negative in order to have a feasible solution (since the sum
56.166 + of the expressions on the left-hand side of the inequalities is zero).
56.167 + It means that the total demand must be greater or equal to the total
56.168 + supply and all the supplies have to be carried out from the supply nodes,
56.169 + but there could be demands that are not satisfied.
56.170 + If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
56.171 + constraints have to be satisfied with equality, i.e. all demands
56.172 + have to be satisfied and all supplies have to be used.
56.173 +
56.174 + If you need the opposite inequalities in the supply/demand constraints
56.175 + (i.e. the total demand is less than the total supply and all the demands
56.176 + have to be satisfied while there could be supplies that are not used),
56.177 + then you could easily transform the problem to the above form by reversing
56.178 + the direction of the arcs and taking the negative of the supply values
56.179 + (e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
56.180
56.181 - \tparam _Digraph The type of the digraph the algorithm runs on.
56.182 - \tparam _LCapMap The type of the lower bound capacity map. The default
56.183 - map type is \ref concepts::Digraph::ArcMap "_Digraph::ArcMap<int>".
56.184 - \tparam _UCapMap The type of the upper bound capacity map. The default
56.185 - map type is \c _LCapMap.
56.186 - \tparam _DeltaMap The type of the map that stores the lower bound
56.187 - for the supply of the nodes. The default map type is
56.188 - \c _Digraph::ArcMap<_UCapMap::Value>.
56.189 + This algorithm either calculates a feasible circulation, or provides
56.190 + a \ref barrier() "barrier", which prooves that a feasible soultion
56.191 + cannot exist.
56.192 +
56.193 + Note that this algorithm also provides a feasible solution for the
56.194 + \ref min_cost_flow "minimum cost flow problem".
56.195 +
56.196 + \tparam GR The type of the digraph the algorithm runs on.
56.197 + \tparam LM The type of the lower bound map. The default
56.198 + map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
56.199 + \tparam UM The type of the upper bound (capacity) map.
56.200 + The default map type is \c LM.
56.201 + \tparam SM The type of the supply map. The default map type is
56.202 + \ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>".
56.203 */
56.204 #ifdef DOXYGEN
56.205 -template< typename _Digraph,
56.206 - typename _LCapMap,
56.207 - typename _UCapMap,
56.208 - typename _DeltaMap,
56.209 - typename _Traits >
56.210 +template< typename GR,
56.211 + typename LM,
56.212 + typename UM,
56.213 + typename SM,
56.214 + typename TR >
56.215 #else
56.216 -template< typename _Digraph,
56.217 - typename _LCapMap = typename _Digraph::template ArcMap<int>,
56.218 - typename _UCapMap = _LCapMap,
56.219 - typename _DeltaMap = typename _Digraph::
56.220 - template NodeMap<typename _UCapMap::Value>,
56.221 - typename _Traits=CirculationDefaultTraits<_Digraph, _LCapMap,
56.222 - _UCapMap, _DeltaMap> >
56.223 +template< typename GR,
56.224 + typename LM = typename GR::template ArcMap<int>,
56.225 + typename UM = LM,
56.226 + typename SM = typename GR::template NodeMap<typename UM::Value>,
56.227 + typename TR = CirculationDefaultTraits<GR, LM, UM, SM> >
56.228 #endif
56.229 class Circulation {
56.230 public:
56.231
56.232 ///The \ref CirculationDefaultTraits "traits class" of the algorithm.
56.233 - typedef _Traits Traits;
56.234 + typedef TR Traits;
56.235 ///The type of the digraph the algorithm runs on.
56.236 typedef typename Traits::Digraph Digraph;
56.237 - ///The type of the flow values.
56.238 + ///The type of the flow and supply values.
56.239 typedef typename Traits::Value Value;
56.240
56.241 - /// The type of the lower bound capacity map.
56.242 - typedef typename Traits::LCapMap LCapMap;
56.243 - /// The type of the upper bound capacity map.
56.244 - typedef typename Traits::UCapMap UCapMap;
56.245 - /// \brief The type of the map that stores the lower bound for
56.246 - /// the supply of the nodes.
56.247 - typedef typename Traits::DeltaMap DeltaMap;
56.248 + ///The type of the lower bound map.
56.249 + typedef typename Traits::LowerMap LowerMap;
56.250 + ///The type of the upper bound (capacity) map.
56.251 + typedef typename Traits::UpperMap UpperMap;
56.252 + ///The type of the supply map.
56.253 + typedef typename Traits::SupplyMap SupplyMap;
56.254 ///The type of the flow map.
56.255 typedef typename Traits::FlowMap FlowMap;
56.256
56.257 @@ -193,9 +218,9 @@
56.258 const Digraph &_g;
56.259 int _node_num;
56.260
56.261 - const LCapMap *_lo;
56.262 - const UCapMap *_up;
56.263 - const DeltaMap *_delta;
56.264 + const LowerMap *_lo;
56.265 + const UpperMap *_up;
56.266 + const SupplyMap *_supply;
56.267
56.268 FlowMap *_flow;
56.269 bool _local_flow;
56.270 @@ -217,9 +242,9 @@
56.271
56.272 ///@{
56.273
56.274 - template <typename _FlowMap>
56.275 + template <typename T>
56.276 struct SetFlowMapTraits : public Traits {
56.277 - typedef _FlowMap FlowMap;
56.278 + typedef T FlowMap;
56.279 static FlowMap *createFlowMap(const Digraph&) {
56.280 LEMON_ASSERT(false, "FlowMap is not initialized");
56.281 return 0; // ignore warnings
56.282 @@ -231,17 +256,17 @@
56.283 ///
56.284 /// \ref named-templ-param "Named parameter" for setting FlowMap
56.285 /// type.
56.286 - template <typename _FlowMap>
56.287 + template <typename T>
56.288 struct SetFlowMap
56.289 - : public Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
56.290 - SetFlowMapTraits<_FlowMap> > {
56.291 - typedef Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
56.292 - SetFlowMapTraits<_FlowMap> > Create;
56.293 + : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
56.294 + SetFlowMapTraits<T> > {
56.295 + typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
56.296 + SetFlowMapTraits<T> > Create;
56.297 };
56.298
56.299 - template <typename _Elevator>
56.300 + template <typename T>
56.301 struct SetElevatorTraits : public Traits {
56.302 - typedef _Elevator Elevator;
56.303 + typedef T Elevator;
56.304 static Elevator *createElevator(const Digraph&, int) {
56.305 LEMON_ASSERT(false, "Elevator is not initialized");
56.306 return 0; // ignore warnings
56.307 @@ -257,17 +282,17 @@
56.308 /// \ref elevator(Elevator&) "elevator()" function before calling
56.309 /// \ref run() or \ref init().
56.310 /// \sa SetStandardElevator
56.311 - template <typename _Elevator>
56.312 + template <typename T>
56.313 struct SetElevator
56.314 - : public Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
56.315 - SetElevatorTraits<_Elevator> > {
56.316 - typedef Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
56.317 - SetElevatorTraits<_Elevator> > Create;
56.318 + : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
56.319 + SetElevatorTraits<T> > {
56.320 + typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
56.321 + SetElevatorTraits<T> > Create;
56.322 };
56.323
56.324 - template <typename _Elevator>
56.325 + template <typename T>
56.326 struct SetStandardElevatorTraits : public Traits {
56.327 - typedef _Elevator Elevator;
56.328 + typedef T Elevator;
56.329 static Elevator *createElevator(const Digraph& digraph, int max_level) {
56.330 return new Elevator(digraph, max_level);
56.331 }
56.332 @@ -285,12 +310,12 @@
56.333 /// algorithm with the \ref elevator(Elevator&) "elevator()" function
56.334 /// before calling \ref run() or \ref init().
56.335 /// \sa SetElevator
56.336 - template <typename _Elevator>
56.337 + template <typename T>
56.338 struct SetStandardElevator
56.339 - : public Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
56.340 - SetStandardElevatorTraits<_Elevator> > {
56.341 - typedef Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
56.342 - SetStandardElevatorTraits<_Elevator> > Create;
56.343 + : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
56.344 + SetStandardElevatorTraits<T> > {
56.345 + typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
56.346 + SetStandardElevatorTraits<T> > Create;
56.347 };
56.348
56.349 /// @}
56.350 @@ -301,18 +326,20 @@
56.351
56.352 public:
56.353
56.354 - /// The constructor of the class.
56.355 + /// Constructor.
56.356
56.357 /// The constructor of the class.
56.358 - /// \param g The digraph the algorithm runs on.
56.359 - /// \param lo The lower bound capacity of the arcs.
56.360 - /// \param up The upper bound capacity of the arcs.
56.361 - /// \param delta The lower bound for the supply of the nodes.
56.362 - Circulation(const Digraph &g,const LCapMap &lo,
56.363 - const UCapMap &up,const DeltaMap &delta)
56.364 - : _g(g), _node_num(),
56.365 - _lo(&lo),_up(&up),_delta(&delta),_flow(0),_local_flow(false),
56.366 - _level(0), _local_level(false), _excess(0), _el() {}
56.367 + ///
56.368 + /// \param graph The digraph the algorithm runs on.
56.369 + /// \param lower The lower bounds for the flow values on the arcs.
56.370 + /// \param upper The upper bounds (capacities) for the flow values
56.371 + /// on the arcs.
56.372 + /// \param supply The signed supply values of the nodes.
56.373 + Circulation(const Digraph &graph, const LowerMap &lower,
56.374 + const UpperMap &upper, const SupplyMap &supply)
56.375 + : _g(graph), _lo(&lower), _up(&upper), _supply(&supply),
56.376 + _flow(NULL), _local_flow(false), _level(NULL), _local_level(false),
56.377 + _excess(NULL) {}
56.378
56.379 /// Destructor.
56.380 ~Circulation() {
56.381 @@ -322,6 +349,13 @@
56.382
56.383 private:
56.384
56.385 + bool checkBoundMaps() {
56.386 + for (ArcIt e(_g);e!=INVALID;++e) {
56.387 + if (_tol.less((*_up)[e], (*_lo)[e])) return false;
56.388 + }
56.389 + return true;
56.390 + }
56.391 +
56.392 void createStructures() {
56.393 _node_num = _el = countNodes(_g);
56.394
56.395 @@ -352,30 +386,30 @@
56.396
56.397 public:
56.398
56.399 - /// Sets the lower bound capacity map.
56.400 + /// Sets the lower bound map.
56.401
56.402 - /// Sets the lower bound capacity map.
56.403 + /// Sets the lower bound map.
56.404 /// \return <tt>(*this)</tt>
56.405 - Circulation& lowerCapMap(const LCapMap& map) {
56.406 + Circulation& lowerMap(const LowerMap& map) {
56.407 _lo = ↦
56.408 return *this;
56.409 }
56.410
56.411 - /// Sets the upper bound capacity map.
56.412 + /// Sets the upper bound (capacity) map.
56.413
56.414 - /// Sets the upper bound capacity map.
56.415 + /// Sets the upper bound (capacity) map.
56.416 /// \return <tt>(*this)</tt>
56.417 - Circulation& upperCapMap(const LCapMap& map) {
56.418 + Circulation& upperMap(const UpperMap& map) {
56.419 _up = ↦
56.420 return *this;
56.421 }
56.422
56.423 - /// Sets the lower bound map for the supply of the nodes.
56.424 + /// Sets the supply map.
56.425
56.426 - /// Sets the lower bound map for the supply of the nodes.
56.427 + /// Sets the supply map.
56.428 /// \return <tt>(*this)</tt>
56.429 - Circulation& deltaMap(const DeltaMap& map) {
56.430 - _delta = ↦
56.431 + Circulation& supplyMap(const SupplyMap& map) {
56.432 + _supply = ↦
56.433 return *this;
56.434 }
56.435
56.436 @@ -423,25 +457,27 @@
56.437 return *_level;
56.438 }
56.439
56.440 - /// \brief Sets the tolerance used by algorithm.
56.441 + /// \brief Sets the tolerance used by the algorithm.
56.442 ///
56.443 - /// Sets the tolerance used by algorithm.
56.444 - Circulation& tolerance(const Tolerance& tolerance) const {
56.445 + /// Sets the tolerance object used by the algorithm.
56.446 + /// \return <tt>(*this)</tt>
56.447 + Circulation& tolerance(const Tolerance& tolerance) {
56.448 _tol = tolerance;
56.449 return *this;
56.450 }
56.451
56.452 /// \brief Returns a const reference to the tolerance.
56.453 ///
56.454 - /// Returns a const reference to the tolerance.
56.455 + /// Returns a const reference to the tolerance object used by
56.456 + /// the algorithm.
56.457 const Tolerance& tolerance() const {
56.458 - return tolerance;
56.459 + return _tol;
56.460 }
56.461
56.462 /// \name Execution Control
56.463 /// The simplest way to execute the algorithm is to call \ref run().\n
56.464 - /// If you need more control on the initial solution or the execution,
56.465 - /// first you have to call one of the \ref init() functions, then
56.466 + /// If you need better control on the initial solution or the execution,
56.467 + /// you have to call one of the \ref init() functions first, then
56.468 /// the \ref start() function.
56.469
56.470 ///@{
56.471 @@ -452,16 +488,19 @@
56.472 /// to the lower bound.
56.473 void init()
56.474 {
56.475 + LEMON_DEBUG(checkBoundMaps(),
56.476 + "Upper bounds must be greater or equal to the lower bounds");
56.477 +
56.478 createStructures();
56.479
56.480 for(NodeIt n(_g);n!=INVALID;++n) {
56.481 - _excess->set(n, (*_delta)[n]);
56.482 + (*_excess)[n] = (*_supply)[n];
56.483 }
56.484
56.485 for (ArcIt e(_g);e!=INVALID;++e) {
56.486 _flow->set(e, (*_lo)[e]);
56.487 - _excess->set(_g.target(e), (*_excess)[_g.target(e)] + (*_flow)[e]);
56.488 - _excess->set(_g.source(e), (*_excess)[_g.source(e)] - (*_flow)[e]);
56.489 + (*_excess)[_g.target(e)] += (*_flow)[e];
56.490 + (*_excess)[_g.source(e)] -= (*_flow)[e];
56.491 }
56.492
56.493 // global relabeling tested, but in general case it provides
56.494 @@ -481,26 +520,29 @@
56.495 /// to construct the initial solution.
56.496 void greedyInit()
56.497 {
56.498 + LEMON_DEBUG(checkBoundMaps(),
56.499 + "Upper bounds must be greater or equal to the lower bounds");
56.500 +
56.501 createStructures();
56.502
56.503 for(NodeIt n(_g);n!=INVALID;++n) {
56.504 - _excess->set(n, (*_delta)[n]);
56.505 + (*_excess)[n] = (*_supply)[n];
56.506 }
56.507
56.508 for (ArcIt e(_g);e!=INVALID;++e) {
56.509 - if (!_tol.positive((*_excess)[_g.target(e)] + (*_up)[e])) {
56.510 + if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) {
56.511 _flow->set(e, (*_up)[e]);
56.512 - _excess->set(_g.target(e), (*_excess)[_g.target(e)] + (*_up)[e]);
56.513 - _excess->set(_g.source(e), (*_excess)[_g.source(e)] - (*_up)[e]);
56.514 - } else if (_tol.positive((*_excess)[_g.target(e)] + (*_lo)[e])) {
56.515 + (*_excess)[_g.target(e)] += (*_up)[e];
56.516 + (*_excess)[_g.source(e)] -= (*_up)[e];
56.517 + } else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) {
56.518 _flow->set(e, (*_lo)[e]);
56.519 - _excess->set(_g.target(e), (*_excess)[_g.target(e)] + (*_lo)[e]);
56.520 - _excess->set(_g.source(e), (*_excess)[_g.source(e)] - (*_lo)[e]);
56.521 + (*_excess)[_g.target(e)] += (*_lo)[e];
56.522 + (*_excess)[_g.source(e)] -= (*_lo)[e];
56.523 } else {
56.524 Value fc = -(*_excess)[_g.target(e)];
56.525 _flow->set(e, fc);
56.526 - _excess->set(_g.target(e), 0);
56.527 - _excess->set(_g.source(e), (*_excess)[_g.source(e)] - fc);
56.528 + (*_excess)[_g.target(e)] = 0;
56.529 + (*_excess)[_g.source(e)] -= fc;
56.530 }
56.531 }
56.532
56.533 @@ -539,16 +581,16 @@
56.534 if((*_level)[v]<actlevel) {
56.535 if(!_tol.less(fc, exc)) {
56.536 _flow->set(e, (*_flow)[e] + exc);
56.537 - _excess->set(v, (*_excess)[v] + exc);
56.538 + (*_excess)[v] += exc;
56.539 if(!_level->active(v) && _tol.positive((*_excess)[v]))
56.540 _level->activate(v);
56.541 - _excess->set(act,0);
56.542 + (*_excess)[act] = 0;
56.543 _level->deactivate(act);
56.544 goto next_l;
56.545 }
56.546 else {
56.547 _flow->set(e, (*_up)[e]);
56.548 - _excess->set(v, (*_excess)[v] + fc);
56.549 + (*_excess)[v] += fc;
56.550 if(!_level->active(v) && _tol.positive((*_excess)[v]))
56.551 _level->activate(v);
56.552 exc-=fc;
56.553 @@ -563,16 +605,16 @@
56.554 if((*_level)[v]<actlevel) {
56.555 if(!_tol.less(fc, exc)) {
56.556 _flow->set(e, (*_flow)[e] - exc);
56.557 - _excess->set(v, (*_excess)[v] + exc);
56.558 + (*_excess)[v] += exc;
56.559 if(!_level->active(v) && _tol.positive((*_excess)[v]))
56.560 _level->activate(v);
56.561 - _excess->set(act,0);
56.562 + (*_excess)[act] = 0;
56.563 _level->deactivate(act);
56.564 goto next_l;
56.565 }
56.566 else {
56.567 _flow->set(e, (*_lo)[e]);
56.568 - _excess->set(v, (*_excess)[v] + fc);
56.569 + (*_excess)[v] += fc;
56.570 if(!_level->active(v) && _tol.positive((*_excess)[v]))
56.571 _level->activate(v);
56.572 exc-=fc;
56.573 @@ -581,7 +623,7 @@
56.574 else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
56.575 }
56.576
56.577 - _excess->set(act, exc);
56.578 + (*_excess)[act] = exc;
56.579 if(!_tol.positive(exc)) _level->deactivate(act);
56.580 else if(mlevel==_node_num) {
56.581 _level->liftHighestActiveToTop();
56.582 @@ -628,9 +670,9 @@
56.583
56.584 ///@{
56.585
56.586 - /// \brief Returns the flow on the given arc.
56.587 + /// \brief Returns the flow value on the given arc.
56.588 ///
56.589 - /// Returns the flow on the given arc.
56.590 + /// Returns the flow value on the given arc.
56.591 ///
56.592 /// \pre Either \ref run() or \ref init() must be called before
56.593 /// using this function.
56.594 @@ -653,8 +695,8 @@
56.595
56.596 Barrier is a set \e B of nodes for which
56.597
56.598 - \f[ \sum_{a\in\delta_{out}(B)} upper(a) -
56.599 - \sum_{a\in\delta_{in}(B)} lower(a) < \sum_{v\in B}delta(v) \f]
56.600 + \f[ \sum_{uv\in A: u\in B} upper(uv) -
56.601 + \sum_{uv\in A: v\in B} lower(uv) < \sum_{v\in B} sup(v) \f]
56.602
56.603 holds. The existence of a set with this property prooves that a
56.604 feasible circualtion cannot exist.
56.605 @@ -684,7 +726,7 @@
56.606 /// empty set, so \c bar[v] will be \c false for all nodes \c v.
56.607 ///
56.608 /// \note This function calls \ref barrier() for each node,
56.609 - /// so it runs in \f$O(n)\f$ time.
56.610 + /// so it runs in O(n) time.
56.611 ///
56.612 /// \pre Either \ref run() or \ref init() must be called before
56.613 /// using this function.
56.614 @@ -717,7 +759,7 @@
56.615 if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false;
56.616 for(NodeIt n(_g);n!=INVALID;++n)
56.617 {
56.618 - Value dif=-(*_delta)[n];
56.619 + Value dif=-(*_supply)[n];
56.620 for(InArcIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e];
56.621 for(OutArcIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e];
56.622 if(_tol.negative(dif)) return false;
56.623 @@ -733,14 +775,20 @@
56.624 bool checkBarrier() const
56.625 {
56.626 Value delta=0;
56.627 + Value inf_cap = std::numeric_limits<Value>::has_infinity ?
56.628 + std::numeric_limits<Value>::infinity() :
56.629 + std::numeric_limits<Value>::max();
56.630 for(NodeIt n(_g);n!=INVALID;++n)
56.631 if(barrier(n))
56.632 - delta-=(*_delta)[n];
56.633 + delta-=(*_supply)[n];
56.634 for(ArcIt e(_g);e!=INVALID;++e)
56.635 {
56.636 Node s=_g.source(e);
56.637 Node t=_g.target(e);
56.638 - if(barrier(s)&&!barrier(t)) delta+=(*_up)[e];
56.639 + if(barrier(s)&&!barrier(t)) {
56.640 + if (_tol.less(inf_cap - (*_up)[e], delta)) return false;
56.641 + delta+=(*_up)[e];
56.642 + }
56.643 else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
56.644 }
56.645 return _tol.negative(delta);
57.1 --- a/lemon/clp.cc Mon Jan 12 23:11:39 2009 +0100
57.2 +++ b/lemon/clp.cc Thu Nov 05 15:48:01 2009 +0100
57.3 @@ -24,7 +24,7 @@
57.4 ClpLp::ClpLp() {
57.5 _prob = new ClpSimplex();
57.6 _init_temporals();
57.7 - messageLevel(MESSAGE_NO_OUTPUT);
57.8 + messageLevel(MESSAGE_NOTHING);
57.9 }
57.10
57.11 ClpLp::ClpLp(const ClpLp& other) {
57.12 @@ -32,7 +32,7 @@
57.13 rows = other.rows;
57.14 cols = other.cols;
57.15 _init_temporals();
57.16 - messageLevel(MESSAGE_NO_OUTPUT);
57.17 + messageLevel(MESSAGE_NOTHING);
57.18 }
57.19
57.20 ClpLp::~ClpLp() {
57.21 @@ -56,12 +56,12 @@
57.22 }
57.23 }
57.24
57.25 - ClpLp* ClpLp::_newSolver() const {
57.26 + ClpLp* ClpLp::newSolver() const {
57.27 ClpLp* newlp = new ClpLp;
57.28 return newlp;
57.29 }
57.30
57.31 - ClpLp* ClpLp::_cloneSolver() const {
57.32 + ClpLp* ClpLp::cloneSolver() const {
57.33 ClpLp* copylp = new ClpLp(*this);
57.34 return copylp;
57.35 }
57.36 @@ -78,6 +78,19 @@
57.37 return _prob->numberRows() - 1;
57.38 }
57.39
57.40 + int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
57.41 + std::vector<int> indexes;
57.42 + std::vector<Value> values;
57.43 +
57.44 + for(ExprIterator it = b; it != e; ++it) {
57.45 + indexes.push_back(it->first);
57.46 + values.push_back(it->second);
57.47 + }
57.48 +
57.49 + _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
57.50 + return _prob->numberRows() - 1;
57.51 + }
57.52 +
57.53
57.54 void ClpLp::_eraseCol(int c) {
57.55 _col_names_ref.erase(_prob->getColumnName(c));
57.56 @@ -430,8 +443,24 @@
57.57 _clear_temporals();
57.58 }
57.59
57.60 - void ClpLp::messageLevel(MessageLevel m) {
57.61 - _prob->setLogLevel(static_cast<int>(m));
57.62 + void ClpLp::_messageLevel(MessageLevel level) {
57.63 + switch (level) {
57.64 + case MESSAGE_NOTHING:
57.65 + _prob->setLogLevel(0);
57.66 + break;
57.67 + case MESSAGE_ERROR:
57.68 + _prob->setLogLevel(1);
57.69 + break;
57.70 + case MESSAGE_WARNING:
57.71 + _prob->setLogLevel(2);
57.72 + break;
57.73 + case MESSAGE_NORMAL:
57.74 + _prob->setLogLevel(3);
57.75 + break;
57.76 + case MESSAGE_VERBOSE:
57.77 + _prob->setLogLevel(4);
57.78 + break;
57.79 + }
57.80 }
57.81
57.82 } //END OF NAMESPACE LEMON
58.1 --- a/lemon/clp.h Mon Jan 12 23:11:39 2009 +0100
58.2 +++ b/lemon/clp.h Thu Nov 05 15:48:01 2009 +0100
58.3 @@ -56,6 +56,11 @@
58.4 /// \e
58.5 ~ClpLp();
58.6
58.7 + /// \e
58.8 + virtual ClpLp* newSolver() const;
58.9 + /// \e
58.10 + virtual ClpLp* cloneSolver() const;
58.11 +
58.12 protected:
58.13
58.14 mutable double* _primal_ray;
58.15 @@ -66,13 +71,11 @@
58.16
58.17 protected:
58.18
58.19 - virtual ClpLp* _newSolver() const;
58.20 - virtual ClpLp* _cloneSolver() const;
58.21 -
58.22 virtual const char* _solverName() const;
58.23
58.24 virtual int _addCol();
58.25 virtual int _addRow();
58.26 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
58.27
58.28 virtual void _eraseCol(int i);
58.29 virtual void _eraseRow(int i);
58.30 @@ -134,6 +137,8 @@
58.31
58.32 virtual void _clear();
58.33
58.34 + virtual void _messageLevel(MessageLevel);
58.35 +
58.36 public:
58.37
58.38 ///Solves LP with primal simplex method.
58.39 @@ -151,26 +156,6 @@
58.40 ///Returns the variable identifier understood by CLP.
58.41 int clpCol(Col c) const { return cols(id(c)); }
58.42
58.43 - ///Enum for \c messageLevel() parameter
58.44 - enum MessageLevel {
58.45 - /// no output (default value)
58.46 - MESSAGE_NO_OUTPUT = 0,
58.47 - /// print final solution
58.48 - MESSAGE_FINAL_SOLUTION = 1,
58.49 - /// print factorization
58.50 - MESSAGE_FACTORIZATION = 2,
58.51 - /// normal output
58.52 - MESSAGE_NORMAL_OUTPUT = 3,
58.53 - /// verbose output
58.54 - MESSAGE_VERBOSE_OUTPUT = 4
58.55 - };
58.56 - ///Set the verbosity of the messages
58.57 -
58.58 - ///Set the verbosity of the messages
58.59 - ///
58.60 - ///\param m is the level of the messages output by the solver routines.
58.61 - void messageLevel(MessageLevel m);
58.62 -
58.63 };
58.64
58.65 } //END OF NAMESPACE LEMON
59.1 --- a/lemon/concepts/digraph.h Mon Jan 12 23:11:39 2009 +0100
59.2 +++ b/lemon/concepts/digraph.h Thu Nov 05 15:48:01 2009 +0100
59.3 @@ -16,8 +16,8 @@
59.4 *
59.5 */
59.6
59.7 -#ifndef LEMON_CONCEPT_DIGRAPH_H
59.8 -#define LEMON_CONCEPT_DIGRAPH_H
59.9 +#ifndef LEMON_CONCEPTS_DIGRAPH_H
59.10 +#define LEMON_CONCEPTS_DIGRAPH_H
59.11
59.12 ///\ingroup graph_concepts
59.13 ///\file
59.14 @@ -35,46 +35,40 @@
59.15 ///
59.16 /// \brief Class describing the concept of directed graphs.
59.17 ///
59.18 - /// This class describes the \ref concept "concept" of the
59.19 - /// immutable directed digraphs.
59.20 + /// This class describes the common interface of all directed
59.21 + /// graphs (digraphs).
59.22 ///
59.23 - /// Note that actual digraph implementation like @ref ListDigraph or
59.24 - /// @ref SmartDigraph may have several additional functionality.
59.25 + /// Like all concept classes, it only provides an interface
59.26 + /// without any sensible implementation. So any general algorithm for
59.27 + /// directed graphs should compile with this class, but it will not
59.28 + /// run properly, of course.
59.29 + /// An actual digraph implementation like \ref ListDigraph or
59.30 + /// \ref SmartDigraph may have additional functionality.
59.31 ///
59.32 - /// \sa concept
59.33 + /// \sa Graph
59.34 class Digraph {
59.35 private:
59.36 - ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
59.37 + /// Diraphs are \e not copy constructible. Use DigraphCopy instead.
59.38 + Digraph(const Digraph &) {}
59.39 + /// \brief Assignment of a digraph to another one is \e not allowed.
59.40 + /// Use DigraphCopy instead.
59.41 + void operator=(const Digraph &) {}
59.42
59.43 - ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
59.44 - ///
59.45 - Digraph(const Digraph &) {};
59.46 - ///\brief Assignment of \ref Digraph "Digraph"s to another ones are
59.47 - ///\e not allowed. Use DigraphCopy() instead.
59.48 + public:
59.49 + /// Default constructor.
59.50 + Digraph() { }
59.51
59.52 - ///Assignment of \ref Digraph "Digraph"s to another ones are
59.53 - ///\e not allowed. Use DigraphCopy() instead.
59.54 -
59.55 - void operator=(const Digraph &) {}
59.56 - public:
59.57 - ///\e
59.58 -
59.59 - /// Defalult constructor.
59.60 -
59.61 - /// Defalult constructor.
59.62 - ///
59.63 - Digraph() { }
59.64 - /// Class for identifying a node of the digraph
59.65 + /// The node type of the digraph
59.66
59.67 /// This class identifies a node of the digraph. It also serves
59.68 /// as a base class of the node iterators,
59.69 - /// thus they will convert to this type.
59.70 + /// thus they convert to this type.
59.71 class Node {
59.72 public:
59.73 /// Default constructor
59.74
59.75 - /// @warning The default constructor sets the iterator
59.76 - /// to an undefined value.
59.77 + /// Default constructor.
59.78 + /// \warning It sets the object to an undefined value.
59.79 Node() { }
59.80 /// Copy constructor.
59.81
59.82 @@ -82,40 +76,39 @@
59.83 ///
59.84 Node(const Node&) { }
59.85
59.86 - /// Invalid constructor \& conversion.
59.87 + /// %Invalid constructor \& conversion.
59.88
59.89 - /// This constructor initializes the iterator to be invalid.
59.90 + /// Initializes the object to be invalid.
59.91 /// \sa Invalid for more details.
59.92 Node(Invalid) { }
59.93 /// Equality operator
59.94
59.95 + /// Equality operator.
59.96 + ///
59.97 /// Two iterators are equal if and only if they point to the
59.98 - /// same object or both are invalid.
59.99 + /// same object or both are \c INVALID.
59.100 bool operator==(Node) const { return true; }
59.101
59.102 /// Inequality operator
59.103
59.104 - /// \sa operator==(Node n)
59.105 - ///
59.106 + /// Inequality operator.
59.107 bool operator!=(Node) const { return true; }
59.108
59.109 /// Artificial ordering operator.
59.110
59.111 - /// To allow the use of digraph descriptors as key type in std::map or
59.112 - /// similar associative container we require this.
59.113 + /// Artificial ordering operator.
59.114 ///
59.115 - /// \note This operator only have to define some strict ordering of
59.116 - /// the items; this order has nothing to do with the iteration
59.117 - /// ordering of the items.
59.118 + /// \note This operator only has to define some strict ordering of
59.119 + /// the nodes; this order has nothing to do with the iteration
59.120 + /// ordering of the nodes.
59.121 bool operator<(Node) const { return false; }
59.122 -
59.123 };
59.124
59.125 - /// This iterator goes through each node.
59.126 + /// Iterator class for the nodes.
59.127
59.128 - /// This iterator goes through each node.
59.129 + /// This iterator goes through each node of the digraph.
59.130 /// Its usage is quite simple, for example you can count the number
59.131 - /// of nodes in digraph \c g of type \c Digraph like this:
59.132 + /// of nodes in a digraph \c g of type \c %Digraph like this:
59.133 ///\code
59.134 /// int count=0;
59.135 /// for (Digraph::NodeIt n(g); n!=INVALID; ++n) ++count;
59.136 @@ -124,30 +117,28 @@
59.137 public:
59.138 /// Default constructor
59.139
59.140 - /// @warning The default constructor sets the iterator
59.141 - /// to an undefined value.
59.142 + /// Default constructor.
59.143 + /// \warning It sets the iterator to an undefined value.
59.144 NodeIt() { }
59.145 /// Copy constructor.
59.146
59.147 /// Copy constructor.
59.148 ///
59.149 NodeIt(const NodeIt& n) : Node(n) { }
59.150 - /// Invalid constructor \& conversion.
59.151 + /// %Invalid constructor \& conversion.
59.152
59.153 - /// Initialize the iterator to be invalid.
59.154 + /// Initializes the iterator to be invalid.
59.155 /// \sa Invalid for more details.
59.156 NodeIt(Invalid) { }
59.157 /// Sets the iterator to the first node.
59.158
59.159 - /// Sets the iterator to the first node of \c g.
59.160 + /// Sets the iterator to the first node of the given digraph.
59.161 ///
59.162 - NodeIt(const Digraph&) { }
59.163 - /// Node -> NodeIt conversion.
59.164 + explicit NodeIt(const Digraph&) { }
59.165 + /// Sets the iterator to the given node.
59.166
59.167 - /// Sets the iterator to the node of \c the digraph pointed by
59.168 - /// the trivial iterator.
59.169 - /// This feature necessitates that each time we
59.170 - /// iterate the arc-set, the iteration order is the same.
59.171 + /// Sets the iterator to the given node of the given digraph.
59.172 + ///
59.173 NodeIt(const Digraph&, const Node&) { }
59.174 /// Next node.
59.175
59.176 @@ -157,7 +148,7 @@
59.177 };
59.178
59.179
59.180 - /// Class for identifying an arc of the digraph
59.181 + /// The arc type of the digraph
59.182
59.183 /// This class identifies an arc of the digraph. It also serves
59.184 /// as a base class of the arc iterators,
59.185 @@ -166,207 +157,214 @@
59.186 public:
59.187 /// Default constructor
59.188
59.189 - /// @warning The default constructor sets the iterator
59.190 - /// to an undefined value.
59.191 + /// Default constructor.
59.192 + /// \warning It sets the object to an undefined value.
59.193 Arc() { }
59.194 /// Copy constructor.
59.195
59.196 /// Copy constructor.
59.197 ///
59.198 Arc(const Arc&) { }
59.199 - /// Initialize the iterator to be invalid.
59.200 + /// %Invalid constructor \& conversion.
59.201
59.202 - /// Initialize the iterator to be invalid.
59.203 - ///
59.204 + /// Initializes the object to be invalid.
59.205 + /// \sa Invalid for more details.
59.206 Arc(Invalid) { }
59.207 /// Equality operator
59.208
59.209 + /// Equality operator.
59.210 + ///
59.211 /// Two iterators are equal if and only if they point to the
59.212 - /// same object or both are invalid.
59.213 + /// same object or both are \c INVALID.
59.214 bool operator==(Arc) const { return true; }
59.215 /// Inequality operator
59.216
59.217 - /// \sa operator==(Arc n)
59.218 - ///
59.219 + /// Inequality operator.
59.220 bool operator!=(Arc) const { return true; }
59.221
59.222 /// Artificial ordering operator.
59.223
59.224 - /// To allow the use of digraph descriptors as key type in std::map or
59.225 - /// similar associative container we require this.
59.226 + /// Artificial ordering operator.
59.227 ///
59.228 - /// \note This operator only have to define some strict ordering of
59.229 - /// the items; this order has nothing to do with the iteration
59.230 - /// ordering of the items.
59.231 + /// \note This operator only has to define some strict ordering of
59.232 + /// the arcs; this order has nothing to do with the iteration
59.233 + /// ordering of the arcs.
59.234 bool operator<(Arc) const { return false; }
59.235 };
59.236
59.237 - /// This iterator goes trough the outgoing arcs of a node.
59.238 + /// Iterator class for the outgoing arcs of a node.
59.239
59.240 /// This iterator goes trough the \e outgoing arcs of a certain node
59.241 /// of a digraph.
59.242 /// Its usage is quite simple, for example you can count the number
59.243 /// of outgoing arcs of a node \c n
59.244 - /// in digraph \c g of type \c Digraph as follows.
59.245 + /// in a digraph \c g of type \c %Digraph as follows.
59.246 ///\code
59.247 /// int count=0;
59.248 - /// for (Digraph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
59.249 + /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
59.250 ///\endcode
59.251 -
59.252 class OutArcIt : public Arc {
59.253 public:
59.254 /// Default constructor
59.255
59.256 - /// @warning The default constructor sets the iterator
59.257 - /// to an undefined value.
59.258 + /// Default constructor.
59.259 + /// \warning It sets the iterator to an undefined value.
59.260 OutArcIt() { }
59.261 /// Copy constructor.
59.262
59.263 /// Copy constructor.
59.264 ///
59.265 OutArcIt(const OutArcIt& e) : Arc(e) { }
59.266 - /// Initialize the iterator to be invalid.
59.267 + /// %Invalid constructor \& conversion.
59.268
59.269 - /// Initialize the iterator to be invalid.
59.270 + /// Initializes the iterator to be invalid.
59.271 + /// \sa Invalid for more details.
59.272 + OutArcIt(Invalid) { }
59.273 + /// Sets the iterator to the first outgoing arc.
59.274 +
59.275 + /// Sets the iterator to the first outgoing arc of the given node.
59.276 ///
59.277 - OutArcIt(Invalid) { }
59.278 - /// This constructor sets the iterator to the first outgoing arc.
59.279 + OutArcIt(const Digraph&, const Node&) { }
59.280 + /// Sets the iterator to the given arc.
59.281
59.282 - /// This constructor sets the iterator to the first outgoing arc of
59.283 - /// the node.
59.284 - OutArcIt(const Digraph&, const Node&) { }
59.285 - /// Arc -> OutArcIt conversion
59.286 -
59.287 - /// Sets the iterator to the value of the trivial iterator.
59.288 - /// This feature necessitates that each time we
59.289 - /// iterate the arc-set, the iteration order is the same.
59.290 + /// Sets the iterator to the given arc of the given digraph.
59.291 + ///
59.292 OutArcIt(const Digraph&, const Arc&) { }
59.293 - ///Next outgoing arc
59.294 + /// Next outgoing arc
59.295
59.296 /// Assign the iterator to the next
59.297 /// outgoing arc of the corresponding node.
59.298 OutArcIt& operator++() { return *this; }
59.299 };
59.300
59.301 - /// This iterator goes trough the incoming arcs of a node.
59.302 + /// Iterator class for the incoming arcs of a node.
59.303
59.304 /// This iterator goes trough the \e incoming arcs of a certain node
59.305 /// of a digraph.
59.306 /// Its usage is quite simple, for example you can count the number
59.307 - /// of outgoing arcs of a node \c n
59.308 - /// in digraph \c g of type \c Digraph as follows.
59.309 + /// of incoming arcs of a node \c n
59.310 + /// in a digraph \c g of type \c %Digraph as follows.
59.311 ///\code
59.312 /// int count=0;
59.313 - /// for(Digraph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
59.314 + /// for(Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
59.315 ///\endcode
59.316 -
59.317 class InArcIt : public Arc {
59.318 public:
59.319 /// Default constructor
59.320
59.321 - /// @warning The default constructor sets the iterator
59.322 - /// to an undefined value.
59.323 + /// Default constructor.
59.324 + /// \warning It sets the iterator to an undefined value.
59.325 InArcIt() { }
59.326 /// Copy constructor.
59.327
59.328 /// Copy constructor.
59.329 ///
59.330 InArcIt(const InArcIt& e) : Arc(e) { }
59.331 - /// Initialize the iterator to be invalid.
59.332 + /// %Invalid constructor \& conversion.
59.333
59.334 - /// Initialize the iterator to be invalid.
59.335 + /// Initializes the iterator to be invalid.
59.336 + /// \sa Invalid for more details.
59.337 + InArcIt(Invalid) { }
59.338 + /// Sets the iterator to the first incoming arc.
59.339 +
59.340 + /// Sets the iterator to the first incoming arc of the given node.
59.341 ///
59.342 - InArcIt(Invalid) { }
59.343 - /// This constructor sets the iterator to first incoming arc.
59.344 + InArcIt(const Digraph&, const Node&) { }
59.345 + /// Sets the iterator to the given arc.
59.346
59.347 - /// This constructor set the iterator to the first incoming arc of
59.348 - /// the node.
59.349 - InArcIt(const Digraph&, const Node&) { }
59.350 - /// Arc -> InArcIt conversion
59.351 -
59.352 - /// Sets the iterator to the value of the trivial iterator \c e.
59.353 - /// This feature necessitates that each time we
59.354 - /// iterate the arc-set, the iteration order is the same.
59.355 + /// Sets the iterator to the given arc of the given digraph.
59.356 + ///
59.357 InArcIt(const Digraph&, const Arc&) { }
59.358 /// Next incoming arc
59.359
59.360 - /// Assign the iterator to the next inarc of the corresponding node.
59.361 - ///
59.362 + /// Assign the iterator to the next
59.363 + /// incoming arc of the corresponding node.
59.364 InArcIt& operator++() { return *this; }
59.365 };
59.366 - /// This iterator goes through each arc.
59.367
59.368 - /// This iterator goes through each arc of a digraph.
59.369 + /// Iterator class for the arcs.
59.370 +
59.371 + /// This iterator goes through each arc of the digraph.
59.372 /// Its usage is quite simple, for example you can count the number
59.373 - /// of arcs in a digraph \c g of type \c Digraph as follows:
59.374 + /// of arcs in a digraph \c g of type \c %Digraph as follows:
59.375 ///\code
59.376 /// int count=0;
59.377 - /// for(Digraph::ArcIt e(g); e!=INVALID; ++e) ++count;
59.378 + /// for(Digraph::ArcIt a(g); a!=INVALID; ++a) ++count;
59.379 ///\endcode
59.380 class ArcIt : public Arc {
59.381 public:
59.382 /// Default constructor
59.383
59.384 - /// @warning The default constructor sets the iterator
59.385 - /// to an undefined value.
59.386 + /// Default constructor.
59.387 + /// \warning It sets the iterator to an undefined value.
59.388 ArcIt() { }
59.389 /// Copy constructor.
59.390
59.391 /// Copy constructor.
59.392 ///
59.393 ArcIt(const ArcIt& e) : Arc(e) { }
59.394 - /// Initialize the iterator to be invalid.
59.395 + /// %Invalid constructor \& conversion.
59.396
59.397 - /// Initialize the iterator to be invalid.
59.398 + /// Initializes the iterator to be invalid.
59.399 + /// \sa Invalid for more details.
59.400 + ArcIt(Invalid) { }
59.401 + /// Sets the iterator to the first arc.
59.402 +
59.403 + /// Sets the iterator to the first arc of the given digraph.
59.404 ///
59.405 - ArcIt(Invalid) { }
59.406 - /// This constructor sets the iterator to the first arc.
59.407 + explicit ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
59.408 + /// Sets the iterator to the given arc.
59.409
59.410 - /// This constructor sets the iterator to the first arc of \c g.
59.411 - ///@param g the digraph
59.412 - ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
59.413 - /// Arc -> ArcIt conversion
59.414 -
59.415 - /// Sets the iterator to the value of the trivial iterator \c e.
59.416 - /// This feature necessitates that each time we
59.417 - /// iterate the arc-set, the iteration order is the same.
59.418 + /// Sets the iterator to the given arc of the given digraph.
59.419 + ///
59.420 ArcIt(const Digraph&, const Arc&) { }
59.421 - ///Next arc
59.422 + /// Next arc
59.423
59.424 /// Assign the iterator to the next arc.
59.425 + ///
59.426 ArcIt& operator++() { return *this; }
59.427 };
59.428 - ///Gives back the target node of an arc.
59.429
59.430 - ///Gives back the target node of an arc.
59.431 + /// \brief The source node of the arc.
59.432 ///
59.433 - Node target(Arc) const { return INVALID; }
59.434 - ///Gives back the source node of an arc.
59.435 -
59.436 - ///Gives back the source node of an arc.
59.437 - ///
59.438 + /// Returns the source node of the given arc.
59.439 Node source(Arc) const { return INVALID; }
59.440
59.441 - /// \brief Returns the ID of the node.
59.442 + /// \brief The target node of the arc.
59.443 + ///
59.444 + /// Returns the target node of the given arc.
59.445 + Node target(Arc) const { return INVALID; }
59.446 +
59.447 + /// \brief The ID of the node.
59.448 + ///
59.449 + /// Returns the ID of the given node.
59.450 int id(Node) const { return -1; }
59.451
59.452 - /// \brief Returns the ID of the arc.
59.453 + /// \brief The ID of the arc.
59.454 + ///
59.455 + /// Returns the ID of the given arc.
59.456 int id(Arc) const { return -1; }
59.457
59.458 - /// \brief Returns the node with the given ID.
59.459 + /// \brief The node with the given ID.
59.460 ///
59.461 - /// \pre The argument should be a valid node ID in the graph.
59.462 + /// Returns the node with the given ID.
59.463 + /// \pre The argument should be a valid node ID in the digraph.
59.464 Node nodeFromId(int) const { return INVALID; }
59.465
59.466 - /// \brief Returns the arc with the given ID.
59.467 + /// \brief The arc with the given ID.
59.468 ///
59.469 - /// \pre The argument should be a valid arc ID in the graph.
59.470 + /// Returns the arc with the given ID.
59.471 + /// \pre The argument should be a valid arc ID in the digraph.
59.472 Arc arcFromId(int) const { return INVALID; }
59.473
59.474 - /// \brief Returns an upper bound on the node IDs.
59.475 + /// \brief An upper bound on the node IDs.
59.476 + ///
59.477 + /// Returns an upper bound on the node IDs.
59.478 int maxNodeId() const { return -1; }
59.479
59.480 - /// \brief Returns an upper bound on the arc IDs.
59.481 + /// \brief An upper bound on the arc IDs.
59.482 + ///
59.483 + /// Returns an upper bound on the arc IDs.
59.484 int maxArcId() const { return -1; }
59.485
59.486 void first(Node&) const {}
59.487 @@ -392,51 +390,52 @@
59.488 // Dummy parameter.
59.489 int maxId(Arc) const { return -1; }
59.490
59.491 + /// \brief The opposite node on the arc.
59.492 + ///
59.493 + /// Returns the opposite node on the given arc.
59.494 + Node oppositeNode(Node, Arc) const { return INVALID; }
59.495 +
59.496 /// \brief The base node of the iterator.
59.497 ///
59.498 - /// Gives back the base node of the iterator.
59.499 - /// It is always the target of the pointed arc.
59.500 - Node baseNode(const InArcIt&) const { return INVALID; }
59.501 + /// Returns the base node of the given outgoing arc iterator
59.502 + /// (i.e. the source node of the corresponding arc).
59.503 + Node baseNode(OutArcIt) const { return INVALID; }
59.504
59.505 /// \brief The running node of the iterator.
59.506 ///
59.507 - /// Gives back the running node of the iterator.
59.508 - /// It is always the source of the pointed arc.
59.509 - Node runningNode(const InArcIt&) const { return INVALID; }
59.510 + /// Returns the running node of the given outgoing arc iterator
59.511 + /// (i.e. the target node of the corresponding arc).
59.512 + Node runningNode(OutArcIt) const { return INVALID; }
59.513
59.514 /// \brief The base node of the iterator.
59.515 ///
59.516 - /// Gives back the base node of the iterator.
59.517 - /// It is always the source of the pointed arc.
59.518 - Node baseNode(const OutArcIt&) const { return INVALID; }
59.519 + /// Returns the base node of the given incomming arc iterator
59.520 + /// (i.e. the target node of the corresponding arc).
59.521 + Node baseNode(InArcIt) const { return INVALID; }
59.522
59.523 /// \brief The running node of the iterator.
59.524 ///
59.525 - /// Gives back the running node of the iterator.
59.526 - /// It is always the target of the pointed arc.
59.527 - Node runningNode(const OutArcIt&) const { return INVALID; }
59.528 + /// Returns the running node of the given incomming arc iterator
59.529 + /// (i.e. the source node of the corresponding arc).
59.530 + Node runningNode(InArcIt) const { return INVALID; }
59.531
59.532 - /// \brief The opposite node on the given arc.
59.533 + /// \brief Standard graph map type for the nodes.
59.534 ///
59.535 - /// Gives back the opposite node on the given arc.
59.536 - Node oppositeNode(const Node&, const Arc&) const { return INVALID; }
59.537 -
59.538 - /// \brief Read write map of the nodes to type \c T.
59.539 - ///
59.540 - /// ReadWrite map of the nodes to type \c T.
59.541 - /// \sa Reference
59.542 + /// Standard graph map type for the nodes.
59.543 + /// It conforms to the ReferenceMap concept.
59.544 template<class T>
59.545 - class NodeMap : public ReadWriteMap< Node, T > {
59.546 + class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
59.547 public:
59.548
59.549 - ///\e
59.550 - NodeMap(const Digraph&) { }
59.551 - ///\e
59.552 + /// Constructor
59.553 + explicit NodeMap(const Digraph&) { }
59.554 + /// Constructor with given initial value
59.555 NodeMap(const Digraph&, T) { }
59.556
59.557 private:
59.558 ///Copy constructor
59.559 - NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
59.560 + NodeMap(const NodeMap& nm) :
59.561 + ReferenceMap<Node, T, T&, const T&>(nm) { }
59.562 ///Assignment operator
59.563 template <typename CMap>
59.564 NodeMap& operator=(const CMap&) {
59.565 @@ -445,21 +444,23 @@
59.566 }
59.567 };
59.568
59.569 - /// \brief Read write map of the arcs to type \c T.
59.570 + /// \brief Standard graph map type for the arcs.
59.571 ///
59.572 - /// Reference map of the arcs to type \c T.
59.573 - /// \sa Reference
59.574 + /// Standard graph map type for the arcs.
59.575 + /// It conforms to the ReferenceMap concept.
59.576 template<class T>
59.577 - class ArcMap : public ReadWriteMap<Arc,T> {
59.578 + class ArcMap : public ReferenceMap<Arc, T, T&, const T&> {
59.579 public:
59.580
59.581 - ///\e
59.582 - ArcMap(const Digraph&) { }
59.583 - ///\e
59.584 + /// Constructor
59.585 + explicit ArcMap(const Digraph&) { }
59.586 + /// Constructor with given initial value
59.587 ArcMap(const Digraph&, T) { }
59.588 +
59.589 private:
59.590 ///Copy constructor
59.591 - ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { }
59.592 + ArcMap(const ArcMap& em) :
59.593 + ReferenceMap<Arc, T, T&, const T&>(em) { }
59.594 ///Assignment operator
59.595 template <typename CMap>
59.596 ArcMap& operator=(const CMap&) {
59.597 @@ -471,6 +472,7 @@
59.598 template <typename _Digraph>
59.599 struct Constraints {
59.600 void constraints() {
59.601 + checkConcept<BaseDigraphComponent, _Digraph>();
59.602 checkConcept<IterableDigraphComponent<>, _Digraph>();
59.603 checkConcept<IDableDigraphComponent<>, _Digraph>();
59.604 checkConcept<MappableDigraphComponent<>, _Digraph>();
59.605 @@ -484,4 +486,4 @@
59.606
59.607
59.608
59.609 -#endif // LEMON_CONCEPT_DIGRAPH_H
59.610 +#endif
60.1 --- a/lemon/concepts/graph.h Mon Jan 12 23:11:39 2009 +0100
60.2 +++ b/lemon/concepts/graph.h Thu Nov 05 15:48:01 2009 +0100
60.3 @@ -18,13 +18,14 @@
60.4
60.5 ///\ingroup graph_concepts
60.6 ///\file
60.7 -///\brief The concept of Undirected Graphs.
60.8 +///\brief The concept of undirected graphs.
60.9
60.10 -#ifndef LEMON_CONCEPT_GRAPH_H
60.11 -#define LEMON_CONCEPT_GRAPH_H
60.12 +#ifndef LEMON_CONCEPTS_GRAPH_H
60.13 +#define LEMON_CONCEPTS_GRAPH_H
60.14
60.15 #include <lemon/concepts/graph_components.h>
60.16 -#include <lemon/concepts/graph.h>
60.17 +#include <lemon/concepts/maps.h>
60.18 +#include <lemon/concept_check.h>
60.19 #include <lemon/core.h>
60.20
60.21 namespace lemon {
60.22 @@ -32,63 +33,74 @@
60.23
60.24 /// \ingroup graph_concepts
60.25 ///
60.26 - /// \brief Class describing the concept of Undirected Graphs.
60.27 + /// \brief Class describing the concept of undirected graphs.
60.28 ///
60.29 - /// This class describes the common interface of all Undirected
60.30 - /// Graphs.
60.31 + /// This class describes the common interface of all undirected
60.32 + /// graphs.
60.33 ///
60.34 - /// As all concept describing classes it provides only interface
60.35 - /// without any sensible implementation. So any algorithm for
60.36 - /// undirected graph should compile with this class, but it will not
60.37 + /// Like all concept classes, it only provides an interface
60.38 + /// without any sensible implementation. So any general algorithm for
60.39 + /// undirected graphs should compile with this class, but it will not
60.40 /// run properly, of course.
60.41 + /// An actual graph implementation like \ref ListGraph or
60.42 + /// \ref SmartGraph may have additional functionality.
60.43 ///
60.44 - /// The LEMON undirected graphs also fulfill the concept of
60.45 - /// directed graphs (\ref lemon::concepts::Digraph "Digraph
60.46 - /// Concept"). Each edges can be seen as two opposite
60.47 - /// directed arc and consequently the undirected graph can be
60.48 - /// seen as the direceted graph of these directed arcs. The
60.49 - /// Graph has the Edge inner class for the edges and
60.50 - /// the Arc type for the directed arcs. The Arc type is
60.51 - /// convertible to Edge or inherited from it so from a directed
60.52 - /// arc we can get the represented edge.
60.53 + /// The undirected graphs also fulfill the concept of \ref Digraph
60.54 + /// "directed graphs", since each edge can also be regarded as two
60.55 + /// oppositely directed arcs.
60.56 + /// Undirected graphs provide an Edge type for the undirected edges and
60.57 + /// an Arc type for the directed arcs. The Arc type is convertible to
60.58 + /// Edge or inherited from it, i.e. the corresponding edge can be
60.59 + /// obtained from an arc.
60.60 + /// EdgeIt and EdgeMap classes can be used for the edges, while ArcIt
60.61 + /// and ArcMap classes can be used for the arcs (just like in digraphs).
60.62 + /// Both InArcIt and OutArcIt iterates on the same edges but with
60.63 + /// opposite direction. IncEdgeIt also iterates on the same edges
60.64 + /// as OutArcIt and InArcIt, but it is not convertible to Arc,
60.65 + /// only to Edge.
60.66 ///
60.67 - /// In the sense of the LEMON each edge has a default
60.68 - /// direction (it should be in every computer implementation,
60.69 - /// because the order of edge's nodes defines an
60.70 - /// orientation). With the default orientation we can define that
60.71 - /// the directed arc is forward or backward directed. With the \c
60.72 - /// direction() and \c direct() function we can get the direction
60.73 - /// of the directed arc and we can direct an edge.
60.74 + /// In LEMON, each undirected edge has an inherent orientation.
60.75 + /// Thus it can defined if an arc is forward or backward oriented in
60.76 + /// an undirected graph with respect to this default oriantation of
60.77 + /// the represented edge.
60.78 + /// With the direction() and direct() functions the direction
60.79 + /// of an arc can be obtained and set, respectively.
60.80 ///
60.81 - /// The EdgeIt is an iterator for the edges. We can use
60.82 - /// the EdgeMap to map values for the edges. The InArcIt and
60.83 - /// OutArcIt iterates on the same edges but with opposite
60.84 - /// direction. The IncEdgeIt iterates also on the same edges
60.85 - /// as the OutArcIt and InArcIt but it is not convertible to Arc just
60.86 - /// to Edge.
60.87 + /// Only nodes and edges can be added to or removed from an undirected
60.88 + /// graph and the corresponding arcs are added or removed automatically.
60.89 + ///
60.90 + /// \sa Digraph
60.91 class Graph {
60.92 + private:
60.93 + /// Graphs are \e not copy constructible. Use DigraphCopy instead.
60.94 + Graph(const Graph&) {}
60.95 + /// \brief Assignment of a graph to another one is \e not allowed.
60.96 + /// Use DigraphCopy instead.
60.97 + void operator=(const Graph&) {}
60.98 +
60.99 public:
60.100 - /// \brief The undirected graph should be tagged by the
60.101 - /// UndirectedTag.
60.102 + /// Default constructor.
60.103 + Graph() {}
60.104 +
60.105 + /// \brief Undirected graphs should be tagged with \c UndirectedTag.
60.106 ///
60.107 - /// The undirected graph should be tagged by the UndirectedTag. This
60.108 - /// tag helps the enable_if technics to make compile time
60.109 + /// Undirected graphs should be tagged with \c UndirectedTag.
60.110 + ///
60.111 + /// This tag helps the \c enable_if technics to make compile time
60.112 /// specializations for undirected graphs.
60.113 typedef True UndirectedTag;
60.114
60.115 - /// \brief The base type of node iterators,
60.116 - /// or in other words, the trivial node iterator.
60.117 - ///
60.118 - /// This is the base type of each node iterator,
60.119 - /// thus each kind of node iterator converts to this.
60.120 - /// More precisely each kind of node iterator should be inherited
60.121 - /// from the trivial node iterator.
60.122 + /// The node type of the graph
60.123 +
60.124 + /// This class identifies a node of the graph. It also serves
60.125 + /// as a base class of the node iterators,
60.126 + /// thus they convert to this type.
60.127 class Node {
60.128 public:
60.129 /// Default constructor
60.130
60.131 - /// @warning The default constructor sets the iterator
60.132 - /// to an undefined value.
60.133 + /// Default constructor.
60.134 + /// \warning It sets the object to an undefined value.
60.135 Node() { }
60.136 /// Copy constructor.
60.137
60.138 @@ -96,40 +108,40 @@
60.139 ///
60.140 Node(const Node&) { }
60.141
60.142 - /// Invalid constructor \& conversion.
60.143 + /// %Invalid constructor \& conversion.
60.144
60.145 - /// This constructor initializes the iterator to be invalid.
60.146 + /// Initializes the object to be invalid.
60.147 /// \sa Invalid for more details.
60.148 Node(Invalid) { }
60.149 /// Equality operator
60.150
60.151 + /// Equality operator.
60.152 + ///
60.153 /// Two iterators are equal if and only if they point to the
60.154 - /// same object or both are invalid.
60.155 + /// same object or both are \c INVALID.
60.156 bool operator==(Node) const { return true; }
60.157
60.158 /// Inequality operator
60.159
60.160 - /// \sa operator==(Node n)
60.161 - ///
60.162 + /// Inequality operator.
60.163 bool operator!=(Node) const { return true; }
60.164
60.165 /// Artificial ordering operator.
60.166
60.167 - /// To allow the use of graph descriptors as key type in std::map or
60.168 - /// similar associative container we require this.
60.169 + /// Artificial ordering operator.
60.170 ///
60.171 - /// \note This operator only have to define some strict ordering of
60.172 + /// \note This operator only has to define some strict ordering of
60.173 /// the items; this order has nothing to do with the iteration
60.174 /// ordering of the items.
60.175 bool operator<(Node) const { return false; }
60.176
60.177 };
60.178
60.179 - /// This iterator goes through each node.
60.180 + /// Iterator class for the nodes.
60.181
60.182 - /// This iterator goes through each node.
60.183 + /// This iterator goes through each node of the graph.
60.184 /// Its usage is quite simple, for example you can count the number
60.185 - /// of nodes in graph \c g of type \c Graph like this:
60.186 + /// of nodes in a graph \c g of type \c %Graph like this:
60.187 ///\code
60.188 /// int count=0;
60.189 /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
60.190 @@ -138,30 +150,28 @@
60.191 public:
60.192 /// Default constructor
60.193
60.194 - /// @warning The default constructor sets the iterator
60.195 - /// to an undefined value.
60.196 + /// Default constructor.
60.197 + /// \warning It sets the iterator to an undefined value.
60.198 NodeIt() { }
60.199 /// Copy constructor.
60.200
60.201 /// Copy constructor.
60.202 ///
60.203 NodeIt(const NodeIt& n) : Node(n) { }
60.204 - /// Invalid constructor \& conversion.
60.205 + /// %Invalid constructor \& conversion.
60.206
60.207 - /// Initialize the iterator to be invalid.
60.208 + /// Initializes the iterator to be invalid.
60.209 /// \sa Invalid for more details.
60.210 NodeIt(Invalid) { }
60.211 /// Sets the iterator to the first node.
60.212
60.213 - /// Sets the iterator to the first node of \c g.
60.214 + /// Sets the iterator to the first node of the given digraph.
60.215 ///
60.216 - NodeIt(const Graph&) { }
60.217 - /// Node -> NodeIt conversion.
60.218 + explicit NodeIt(const Graph&) { }
60.219 + /// Sets the iterator to the given node.
60.220
60.221 - /// Sets the iterator to the node of \c the graph pointed by
60.222 - /// the trivial iterator.
60.223 - /// This feature necessitates that each time we
60.224 - /// iterate the arc-set, the iteration order is the same.
60.225 + /// Sets the iterator to the given node of the given digraph.
60.226 + ///
60.227 NodeIt(const Graph&, const Node&) { }
60.228 /// Next node.
60.229
60.230 @@ -171,54 +181,55 @@
60.231 };
60.232
60.233
60.234 - /// The base type of the edge iterators.
60.235 + /// The edge type of the graph
60.236
60.237 - /// The base type of the edge iterators.
60.238 - ///
60.239 + /// This class identifies an edge of the graph. It also serves
60.240 + /// as a base class of the edge iterators,
60.241 + /// thus they will convert to this type.
60.242 class Edge {
60.243 public:
60.244 /// Default constructor
60.245
60.246 - /// @warning The default constructor sets the iterator
60.247 - /// to an undefined value.
60.248 + /// Default constructor.
60.249 + /// \warning It sets the object to an undefined value.
60.250 Edge() { }
60.251 /// Copy constructor.
60.252
60.253 /// Copy constructor.
60.254 ///
60.255 Edge(const Edge&) { }
60.256 - /// Initialize the iterator to be invalid.
60.257 + /// %Invalid constructor \& conversion.
60.258
60.259 - /// Initialize the iterator to be invalid.
60.260 - ///
60.261 + /// Initializes the object to be invalid.
60.262 + /// \sa Invalid for more details.
60.263 Edge(Invalid) { }
60.264 /// Equality operator
60.265
60.266 + /// Equality operator.
60.267 + ///
60.268 /// Two iterators are equal if and only if they point to the
60.269 - /// same object or both are invalid.
60.270 + /// same object or both are \c INVALID.
60.271 bool operator==(Edge) const { return true; }
60.272 /// Inequality operator
60.273
60.274 - /// \sa operator==(Edge n)
60.275 - ///
60.276 + /// Inequality operator.
60.277 bool operator!=(Edge) const { return true; }
60.278
60.279 /// Artificial ordering operator.
60.280
60.281 - /// To allow the use of graph descriptors as key type in std::map or
60.282 - /// similar associative container we require this.
60.283 + /// Artificial ordering operator.
60.284 ///
60.285 - /// \note This operator only have to define some strict ordering of
60.286 - /// the items; this order has nothing to do with the iteration
60.287 - /// ordering of the items.
60.288 + /// \note This operator only has to define some strict ordering of
60.289 + /// the edges; this order has nothing to do with the iteration
60.290 + /// ordering of the edges.
60.291 bool operator<(Edge) const { return false; }
60.292 };
60.293
60.294 - /// This iterator goes through each edge.
60.295 + /// Iterator class for the edges.
60.296
60.297 - /// This iterator goes through each edge of a graph.
60.298 + /// This iterator goes through each edge of the graph.
60.299 /// Its usage is quite simple, for example you can count the number
60.300 - /// of edges in a graph \c g of type \c Graph as follows:
60.301 + /// of edges in a graph \c g of type \c %Graph as follows:
60.302 ///\code
60.303 /// int count=0;
60.304 /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
60.305 @@ -227,294 +238,291 @@
60.306 public:
60.307 /// Default constructor
60.308
60.309 - /// @warning The default constructor sets the iterator
60.310 - /// to an undefined value.
60.311 + /// Default constructor.
60.312 + /// \warning It sets the iterator to an undefined value.
60.313 EdgeIt() { }
60.314 /// Copy constructor.
60.315
60.316 /// Copy constructor.
60.317 ///
60.318 EdgeIt(const EdgeIt& e) : Edge(e) { }
60.319 - /// Initialize the iterator to be invalid.
60.320 + /// %Invalid constructor \& conversion.
60.321
60.322 - /// Initialize the iterator to be invalid.
60.323 + /// Initializes the iterator to be invalid.
60.324 + /// \sa Invalid for more details.
60.325 + EdgeIt(Invalid) { }
60.326 + /// Sets the iterator to the first edge.
60.327 +
60.328 + /// Sets the iterator to the first edge of the given graph.
60.329 ///
60.330 - EdgeIt(Invalid) { }
60.331 - /// This constructor sets the iterator to the first edge.
60.332 + explicit EdgeIt(const Graph&) { }
60.333 + /// Sets the iterator to the given edge.
60.334
60.335 - /// This constructor sets the iterator to the first edge.
60.336 - EdgeIt(const Graph&) { }
60.337 - /// Edge -> EdgeIt conversion
60.338 -
60.339 - /// Sets the iterator to the value of the trivial iterator.
60.340 - /// This feature necessitates that each time we
60.341 - /// iterate the edge-set, the iteration order is the
60.342 - /// same.
60.343 + /// Sets the iterator to the given edge of the given graph.
60.344 + ///
60.345 EdgeIt(const Graph&, const Edge&) { }
60.346 /// Next edge
60.347
60.348 /// Assign the iterator to the next edge.
60.349 + ///
60.350 EdgeIt& operator++() { return *this; }
60.351 };
60.352
60.353 - /// \brief This iterator goes trough the incident undirected
60.354 - /// arcs of a node.
60.355 - ///
60.356 - /// This iterator goes trough the incident edges
60.357 - /// of a certain node of a graph. You should assume that the
60.358 - /// loop arcs will be iterated twice.
60.359 - ///
60.360 + /// Iterator class for the incident edges of a node.
60.361 +
60.362 + /// This iterator goes trough the incident undirected edges
60.363 + /// of a certain node of a graph.
60.364 /// Its usage is quite simple, for example you can compute the
60.365 - /// degree (i.e. count the number of incident arcs of a node \c n
60.366 - /// in graph \c g of type \c Graph as follows.
60.367 + /// degree (i.e. the number of incident edges) of a node \c n
60.368 + /// in a graph \c g of type \c %Graph as follows.
60.369 ///
60.370 ///\code
60.371 /// int count=0;
60.372 /// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
60.373 ///\endcode
60.374 + ///
60.375 + /// \warning Loop edges will be iterated twice.
60.376 class IncEdgeIt : public Edge {
60.377 public:
60.378 /// Default constructor
60.379
60.380 - /// @warning The default constructor sets the iterator
60.381 - /// to an undefined value.
60.382 + /// Default constructor.
60.383 + /// \warning It sets the iterator to an undefined value.
60.384 IncEdgeIt() { }
60.385 /// Copy constructor.
60.386
60.387 /// Copy constructor.
60.388 ///
60.389 IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
60.390 - /// Initialize the iterator to be invalid.
60.391 + /// %Invalid constructor \& conversion.
60.392
60.393 - /// Initialize the iterator to be invalid.
60.394 + /// Initializes the iterator to be invalid.
60.395 + /// \sa Invalid for more details.
60.396 + IncEdgeIt(Invalid) { }
60.397 + /// Sets the iterator to the first incident edge.
60.398 +
60.399 + /// Sets the iterator to the first incident edge of the given node.
60.400 ///
60.401 - IncEdgeIt(Invalid) { }
60.402 - /// This constructor sets the iterator to first incident arc.
60.403 + IncEdgeIt(const Graph&, const Node&) { }
60.404 + /// Sets the iterator to the given edge.
60.405
60.406 - /// This constructor set the iterator to the first incident arc of
60.407 - /// the node.
60.408 - IncEdgeIt(const Graph&, const Node&) { }
60.409 - /// Edge -> IncEdgeIt conversion
60.410 + /// Sets the iterator to the given edge of the given graph.
60.411 + ///
60.412 + IncEdgeIt(const Graph&, const Edge&) { }
60.413 + /// Next incident edge
60.414
60.415 - /// Sets the iterator to the value of the trivial iterator \c e.
60.416 - /// This feature necessitates that each time we
60.417 - /// iterate the arc-set, the iteration order is the same.
60.418 - IncEdgeIt(const Graph&, const Edge&) { }
60.419 - /// Next incident arc
60.420 -
60.421 - /// Assign the iterator to the next incident arc
60.422 + /// Assign the iterator to the next incident edge
60.423 /// of the corresponding node.
60.424 IncEdgeIt& operator++() { return *this; }
60.425 };
60.426
60.427 - /// The directed arc type.
60.428 + /// The arc type of the graph
60.429
60.430 - /// The directed arc type. It can be converted to the
60.431 - /// edge or it should be inherited from the undirected
60.432 - /// arc.
60.433 - class Arc : public Edge {
60.434 + /// This class identifies a directed arc of the graph. It also serves
60.435 + /// as a base class of the arc iterators,
60.436 + /// thus they will convert to this type.
60.437 + class Arc {
60.438 public:
60.439 /// Default constructor
60.440
60.441 - /// @warning The default constructor sets the iterator
60.442 - /// to an undefined value.
60.443 + /// Default constructor.
60.444 + /// \warning It sets the object to an undefined value.
60.445 Arc() { }
60.446 /// Copy constructor.
60.447
60.448 /// Copy constructor.
60.449 ///
60.450 - Arc(const Arc& e) : Edge(e) { }
60.451 - /// Initialize the iterator to be invalid.
60.452 + Arc(const Arc&) { }
60.453 + /// %Invalid constructor \& conversion.
60.454
60.455 - /// Initialize the iterator to be invalid.
60.456 - ///
60.457 + /// Initializes the object to be invalid.
60.458 + /// \sa Invalid for more details.
60.459 Arc(Invalid) { }
60.460 /// Equality operator
60.461
60.462 + /// Equality operator.
60.463 + ///
60.464 /// Two iterators are equal if and only if they point to the
60.465 - /// same object or both are invalid.
60.466 + /// same object or both are \c INVALID.
60.467 bool operator==(Arc) const { return true; }
60.468 /// Inequality operator
60.469
60.470 - /// \sa operator==(Arc n)
60.471 - ///
60.472 + /// Inequality operator.
60.473 bool operator!=(Arc) const { return true; }
60.474
60.475 /// Artificial ordering operator.
60.476
60.477 - /// To allow the use of graph descriptors as key type in std::map or
60.478 - /// similar associative container we require this.
60.479 + /// Artificial ordering operator.
60.480 ///
60.481 - /// \note This operator only have to define some strict ordering of
60.482 - /// the items; this order has nothing to do with the iteration
60.483 - /// ordering of the items.
60.484 + /// \note This operator only has to define some strict ordering of
60.485 + /// the arcs; this order has nothing to do with the iteration
60.486 + /// ordering of the arcs.
60.487 bool operator<(Arc) const { return false; }
60.488
60.489 + /// Converison to \c Edge
60.490 +
60.491 + /// Converison to \c Edge.
60.492 + ///
60.493 + operator Edge() const { return Edge(); }
60.494 };
60.495 - /// This iterator goes through each directed arc.
60.496
60.497 - /// This iterator goes through each arc of a graph.
60.498 + /// Iterator class for the arcs.
60.499 +
60.500 + /// This iterator goes through each directed arc of the graph.
60.501 /// Its usage is quite simple, for example you can count the number
60.502 - /// of arcs in a graph \c g of type \c Graph as follows:
60.503 + /// of arcs in a graph \c g of type \c %Graph as follows:
60.504 ///\code
60.505 /// int count=0;
60.506 - /// for(Graph::ArcIt e(g); e!=INVALID; ++e) ++count;
60.507 + /// for(Graph::ArcIt a(g); a!=INVALID; ++a) ++count;
60.508 ///\endcode
60.509 class ArcIt : public Arc {
60.510 public:
60.511 /// Default constructor
60.512
60.513 - /// @warning The default constructor sets the iterator
60.514 - /// to an undefined value.
60.515 + /// Default constructor.
60.516 + /// \warning It sets the iterator to an undefined value.
60.517 ArcIt() { }
60.518 /// Copy constructor.
60.519
60.520 /// Copy constructor.
60.521 ///
60.522 ArcIt(const ArcIt& e) : Arc(e) { }
60.523 - /// Initialize the iterator to be invalid.
60.524 + /// %Invalid constructor \& conversion.
60.525
60.526 - /// Initialize the iterator to be invalid.
60.527 + /// Initializes the iterator to be invalid.
60.528 + /// \sa Invalid for more details.
60.529 + ArcIt(Invalid) { }
60.530 + /// Sets the iterator to the first arc.
60.531 +
60.532 + /// Sets the iterator to the first arc of the given graph.
60.533 ///
60.534 - ArcIt(Invalid) { }
60.535 - /// This constructor sets the iterator to the first arc.
60.536 + explicit ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
60.537 + /// Sets the iterator to the given arc.
60.538
60.539 - /// This constructor sets the iterator to the first arc of \c g.
60.540 - ///@param g the graph
60.541 - ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
60.542 - /// Arc -> ArcIt conversion
60.543 -
60.544 - /// Sets the iterator to the value of the trivial iterator \c e.
60.545 - /// This feature necessitates that each time we
60.546 - /// iterate the arc-set, the iteration order is the same.
60.547 + /// Sets the iterator to the given arc of the given graph.
60.548 + ///
60.549 ArcIt(const Graph&, const Arc&) { }
60.550 - ///Next arc
60.551 + /// Next arc
60.552
60.553 /// Assign the iterator to the next arc.
60.554 + ///
60.555 ArcIt& operator++() { return *this; }
60.556 };
60.557
60.558 - /// This iterator goes trough the outgoing directed arcs of a node.
60.559 + /// Iterator class for the outgoing arcs of a node.
60.560
60.561 - /// This iterator goes trough the \e outgoing arcs of a certain node
60.562 - /// of a graph.
60.563 + /// This iterator goes trough the \e outgoing directed arcs of a
60.564 + /// certain node of a graph.
60.565 /// Its usage is quite simple, for example you can count the number
60.566 /// of outgoing arcs of a node \c n
60.567 - /// in graph \c g of type \c Graph as follows.
60.568 + /// in a graph \c g of type \c %Graph as follows.
60.569 ///\code
60.570 /// int count=0;
60.571 - /// for (Graph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
60.572 + /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
60.573 ///\endcode
60.574 -
60.575 class OutArcIt : public Arc {
60.576 public:
60.577 /// Default constructor
60.578
60.579 - /// @warning The default constructor sets the iterator
60.580 - /// to an undefined value.
60.581 + /// Default constructor.
60.582 + /// \warning It sets the iterator to an undefined value.
60.583 OutArcIt() { }
60.584 /// Copy constructor.
60.585
60.586 /// Copy constructor.
60.587 ///
60.588 OutArcIt(const OutArcIt& e) : Arc(e) { }
60.589 - /// Initialize the iterator to be invalid.
60.590 + /// %Invalid constructor \& conversion.
60.591
60.592 - /// Initialize the iterator to be invalid.
60.593 + /// Initializes the iterator to be invalid.
60.594 + /// \sa Invalid for more details.
60.595 + OutArcIt(Invalid) { }
60.596 + /// Sets the iterator to the first outgoing arc.
60.597 +
60.598 + /// Sets the iterator to the first outgoing arc of the given node.
60.599 ///
60.600 - OutArcIt(Invalid) { }
60.601 - /// This constructor sets the iterator to the first outgoing arc.
60.602 -
60.603 - /// This constructor sets the iterator to the first outgoing arc of
60.604 - /// the node.
60.605 - ///@param n the node
60.606 - ///@param g the graph
60.607 OutArcIt(const Graph& n, const Node& g) {
60.608 ignore_unused_variable_warning(n);
60.609 ignore_unused_variable_warning(g);
60.610 }
60.611 - /// Arc -> OutArcIt conversion
60.612 + /// Sets the iterator to the given arc.
60.613
60.614 - /// Sets the iterator to the value of the trivial iterator.
60.615 - /// This feature necessitates that each time we
60.616 - /// iterate the arc-set, the iteration order is the same.
60.617 + /// Sets the iterator to the given arc of the given graph.
60.618 + ///
60.619 OutArcIt(const Graph&, const Arc&) { }
60.620 - ///Next outgoing arc
60.621 + /// Next outgoing arc
60.622
60.623 /// Assign the iterator to the next
60.624 /// outgoing arc of the corresponding node.
60.625 OutArcIt& operator++() { return *this; }
60.626 };
60.627
60.628 - /// This iterator goes trough the incoming directed arcs of a node.
60.629 + /// Iterator class for the incoming arcs of a node.
60.630
60.631 - /// This iterator goes trough the \e incoming arcs of a certain node
60.632 - /// of a graph.
60.633 + /// This iterator goes trough the \e incoming directed arcs of a
60.634 + /// certain node of a graph.
60.635 /// Its usage is quite simple, for example you can count the number
60.636 - /// of outgoing arcs of a node \c n
60.637 - /// in graph \c g of type \c Graph as follows.
60.638 + /// of incoming arcs of a node \c n
60.639 + /// in a graph \c g of type \c %Graph as follows.
60.640 ///\code
60.641 /// int count=0;
60.642 - /// for(Graph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
60.643 + /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
60.644 ///\endcode
60.645 -
60.646 class InArcIt : public Arc {
60.647 public:
60.648 /// Default constructor
60.649
60.650 - /// @warning The default constructor sets the iterator
60.651 - /// to an undefined value.
60.652 + /// Default constructor.
60.653 + /// \warning It sets the iterator to an undefined value.
60.654 InArcIt() { }
60.655 /// Copy constructor.
60.656
60.657 /// Copy constructor.
60.658 ///
60.659 InArcIt(const InArcIt& e) : Arc(e) { }
60.660 - /// Initialize the iterator to be invalid.
60.661 + /// %Invalid constructor \& conversion.
60.662
60.663 - /// Initialize the iterator to be invalid.
60.664 + /// Initializes the iterator to be invalid.
60.665 + /// \sa Invalid for more details.
60.666 + InArcIt(Invalid) { }
60.667 + /// Sets the iterator to the first incoming arc.
60.668 +
60.669 + /// Sets the iterator to the first incoming arc of the given node.
60.670 ///
60.671 - InArcIt(Invalid) { }
60.672 - /// This constructor sets the iterator to first incoming arc.
60.673 -
60.674 - /// This constructor set the iterator to the first incoming arc of
60.675 - /// the node.
60.676 - ///@param n the node
60.677 - ///@param g the graph
60.678 InArcIt(const Graph& g, const Node& n) {
60.679 ignore_unused_variable_warning(n);
60.680 ignore_unused_variable_warning(g);
60.681 }
60.682 - /// Arc -> InArcIt conversion
60.683 + /// Sets the iterator to the given arc.
60.684
60.685 - /// Sets the iterator to the value of the trivial iterator \c e.
60.686 - /// This feature necessitates that each time we
60.687 - /// iterate the arc-set, the iteration order is the same.
60.688 + /// Sets the iterator to the given arc of the given graph.
60.689 + ///
60.690 InArcIt(const Graph&, const Arc&) { }
60.691 /// Next incoming arc
60.692
60.693 - /// Assign the iterator to the next inarc of the corresponding node.
60.694 - ///
60.695 + /// Assign the iterator to the next
60.696 + /// incoming arc of the corresponding node.
60.697 InArcIt& operator++() { return *this; }
60.698 };
60.699
60.700 - /// \brief Read write map of the nodes to type \c T.
60.701 + /// \brief Standard graph map type for the nodes.
60.702 ///
60.703 - /// ReadWrite map of the nodes to type \c T.
60.704 - /// \sa Reference
60.705 + /// Standard graph map type for the nodes.
60.706 + /// It conforms to the ReferenceMap concept.
60.707 template<class T>
60.708 - class NodeMap : public ReadWriteMap< Node, T >
60.709 + class NodeMap : public ReferenceMap<Node, T, T&, const T&>
60.710 {
60.711 public:
60.712
60.713 - ///\e
60.714 - NodeMap(const Graph&) { }
60.715 - ///\e
60.716 + /// Constructor
60.717 + explicit NodeMap(const Graph&) { }
60.718 + /// Constructor with given initial value
60.719 NodeMap(const Graph&, T) { }
60.720
60.721 private:
60.722 ///Copy constructor
60.723 - NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
60.724 + NodeMap(const NodeMap& nm) :
60.725 + ReferenceMap<Node, T, T&, const T&>(nm) { }
60.726 ///Assignment operator
60.727 template <typename CMap>
60.728 NodeMap& operator=(const CMap&) {
60.729 @@ -523,22 +531,24 @@
60.730 }
60.731 };
60.732
60.733 - /// \brief Read write map of the directed arcs to type \c T.
60.734 + /// \brief Standard graph map type for the arcs.
60.735 ///
60.736 - /// Reference map of the directed arcs to type \c T.
60.737 - /// \sa Reference
60.738 + /// Standard graph map type for the arcs.
60.739 + /// It conforms to the ReferenceMap concept.
60.740 template<class T>
60.741 - class ArcMap : public ReadWriteMap<Arc,T>
60.742 + class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
60.743 {
60.744 public:
60.745
60.746 - ///\e
60.747 - ArcMap(const Graph&) { }
60.748 - ///\e
60.749 + /// Constructor
60.750 + explicit ArcMap(const Graph&) { }
60.751 + /// Constructor with given initial value
60.752 ArcMap(const Graph&, T) { }
60.753 +
60.754 private:
60.755 ///Copy constructor
60.756 - ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { }
60.757 + ArcMap(const ArcMap& em) :
60.758 + ReferenceMap<Arc, T, T&, const T&>(em) { }
60.759 ///Assignment operator
60.760 template <typename CMap>
60.761 ArcMap& operator=(const CMap&) {
60.762 @@ -547,22 +557,24 @@
60.763 }
60.764 };
60.765
60.766 - /// Read write map of the edges to type \c T.
60.767 -
60.768 - /// Reference map of the arcs to type \c T.
60.769 - /// \sa Reference
60.770 + /// \brief Standard graph map type for the edges.
60.771 + ///
60.772 + /// Standard graph map type for the edges.
60.773 + /// It conforms to the ReferenceMap concept.
60.774 template<class T>
60.775 - class EdgeMap : public ReadWriteMap<Edge,T>
60.776 + class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
60.777 {
60.778 public:
60.779
60.780 - ///\e
60.781 - EdgeMap(const Graph&) { }
60.782 - ///\e
60.783 + /// Constructor
60.784 + explicit EdgeMap(const Graph&) { }
60.785 + /// Constructor with given initial value
60.786 EdgeMap(const Graph&, T) { }
60.787 +
60.788 private:
60.789 ///Copy constructor
60.790 - EdgeMap(const EdgeMap& em) : ReadWriteMap<Edge,T>(em) {}
60.791 + EdgeMap(const EdgeMap& em) :
60.792 + ReferenceMap<Edge, T, T&, const T&>(em) {}
60.793 ///Assignment operator
60.794 template <typename CMap>
60.795 EdgeMap& operator=(const CMap&) {
60.796 @@ -571,95 +583,124 @@
60.797 }
60.798 };
60.799
60.800 - /// \brief Direct the given edge.
60.801 + /// \brief The first node of the edge.
60.802 ///
60.803 - /// Direct the given edge. The returned arc source
60.804 - /// will be the given node.
60.805 - Arc direct(const Edge&, const Node&) const {
60.806 + /// Returns the first node of the given edge.
60.807 + ///
60.808 + /// Edges don't have source and target nodes, however methods
60.809 + /// u() and v() are used to query the two end-nodes of an edge.
60.810 + /// The orientation of an edge that arises this way is called
60.811 + /// the inherent direction, it is used to define the default
60.812 + /// direction for the corresponding arcs.
60.813 + /// \sa v()
60.814 + /// \sa direction()
60.815 + Node u(Edge) const { return INVALID; }
60.816 +
60.817 + /// \brief The second node of the edge.
60.818 + ///
60.819 + /// Returns the second node of the given edge.
60.820 + ///
60.821 + /// Edges don't have source and target nodes, however methods
60.822 + /// u() and v() are used to query the two end-nodes of an edge.
60.823 + /// The orientation of an edge that arises this way is called
60.824 + /// the inherent direction, it is used to define the default
60.825 + /// direction for the corresponding arcs.
60.826 + /// \sa u()
60.827 + /// \sa direction()
60.828 + Node v(Edge) const { return INVALID; }
60.829 +
60.830 + /// \brief The source node of the arc.
60.831 + ///
60.832 + /// Returns the source node of the given arc.
60.833 + Node source(Arc) const { return INVALID; }
60.834 +
60.835 + /// \brief The target node of the arc.
60.836 + ///
60.837 + /// Returns the target node of the given arc.
60.838 + Node target(Arc) const { return INVALID; }
60.839 +
60.840 + /// \brief The ID of the node.
60.841 + ///
60.842 + /// Returns the ID of the given node.
60.843 + int id(Node) const { return -1; }
60.844 +
60.845 + /// \brief The ID of the edge.
60.846 + ///
60.847 + /// Returns the ID of the given edge.
60.848 + int id(Edge) const { return -1; }
60.849 +
60.850 + /// \brief The ID of the arc.
60.851 + ///
60.852 + /// Returns the ID of the given arc.
60.853 + int id(Arc) const { return -1; }
60.854 +
60.855 + /// \brief The node with the given ID.
60.856 + ///
60.857 + /// Returns the node with the given ID.
60.858 + /// \pre The argument should be a valid node ID in the graph.
60.859 + Node nodeFromId(int) const { return INVALID; }
60.860 +
60.861 + /// \brief The edge with the given ID.
60.862 + ///
60.863 + /// Returns the edge with the given ID.
60.864 + /// \pre The argument should be a valid edge ID in the graph.
60.865 + Edge edgeFromId(int) const { return INVALID; }
60.866 +
60.867 + /// \brief The arc with the given ID.
60.868 + ///
60.869 + /// Returns the arc with the given ID.
60.870 + /// \pre The argument should be a valid arc ID in the graph.
60.871 + Arc arcFromId(int) const { return INVALID; }
60.872 +
60.873 + /// \brief An upper bound on the node IDs.
60.874 + ///
60.875 + /// Returns an upper bound on the node IDs.
60.876 + int maxNodeId() const { return -1; }
60.877 +
60.878 + /// \brief An upper bound on the edge IDs.
60.879 + ///
60.880 + /// Returns an upper bound on the edge IDs.
60.881 + int maxEdgeId() const { return -1; }
60.882 +
60.883 + /// \brief An upper bound on the arc IDs.
60.884 + ///
60.885 + /// Returns an upper bound on the arc IDs.
60.886 + int maxArcId() const { return -1; }
60.887 +
60.888 + /// \brief The direction of the arc.
60.889 + ///
60.890 + /// Returns \c true if the direction of the given arc is the same as
60.891 + /// the inherent orientation of the represented edge.
60.892 + bool direction(Arc) const { return true; }
60.893 +
60.894 + /// \brief Direct the edge.
60.895 + ///
60.896 + /// Direct the given edge. The returned arc
60.897 + /// represents the given edge and its direction comes
60.898 + /// from the bool parameter. If it is \c true, then the direction
60.899 + /// of the arc is the same as the inherent orientation of the edge.
60.900 + Arc direct(Edge, bool) const {
60.901 return INVALID;
60.902 }
60.903
60.904 - /// \brief Direct the given edge.
60.905 + /// \brief Direct the edge.
60.906 ///
60.907 - /// Direct the given edge. The returned arc
60.908 - /// represents the given edge and the direction comes
60.909 - /// from the bool parameter. The source of the edge and
60.910 - /// the directed arc is the same when the given bool is true.
60.911 - Arc direct(const Edge&, bool) const {
60.912 + /// Direct the given edge. The returned arc represents the given
60.913 + /// edge and its source node is the given node.
60.914 + Arc direct(Edge, Node) const {
60.915 return INVALID;
60.916 }
60.917
60.918 - /// \brief Returns true if the arc has default orientation.
60.919 + /// \brief The oppositely directed arc.
60.920 ///
60.921 - /// Returns whether the given directed arc is same orientation as
60.922 - /// the corresponding edge's default orientation.
60.923 - bool direction(Arc) const { return true; }
60.924 -
60.925 - /// \brief Returns the opposite directed arc.
60.926 - ///
60.927 - /// Returns the opposite directed arc.
60.928 + /// Returns the oppositely directed arc representing the same edge.
60.929 Arc oppositeArc(Arc) const { return INVALID; }
60.930
60.931 - /// \brief Opposite node on an arc
60.932 + /// \brief The opposite node on the edge.
60.933 ///
60.934 - /// \return the opposite of the given Node on the given Edge
60.935 + /// Returns the opposite node on the given edge.
60.936 Node oppositeNode(Node, Edge) const { return INVALID; }
60.937
60.938 - /// \brief First node of the edge.
60.939 - ///
60.940 - /// \return the first node of the given Edge.
60.941 - ///
60.942 - /// Naturally edges don't have direction and thus
60.943 - /// don't have source and target node. But we use these two methods
60.944 - /// to query the two nodes of the arc. The direction of the arc
60.945 - /// which arises this way is called the inherent direction of the
60.946 - /// edge, and is used to define the "default" direction
60.947 - /// of the directed versions of the arcs.
60.948 - /// \sa direction
60.949 - Node u(Edge) const { return INVALID; }
60.950 -
60.951 - /// \brief Second node of the edge.
60.952 - Node v(Edge) const { return INVALID; }
60.953 -
60.954 - /// \brief Source node of the directed arc.
60.955 - Node source(Arc) const { return INVALID; }
60.956 -
60.957 - /// \brief Target node of the directed arc.
60.958 - Node target(Arc) const { return INVALID; }
60.959 -
60.960 - /// \brief Returns the id of the node.
60.961 - int id(Node) const { return -1; }
60.962 -
60.963 - /// \brief Returns the id of the edge.
60.964 - int id(Edge) const { return -1; }
60.965 -
60.966 - /// \brief Returns the id of the arc.
60.967 - int id(Arc) const { return -1; }
60.968 -
60.969 - /// \brief Returns the node with the given id.
60.970 - ///
60.971 - /// \pre The argument should be a valid node id in the graph.
60.972 - Node nodeFromId(int) const { return INVALID; }
60.973 -
60.974 - /// \brief Returns the edge with the given id.
60.975 - ///
60.976 - /// \pre The argument should be a valid edge id in the graph.
60.977 - Edge edgeFromId(int) const { return INVALID; }
60.978 -
60.979 - /// \brief Returns the arc with the given id.
60.980 - ///
60.981 - /// \pre The argument should be a valid arc id in the graph.
60.982 - Arc arcFromId(int) const { return INVALID; }
60.983 -
60.984 - /// \brief Returns an upper bound on the node IDs.
60.985 - int maxNodeId() const { return -1; }
60.986 -
60.987 - /// \brief Returns an upper bound on the edge IDs.
60.988 - int maxEdgeId() const { return -1; }
60.989 -
60.990 - /// \brief Returns an upper bound on the arc IDs.
60.991 - int maxArcId() const { return -1; }
60.992 -
60.993 void first(Node&) const {}
60.994 void next(Node&) const {}
60.995
60.996 @@ -692,51 +733,44 @@
60.997 // Dummy parameter.
60.998 int maxId(Arc) const { return -1; }
60.999
60.1000 - /// \brief Base node of the iterator
60.1001 + /// \brief The base node of the iterator.
60.1002 ///
60.1003 - /// Returns the base node (the source in this case) of the iterator
60.1004 - Node baseNode(OutArcIt e) const {
60.1005 - return source(e);
60.1006 - }
60.1007 - /// \brief Running node of the iterator
60.1008 + /// Returns the base node of the given incident edge iterator.
60.1009 + Node baseNode(IncEdgeIt) const { return INVALID; }
60.1010 +
60.1011 + /// \brief The running node of the iterator.
60.1012 ///
60.1013 - /// Returns the running node (the target in this case) of the
60.1014 - /// iterator
60.1015 - Node runningNode(OutArcIt e) const {
60.1016 - return target(e);
60.1017 - }
60.1018 + /// Returns the running node of the given incident edge iterator.
60.1019 + Node runningNode(IncEdgeIt) const { return INVALID; }
60.1020
60.1021 - /// \brief Base node of the iterator
60.1022 + /// \brief The base node of the iterator.
60.1023 ///
60.1024 - /// Returns the base node (the target in this case) of the iterator
60.1025 - Node baseNode(InArcIt e) const {
60.1026 - return target(e);
60.1027 - }
60.1028 - /// \brief Running node of the iterator
60.1029 + /// Returns the base node of the given outgoing arc iterator
60.1030 + /// (i.e. the source node of the corresponding arc).
60.1031 + Node baseNode(OutArcIt) const { return INVALID; }
60.1032 +
60.1033 + /// \brief The running node of the iterator.
60.1034 ///
60.1035 - /// Returns the running node (the source in this case) of the
60.1036 - /// iterator
60.1037 - Node runningNode(InArcIt e) const {
60.1038 - return source(e);
60.1039 - }
60.1040 + /// Returns the running node of the given outgoing arc iterator
60.1041 + /// (i.e. the target node of the corresponding arc).
60.1042 + Node runningNode(OutArcIt) const { return INVALID; }
60.1043
60.1044 - /// \brief Base node of the iterator
60.1045 + /// \brief The base node of the iterator.
60.1046 ///
60.1047 - /// Returns the base node of the iterator
60.1048 - Node baseNode(IncEdgeIt) const {
60.1049 - return INVALID;
60.1050 - }
60.1051 + /// Returns the base node of the given incomming arc iterator
60.1052 + /// (i.e. the target node of the corresponding arc).
60.1053 + Node baseNode(InArcIt) const { return INVALID; }
60.1054
60.1055 - /// \brief Running node of the iterator
60.1056 + /// \brief The running node of the iterator.
60.1057 ///
60.1058 - /// Returns the running node of the iterator
60.1059 - Node runningNode(IncEdgeIt) const {
60.1060 - return INVALID;
60.1061 - }
60.1062 + /// Returns the running node of the given incomming arc iterator
60.1063 + /// (i.e. the source node of the corresponding arc).
60.1064 + Node runningNode(InArcIt) const { return INVALID; }
60.1065
60.1066 template <typename _Graph>
60.1067 struct Constraints {
60.1068 void constraints() {
60.1069 + checkConcept<BaseGraphComponent, _Graph>();
60.1070 checkConcept<IterableGraphComponent<>, _Graph>();
60.1071 checkConcept<IDableGraphComponent<>, _Graph>();
60.1072 checkConcept<MappableGraphComponent<>, _Graph>();
61.1 --- a/lemon/concepts/graph_components.h Mon Jan 12 23:11:39 2009 +0100
61.2 +++ b/lemon/concepts/graph_components.h Thu Nov 05 15:48:01 2009 +0100
61.3 @@ -20,9 +20,8 @@
61.4 ///\file
61.5 ///\brief The concept of graph components.
61.6
61.7 -
61.8 -#ifndef LEMON_CONCEPT_GRAPH_COMPONENTS_H
61.9 -#define LEMON_CONCEPT_GRAPH_COMPONENTS_H
61.10 +#ifndef LEMON_CONCEPTS_GRAPH_COMPONENTS_H
61.11 +#define LEMON_CONCEPTS_GRAPH_COMPONENTS_H
61.12
61.13 #include <lemon/core.h>
61.14 #include <lemon/concepts/maps.h>
61.15 @@ -32,75 +31,83 @@
61.16 namespace lemon {
61.17 namespace concepts {
61.18
61.19 - /// \brief Skeleton class for graph Node and Arc types
61.20 + /// \brief Concept class for \c Node, \c Arc and \c Edge types.
61.21 ///
61.22 - /// This class describes the interface of Node and Arc (and Edge
61.23 - /// in undirected graphs) subtypes of graph types.
61.24 + /// This class describes the concept of \c Node, \c Arc and \c Edge
61.25 + /// subtypes of digraph and graph types.
61.26 ///
61.27 /// \note This class is a template class so that we can use it to
61.28 - /// create graph skeleton classes. The reason for this is than Node
61.29 - /// and Arc types should \em not derive from the same base class.
61.30 - /// For Node you should instantiate it with character 'n' and for Arc
61.31 - /// with 'a'.
61.32 -
61.33 + /// create graph skeleton classes. The reason for this is that \c Node
61.34 + /// and \c Arc (or \c Edge) types should \e not derive from the same
61.35 + /// base class. For \c Node you should instantiate it with character
61.36 + /// \c 'n', for \c Arc with \c 'a' and for \c Edge with \c 'e'.
61.37 #ifndef DOXYGEN
61.38 - template <char _selector = '0'>
61.39 + template <char sel = '0'>
61.40 #endif
61.41 class GraphItem {
61.42 public:
61.43 /// \brief Default constructor.
61.44 ///
61.45 + /// Default constructor.
61.46 /// \warning The default constructor is not required to set
61.47 /// the item to some well-defined value. So you should consider it
61.48 /// as uninitialized.
61.49 GraphItem() {}
61.50 +
61.51 /// \brief Copy constructor.
61.52 ///
61.53 /// Copy constructor.
61.54 + GraphItem(const GraphItem &) {}
61.55 +
61.56 + /// \brief Constructor for conversion from \c INVALID.
61.57 ///
61.58 - GraphItem(const GraphItem &) {}
61.59 - /// \brief Invalid constructor \& conversion.
61.60 - ///
61.61 - /// This constructor initializes the item to be invalid.
61.62 + /// Constructor for conversion from \c INVALID.
61.63 + /// It initializes the item to be invalid.
61.64 /// \sa Invalid for more details.
61.65 GraphItem(Invalid) {}
61.66 - /// \brief Assign operator for nodes.
61.67 +
61.68 + /// \brief Assignment operator.
61.69 ///
61.70 - /// The nodes are assignable.
61.71 + /// Assignment operator for the item.
61.72 + GraphItem& operator=(const GraphItem&) { return *this; }
61.73 +
61.74 + /// \brief Assignment operator for INVALID.
61.75 ///
61.76 - GraphItem& operator=(GraphItem const&) { return *this; }
61.77 + /// This operator makes the item invalid.
61.78 + GraphItem& operator=(Invalid) { return *this; }
61.79 +
61.80 /// \brief Equality operator.
61.81 ///
61.82 - /// Two iterators are equal if and only if they represents the
61.83 - /// same node in the graph or both are invalid.
61.84 - bool operator==(GraphItem) const { return false; }
61.85 + /// Equality operator.
61.86 + bool operator==(const GraphItem&) const { return false; }
61.87 +
61.88 /// \brief Inequality operator.
61.89 ///
61.90 - /// \sa operator==(const Node& n)
61.91 + /// Inequality operator.
61.92 + bool operator!=(const GraphItem&) const { return false; }
61.93 +
61.94 + /// \brief Ordering operator.
61.95 ///
61.96 - bool operator!=(GraphItem) const { return false; }
61.97 -
61.98 - /// \brief Artificial ordering operator.
61.99 + /// This operator defines an ordering of the items.
61.100 + /// It makes possible to use graph item types as key types in
61.101 + /// associative containers (e.g. \c std::map).
61.102 ///
61.103 - /// To allow the use of graph descriptors as key type in std::map or
61.104 - /// similar associative container we require this.
61.105 - ///
61.106 - /// \note This operator only have to define some strict ordering of
61.107 + /// \note This operator only has to define some strict ordering of
61.108 /// the items; this order has nothing to do with the iteration
61.109 /// ordering of the items.
61.110 - bool operator<(GraphItem) const { return false; }
61.111 + bool operator<(const GraphItem&) const { return false; }
61.112
61.113 template<typename _GraphItem>
61.114 struct Constraints {
61.115 void constraints() {
61.116 _GraphItem i1;
61.117 + i1=INVALID;
61.118 _GraphItem i2 = i1;
61.119 _GraphItem i3 = INVALID;
61.120
61.121 i1 = i2 = i3;
61.122
61.123 bool b;
61.124 - // b = (ia == ib) && (ia != ib) && (ia < ib);
61.125 b = (ia == ib) && (ia != ib);
61.126 b = (ia == INVALID) && (ib != INVALID);
61.127 b = (ia < ib);
61.128 @@ -111,13 +118,12 @@
61.129 };
61.130 };
61.131
61.132 - /// \brief An empty base directed graph class.
61.133 + /// \brief Base skeleton class for directed graphs.
61.134 ///
61.135 - /// This class provides the minimal set of features needed for a
61.136 - /// directed graph structure. All digraph concepts have to be
61.137 - /// conform to this base directed graph. It just provides types
61.138 - /// for nodes and arcs and functions to get the source and the
61.139 - /// target of the arcs.
61.140 + /// This class describes the base interface of directed graph types.
61.141 + /// All digraph %concepts have to conform to this class.
61.142 + /// It just provides types for nodes and arcs and functions
61.143 + /// to get the source and the target nodes of arcs.
61.144 class BaseDigraphComponent {
61.145 public:
61.146
61.147 @@ -125,31 +131,27 @@
61.148
61.149 /// \brief Node class of the digraph.
61.150 ///
61.151 - /// This class represents the Nodes of the digraph.
61.152 - ///
61.153 + /// This class represents the nodes of the digraph.
61.154 typedef GraphItem<'n'> Node;
61.155
61.156 /// \brief Arc class of the digraph.
61.157 ///
61.158 - /// This class represents the Arcs of the digraph.
61.159 + /// This class represents the arcs of the digraph.
61.160 + typedef GraphItem<'a'> Arc;
61.161 +
61.162 + /// \brief Return the source node of an arc.
61.163 ///
61.164 - typedef GraphItem<'e'> Arc;
61.165 + /// This function returns the source node of an arc.
61.166 + Node source(const Arc&) const { return INVALID; }
61.167
61.168 - /// \brief Gives back the target node of an arc.
61.169 + /// \brief Return the target node of an arc.
61.170 ///
61.171 - /// Gives back the target node of an arc.
61.172 + /// This function returns the target node of an arc.
61.173 + Node target(const Arc&) const { return INVALID; }
61.174 +
61.175 + /// \brief Return the opposite node on the given arc.
61.176 ///
61.177 - Node target(const Arc&) const { return INVALID;}
61.178 -
61.179 - /// \brief Gives back the source node of an arc.
61.180 - ///
61.181 - /// Gives back the source node of an arc.
61.182 - ///
61.183 - Node source(const Arc&) const { return INVALID;}
61.184 -
61.185 - /// \brief Gives back the opposite node on the given arc.
61.186 - ///
61.187 - /// Gives back the opposite node on the given arc.
61.188 + /// This function returns the opposite node on the given arc.
61.189 Node oppositeNode(const Node&, const Arc&) const {
61.190 return INVALID;
61.191 }
61.192 @@ -175,91 +177,92 @@
61.193 };
61.194 };
61.195
61.196 - /// \brief An empty base undirected graph class.
61.197 + /// \brief Base skeleton class for undirected graphs.
61.198 ///
61.199 - /// This class provides the minimal set of features needed for an
61.200 - /// undirected graph structure. All undirected graph concepts have
61.201 - /// to be conform to this base graph. It just provides types for
61.202 - /// nodes, arcs and edges and functions to get the
61.203 - /// source and the target of the arcs and edges,
61.204 - /// conversion from arcs to edges and function to get
61.205 - /// both direction of the edges.
61.206 + /// This class describes the base interface of undirected graph types.
61.207 + /// All graph %concepts have to conform to this class.
61.208 + /// It extends the interface of \ref BaseDigraphComponent with an
61.209 + /// \c Edge type and functions to get the end nodes of edges,
61.210 + /// to convert from arcs to edges and to get both direction of edges.
61.211 class BaseGraphComponent : public BaseDigraphComponent {
61.212 public:
61.213 +
61.214 + typedef BaseGraphComponent Graph;
61.215 +
61.216 typedef BaseDigraphComponent::Node Node;
61.217 typedef BaseDigraphComponent::Arc Arc;
61.218 - /// \brief Undirected arc class of the graph.
61.219 +
61.220 + /// \brief Undirected edge class of the graph.
61.221 ///
61.222 - /// This class represents the edges of the graph.
61.223 - /// The undirected graphs can be used as a directed graph which
61.224 - /// for each arc contains the opposite arc too so the graph is
61.225 - /// bidirected. The edge represents two opposite
61.226 - /// directed arcs.
61.227 - class Edge : public GraphItem<'u'> {
61.228 + /// This class represents the undirected edges of the graph.
61.229 + /// Undirected graphs can be used as directed graphs, each edge is
61.230 + /// represented by two opposite directed arcs.
61.231 + class Edge : public GraphItem<'e'> {
61.232 + typedef GraphItem<'e'> Parent;
61.233 +
61.234 public:
61.235 - typedef GraphItem<'u'> Parent;
61.236 /// \brief Default constructor.
61.237 ///
61.238 + /// Default constructor.
61.239 /// \warning The default constructor is not required to set
61.240 /// the item to some well-defined value. So you should consider it
61.241 /// as uninitialized.
61.242 Edge() {}
61.243 +
61.244 /// \brief Copy constructor.
61.245 ///
61.246 /// Copy constructor.
61.247 + Edge(const Edge &) : Parent() {}
61.248 +
61.249 + /// \brief Constructor for conversion from \c INVALID.
61.250 ///
61.251 - Edge(const Edge &) : Parent() {}
61.252 - /// \brief Invalid constructor \& conversion.
61.253 - ///
61.254 - /// This constructor initializes the item to be invalid.
61.255 + /// Constructor for conversion from \c INVALID.
61.256 + /// It initializes the item to be invalid.
61.257 /// \sa Invalid for more details.
61.258 Edge(Invalid) {}
61.259 - /// \brief Converter from arc to edge.
61.260 +
61.261 + /// \brief Constructor for conversion from an arc.
61.262 ///
61.263 + /// Constructor for conversion from an arc.
61.264 /// Besides the core graph item functionality each arc should
61.265 /// be convertible to the represented edge.
61.266 Edge(const Arc&) {}
61.267 - /// \brief Assign arc to edge.
61.268 - ///
61.269 - /// Besides the core graph item functionality each arc should
61.270 - /// be convertible to the represented edge.
61.271 - Edge& operator=(const Arc&) { return *this; }
61.272 - };
61.273 + };
61.274
61.275 - /// \brief Returns the direction of the arc.
61.276 + /// \brief Return one end node of an edge.
61.277 + ///
61.278 + /// This function returns one end node of an edge.
61.279 + Node u(const Edge&) const { return INVALID; }
61.280 +
61.281 + /// \brief Return the other end node of an edge.
61.282 + ///
61.283 + /// This function returns the other end node of an edge.
61.284 + Node v(const Edge&) const { return INVALID; }
61.285 +
61.286 + /// \brief Return a directed arc related to an edge.
61.287 + ///
61.288 + /// This function returns a directed arc from its direction and the
61.289 + /// represented edge.
61.290 + Arc direct(const Edge&, bool) const { return INVALID; }
61.291 +
61.292 + /// \brief Return a directed arc related to an edge.
61.293 + ///
61.294 + /// This function returns a directed arc from its source node and the
61.295 + /// represented edge.
61.296 + Arc direct(const Edge&, const Node&) const { return INVALID; }
61.297 +
61.298 + /// \brief Return the direction of the arc.
61.299 ///
61.300 /// Returns the direction of the arc. Each arc represents an
61.301 /// edge with a direction. It gives back the
61.302 /// direction.
61.303 bool direction(const Arc&) const { return true; }
61.304
61.305 - /// \brief Returns the directed arc.
61.306 + /// \brief Return the opposite arc.
61.307 ///
61.308 - /// Returns the directed arc from its direction and the
61.309 - /// represented edge.
61.310 - Arc direct(const Edge&, bool) const { return INVALID;}
61.311 -
61.312 - /// \brief Returns the directed arc.
61.313 - ///
61.314 - /// Returns the directed arc from its source and the
61.315 - /// represented edge.
61.316 - Arc direct(const Edge&, const Node&) const { return INVALID;}
61.317 -
61.318 - /// \brief Returns the opposite arc.
61.319 - ///
61.320 - /// Returns the opposite arc. It is the arc representing the
61.321 - /// same edge and has opposite direction.
61.322 - Arc oppositeArc(const Arc&) const { return INVALID;}
61.323 -
61.324 - /// \brief Gives back one ending of an edge.
61.325 - ///
61.326 - /// Gives back one ending of an edge.
61.327 - Node u(const Edge&) const { return INVALID;}
61.328 -
61.329 - /// \brief Gives back the other ending of an edge.
61.330 - ///
61.331 - /// Gives back the other ending of an edge.
61.332 - Node v(const Edge&) const { return INVALID;}
61.333 + /// This function returns the opposite arc, i.e. the arc representing
61.334 + /// the same edge and has opposite direction.
61.335 + Arc oppositeArc(const Arc&) const { return INVALID; }
61.336
61.337 template <typename _Graph>
61.338 struct Constraints {
61.339 @@ -269,7 +272,7 @@
61.340
61.341 void constraints() {
61.342 checkConcept<BaseDigraphComponent, _Graph>();
61.343 - checkConcept<GraphItem<'u'>, Edge>();
61.344 + checkConcept<GraphItem<'e'>, Edge>();
61.345 {
61.346 Node n;
61.347 Edge ue(INVALID);
61.348 @@ -277,6 +280,7 @@
61.349 n = graph.u(ue);
61.350 n = graph.v(ue);
61.351 e = graph.direct(ue, true);
61.352 + e = graph.direct(ue, false);
61.353 e = graph.direct(ue, n);
61.354 e = graph.oppositeArc(e);
61.355 ue = e;
61.356 @@ -290,59 +294,57 @@
61.357
61.358 };
61.359
61.360 - /// \brief An empty idable base digraph class.
61.361 + /// \brief Skeleton class for \e idable directed graphs.
61.362 ///
61.363 - /// This class provides beside the core digraph features
61.364 - /// core id functions for the digraph structure.
61.365 - /// The most of the base digraphs should be conform to this concept.
61.366 - /// The id's are unique and immutable.
61.367 - template <typename _Base = BaseDigraphComponent>
61.368 - class IDableDigraphComponent : public _Base {
61.369 + /// This class describes the interface of \e idable directed graphs.
61.370 + /// It extends \ref BaseDigraphComponent with the core ID functions.
61.371 + /// The ids of the items must be unique and immutable.
61.372 + /// This concept is part of the Digraph concept.
61.373 + template <typename BAS = BaseDigraphComponent>
61.374 + class IDableDigraphComponent : public BAS {
61.375 public:
61.376
61.377 - typedef _Base Base;
61.378 + typedef BAS Base;
61.379 typedef typename Base::Node Node;
61.380 typedef typename Base::Arc Arc;
61.381
61.382 - /// \brief Gives back an unique integer id for the Node.
61.383 + /// \brief Return a unique integer id for the given node.
61.384 ///
61.385 - /// Gives back an unique integer id for the Node.
61.386 + /// This function returns a unique integer id for the given node.
61.387 + int id(const Node&) const { return -1; }
61.388 +
61.389 + /// \brief Return the node by its unique id.
61.390 ///
61.391 - int id(const Node&) const { return -1;}
61.392 + /// This function returns the node by its unique id.
61.393 + /// If the digraph does not contain a node with the given id,
61.394 + /// then the result of the function is undefined.
61.395 + Node nodeFromId(int) const { return INVALID; }
61.396
61.397 - /// \brief Gives back the node by the unique id.
61.398 + /// \brief Return a unique integer id for the given arc.
61.399 ///
61.400 - /// Gives back the node by the unique id.
61.401 - /// If the digraph does not contain node with the given id
61.402 - /// then the result of the function is undetermined.
61.403 - Node nodeFromId(int) const { return INVALID;}
61.404 + /// This function returns a unique integer id for the given arc.
61.405 + int id(const Arc&) const { return -1; }
61.406
61.407 - /// \brief Gives back an unique integer id for the Arc.
61.408 + /// \brief Return the arc by its unique id.
61.409 ///
61.410 - /// Gives back an unique integer id for the Arc.
61.411 + /// This function returns the arc by its unique id.
61.412 + /// If the digraph does not contain an arc with the given id,
61.413 + /// then the result of the function is undefined.
61.414 + Arc arcFromId(int) const { return INVALID; }
61.415 +
61.416 + /// \brief Return an integer greater or equal to the maximum
61.417 + /// node id.
61.418 ///
61.419 - int id(const Arc&) const { return -1;}
61.420 + /// This function returns an integer greater or equal to the
61.421 + /// maximum node id.
61.422 + int maxNodeId() const { return -1; }
61.423
61.424 - /// \brief Gives back the arc by the unique id.
61.425 + /// \brief Return an integer greater or equal to the maximum
61.426 + /// arc id.
61.427 ///
61.428 - /// Gives back the arc by the unique id.
61.429 - /// If the digraph does not contain arc with the given id
61.430 - /// then the result of the function is undetermined.
61.431 - Arc arcFromId(int) const { return INVALID;}
61.432 -
61.433 - /// \brief Gives back an integer greater or equal to the maximum
61.434 - /// Node id.
61.435 - ///
61.436 - /// Gives back an integer greater or equal to the maximum Node
61.437 - /// id.
61.438 - int maxNodeId() const { return -1;}
61.439 -
61.440 - /// \brief Gives back an integer greater or equal to the maximum
61.441 - /// Arc id.
61.442 - ///
61.443 - /// Gives back an integer greater or equal to the maximum Arc
61.444 - /// id.
61.445 - int maxArcId() const { return -1;}
61.446 + /// This function returns an integer greater or equal to the
61.447 + /// maximum arc id.
61.448 + int maxArcId() const { return -1; }
61.449
61.450 template <typename _Digraph>
61.451 struct Constraints {
61.452 @@ -350,10 +352,12 @@
61.453 void constraints() {
61.454 checkConcept<Base, _Digraph >();
61.455 typename _Digraph::Node node;
61.456 + node=INVALID;
61.457 int nid = digraph.id(node);
61.458 nid = digraph.id(node);
61.459 node = digraph.nodeFromId(nid);
61.460 typename _Digraph::Arc arc;
61.461 + arc=INVALID;
61.462 int eid = digraph.id(arc);
61.463 eid = digraph.id(arc);
61.464 arc = digraph.arcFromId(eid);
61.465 @@ -368,46 +372,45 @@
61.466 };
61.467 };
61.468
61.469 - /// \brief An empty idable base undirected graph class.
61.470 + /// \brief Skeleton class for \e idable undirected graphs.
61.471 ///
61.472 - /// This class provides beside the core undirected graph features
61.473 - /// core id functions for the undirected graph structure. The
61.474 - /// most of the base undirected graphs should be conform to this
61.475 - /// concept. The id's are unique and immutable.
61.476 - template <typename _Base = BaseGraphComponent>
61.477 - class IDableGraphComponent : public IDableDigraphComponent<_Base> {
61.478 + /// This class describes the interface of \e idable undirected
61.479 + /// graphs. It extends \ref IDableDigraphComponent with the core ID
61.480 + /// functions of undirected graphs.
61.481 + /// The ids of the items must be unique and immutable.
61.482 + /// This concept is part of the Graph concept.
61.483 + template <typename BAS = BaseGraphComponent>
61.484 + class IDableGraphComponent : public IDableDigraphComponent<BAS> {
61.485 public:
61.486
61.487 - typedef _Base Base;
61.488 + typedef BAS Base;
61.489 typedef typename Base::Edge Edge;
61.490
61.491 - using IDableDigraphComponent<_Base>::id;
61.492 + using IDableDigraphComponent<Base>::id;
61.493
61.494 - /// \brief Gives back an unique integer id for the Edge.
61.495 + /// \brief Return a unique integer id for the given edge.
61.496 ///
61.497 - /// Gives back an unique integer id for the Edge.
61.498 + /// This function returns a unique integer id for the given edge.
61.499 + int id(const Edge&) const { return -1; }
61.500 +
61.501 + /// \brief Return the edge by its unique id.
61.502 ///
61.503 - int id(const Edge&) const { return -1;}
61.504 + /// This function returns the edge by its unique id.
61.505 + /// If the graph does not contain an edge with the given id,
61.506 + /// then the result of the function is undefined.
61.507 + Edge edgeFromId(int) const { return INVALID; }
61.508
61.509 - /// \brief Gives back the edge by the unique id.
61.510 + /// \brief Return an integer greater or equal to the maximum
61.511 + /// edge id.
61.512 ///
61.513 - /// Gives back the edge by the unique id. If the
61.514 - /// graph does not contain arc with the given id then the
61.515 - /// result of the function is undetermined.
61.516 - Edge edgeFromId(int) const { return INVALID;}
61.517 -
61.518 - /// \brief Gives back an integer greater or equal to the maximum
61.519 - /// Edge id.
61.520 - ///
61.521 - /// Gives back an integer greater or equal to the maximum Edge
61.522 - /// id.
61.523 - int maxEdgeId() const { return -1;}
61.524 + /// This function returns an integer greater or equal to the
61.525 + /// maximum edge id.
61.526 + int maxEdgeId() const { return -1; }
61.527
61.528 template <typename _Graph>
61.529 struct Constraints {
61.530
61.531 void constraints() {
61.532 - checkConcept<Base, _Graph >();
61.533 checkConcept<IDableDigraphComponent<Base>, _Graph >();
61.534 typename _Graph::Edge edge;
61.535 int ueid = graph.id(edge);
61.536 @@ -421,231 +424,243 @@
61.537 };
61.538 };
61.539
61.540 - /// \brief Skeleton class for graph NodeIt and ArcIt
61.541 + /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types.
61.542 ///
61.543 - /// Skeleton class for graph NodeIt and ArcIt.
61.544 - ///
61.545 - template <typename _Graph, typename _Item>
61.546 - class GraphItemIt : public _Item {
61.547 + /// This class describes the concept of \c NodeIt, \c ArcIt and
61.548 + /// \c EdgeIt subtypes of digraph and graph types.
61.549 + template <typename GR, typename Item>
61.550 + class GraphItemIt : public Item {
61.551 public:
61.552 /// \brief Default constructor.
61.553 ///
61.554 - /// @warning The default constructor sets the iterator
61.555 - /// to an undefined value.
61.556 + /// Default constructor.
61.557 + /// \warning The default constructor is not required to set
61.558 + /// the iterator to some well-defined value. So you should consider it
61.559 + /// as uninitialized.
61.560 GraphItemIt() {}
61.561 +
61.562 /// \brief Copy constructor.
61.563 ///
61.564 /// Copy constructor.
61.565 + GraphItemIt(const GraphItemIt& it) : Item(it) {}
61.566 +
61.567 + /// \brief Constructor that sets the iterator to the first item.
61.568 ///
61.569 - GraphItemIt(const GraphItemIt& ) {}
61.570 - /// \brief Sets the iterator to the first item.
61.571 + /// Constructor that sets the iterator to the first item.
61.572 + explicit GraphItemIt(const GR&) {}
61.573 +
61.574 + /// \brief Constructor for conversion from \c INVALID.
61.575 ///
61.576 - /// Sets the iterator to the first item of \c the graph.
61.577 - ///
61.578 - explicit GraphItemIt(const _Graph&) {}
61.579 - /// \brief Invalid constructor \& conversion.
61.580 - ///
61.581 - /// This constructor initializes the item to be invalid.
61.582 + /// Constructor for conversion from \c INVALID.
61.583 + /// It initializes the iterator to be invalid.
61.584 /// \sa Invalid for more details.
61.585 GraphItemIt(Invalid) {}
61.586 - /// \brief Assign operator for items.
61.587 +
61.588 + /// \brief Assignment operator.
61.589 ///
61.590 - /// The items are assignable.
61.591 + /// Assignment operator for the iterator.
61.592 + GraphItemIt& operator=(const GraphItemIt&) { return *this; }
61.593 +
61.594 + /// \brief Increment the iterator.
61.595 ///
61.596 - GraphItemIt& operator=(const GraphItemIt&) { return *this; }
61.597 - /// \brief Next item.
61.598 - ///
61.599 - /// Assign the iterator to the next item.
61.600 - ///
61.601 + /// This operator increments the iterator, i.e. assigns it to the
61.602 + /// next item.
61.603 GraphItemIt& operator++() { return *this; }
61.604 +
61.605 /// \brief Equality operator
61.606 ///
61.607 + /// Equality operator.
61.608 /// Two iterators are equal if and only if they point to the
61.609 /// same object or both are invalid.
61.610 bool operator==(const GraphItemIt&) const { return true;}
61.611 +
61.612 /// \brief Inequality operator
61.613 ///
61.614 - /// \sa operator==(Node n)
61.615 - ///
61.616 + /// Inequality operator.
61.617 + /// Two iterators are equal if and only if they point to the
61.618 + /// same object or both are invalid.
61.619 bool operator!=(const GraphItemIt&) const { return true;}
61.620
61.621 template<typename _GraphItemIt>
61.622 struct Constraints {
61.623 void constraints() {
61.624 + checkConcept<GraphItem<>, _GraphItemIt>();
61.625 _GraphItemIt it1(g);
61.626 _GraphItemIt it2;
61.627 + _GraphItemIt it3 = it1;
61.628 + _GraphItemIt it4 = INVALID;
61.629
61.630 it2 = ++it1;
61.631 ++it2 = it1;
61.632 ++(++it1);
61.633
61.634 - _Item bi = it1;
61.635 + Item bi = it1;
61.636 bi = it2;
61.637 }
61.638 - _Graph& g;
61.639 + const GR& g;
61.640 };
61.641 };
61.642
61.643 - /// \brief Skeleton class for graph InArcIt and OutArcIt
61.644 + /// \brief Concept class for \c InArcIt, \c OutArcIt and
61.645 + /// \c IncEdgeIt types.
61.646 ///
61.647 - /// \note Because InArcIt and OutArcIt may not inherit from the same
61.648 - /// base class, the _selector is a additional template parameter. For
61.649 - /// InArcIt you should instantiate it with character 'i' and for
61.650 - /// OutArcIt with 'o'.
61.651 - template <typename _Graph,
61.652 - typename _Item = typename _Graph::Arc,
61.653 - typename _Base = typename _Graph::Node,
61.654 - char _selector = '0'>
61.655 - class GraphIncIt : public _Item {
61.656 + /// This class describes the concept of \c InArcIt, \c OutArcIt
61.657 + /// and \c IncEdgeIt subtypes of digraph and graph types.
61.658 + ///
61.659 + /// \note Since these iterator classes do not inherit from the same
61.660 + /// base class, there is an additional template parameter (selector)
61.661 + /// \c sel. For \c InArcIt you should instantiate it with character
61.662 + /// \c 'i', for \c OutArcIt with \c 'o' and for \c IncEdgeIt with \c 'e'.
61.663 + template <typename GR,
61.664 + typename Item = typename GR::Arc,
61.665 + typename Base = typename GR::Node,
61.666 + char sel = '0'>
61.667 + class GraphIncIt : public Item {
61.668 public:
61.669 /// \brief Default constructor.
61.670 ///
61.671 - /// @warning The default constructor sets the iterator
61.672 - /// to an undefined value.
61.673 + /// Default constructor.
61.674 + /// \warning The default constructor is not required to set
61.675 + /// the iterator to some well-defined value. So you should consider it
61.676 + /// as uninitialized.
61.677 GraphIncIt() {}
61.678 +
61.679 /// \brief Copy constructor.
61.680 ///
61.681 /// Copy constructor.
61.682 + GraphIncIt(const GraphIncIt& it) : Item(it) {}
61.683 +
61.684 + /// \brief Constructor that sets the iterator to the first
61.685 + /// incoming or outgoing arc.
61.686 ///
61.687 - GraphIncIt(GraphIncIt const& gi) : _Item(gi) {}
61.688 - /// \brief Sets the iterator to the first arc incoming into or outgoing
61.689 - /// from the node.
61.690 + /// Constructor that sets the iterator to the first arc
61.691 + /// incoming to or outgoing from the given node.
61.692 + explicit GraphIncIt(const GR&, const Base&) {}
61.693 +
61.694 + /// \brief Constructor for conversion from \c INVALID.
61.695 ///
61.696 - /// Sets the iterator to the first arc incoming into or outgoing
61.697 - /// from the node.
61.698 - ///
61.699 - explicit GraphIncIt(const _Graph&, const _Base&) {}
61.700 - /// \brief Invalid constructor \& conversion.
61.701 - ///
61.702 - /// This constructor initializes the item to be invalid.
61.703 + /// Constructor for conversion from \c INVALID.
61.704 + /// It initializes the iterator to be invalid.
61.705 /// \sa Invalid for more details.
61.706 GraphIncIt(Invalid) {}
61.707 - /// \brief Assign operator for iterators.
61.708 +
61.709 + /// \brief Assignment operator.
61.710 ///
61.711 - /// The iterators are assignable.
61.712 + /// Assignment operator for the iterator.
61.713 + GraphIncIt& operator=(const GraphIncIt&) { return *this; }
61.714 +
61.715 + /// \brief Increment the iterator.
61.716 ///
61.717 - GraphIncIt& operator=(GraphIncIt const&) { return *this; }
61.718 - /// \brief Next item.
61.719 - ///
61.720 - /// Assign the iterator to the next item.
61.721 - ///
61.722 + /// This operator increments the iterator, i.e. assigns it to the
61.723 + /// next arc incoming to or outgoing from the given node.
61.724 GraphIncIt& operator++() { return *this; }
61.725
61.726 /// \brief Equality operator
61.727 ///
61.728 + /// Equality operator.
61.729 /// Two iterators are equal if and only if they point to the
61.730 /// same object or both are invalid.
61.731 bool operator==(const GraphIncIt&) const { return true;}
61.732
61.733 /// \brief Inequality operator
61.734 ///
61.735 - /// \sa operator==(Node n)
61.736 - ///
61.737 + /// Inequality operator.
61.738 + /// Two iterators are equal if and only if they point to the
61.739 + /// same object or both are invalid.
61.740 bool operator!=(const GraphIncIt&) const { return true;}
61.741
61.742 template <typename _GraphIncIt>
61.743 struct Constraints {
61.744 void constraints() {
61.745 - checkConcept<GraphItem<_selector>, _GraphIncIt>();
61.746 + checkConcept<GraphItem<sel>, _GraphIncIt>();
61.747 _GraphIncIt it1(graph, node);
61.748 _GraphIncIt it2;
61.749 + _GraphIncIt it3 = it1;
61.750 + _GraphIncIt it4 = INVALID;
61.751
61.752 it2 = ++it1;
61.753 ++it2 = it1;
61.754 ++(++it1);
61.755 - _Item e = it1;
61.756 + Item e = it1;
61.757 e = it2;
61.758 -
61.759 }
61.760 -
61.761 - _Item arc;
61.762 - _Base node;
61.763 - _Graph graph;
61.764 - _GraphIncIt it;
61.765 + const Base& node;
61.766 + const GR& graph;
61.767 };
61.768 };
61.769
61.770 -
61.771 - /// \brief An empty iterable digraph class.
61.772 + /// \brief Skeleton class for iterable directed graphs.
61.773 ///
61.774 - /// This class provides beside the core digraph features
61.775 - /// iterator based iterable interface for the digraph structure.
61.776 + /// This class describes the interface of iterable directed
61.777 + /// graphs. It extends \ref BaseDigraphComponent with the core
61.778 + /// iterable interface.
61.779 /// This concept is part of the Digraph concept.
61.780 - template <typename _Base = BaseDigraphComponent>
61.781 - class IterableDigraphComponent : public _Base {
61.782 + template <typename BAS = BaseDigraphComponent>
61.783 + class IterableDigraphComponent : public BAS {
61.784
61.785 public:
61.786
61.787 - typedef _Base Base;
61.788 + typedef BAS Base;
61.789 typedef typename Base::Node Node;
61.790 typedef typename Base::Arc Arc;
61.791
61.792 typedef IterableDigraphComponent Digraph;
61.793
61.794 - /// \name Base iteration
61.795 + /// \name Base Iteration
61.796 ///
61.797 - /// This interface provides functions for iteration on digraph items
61.798 + /// This interface provides functions for iteration on digraph items.
61.799 ///
61.800 /// @{
61.801
61.802 - /// \brief Gives back the first node in the iterating order.
61.803 + /// \brief Return the first node.
61.804 ///
61.805 - /// Gives back the first node in the iterating order.
61.806 - ///
61.807 + /// This function gives back the first node in the iteration order.
61.808 void first(Node&) const {}
61.809
61.810 - /// \brief Gives back the next node in the iterating order.
61.811 + /// \brief Return the next node.
61.812 ///
61.813 - /// Gives back the next node in the iterating order.
61.814 - ///
61.815 + /// This function gives back the next node in the iteration order.
61.816 void next(Node&) const {}
61.817
61.818 - /// \brief Gives back the first arc in the iterating order.
61.819 + /// \brief Return the first arc.
61.820 ///
61.821 - /// Gives back the first arc in the iterating order.
61.822 - ///
61.823 + /// This function gives back the first arc in the iteration order.
61.824 void first(Arc&) const {}
61.825
61.826 - /// \brief Gives back the next arc in the iterating order.
61.827 + /// \brief Return the next arc.
61.828 ///
61.829 - /// Gives back the next arc in the iterating order.
61.830 - ///
61.831 + /// This function gives back the next arc in the iteration order.
61.832 void next(Arc&) const {}
61.833
61.834 -
61.835 - /// \brief Gives back the first of the arcs point to the given
61.836 - /// node.
61.837 + /// \brief Return the first arc incomming to the given node.
61.838 ///
61.839 - /// Gives back the first of the arcs point to the given node.
61.840 - ///
61.841 + /// This function gives back the first arc incomming to the
61.842 + /// given node.
61.843 void firstIn(Arc&, const Node&) const {}
61.844
61.845 - /// \brief Gives back the next of the arcs points to the given
61.846 - /// node.
61.847 + /// \brief Return the next arc incomming to the given node.
61.848 ///
61.849 - /// Gives back the next of the arcs points to the given node.
61.850 - ///
61.851 + /// This function gives back the next arc incomming to the
61.852 + /// given node.
61.853 void nextIn(Arc&) const {}
61.854
61.855 - /// \brief Gives back the first of the arcs start from the
61.856 + /// \brief Return the first arc outgoing form the given node.
61.857 + ///
61.858 + /// This function gives back the first arc outgoing form the
61.859 /// given node.
61.860 - ///
61.861 - /// Gives back the first of the arcs start from the given node.
61.862 - ///
61.863 void firstOut(Arc&, const Node&) const {}
61.864
61.865 - /// \brief Gives back the next of the arcs start from the given
61.866 - /// node.
61.867 + /// \brief Return the next arc outgoing form the given node.
61.868 ///
61.869 - /// Gives back the next of the arcs start from the given node.
61.870 - ///
61.871 + /// This function gives back the next arc outgoing form the
61.872 + /// given node.
61.873 void nextOut(Arc&) const {}
61.874
61.875 /// @}
61.876
61.877 - /// \name Class based iteration
61.878 + /// \name Class Based Iteration
61.879 ///
61.880 - /// This interface provides functions for iteration on digraph items
61.881 + /// This interface provides iterator classes for digraph items.
61.882 ///
61.883 /// @{
61.884
61.885 @@ -655,15 +670,15 @@
61.886 ///
61.887 typedef GraphItemIt<Digraph, Node> NodeIt;
61.888
61.889 - /// \brief This iterator goes through each node.
61.890 + /// \brief This iterator goes through each arc.
61.891 ///
61.892 - /// This iterator goes through each node.
61.893 + /// This iterator goes through each arc.
61.894 ///
61.895 typedef GraphItemIt<Digraph, Arc> ArcIt;
61.896
61.897 /// \brief This iterator goes trough the incoming arcs of a node.
61.898 ///
61.899 - /// This iterator goes trough the \e inccoming arcs of a certain node
61.900 + /// This iterator goes trough the \e incoming arcs of a certain node
61.901 /// of a digraph.
61.902 typedef GraphIncIt<Digraph, Arc, Node, 'i'> InArcIt;
61.903
61.904 @@ -675,26 +690,26 @@
61.905
61.906 /// \brief The base node of the iterator.
61.907 ///
61.908 - /// Gives back the base node of the iterator.
61.909 - /// It is always the target of the pointed arc.
61.910 + /// This function gives back the base node of the iterator.
61.911 + /// It is always the target node of the pointed arc.
61.912 Node baseNode(const InArcIt&) const { return INVALID; }
61.913
61.914 /// \brief The running node of the iterator.
61.915 ///
61.916 - /// Gives back the running node of the iterator.
61.917 - /// It is always the source of the pointed arc.
61.918 + /// This function gives back the running node of the iterator.
61.919 + /// It is always the source node of the pointed arc.
61.920 Node runningNode(const InArcIt&) const { return INVALID; }
61.921
61.922 /// \brief The base node of the iterator.
61.923 ///
61.924 - /// Gives back the base node of the iterator.
61.925 - /// It is always the source of the pointed arc.
61.926 + /// This function gives back the base node of the iterator.
61.927 + /// It is always the source node of the pointed arc.
61.928 Node baseNode(const OutArcIt&) const { return INVALID; }
61.929
61.930 /// \brief The running node of the iterator.
61.931 ///
61.932 - /// Gives back the running node of the iterator.
61.933 - /// It is always the target of the pointed arc.
61.934 + /// This function gives back the running node of the iterator.
61.935 + /// It is always the target node of the pointed arc.
61.936 Node runningNode(const OutArcIt&) const { return INVALID; }
61.937
61.938 /// @}
61.939 @@ -736,31 +751,31 @@
61.940 typename _Digraph::Node, 'o'>, typename _Digraph::OutArcIt>();
61.941
61.942 typename _Digraph::Node n;
61.943 - typename _Digraph::InArcIt ieit(INVALID);
61.944 - typename _Digraph::OutArcIt oeit(INVALID);
61.945 - n = digraph.baseNode(ieit);
61.946 - n = digraph.runningNode(ieit);
61.947 - n = digraph.baseNode(oeit);
61.948 - n = digraph.runningNode(oeit);
61.949 + const typename _Digraph::InArcIt iait(INVALID);
61.950 + const typename _Digraph::OutArcIt oait(INVALID);
61.951 + n = digraph.baseNode(iait);
61.952 + n = digraph.runningNode(iait);
61.953 + n = digraph.baseNode(oait);
61.954 + n = digraph.runningNode(oait);
61.955 ignore_unused_variable_warning(n);
61.956 }
61.957 }
61.958
61.959 const _Digraph& digraph;
61.960 -
61.961 };
61.962 };
61.963
61.964 - /// \brief An empty iterable undirected graph class.
61.965 + /// \brief Skeleton class for iterable undirected graphs.
61.966 ///
61.967 - /// This class provides beside the core graph features iterator
61.968 - /// based iterable interface for the undirected graph structure.
61.969 + /// This class describes the interface of iterable undirected
61.970 + /// graphs. It extends \ref IterableDigraphComponent with the core
61.971 + /// iterable interface of undirected graphs.
61.972 /// This concept is part of the Graph concept.
61.973 - template <typename _Base = BaseGraphComponent>
61.974 - class IterableGraphComponent : public IterableDigraphComponent<_Base> {
61.975 + template <typename BAS = BaseGraphComponent>
61.976 + class IterableGraphComponent : public IterableDigraphComponent<BAS> {
61.977 public:
61.978
61.979 - typedef _Base Base;
61.980 + typedef BAS Base;
61.981 typedef typename Base::Node Node;
61.982 typedef typename Base::Arc Arc;
61.983 typedef typename Base::Edge Edge;
61.984 @@ -768,75 +783,71 @@
61.985
61.986 typedef IterableGraphComponent Graph;
61.987
61.988 - /// \name Base iteration
61.989 + /// \name Base Iteration
61.990 ///
61.991 - /// This interface provides functions for iteration on graph items
61.992 + /// This interface provides functions for iteration on edges.
61.993 + ///
61.994 /// @{
61.995
61.996 - using IterableDigraphComponent<_Base>::first;
61.997 - using IterableDigraphComponent<_Base>::next;
61.998 + using IterableDigraphComponent<Base>::first;
61.999 + using IterableDigraphComponent<Base>::next;
61.1000
61.1001 - /// \brief Gives back the first edge in the iterating
61.1002 - /// order.
61.1003 + /// \brief Return the first edge.
61.1004 ///
61.1005 - /// Gives back the first edge in the iterating order.
61.1006 - ///
61.1007 + /// This function gives back the first edge in the iteration order.
61.1008 void first(Edge&) const {}
61.1009
61.1010 - /// \brief Gives back the next edge in the iterating
61.1011 - /// order.
61.1012 + /// \brief Return the next edge.
61.1013 ///
61.1014 - /// Gives back the next edge in the iterating order.
61.1015 - ///
61.1016 + /// This function gives back the next edge in the iteration order.
61.1017 void next(Edge&) const {}
61.1018
61.1019 -
61.1020 - /// \brief Gives back the first of the edges from the
61.1021 + /// \brief Return the first edge incident to the given node.
61.1022 + ///
61.1023 + /// This function gives back the first edge incident to the given
61.1024 + /// node. The bool parameter gives back the direction for which the
61.1025 + /// source node of the directed arc representing the edge is the
61.1026 /// given node.
61.1027 - ///
61.1028 - /// Gives back the first of the edges from the given
61.1029 - /// node. The bool parameter gives back that direction which
61.1030 - /// gives a good direction of the edge so the source of the
61.1031 - /// directed arc is the given node.
61.1032 void firstInc(Edge&, bool&, const Node&) const {}
61.1033
61.1034 /// \brief Gives back the next of the edges from the
61.1035 /// given node.
61.1036 ///
61.1037 - /// Gives back the next of the edges from the given
61.1038 - /// node. The bool parameter should be used as the \c firstInc()
61.1039 - /// use it.
61.1040 + /// This function gives back the next edge incident to the given
61.1041 + /// node. The bool parameter should be used as \c firstInc() use it.
61.1042 void nextInc(Edge&, bool&) const {}
61.1043
61.1044 - using IterableDigraphComponent<_Base>::baseNode;
61.1045 - using IterableDigraphComponent<_Base>::runningNode;
61.1046 + using IterableDigraphComponent<Base>::baseNode;
61.1047 + using IterableDigraphComponent<Base>::runningNode;
61.1048
61.1049 /// @}
61.1050
61.1051 - /// \name Class based iteration
61.1052 + /// \name Class Based Iteration
61.1053 ///
61.1054 - /// This interface provides functions for iteration on graph items
61.1055 + /// This interface provides iterator classes for edges.
61.1056 ///
61.1057 /// @{
61.1058
61.1059 - /// \brief This iterator goes through each node.
61.1060 + /// \brief This iterator goes through each edge.
61.1061 ///
61.1062 - /// This iterator goes through each node.
61.1063 + /// This iterator goes through each edge.
61.1064 typedef GraphItemIt<Graph, Edge> EdgeIt;
61.1065 - /// \brief This iterator goes trough the incident arcs of a
61.1066 +
61.1067 + /// \brief This iterator goes trough the incident edges of a
61.1068 /// node.
61.1069 ///
61.1070 - /// This iterator goes trough the incident arcs of a certain
61.1071 + /// This iterator goes trough the incident edges of a certain
61.1072 /// node of a graph.
61.1073 - typedef GraphIncIt<Graph, Edge, Node, 'u'> IncEdgeIt;
61.1074 + typedef GraphIncIt<Graph, Edge, Node, 'e'> IncEdgeIt;
61.1075 +
61.1076 /// \brief The base node of the iterator.
61.1077 ///
61.1078 - /// Gives back the base node of the iterator.
61.1079 + /// This function gives back the base node of the iterator.
61.1080 Node baseNode(const IncEdgeIt&) const { return INVALID; }
61.1081
61.1082 /// \brief The running node of the iterator.
61.1083 ///
61.1084 - /// Gives back the running node of the iterator.
61.1085 + /// This function gives back the running node of the iterator.
61.1086 Node runningNode(const IncEdgeIt&) const { return INVALID; }
61.1087
61.1088 /// @}
61.1089 @@ -865,54 +876,54 @@
61.1090 checkConcept<GraphItemIt<_Graph, typename _Graph::Edge>,
61.1091 typename _Graph::EdgeIt >();
61.1092 checkConcept<GraphIncIt<_Graph, typename _Graph::Edge,
61.1093 - typename _Graph::Node, 'u'>, typename _Graph::IncEdgeIt>();
61.1094 + typename _Graph::Node, 'e'>, typename _Graph::IncEdgeIt>();
61.1095
61.1096 typename _Graph::Node n;
61.1097 - typename _Graph::IncEdgeIt ueit(INVALID);
61.1098 - n = graph.baseNode(ueit);
61.1099 - n = graph.runningNode(ueit);
61.1100 + const typename _Graph::IncEdgeIt ieit(INVALID);
61.1101 + n = graph.baseNode(ieit);
61.1102 + n = graph.runningNode(ieit);
61.1103 }
61.1104 }
61.1105
61.1106 const _Graph& graph;
61.1107 -
61.1108 };
61.1109 };
61.1110
61.1111 - /// \brief An empty alteration notifier digraph class.
61.1112 + /// \brief Skeleton class for alterable directed graphs.
61.1113 ///
61.1114 - /// This class provides beside the core digraph features alteration
61.1115 - /// notifier interface for the digraph structure. This implements
61.1116 + /// This class describes the interface of alterable directed
61.1117 + /// graphs. It extends \ref BaseDigraphComponent with the alteration
61.1118 + /// notifier interface. It implements
61.1119 /// an observer-notifier pattern for each digraph item. More
61.1120 /// obsevers can be registered into the notifier and whenever an
61.1121 - /// alteration occured in the digraph all the observers will
61.1122 + /// alteration occured in the digraph all the observers will be
61.1123 /// notified about it.
61.1124 - template <typename _Base = BaseDigraphComponent>
61.1125 - class AlterableDigraphComponent : public _Base {
61.1126 + template <typename BAS = BaseDigraphComponent>
61.1127 + class AlterableDigraphComponent : public BAS {
61.1128 public:
61.1129
61.1130 - typedef _Base Base;
61.1131 + typedef BAS Base;
61.1132 typedef typename Base::Node Node;
61.1133 typedef typename Base::Arc Arc;
61.1134
61.1135
61.1136 - /// The node observer registry.
61.1137 + /// Node alteration notifier class.
61.1138 typedef AlterationNotifier<AlterableDigraphComponent, Node>
61.1139 NodeNotifier;
61.1140 - /// The arc observer registry.
61.1141 + /// Arc alteration notifier class.
61.1142 typedef AlterationNotifier<AlterableDigraphComponent, Arc>
61.1143 ArcNotifier;
61.1144
61.1145 - /// \brief Gives back the node alteration notifier.
61.1146 + /// \brief Return the node alteration notifier.
61.1147 ///
61.1148 - /// Gives back the node alteration notifier.
61.1149 + /// This function gives back the node alteration notifier.
61.1150 NodeNotifier& notifier(Node) const {
61.1151 - return NodeNotifier();
61.1152 + return NodeNotifier();
61.1153 }
61.1154
61.1155 - /// \brief Gives back the arc alteration notifier.
61.1156 + /// \brief Return the arc alteration notifier.
61.1157 ///
61.1158 - /// Gives back the arc alteration notifier.
61.1159 + /// This function gives back the arc alteration notifier.
61.1160 ArcNotifier& notifier(Arc) const {
61.1161 return ArcNotifier();
61.1162 }
61.1163 @@ -932,34 +943,33 @@
61.1164 }
61.1165
61.1166 const _Digraph& digraph;
61.1167 -
61.1168 };
61.1169 -
61.1170 };
61.1171
61.1172 - /// \brief An empty alteration notifier undirected graph class.
61.1173 + /// \brief Skeleton class for alterable undirected graphs.
61.1174 ///
61.1175 - /// This class provides beside the core graph features alteration
61.1176 - /// notifier interface for the graph structure. This implements
61.1177 - /// an observer-notifier pattern for each graph item. More
61.1178 + /// This class describes the interface of alterable undirected
61.1179 + /// graphs. It extends \ref AlterableDigraphComponent with the alteration
61.1180 + /// notifier interface of undirected graphs. It implements
61.1181 + /// an observer-notifier pattern for the edges. More
61.1182 /// obsevers can be registered into the notifier and whenever an
61.1183 - /// alteration occured in the graph all the observers will
61.1184 + /// alteration occured in the graph all the observers will be
61.1185 /// notified about it.
61.1186 - template <typename _Base = BaseGraphComponent>
61.1187 - class AlterableGraphComponent : public AlterableDigraphComponent<_Base> {
61.1188 + template <typename BAS = BaseGraphComponent>
61.1189 + class AlterableGraphComponent : public AlterableDigraphComponent<BAS> {
61.1190 public:
61.1191
61.1192 - typedef _Base Base;
61.1193 + typedef BAS Base;
61.1194 typedef typename Base::Edge Edge;
61.1195
61.1196
61.1197 - /// The arc observer registry.
61.1198 + /// Edge alteration notifier class.
61.1199 typedef AlterationNotifier<AlterableGraphComponent, Edge>
61.1200 EdgeNotifier;
61.1201
61.1202 - /// \brief Gives back the arc alteration notifier.
61.1203 + /// \brief Return the edge alteration notifier.
61.1204 ///
61.1205 - /// Gives back the arc alteration notifier.
61.1206 + /// This function gives back the edge alteration notifier.
61.1207 EdgeNotifier& notifier(Edge) const {
61.1208 return EdgeNotifier();
61.1209 }
61.1210 @@ -967,44 +977,48 @@
61.1211 template <typename _Graph>
61.1212 struct Constraints {
61.1213 void constraints() {
61.1214 - checkConcept<AlterableGraphComponent<Base>, _Graph>();
61.1215 + checkConcept<AlterableDigraphComponent<Base>, _Graph>();
61.1216 typename _Graph::EdgeNotifier& uen
61.1217 = graph.notifier(typename _Graph::Edge());
61.1218 ignore_unused_variable_warning(uen);
61.1219 }
61.1220
61.1221 const _Graph& graph;
61.1222 -
61.1223 };
61.1224 -
61.1225 };
61.1226
61.1227 - /// \brief Class describing the concept of graph maps
61.1228 + /// \brief Concept class for standard graph maps.
61.1229 ///
61.1230 - /// This class describes the common interface of the graph maps
61.1231 - /// (NodeMap, ArcMap), that is maps that can be used to
61.1232 - /// associate data to graph descriptors (nodes or arcs).
61.1233 - template <typename _Graph, typename _Item, typename _Value>
61.1234 - class GraphMap : public ReadWriteMap<_Item, _Value> {
61.1235 + /// This class describes the concept of standard graph maps, i.e.
61.1236 + /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and
61.1237 + /// graph types, which can be used for associating data to graph items.
61.1238 + /// The standard graph maps must conform to the ReferenceMap concept.
61.1239 + template <typename GR, typename K, typename V>
61.1240 + class GraphMap : public ReferenceMap<K, V, V&, const V&> {
61.1241 + typedef ReferenceMap<K, V, V&, const V&> Parent;
61.1242 +
61.1243 public:
61.1244
61.1245 - typedef ReadWriteMap<_Item, _Value> Parent;
61.1246 + /// The key type of the map.
61.1247 + typedef K Key;
61.1248 + /// The value type of the map.
61.1249 + typedef V Value;
61.1250 + /// The reference type of the map.
61.1251 + typedef Value& Reference;
61.1252 + /// The const reference type of the map.
61.1253 + typedef const Value& ConstReference;
61.1254
61.1255 - /// The graph type of the map.
61.1256 - typedef _Graph Graph;
61.1257 - /// The key type of the map.
61.1258 - typedef _Item Key;
61.1259 - /// The value type of the map.
61.1260 - typedef _Value Value;
61.1261 + // The reference map tag.
61.1262 + typedef True ReferenceMapTag;
61.1263
61.1264 /// \brief Construct a new map.
61.1265 ///
61.1266 /// Construct a new map for the graph.
61.1267 - explicit GraphMap(const Graph&) {}
61.1268 + explicit GraphMap(const GR&) {}
61.1269 /// \brief Construct a new map with default value.
61.1270 ///
61.1271 - /// Construct a new map for the graph and initalise the values.
61.1272 - GraphMap(const Graph&, const Value&) {}
61.1273 + /// Construct a new map for the graph and initalize the values.
61.1274 + GraphMap(const GR&, const Value&) {}
61.1275
61.1276 private:
61.1277 /// \brief Copy constructor.
61.1278 @@ -1012,9 +1026,9 @@
61.1279 /// Copy Constructor.
61.1280 GraphMap(const GraphMap&) : Parent() {}
61.1281
61.1282 - /// \brief Assign operator.
61.1283 + /// \brief Assignment operator.
61.1284 ///
61.1285 - /// Assign operator. It does not mofify the underlying graph,
61.1286 + /// Assignment operator. It does not mofify the underlying graph,
61.1287 /// it just iterates on the current item set and set the map
61.1288 /// with the value returned by the assigned map.
61.1289 template <typename CMap>
61.1290 @@ -1027,53 +1041,55 @@
61.1291 template<typename _Map>
61.1292 struct Constraints {
61.1293 void constraints() {
61.1294 - checkConcept<ReadWriteMap<Key, Value>, _Map >();
61.1295 - // Construction with a graph parameter
61.1296 - _Map a(g);
61.1297 - // Constructor with a graph and a default value parameter
61.1298 - _Map a2(g,t);
61.1299 - // Copy constructor.
61.1300 - // _Map b(c);
61.1301 + checkConcept
61.1302 + <ReferenceMap<Key, Value, Value&, const Value&>, _Map>();
61.1303 + _Map m1(g);
61.1304 + _Map m2(g,t);
61.1305 +
61.1306 + // Copy constructor
61.1307 + // _Map m3(m);
61.1308
61.1309 + // Assignment operator
61.1310 // ReadMap<Key, Value> cmap;
61.1311 - // b = cmap;
61.1312 + // m3 = cmap;
61.1313
61.1314 - ignore_unused_variable_warning(a);
61.1315 - ignore_unused_variable_warning(a2);
61.1316 - // ignore_unused_variable_warning(b);
61.1317 + ignore_unused_variable_warning(m1);
61.1318 + ignore_unused_variable_warning(m2);
61.1319 + // ignore_unused_variable_warning(m3);
61.1320 }
61.1321
61.1322 - const _Map &c;
61.1323 - const Graph &g;
61.1324 + const _Map &m;
61.1325 + const GR &g;
61.1326 const typename GraphMap::Value &t;
61.1327 };
61.1328
61.1329 };
61.1330
61.1331 - /// \brief An empty mappable digraph class.
61.1332 + /// \brief Skeleton class for mappable directed graphs.
61.1333 ///
61.1334 - /// This class provides beside the core digraph features
61.1335 - /// map interface for the digraph structure.
61.1336 + /// This class describes the interface of mappable directed graphs.
61.1337 + /// It extends \ref BaseDigraphComponent with the standard digraph
61.1338 + /// map classes, namely \c NodeMap and \c ArcMap.
61.1339 /// This concept is part of the Digraph concept.
61.1340 - template <typename _Base = BaseDigraphComponent>
61.1341 - class MappableDigraphComponent : public _Base {
61.1342 + template <typename BAS = BaseDigraphComponent>
61.1343 + class MappableDigraphComponent : public BAS {
61.1344 public:
61.1345
61.1346 - typedef _Base Base;
61.1347 + typedef BAS Base;
61.1348 typedef typename Base::Node Node;
61.1349 typedef typename Base::Arc Arc;
61.1350
61.1351 typedef MappableDigraphComponent Digraph;
61.1352
61.1353 - /// \brief ReadWrite map of the nodes.
61.1354 + /// \brief Standard graph map for the nodes.
61.1355 ///
61.1356 - /// ReadWrite map of the nodes.
61.1357 - ///
61.1358 - template <typename _Value>
61.1359 - class NodeMap : public GraphMap<Digraph, Node, _Value> {
61.1360 + /// Standard graph map for the nodes.
61.1361 + /// It conforms to the ReferenceMap concept.
61.1362 + template <typename V>
61.1363 + class NodeMap : public GraphMap<MappableDigraphComponent, Node, V> {
61.1364 + typedef GraphMap<MappableDigraphComponent, Node, V> Parent;
61.1365 +
61.1366 public:
61.1367 - typedef GraphMap<MappableDigraphComponent, Node, _Value> Parent;
61.1368 -
61.1369 /// \brief Construct a new map.
61.1370 ///
61.1371 /// Construct a new map for the digraph.
61.1372 @@ -1082,8 +1098,8 @@
61.1373
61.1374 /// \brief Construct a new map with default value.
61.1375 ///
61.1376 - /// Construct a new map for the digraph and initalise the values.
61.1377 - NodeMap(const MappableDigraphComponent& digraph, const _Value& value)
61.1378 + /// Construct a new map for the digraph and initalize the values.
61.1379 + NodeMap(const MappableDigraphComponent& digraph, const V& value)
61.1380 : Parent(digraph, value) {}
61.1381
61.1382 private:
61.1383 @@ -1092,26 +1108,26 @@
61.1384 /// Copy Constructor.
61.1385 NodeMap(const NodeMap& nm) : Parent(nm) {}
61.1386
61.1387 - /// \brief Assign operator.
61.1388 + /// \brief Assignment operator.
61.1389 ///
61.1390 - /// Assign operator.
61.1391 + /// Assignment operator.
61.1392 template <typename CMap>
61.1393 NodeMap& operator=(const CMap&) {
61.1394 - checkConcept<ReadMap<Node, _Value>, CMap>();
61.1395 + checkConcept<ReadMap<Node, V>, CMap>();
61.1396 return *this;
61.1397 }
61.1398
61.1399 };
61.1400
61.1401 - /// \brief ReadWrite map of the arcs.
61.1402 + /// \brief Standard graph map for the arcs.
61.1403 ///
61.1404 - /// ReadWrite map of the arcs.
61.1405 - ///
61.1406 - template <typename _Value>
61.1407 - class ArcMap : public GraphMap<Digraph, Arc, _Value> {
61.1408 + /// Standard graph map for the arcs.
61.1409 + /// It conforms to the ReferenceMap concept.
61.1410 + template <typename V>
61.1411 + class ArcMap : public GraphMap<MappableDigraphComponent, Arc, V> {
61.1412 + typedef GraphMap<MappableDigraphComponent, Arc, V> Parent;
61.1413 +
61.1414 public:
61.1415 - typedef GraphMap<MappableDigraphComponent, Arc, _Value> Parent;
61.1416 -
61.1417 /// \brief Construct a new map.
61.1418 ///
61.1419 /// Construct a new map for the digraph.
61.1420 @@ -1120,8 +1136,8 @@
61.1421
61.1422 /// \brief Construct a new map with default value.
61.1423 ///
61.1424 - /// Construct a new map for the digraph and initalise the values.
61.1425 - ArcMap(const MappableDigraphComponent& digraph, const _Value& value)
61.1426 + /// Construct a new map for the digraph and initalize the values.
61.1427 + ArcMap(const MappableDigraphComponent& digraph, const V& value)
61.1428 : Parent(digraph, value) {}
61.1429
61.1430 private:
61.1431 @@ -1130,12 +1146,12 @@
61.1432 /// Copy Constructor.
61.1433 ArcMap(const ArcMap& nm) : Parent(nm) {}
61.1434
61.1435 - /// \brief Assign operator.
61.1436 + /// \brief Assignment operator.
61.1437 ///
61.1438 - /// Assign operator.
61.1439 + /// Assignment operator.
61.1440 template <typename CMap>
61.1441 ArcMap& operator=(const CMap&) {
61.1442 - checkConcept<ReadMap<Arc, _Value>, CMap>();
61.1443 + checkConcept<ReadMap<Arc, V>, CMap>();
61.1444 return *this;
61.1445 }
61.1446
61.1447 @@ -1182,33 +1198,34 @@
61.1448 }
61.1449 }
61.1450
61.1451 - _Digraph& digraph;
61.1452 + const _Digraph& digraph;
61.1453 };
61.1454 };
61.1455
61.1456 - /// \brief An empty mappable base bipartite graph class.
61.1457 + /// \brief Skeleton class for mappable undirected graphs.
61.1458 ///
61.1459 - /// This class provides beside the core graph features
61.1460 - /// map interface for the graph structure.
61.1461 + /// This class describes the interface of mappable undirected graphs.
61.1462 + /// It extends \ref MappableDigraphComponent with the standard graph
61.1463 + /// map class for edges (\c EdgeMap).
61.1464 /// This concept is part of the Graph concept.
61.1465 - template <typename _Base = BaseGraphComponent>
61.1466 - class MappableGraphComponent : public MappableDigraphComponent<_Base> {
61.1467 + template <typename BAS = BaseGraphComponent>
61.1468 + class MappableGraphComponent : public MappableDigraphComponent<BAS> {
61.1469 public:
61.1470
61.1471 - typedef _Base Base;
61.1472 + typedef BAS Base;
61.1473 typedef typename Base::Edge Edge;
61.1474
61.1475 typedef MappableGraphComponent Graph;
61.1476
61.1477 - /// \brief ReadWrite map of the edges.
61.1478 + /// \brief Standard graph map for the edges.
61.1479 ///
61.1480 - /// ReadWrite map of the edges.
61.1481 - ///
61.1482 - template <typename _Value>
61.1483 - class EdgeMap : public GraphMap<Graph, Edge, _Value> {
61.1484 + /// Standard graph map for the edges.
61.1485 + /// It conforms to the ReferenceMap concept.
61.1486 + template <typename V>
61.1487 + class EdgeMap : public GraphMap<MappableGraphComponent, Edge, V> {
61.1488 + typedef GraphMap<MappableGraphComponent, Edge, V> Parent;
61.1489 +
61.1490 public:
61.1491 - typedef GraphMap<MappableGraphComponent, Edge, _Value> Parent;
61.1492 -
61.1493 /// \brief Construct a new map.
61.1494 ///
61.1495 /// Construct a new map for the graph.
61.1496 @@ -1217,8 +1234,8 @@
61.1497
61.1498 /// \brief Construct a new map with default value.
61.1499 ///
61.1500 - /// Construct a new map for the graph and initalise the values.
61.1501 - EdgeMap(const MappableGraphComponent& graph, const _Value& value)
61.1502 + /// Construct a new map for the graph and initalize the values.
61.1503 + EdgeMap(const MappableGraphComponent& graph, const V& value)
61.1504 : Parent(graph, value) {}
61.1505
61.1506 private:
61.1507 @@ -1227,12 +1244,12 @@
61.1508 /// Copy Constructor.
61.1509 EdgeMap(const EdgeMap& nm) : Parent(nm) {}
61.1510
61.1511 - /// \brief Assign operator.
61.1512 + /// \brief Assignment operator.
61.1513 ///
61.1514 - /// Assign operator.
61.1515 + /// Assignment operator.
61.1516 template <typename CMap>
61.1517 EdgeMap& operator=(const CMap&) {
61.1518 - checkConcept<ReadMap<Edge, _Value>, CMap>();
61.1519 + checkConcept<ReadMap<Edge, V>, CMap>();
61.1520 return *this;
61.1521 }
61.1522
61.1523 @@ -1249,7 +1266,7 @@
61.1524 };
61.1525
61.1526 void constraints() {
61.1527 - checkConcept<MappableGraphComponent<Base>, _Graph>();
61.1528 + checkConcept<MappableDigraphComponent<Base>, _Graph>();
61.1529
61.1530 { // int map test
61.1531 typedef typename _Graph::template EdgeMap<int> IntEdgeMap;
61.1532 @@ -1266,35 +1283,35 @@
61.1533 }
61.1534 }
61.1535
61.1536 - _Graph& graph;
61.1537 + const _Graph& graph;
61.1538 };
61.1539 };
61.1540
61.1541 - /// \brief An empty extendable digraph class.
61.1542 + /// \brief Skeleton class for extendable directed graphs.
61.1543 ///
61.1544 - /// This class provides beside the core digraph features digraph
61.1545 - /// extendable interface for the digraph structure. The main
61.1546 - /// difference between the base and this interface is that the
61.1547 - /// digraph alterations should handled already on this level.
61.1548 - template <typename _Base = BaseDigraphComponent>
61.1549 - class ExtendableDigraphComponent : public _Base {
61.1550 + /// This class describes the interface of extendable directed graphs.
61.1551 + /// It extends \ref BaseDigraphComponent with functions for adding
61.1552 + /// nodes and arcs to the digraph.
61.1553 + /// This concept requires \ref AlterableDigraphComponent.
61.1554 + template <typename BAS = BaseDigraphComponent>
61.1555 + class ExtendableDigraphComponent : public BAS {
61.1556 public:
61.1557 - typedef _Base Base;
61.1558 + typedef BAS Base;
61.1559
61.1560 - typedef typename _Base::Node Node;
61.1561 - typedef typename _Base::Arc Arc;
61.1562 + typedef typename Base::Node Node;
61.1563 + typedef typename Base::Arc Arc;
61.1564
61.1565 - /// \brief Adds a new node to the digraph.
61.1566 + /// \brief Add a new node to the digraph.
61.1567 ///
61.1568 - /// Adds a new node to the digraph.
61.1569 - ///
61.1570 + /// This function adds a new node to the digraph.
61.1571 Node addNode() {
61.1572 return INVALID;
61.1573 }
61.1574
61.1575 - /// \brief Adds a new arc connects the given two nodes.
61.1576 + /// \brief Add a new arc connecting the given two nodes.
61.1577 ///
61.1578 - /// Adds a new arc connects the the given two nodes.
61.1579 + /// This function adds a new arc connecting the given two nodes
61.1580 + /// of the digraph.
61.1581 Arc addArc(const Node&, const Node&) {
61.1582 return INVALID;
61.1583 }
61.1584 @@ -1314,33 +1331,32 @@
61.1585 };
61.1586 };
61.1587
61.1588 - /// \brief An empty extendable base undirected graph class.
61.1589 + /// \brief Skeleton class for extendable undirected graphs.
61.1590 ///
61.1591 - /// This class provides beside the core undirected graph features
61.1592 - /// core undircted graph extend interface for the graph structure.
61.1593 - /// The main difference between the base and this interface is
61.1594 - /// that the graph alterations should handled already on this
61.1595 - /// level.
61.1596 - template <typename _Base = BaseGraphComponent>
61.1597 - class ExtendableGraphComponent : public _Base {
61.1598 + /// This class describes the interface of extendable undirected graphs.
61.1599 + /// It extends \ref BaseGraphComponent with functions for adding
61.1600 + /// nodes and edges to the graph.
61.1601 + /// This concept requires \ref AlterableGraphComponent.
61.1602 + template <typename BAS = BaseGraphComponent>
61.1603 + class ExtendableGraphComponent : public BAS {
61.1604 public:
61.1605
61.1606 - typedef _Base Base;
61.1607 - typedef typename _Base::Node Node;
61.1608 - typedef typename _Base::Edge Edge;
61.1609 + typedef BAS Base;
61.1610 + typedef typename Base::Node Node;
61.1611 + typedef typename Base::Edge Edge;
61.1612
61.1613 - /// \brief Adds a new node to the graph.
61.1614 + /// \brief Add a new node to the digraph.
61.1615 ///
61.1616 - /// Adds a new node to the graph.
61.1617 - ///
61.1618 + /// This function adds a new node to the digraph.
61.1619 Node addNode() {
61.1620 return INVALID;
61.1621 }
61.1622
61.1623 - /// \brief Adds a new arc connects the given two nodes.
61.1624 + /// \brief Add a new edge connecting the given two nodes.
61.1625 ///
61.1626 - /// Adds a new arc connects the the given two nodes.
61.1627 - Edge addArc(const Node&, const Node&) {
61.1628 + /// This function adds a new edge connecting the given two nodes
61.1629 + /// of the graph.
61.1630 + Edge addEdge(const Node&, const Node&) {
61.1631 return INVALID;
61.1632 }
61.1633
61.1634 @@ -1359,39 +1375,38 @@
61.1635 };
61.1636 };
61.1637
61.1638 - /// \brief An empty erasable digraph class.
61.1639 + /// \brief Skeleton class for erasable directed graphs.
61.1640 ///
61.1641 - /// This class provides beside the core digraph features core erase
61.1642 - /// functions for the digraph structure. The main difference between
61.1643 - /// the base and this interface is that the digraph alterations
61.1644 - /// should handled already on this level.
61.1645 - template <typename _Base = BaseDigraphComponent>
61.1646 - class ErasableDigraphComponent : public _Base {
61.1647 + /// This class describes the interface of erasable directed graphs.
61.1648 + /// It extends \ref BaseDigraphComponent with functions for removing
61.1649 + /// nodes and arcs from the digraph.
61.1650 + /// This concept requires \ref AlterableDigraphComponent.
61.1651 + template <typename BAS = BaseDigraphComponent>
61.1652 + class ErasableDigraphComponent : public BAS {
61.1653 public:
61.1654
61.1655 - typedef _Base Base;
61.1656 + typedef BAS Base;
61.1657 typedef typename Base::Node Node;
61.1658 typedef typename Base::Arc Arc;
61.1659
61.1660 /// \brief Erase a node from the digraph.
61.1661 ///
61.1662 - /// Erase a node from the digraph. This function should
61.1663 - /// erase all arcs connecting to the node.
61.1664 + /// This function erases the given node from the digraph and all arcs
61.1665 + /// connected to the node.
61.1666 void erase(const Node&) {}
61.1667
61.1668 /// \brief Erase an arc from the digraph.
61.1669 ///
61.1670 - /// Erase an arc from the digraph.
61.1671 - ///
61.1672 + /// This function erases the given arc from the digraph.
61.1673 void erase(const Arc&) {}
61.1674
61.1675 template <typename _Digraph>
61.1676 struct Constraints {
61.1677 void constraints() {
61.1678 checkConcept<Base, _Digraph>();
61.1679 - typename _Digraph::Node node;
61.1680 + const typename _Digraph::Node node(INVALID);
61.1681 digraph.erase(node);
61.1682 - typename _Digraph::Arc arc;
61.1683 + const typename _Digraph::Arc arc(INVALID);
61.1684 digraph.erase(arc);
61.1685 }
61.1686
61.1687 @@ -1399,39 +1414,38 @@
61.1688 };
61.1689 };
61.1690
61.1691 - /// \brief An empty erasable base undirected graph class.
61.1692 + /// \brief Skeleton class for erasable undirected graphs.
61.1693 ///
61.1694 - /// This class provides beside the core undirected graph features
61.1695 - /// core erase functions for the undirceted graph structure. The
61.1696 - /// main difference between the base and this interface is that
61.1697 - /// the graph alterations should handled already on this level.
61.1698 - template <typename _Base = BaseGraphComponent>
61.1699 - class ErasableGraphComponent : public _Base {
61.1700 + /// This class describes the interface of erasable undirected graphs.
61.1701 + /// It extends \ref BaseGraphComponent with functions for removing
61.1702 + /// nodes and edges from the graph.
61.1703 + /// This concept requires \ref AlterableGraphComponent.
61.1704 + template <typename BAS = BaseGraphComponent>
61.1705 + class ErasableGraphComponent : public BAS {
61.1706 public:
61.1707
61.1708 - typedef _Base Base;
61.1709 + typedef BAS Base;
61.1710 typedef typename Base::Node Node;
61.1711 typedef typename Base::Edge Edge;
61.1712
61.1713 /// \brief Erase a node from the graph.
61.1714 ///
61.1715 - /// Erase a node from the graph. This function should erase
61.1716 - /// arcs connecting to the node.
61.1717 + /// This function erases the given node from the graph and all edges
61.1718 + /// connected to the node.
61.1719 void erase(const Node&) {}
61.1720
61.1721 - /// \brief Erase an arc from the graph.
61.1722 + /// \brief Erase an edge from the digraph.
61.1723 ///
61.1724 - /// Erase an arc from the graph.
61.1725 - ///
61.1726 + /// This function erases the given edge from the digraph.
61.1727 void erase(const Edge&) {}
61.1728
61.1729 template <typename _Graph>
61.1730 struct Constraints {
61.1731 void constraints() {
61.1732 checkConcept<Base, _Graph>();
61.1733 - typename _Graph::Node node;
61.1734 + const typename _Graph::Node node(INVALID);
61.1735 graph.erase(node);
61.1736 - typename _Graph::Edge edge;
61.1737 + const typename _Graph::Edge edge(INVALID);
61.1738 graph.erase(edge);
61.1739 }
61.1740
61.1741 @@ -1439,22 +1453,21 @@
61.1742 };
61.1743 };
61.1744
61.1745 - /// \brief An empty clearable base digraph class.
61.1746 + /// \brief Skeleton class for clearable directed graphs.
61.1747 ///
61.1748 - /// This class provides beside the core digraph features core clear
61.1749 - /// functions for the digraph structure. The main difference between
61.1750 - /// the base and this interface is that the digraph alterations
61.1751 - /// should handled already on this level.
61.1752 - template <typename _Base = BaseDigraphComponent>
61.1753 - class ClearableDigraphComponent : public _Base {
61.1754 + /// This class describes the interface of clearable directed graphs.
61.1755 + /// It extends \ref BaseDigraphComponent with a function for clearing
61.1756 + /// the digraph.
61.1757 + /// This concept requires \ref AlterableDigraphComponent.
61.1758 + template <typename BAS = BaseDigraphComponent>
61.1759 + class ClearableDigraphComponent : public BAS {
61.1760 public:
61.1761
61.1762 - typedef _Base Base;
61.1763 + typedef BAS Base;
61.1764
61.1765 /// \brief Erase all nodes and arcs from the digraph.
61.1766 ///
61.1767 - /// Erase all nodes and arcs from the digraph.
61.1768 - ///
61.1769 + /// This function erases all nodes and arcs from the digraph.
61.1770 void clear() {}
61.1771
61.1772 template <typename _Digraph>
61.1773 @@ -1464,29 +1477,35 @@
61.1774 digraph.clear();
61.1775 }
61.1776
61.1777 - _Digraph digraph;
61.1778 + _Digraph& digraph;
61.1779 };
61.1780 };
61.1781
61.1782 - /// \brief An empty clearable base undirected graph class.
61.1783 + /// \brief Skeleton class for clearable undirected graphs.
61.1784 ///
61.1785 - /// This class provides beside the core undirected graph features
61.1786 - /// core clear functions for the undirected graph structure. The
61.1787 - /// main difference between the base and this interface is that
61.1788 - /// the graph alterations should handled already on this level.
61.1789 - template <typename _Base = BaseGraphComponent>
61.1790 - class ClearableGraphComponent : public ClearableDigraphComponent<_Base> {
61.1791 + /// This class describes the interface of clearable undirected graphs.
61.1792 + /// It extends \ref BaseGraphComponent with a function for clearing
61.1793 + /// the graph.
61.1794 + /// This concept requires \ref AlterableGraphComponent.
61.1795 + template <typename BAS = BaseGraphComponent>
61.1796 + class ClearableGraphComponent : public ClearableDigraphComponent<BAS> {
61.1797 public:
61.1798
61.1799 - typedef _Base Base;
61.1800 + typedef BAS Base;
61.1801 +
61.1802 + /// \brief Erase all nodes and edges from the graph.
61.1803 + ///
61.1804 + /// This function erases all nodes and edges from the graph.
61.1805 + void clear() {}
61.1806
61.1807 template <typename _Graph>
61.1808 struct Constraints {
61.1809 void constraints() {
61.1810 - checkConcept<ClearableGraphComponent<Base>, _Graph>();
61.1811 + checkConcept<Base, _Graph>();
61.1812 + graph.clear();
61.1813 }
61.1814
61.1815 - _Graph graph;
61.1816 + _Graph& graph;
61.1817 };
61.1818 };
61.1819
62.1 --- a/lemon/concepts/heap.h Mon Jan 12 23:11:39 2009 +0100
62.2 +++ b/lemon/concepts/heap.h Thu Nov 05 15:48:01 2009 +0100
62.3 @@ -16,14 +16,15 @@
62.4 *
62.5 */
62.6
62.7 +#ifndef LEMON_CONCEPTS_HEAP_H
62.8 +#define LEMON_CONCEPTS_HEAP_H
62.9 +
62.10 ///\ingroup concept
62.11 ///\file
62.12 ///\brief The concept of heaps.
62.13
62.14 -#ifndef LEMON_CONCEPT_HEAP_H
62.15 -#define LEMON_CONCEPT_HEAP_H
62.16 -
62.17 #include <lemon/core.h>
62.18 +#include <lemon/concept_check.h>
62.19
62.20 namespace lemon {
62.21
62.22 @@ -34,123 +35,160 @@
62.23
62.24 /// \brief The heap concept.
62.25 ///
62.26 - /// Concept class describing the main interface of heaps.
62.27 - template <typename Priority, typename ItemIntMap>
62.28 + /// This concept class describes the main interface of heaps.
62.29 + /// The various \ref heaps "heap structures" are efficient
62.30 + /// implementations of the abstract data type \e priority \e queue.
62.31 + /// They store items with specified values called \e priorities
62.32 + /// in such a way that finding and removing the item with minimum
62.33 + /// priority are efficient. The basic operations are adding and
62.34 + /// erasing items, changing the priority of an item, etc.
62.35 + ///
62.36 + /// Heaps are crucial in several algorithms, such as Dijkstra and Prim.
62.37 + /// Any class that conforms to this concept can be used easily in such
62.38 + /// algorithms.
62.39 + ///
62.40 + /// \tparam PR Type of the priorities of the items.
62.41 + /// \tparam IM A read-writable item map with \c int values, used
62.42 + /// internally to handle the cross references.
62.43 + /// \tparam CMP A functor class for comparing the priorities.
62.44 + /// The default is \c std::less<PR>.
62.45 +#ifdef DOXYGEN
62.46 + template <typename PR, typename IM, typename CMP>
62.47 +#else
62.48 + template <typename PR, typename IM, typename CMP = std::less<PR> >
62.49 +#endif
62.50 class Heap {
62.51 public:
62.52
62.53 + /// Type of the item-int map.
62.54 + typedef IM ItemIntMap;
62.55 + /// Type of the priorities.
62.56 + typedef PR Prio;
62.57 /// Type of the items stored in the heap.
62.58 typedef typename ItemIntMap::Key Item;
62.59
62.60 - /// Type of the priorities.
62.61 - typedef Priority Prio;
62.62 -
62.63 /// \brief Type to represent the states of the items.
62.64 ///
62.65 /// Each item has a state associated to it. It can be "in heap",
62.66 - /// "pre heap" or "post heap". The later two are indifferent
62.67 - /// from the point of view of the heap, but may be useful for
62.68 - /// the user.
62.69 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
62.70 + /// heap's point of view, but may be useful to the user.
62.71 ///
62.72 - /// The \c ItemIntMap must be initialized in such a way, that it
62.73 - /// assigns \c PRE_HEAP (<tt>-1</tt>) to every item.
62.74 + /// The item-int map must be initialized in such way that it assigns
62.75 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
62.76 enum State {
62.77 - IN_HEAP = 0,
62.78 - PRE_HEAP = -1,
62.79 - POST_HEAP = -2
62.80 + IN_HEAP = 0, ///< = 0. The "in heap" state constant.
62.81 + PRE_HEAP = -1, ///< = -1. The "pre-heap" state constant.
62.82 + POST_HEAP = -2 ///< = -2. The "post-heap" state constant.
62.83 };
62.84
62.85 - /// \brief The constructor.
62.86 + /// \brief Constructor.
62.87 ///
62.88 - /// The constructor.
62.89 + /// Constructor.
62.90 /// \param map A map that assigns \c int values to keys of type
62.91 /// \c Item. It is used internally by the heap implementations to
62.92 /// handle the cross references. The assigned value must be
62.93 - /// \c PRE_HEAP (<tt>-1</tt>) for every item.
62.94 + /// \c PRE_HEAP (<tt>-1</tt>) for each item.
62.95 explicit Heap(ItemIntMap &map) {}
62.96
62.97 + /// \brief Constructor.
62.98 + ///
62.99 + /// Constructor.
62.100 + /// \param map A map that assigns \c int values to keys of type
62.101 + /// \c Item. It is used internally by the heap implementations to
62.102 + /// handle the cross references. The assigned value must be
62.103 + /// \c PRE_HEAP (<tt>-1</tt>) for each item.
62.104 + /// \param comp The function object used for comparing the priorities.
62.105 + explicit Heap(ItemIntMap &map, const CMP &comp) {}
62.106 +
62.107 /// \brief The number of items stored in the heap.
62.108 ///
62.109 - /// Returns the number of items stored in the heap.
62.110 + /// This function returns the number of items stored in the heap.
62.111 int size() const { return 0; }
62.112
62.113 - /// \brief Checks if the heap is empty.
62.114 + /// \brief Check if the heap is empty.
62.115 ///
62.116 - /// Returns \c true if the heap is empty.
62.117 + /// This function returns \c true if the heap is empty.
62.118 bool empty() const { return false; }
62.119
62.120 - /// \brief Makes the heap empty.
62.121 + /// \brief Make the heap empty.
62.122 ///
62.123 - /// Makes the heap empty.
62.124 - void clear();
62.125 + /// This functon makes the heap empty.
62.126 + /// It does not change the cross reference map. If you want to reuse
62.127 + /// a heap that is not surely empty, you should first clear it and
62.128 + /// then you should set the cross reference map to \c PRE_HEAP
62.129 + /// for each item.
62.130 + void clear() {}
62.131
62.132 - /// \brief Inserts an item into the heap with the given priority.
62.133 + /// \brief Insert an item into the heap with the given priority.
62.134 ///
62.135 - /// Inserts the given item into the heap with the given priority.
62.136 + /// This function inserts the given item into the heap with the
62.137 + /// given priority.
62.138 /// \param i The item to insert.
62.139 /// \param p The priority of the item.
62.140 + /// \pre \e i must not be stored in the heap.
62.141 void push(const Item &i, const Prio &p) {}
62.142
62.143 - /// \brief Returns the item having minimum priority.
62.144 + /// \brief Return the item having minimum priority.
62.145 ///
62.146 - /// Returns the item having minimum priority.
62.147 + /// This function returns the item having minimum priority.
62.148 /// \pre The heap must be non-empty.
62.149 Item top() const {}
62.150
62.151 /// \brief The minimum priority.
62.152 ///
62.153 - /// Returns the minimum priority.
62.154 + /// This function returns the minimum priority.
62.155 /// \pre The heap must be non-empty.
62.156 Prio prio() const {}
62.157
62.158 - /// \brief Removes the item having minimum priority.
62.159 + /// \brief Remove the item having minimum priority.
62.160 ///
62.161 - /// Removes the item having minimum priority.
62.162 + /// This function removes the item having minimum priority.
62.163 /// \pre The heap must be non-empty.
62.164 void pop() {}
62.165
62.166 - /// \brief Removes an item from the heap.
62.167 + /// \brief Remove the given item from the heap.
62.168 ///
62.169 - /// Removes the given item from the heap if it is already stored.
62.170 + /// This function removes the given item from the heap if it is
62.171 + /// already stored.
62.172 /// \param i The item to delete.
62.173 + /// \pre \e i must be in the heap.
62.174 void erase(const Item &i) {}
62.175
62.176 - /// \brief The priority of an item.
62.177 + /// \brief The priority of the given item.
62.178 ///
62.179 - /// Returns the priority of the given item.
62.180 - /// \pre \c i must be in the heap.
62.181 + /// This function returns the priority of the given item.
62.182 /// \param i The item.
62.183 + /// \pre \e i must be in the heap.
62.184 Prio operator[](const Item &i) const {}
62.185
62.186 - /// \brief Sets the priority of an item or inserts it, if it is
62.187 + /// \brief Set the priority of an item or insert it, if it is
62.188 /// not stored in the heap.
62.189 ///
62.190 /// This method sets the priority of the given item if it is
62.191 - /// already stored in the heap.
62.192 - /// Otherwise it inserts the given item with the given priority.
62.193 + /// already stored in the heap. Otherwise it inserts the given
62.194 + /// item into the heap with the given priority.
62.195 ///
62.196 /// \param i The item.
62.197 /// \param p The priority.
62.198 void set(const Item &i, const Prio &p) {}
62.199
62.200 - /// \brief Decreases the priority of an item to the given value.
62.201 + /// \brief Decrease the priority of an item to the given value.
62.202 ///
62.203 - /// Decreases the priority of an item to the given value.
62.204 - /// \pre \c i must be stored in the heap with priority at least \c p.
62.205 + /// This function decreases the priority of an item to the given value.
62.206 /// \param i The item.
62.207 /// \param p The priority.
62.208 + /// \pre \e i must be stored in the heap with priority at least \e p.
62.209 void decrease(const Item &i, const Prio &p) {}
62.210
62.211 - /// \brief Increases the priority of an item to the given value.
62.212 + /// \brief Increase the priority of an item to the given value.
62.213 ///
62.214 - /// Increases the priority of an item to the given value.
62.215 - /// \pre \c i must be stored in the heap with priority at most \c p.
62.216 + /// This function increases the priority of an item to the given value.
62.217 /// \param i The item.
62.218 /// \param p The priority.
62.219 + /// \pre \e i must be stored in the heap with priority at most \e p.
62.220 void increase(const Item &i, const Prio &p) {}
62.221
62.222 - /// \brief Returns if an item is in, has already been in, or has
62.223 - /// never been in the heap.
62.224 + /// \brief Return the state of an item.
62.225 ///
62.226 /// This method returns \c PRE_HEAP if the given item has never
62.227 /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
62.228 @@ -160,11 +198,11 @@
62.229 /// \param i The item.
62.230 State state(const Item &i) const {}
62.231
62.232 - /// \brief Sets the state of an item in the heap.
62.233 + /// \brief Set the state of an item in the heap.
62.234 ///
62.235 - /// Sets the state of the given item in the heap. It can be used
62.236 - /// to manually clear the heap when it is important to achive the
62.237 - /// better time complexity.
62.238 + /// This function sets the state of the given item in the heap.
62.239 + /// It can be used to manually clear the heap when it is important
62.240 + /// to achive better time complexity.
62.241 /// \param i The item.
62.242 /// \param st The state. It should not be \c IN_HEAP.
62.243 void state(const Item& i, State st) {}
62.244 @@ -242,4 +280,4 @@
62.245 /// @}
62.246 } // namespace lemon
62.247 }
62.248 -#endif // LEMON_CONCEPT_PATH_H
62.249 +#endif
63.1 --- a/lemon/concepts/maps.h Mon Jan 12 23:11:39 2009 +0100
63.2 +++ b/lemon/concepts/maps.h Thu Nov 05 15:48:01 2009 +0100
63.3 @@ -16,8 +16,8 @@
63.4 *
63.5 */
63.6
63.7 -#ifndef LEMON_CONCEPT_MAPS_H
63.8 -#define LEMON_CONCEPT_MAPS_H
63.9 +#ifndef LEMON_CONCEPTS_MAPS_H
63.10 +#define LEMON_CONCEPTS_MAPS_H
63.11
63.12 #include <lemon/core.h>
63.13 #include <lemon/concept_check.h>
63.14 @@ -182,7 +182,8 @@
63.15
63.16 template<typename _ReferenceMap>
63.17 struct Constraints {
63.18 - void constraints() {
63.19 + typename enable_if<typename _ReferenceMap::ReferenceMapTag, void>::type
63.20 + constraints() {
63.21 checkConcept<ReadWriteMap<K, T>, _ReferenceMap >();
63.22 ref = m[key];
63.23 m[key] = val;
63.24 @@ -213,4 +214,4 @@
63.25
63.26 } //namespace lemon
63.27
63.28 -#endif // LEMON_CONCEPT_MAPS_H
63.29 +#endif
64.1 --- a/lemon/concepts/path.h Mon Jan 12 23:11:39 2009 +0100
64.2 +++ b/lemon/concepts/path.h Thu Nov 05 15:48:01 2009 +0100
64.3 @@ -21,8 +21,8 @@
64.4 ///\brief Classes for representing paths in digraphs.
64.5 ///
64.6
64.7 -#ifndef LEMON_CONCEPT_PATH_H
64.8 -#define LEMON_CONCEPT_PATH_H
64.9 +#ifndef LEMON_CONCEPTS_PATH_H
64.10 +#define LEMON_CONCEPTS_PATH_H
64.11
64.12 #include <lemon/core.h>
64.13 #include <lemon/concept_check.h>
64.14 @@ -38,19 +38,19 @@
64.15 ///
64.16 /// A skeleton structure for representing directed paths in a
64.17 /// digraph.
64.18 - /// \tparam _Digraph The digraph type in which the path is.
64.19 + /// \tparam GR The digraph type in which the path is.
64.20 ///
64.21 /// In a sense, the path can be treated as a list of arcs. The
64.22 /// lemon path type stores just this list. As a consequence it
64.23 /// cannot enumerate the nodes in the path and the zero length
64.24 /// paths cannot store the source.
64.25 ///
64.26 - template <typename _Digraph>
64.27 + template <typename GR>
64.28 class Path {
64.29 public:
64.30
64.31 /// Type of the underlying digraph.
64.32 - typedef _Digraph Digraph;
64.33 + typedef GR Digraph;
64.34 /// Arc type of the underlying digraph.
64.35 typedef typename Digraph::Arc Arc;
64.36
64.37 @@ -205,18 +205,17 @@
64.38 /// LEMON such algorithms gives back a path dumper what can
64.39 /// assigned to a real path and the dumpers can be implemented as
64.40 /// an adaptor class to the predecessor map.
64.41 -
64.42 - /// \tparam _Digraph The digraph type in which the path is.
64.43 + ///
64.44 + /// \tparam GR The digraph type in which the path is.
64.45 ///
64.46 /// The paths can be constructed from any path type by a
64.47 /// template constructor or a template assignment operator.
64.48 - ///
64.49 - template <typename _Digraph>
64.50 + template <typename GR>
64.51 class PathDumper {
64.52 public:
64.53
64.54 /// Type of the underlying digraph.
64.55 - typedef _Digraph Digraph;
64.56 + typedef GR Digraph;
64.57 /// Arc type of the underlying digraph.
64.58 typedef typename Digraph::Arc Arc;
64.59
64.60 @@ -305,4 +304,4 @@
64.61
64.62 } // namespace lemon
64.63
64.64 -#endif // LEMON_CONCEPT_PATH_H
64.65 +#endif
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
65.2 +++ b/lemon/config.h.cmake Thu Nov 05 15:48:01 2009 +0100
65.3 @@ -0,0 +1,8 @@
65.4 +#define LEMON_VERSION "@PROJECT_VERSION@"
65.5 +#cmakedefine LEMON_HAVE_LONG_LONG 1
65.6 +#cmakedefine LEMON_HAVE_LP 1
65.7 +#cmakedefine LEMON_HAVE_MIP 1
65.8 +#cmakedefine LEMON_HAVE_GLPK 1
65.9 +#cmakedefine LEMON_HAVE_CPLEX 1
65.10 +#cmakedefine LEMON_HAVE_CLP 1
65.11 +#cmakedefine LEMON_HAVE_CBC 1
66.1 --- a/lemon/config.h.in Mon Jan 12 23:11:39 2009 +0100
66.2 +++ b/lemon/config.h.in Thu Nov 05 15:48:01 2009 +0100
66.3 @@ -1,17 +1,26 @@
66.4 +/* The version string */
66.5 +#undef LEMON_VERSION
66.6 +
66.7 +/* Define to 1 if you have long long */
66.8 +#undef LEMON_HAVE_LONG_LONG
66.9 +
66.10 /* Define to 1 if you have any LP solver. */
66.11 -#undef HAVE_LP
66.12 +#undef LEMON_HAVE_LP
66.13
66.14 /* Define to 1 if you have any MIP solver. */
66.15 -#undef HAVE_MIP
66.16 +#undef LEMON_HAVE_MIP
66.17
66.18 /* Define to 1 if you have CPLEX. */
66.19 -#undef HAVE_CPLEX
66.20 +#undef LEMON_HAVE_CPLEX
66.21
66.22 /* Define to 1 if you have GLPK. */
66.23 -#undef HAVE_GLPK
66.24 +#undef LEMON_HAVE_GLPK
66.25
66.26 /* Define to 1 if you have SOPLEX */
66.27 -#undef HAVE_SOPLEX
66.28 +#undef LEMON_HAVE_SOPLEX
66.29
66.30 /* Define to 1 if you have CLP */
66.31 -#undef HAVE_CLP
66.32 +#undef LEMON_HAVE_CLP
66.33 +
66.34 +/* Define to 1 if you have CBC */
66.35 +#undef LEMON_HAVE_CBC
67.1 --- a/lemon/connectivity.h Mon Jan 12 23:11:39 2009 +0100
67.2 +++ b/lemon/connectivity.h Thu Nov 05 15:48:01 2009 +0100
67.3 @@ -32,7 +32,7 @@
67.4 #include <stack>
67.5 #include <functional>
67.6
67.7 -/// \ingroup connectivity
67.8 +/// \ingroup graph_properties
67.9 /// \file
67.10 /// \brief Connectivity algorithms
67.11 ///
67.12 @@ -40,14 +40,18 @@
67.13
67.14 namespace lemon {
67.15
67.16 - /// \ingroup connectivity
67.17 + /// \ingroup graph_properties
67.18 ///
67.19 - /// \brief Check whether the given undirected graph is connected.
67.20 + /// \brief Check whether an undirected graph is connected.
67.21 ///
67.22 - /// Check whether the given undirected graph is connected.
67.23 - /// \param graph The undirected graph.
67.24 - /// \return %True when there is path between any two nodes in the graph.
67.25 + /// This function checks whether the given undirected graph is connected,
67.26 + /// i.e. there is a path between any two nodes in the graph.
67.27 + ///
67.28 + /// \return \c true if the graph is connected.
67.29 /// \note By definition, the empty graph is connected.
67.30 + ///
67.31 + /// \see countConnectedComponents(), connectedComponents()
67.32 + /// \see stronglyConnected()
67.33 template <typename Graph>
67.34 bool connected(const Graph& graph) {
67.35 checkConcept<concepts::Graph, Graph>();
67.36 @@ -63,16 +67,22 @@
67.37 return true;
67.38 }
67.39
67.40 - /// \ingroup connectivity
67.41 + /// \ingroup graph_properties
67.42 ///
67.43 /// \brief Count the number of connected components of an undirected graph
67.44 ///
67.45 - /// Count the number of connected components of an undirected graph
67.46 + /// This function counts the number of connected components of the given
67.47 + /// undirected graph.
67.48 ///
67.49 - /// \param graph The graph. It must be undirected.
67.50 - /// \return The number of components
67.51 + /// The connected components are the classes of an equivalence relation
67.52 + /// on the nodes of an undirected graph. Two nodes are in the same class
67.53 + /// if they are connected with a path.
67.54 + ///
67.55 + /// \return The number of connected components.
67.56 /// \note By definition, the empty graph consists
67.57 /// of zero connected components.
67.58 + ///
67.59 + /// \see connected(), connectedComponents()
67.60 template <typename Graph>
67.61 int countConnectedComponents(const Graph &graph) {
67.62 checkConcept<concepts::Graph, Graph>();
67.63 @@ -105,19 +115,30 @@
67.64 return compNum;
67.65 }
67.66
67.67 - /// \ingroup connectivity
67.68 + /// \ingroup graph_properties
67.69 ///
67.70 /// \brief Find the connected components of an undirected graph
67.71 ///
67.72 - /// Find the connected components of an undirected graph.
67.73 + /// This function finds the connected components of the given undirected
67.74 + /// graph.
67.75 ///
67.76 - /// \param graph The graph. It must be undirected.
67.77 + /// The connected components are the classes of an equivalence relation
67.78 + /// on the nodes of an undirected graph. Two nodes are in the same class
67.79 + /// if they are connected with a path.
67.80 + ///
67.81 + /// \image html connected_components.png
67.82 + /// \image latex connected_components.eps "Connected components" width=\textwidth
67.83 + ///
67.84 + /// \param graph The undirected graph.
67.85 /// \retval compMap A writable node map. The values will be set from 0 to
67.86 - /// the number of the connected components minus one. Each values of the map
67.87 - /// will be set exactly once, the values of a certain component will be
67.88 + /// the number of the connected components minus one. Each value of the map
67.89 + /// will be set exactly once, and the values of a certain component will be
67.90 /// set continuously.
67.91 - /// \return The number of components
67.92 + /// \return The number of connected components.
67.93 + /// \note By definition, the empty graph consists
67.94 + /// of zero connected components.
67.95 ///
67.96 + /// \see connected(), countConnectedComponents()
67.97 template <class Graph, class NodeMap>
67.98 int connectedComponents(const Graph &graph, NodeMap &compMap) {
67.99 checkConcept<concepts::Graph, Graph>();
67.100 @@ -227,17 +248,19 @@
67.101 }
67.102
67.103
67.104 - /// \ingroup connectivity
67.105 + /// \ingroup graph_properties
67.106 ///
67.107 - /// \brief Check whether the given directed graph is strongly connected.
67.108 + /// \brief Check whether a directed graph is strongly connected.
67.109 ///
67.110 - /// Check whether the given directed graph is strongly connected. The
67.111 - /// graph is strongly connected when any two nodes of the graph are
67.112 + /// This function checks whether the given directed graph is strongly
67.113 + /// connected, i.e. any two nodes of the digraph are
67.114 /// connected with directed paths in both direction.
67.115 - /// \return %False when the graph is not strongly connected.
67.116 - /// \see connected
67.117 ///
67.118 - /// \note By definition, the empty graph is strongly connected.
67.119 + /// \return \c true if the digraph is strongly connected.
67.120 + /// \note By definition, the empty digraph is strongly connected.
67.121 + ///
67.122 + /// \see countStronglyConnectedComponents(), stronglyConnectedComponents()
67.123 + /// \see connected()
67.124 template <typename Digraph>
67.125 bool stronglyConnected(const Digraph& digraph) {
67.126 checkConcept<concepts::Digraph, Digraph>();
67.127 @@ -268,7 +291,7 @@
67.128 typedef typename RDigraph::NodeIt RNodeIt;
67.129 RDigraph rdigraph(digraph);
67.130
67.131 - typedef DfsVisitor<Digraph> RVisitor;
67.132 + typedef DfsVisitor<RDigraph> RVisitor;
67.133 RVisitor rvisitor;
67.134
67.135 DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
67.136 @@ -285,20 +308,24 @@
67.137 return true;
67.138 }
67.139
67.140 - /// \ingroup connectivity
67.141 + /// \ingroup graph_properties
67.142 ///
67.143 - /// \brief Count the strongly connected components of a directed graph
67.144 + /// \brief Count the number of strongly connected components of a
67.145 + /// directed graph
67.146 ///
67.147 - /// Count the strongly connected components of a directed graph.
67.148 + /// This function counts the number of strongly connected components of
67.149 + /// the given directed graph.
67.150 + ///
67.151 /// The strongly connected components are the classes of an
67.152 - /// equivalence relation on the nodes of the graph. Two nodes are in
67.153 + /// equivalence relation on the nodes of a digraph. Two nodes are in
67.154 /// the same class if they are connected with directed paths in both
67.155 /// direction.
67.156 ///
67.157 - /// \param digraph The graph.
67.158 - /// \return The number of components
67.159 - /// \note By definition, the empty graph has zero
67.160 + /// \return The number of strongly connected components.
67.161 + /// \note By definition, the empty digraph has zero
67.162 /// strongly connected components.
67.163 + ///
67.164 + /// \see stronglyConnected(), stronglyConnectedComponents()
67.165 template <typename Digraph>
67.166 int countStronglyConnectedComponents(const Digraph& digraph) {
67.167 checkConcept<concepts::Digraph, Digraph>();
67.168 @@ -349,25 +376,33 @@
67.169 return compNum;
67.170 }
67.171
67.172 - /// \ingroup connectivity
67.173 + /// \ingroup graph_properties
67.174 ///
67.175 /// \brief Find the strongly connected components of a directed graph
67.176 ///
67.177 - /// Find the strongly connected components of a directed graph. The
67.178 - /// strongly connected components are the classes of an equivalence
67.179 - /// relation on the nodes of the graph. Two nodes are in
67.180 - /// relationship when there are directed paths between them in both
67.181 - /// direction. In addition, the numbering of components will satisfy
67.182 - /// that there is no arc going from a higher numbered component to
67.183 - /// a lower.
67.184 + /// This function finds the strongly connected components of the given
67.185 + /// directed graph. In addition, the numbering of the components will
67.186 + /// satisfy that there is no arc going from a higher numbered component
67.187 + /// to a lower one (i.e. it provides a topological order of the components).
67.188 + ///
67.189 + /// The strongly connected components are the classes of an
67.190 + /// equivalence relation on the nodes of a digraph. Two nodes are in
67.191 + /// the same class if they are connected with directed paths in both
67.192 + /// direction.
67.193 + ///
67.194 + /// \image html strongly_connected_components.png
67.195 + /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
67.196 ///
67.197 /// \param digraph The digraph.
67.198 /// \retval compMap A writable node map. The values will be set from 0 to
67.199 /// the number of the strongly connected components minus one. Each value
67.200 - /// of the map will be set exactly once, the values of a certain component
67.201 - /// will be set continuously.
67.202 - /// \return The number of components
67.203 + /// of the map will be set exactly once, and the values of a certain
67.204 + /// component will be set continuously.
67.205 + /// \return The number of strongly connected components.
67.206 + /// \note By definition, the empty digraph has zero
67.207 + /// strongly connected components.
67.208 ///
67.209 + /// \see stronglyConnected(), countStronglyConnectedComponents()
67.210 template <typename Digraph, typename NodeMap>
67.211 int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
67.212 checkConcept<concepts::Digraph, Digraph>();
67.213 @@ -416,23 +451,28 @@
67.214 return compNum;
67.215 }
67.216
67.217 - /// \ingroup connectivity
67.218 + /// \ingroup graph_properties
67.219 ///
67.220 /// \brief Find the cut arcs of the strongly connected components.
67.221 ///
67.222 - /// Find the cut arcs of the strongly connected components.
67.223 - /// The strongly connected components are the classes of an equivalence
67.224 - /// relation on the nodes of the graph. Two nodes are in relationship
67.225 - /// when there are directed paths between them in both direction.
67.226 + /// This function finds the cut arcs of the strongly connected components
67.227 + /// of the given digraph.
67.228 + ///
67.229 + /// The strongly connected components are the classes of an
67.230 + /// equivalence relation on the nodes of a digraph. Two nodes are in
67.231 + /// the same class if they are connected with directed paths in both
67.232 + /// direction.
67.233 /// The strongly connected components are separated by the cut arcs.
67.234 ///
67.235 - /// \param graph The graph.
67.236 - /// \retval cutMap A writable node map. The values will be set true when the
67.237 - /// arc is a cut arc.
67.238 + /// \param digraph The digraph.
67.239 + /// \retval cutMap A writable arc map. The values will be set to \c true
67.240 + /// for the cut arcs (exactly once for each cut arc), and will not be
67.241 + /// changed for other arcs.
67.242 + /// \return The number of cut arcs.
67.243 ///
67.244 - /// \return The number of cut arcs
67.245 + /// \see stronglyConnected(), stronglyConnectedComponents()
67.246 template <typename Digraph, typename ArcMap>
67.247 - int stronglyConnectedCutArcs(const Digraph& graph, ArcMap& cutMap) {
67.248 + int stronglyConnectedCutArcs(const Digraph& digraph, ArcMap& cutMap) {
67.249 checkConcept<concepts::Digraph, Digraph>();
67.250 typedef typename Digraph::Node Node;
67.251 typedef typename Digraph::Arc Arc;
67.252 @@ -444,13 +484,13 @@
67.253 typedef std::vector<Node> Container;
67.254 typedef typename Container::iterator Iterator;
67.255
67.256 - Container nodes(countNodes(graph));
67.257 + Container nodes(countNodes(digraph));
67.258 typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
67.259 Visitor visitor(nodes.begin());
67.260
67.261 - DfsVisit<Digraph, Visitor> dfs(graph, visitor);
67.262 + DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
67.263 dfs.init();
67.264 - for (NodeIt it(graph); it != INVALID; ++it) {
67.265 + for (NodeIt it(digraph); it != INVALID; ++it) {
67.266 if (!dfs.reached(it)) {
67.267 dfs.addSource(it);
67.268 dfs.start();
67.269 @@ -460,14 +500,14 @@
67.270 typedef typename Container::reverse_iterator RIterator;
67.271 typedef ReverseDigraph<const Digraph> RDigraph;
67.272
67.273 - RDigraph rgraph(graph);
67.274 + RDigraph rdigraph(digraph);
67.275
67.276 int cutNum = 0;
67.277
67.278 typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
67.279 - RVisitor rvisitor(rgraph, cutMap, cutNum);
67.280 + RVisitor rvisitor(rdigraph, cutMap, cutNum);
67.281
67.282 - DfsVisit<RDigraph, RVisitor> rdfs(rgraph, rvisitor);
67.283 + DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
67.284
67.285 rdfs.init();
67.286 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
67.287 @@ -700,32 +740,37 @@
67.288 template <typename Graph>
67.289 int countBiNodeConnectedComponents(const Graph& graph);
67.290
67.291 - /// \ingroup connectivity
67.292 + /// \ingroup graph_properties
67.293 ///
67.294 - /// \brief Checks the graph is bi-node-connected.
67.295 + /// \brief Check whether an undirected graph is bi-node-connected.
67.296 ///
67.297 - /// This function checks that the undirected graph is bi-node-connected
67.298 - /// graph. The graph is bi-node-connected if any two undirected edge is
67.299 - /// on same circle.
67.300 + /// This function checks whether the given undirected graph is
67.301 + /// bi-node-connected, i.e. any two edges are on same circle.
67.302 ///
67.303 - /// \param graph The graph.
67.304 - /// \return %True when the graph bi-node-connected.
67.305 + /// \return \c true if the graph bi-node-connected.
67.306 + /// \note By definition, the empty graph is bi-node-connected.
67.307 + ///
67.308 + /// \see countBiNodeConnectedComponents(), biNodeConnectedComponents()
67.309 template <typename Graph>
67.310 bool biNodeConnected(const Graph& graph) {
67.311 return countBiNodeConnectedComponents(graph) <= 1;
67.312 }
67.313
67.314 - /// \ingroup connectivity
67.315 + /// \ingroup graph_properties
67.316 ///
67.317 - /// \brief Count the biconnected components.
67.318 + /// \brief Count the number of bi-node-connected components of an
67.319 + /// undirected graph.
67.320 ///
67.321 - /// This function finds the bi-node-connected components in an undirected
67.322 - /// graph. The biconnected components are the classes of an equivalence
67.323 - /// relation on the undirected edges. Two undirected edge is in relationship
67.324 - /// when they are on same circle.
67.325 + /// This function counts the number of bi-node-connected components of
67.326 + /// the given undirected graph.
67.327 ///
67.328 - /// \param graph The graph.
67.329 - /// \return The number of components.
67.330 + /// The bi-node-connected components are the classes of an equivalence
67.331 + /// relation on the edges of a undirected graph. Two edges are in the
67.332 + /// same class if they are on same circle.
67.333 + ///
67.334 + /// \return The number of bi-node-connected components.
67.335 + ///
67.336 + /// \see biNodeConnected(), biNodeConnectedComponents()
67.337 template <typename Graph>
67.338 int countBiNodeConnectedComponents(const Graph& graph) {
67.339 checkConcept<concepts::Graph, Graph>();
67.340 @@ -750,22 +795,28 @@
67.341 return compNum;
67.342 }
67.343
67.344 - /// \ingroup connectivity
67.345 + /// \ingroup graph_properties
67.346 ///
67.347 - /// \brief Find the bi-node-connected components.
67.348 + /// \brief Find the bi-node-connected components of an undirected graph.
67.349 ///
67.350 - /// This function finds the bi-node-connected components in an undirected
67.351 - /// graph. The bi-node-connected components are the classes of an equivalence
67.352 - /// relation on the undirected edges. Two undirected edge are in relationship
67.353 - /// when they are on same circle.
67.354 + /// This function finds the bi-node-connected components of the given
67.355 + /// undirected graph.
67.356 ///
67.357 - /// \param graph The graph.
67.358 - /// \retval compMap A writable uedge map. The values will be set from 0
67.359 - /// to the number of the biconnected components minus one. Each values
67.360 - /// of the map will be set exactly once, the values of a certain component
67.361 - /// will be set continuously.
67.362 - /// \return The number of components.
67.363 + /// The bi-node-connected components are the classes of an equivalence
67.364 + /// relation on the edges of a undirected graph. Two edges are in the
67.365 + /// same class if they are on same circle.
67.366 ///
67.367 + /// \image html node_biconnected_components.png
67.368 + /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
67.369 + ///
67.370 + /// \param graph The undirected graph.
67.371 + /// \retval compMap A writable edge map. The values will be set from 0
67.372 + /// to the number of the bi-node-connected components minus one. Each
67.373 + /// value of the map will be set exactly once, and the values of a
67.374 + /// certain component will be set continuously.
67.375 + /// \return The number of bi-node-connected components.
67.376 + ///
67.377 + /// \see biNodeConnected(), countBiNodeConnectedComponents()
67.378 template <typename Graph, typename EdgeMap>
67.379 int biNodeConnectedComponents(const Graph& graph,
67.380 EdgeMap& compMap) {
67.381 @@ -793,20 +844,27 @@
67.382 return compNum;
67.383 }
67.384
67.385 - /// \ingroup connectivity
67.386 + /// \ingroup graph_properties
67.387 ///
67.388 - /// \brief Find the bi-node-connected cut nodes.
67.389 + /// \brief Find the bi-node-connected cut nodes in an undirected graph.
67.390 ///
67.391 - /// This function finds the bi-node-connected cut nodes in an undirected
67.392 - /// graph. The bi-node-connected components are the classes of an equivalence
67.393 - /// relation on the undirected edges. Two undirected edges are in
67.394 - /// relationship when they are on same circle. The biconnected components
67.395 - /// are separted by nodes which are the cut nodes of the components.
67.396 + /// This function finds the bi-node-connected cut nodes in the given
67.397 + /// undirected graph.
67.398 ///
67.399 - /// \param graph The graph.
67.400 - /// \retval cutMap A writable edge map. The values will be set true when
67.401 - /// the node separate two or more components.
67.402 + /// The bi-node-connected components are the classes of an equivalence
67.403 + /// relation on the edges of a undirected graph. Two edges are in the
67.404 + /// same class if they are on same circle.
67.405 + /// The bi-node-connected components are separted by the cut nodes of
67.406 + /// the components.
67.407 + ///
67.408 + /// \param graph The undirected graph.
67.409 + /// \retval cutMap A writable node map. The values will be set to
67.410 + /// \c true for the nodes that separate two or more components
67.411 + /// (exactly once for each cut node), and will not be changed for
67.412 + /// other nodes.
67.413 /// \return The number of the cut nodes.
67.414 + ///
67.415 + /// \see biNodeConnected(), biNodeConnectedComponents()
67.416 template <typename Graph, typename NodeMap>
67.417 int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
67.418 checkConcept<concepts::Graph, Graph>();
67.419 @@ -1023,32 +1081,39 @@
67.420 template <typename Graph>
67.421 int countBiEdgeConnectedComponents(const Graph& graph);
67.422
67.423 - /// \ingroup connectivity
67.424 + /// \ingroup graph_properties
67.425 ///
67.426 - /// \brief Checks that the graph is bi-edge-connected.
67.427 + /// \brief Check whether an undirected graph is bi-edge-connected.
67.428 ///
67.429 - /// This function checks that the graph is bi-edge-connected. The undirected
67.430 - /// graph is bi-edge-connected when any two nodes are connected with two
67.431 - /// edge-disjoint paths.
67.432 + /// This function checks whether the given undirected graph is
67.433 + /// bi-edge-connected, i.e. any two nodes are connected with at least
67.434 + /// two edge-disjoint paths.
67.435 ///
67.436 - /// \param graph The undirected graph.
67.437 - /// \return The number of components.
67.438 + /// \return \c true if the graph is bi-edge-connected.
67.439 + /// \note By definition, the empty graph is bi-edge-connected.
67.440 + ///
67.441 + /// \see countBiEdgeConnectedComponents(), biEdgeConnectedComponents()
67.442 template <typename Graph>
67.443 bool biEdgeConnected(const Graph& graph) {
67.444 return countBiEdgeConnectedComponents(graph) <= 1;
67.445 }
67.446
67.447 - /// \ingroup connectivity
67.448 + /// \ingroup graph_properties
67.449 ///
67.450 - /// \brief Count the bi-edge-connected components.
67.451 + /// \brief Count the number of bi-edge-connected components of an
67.452 + /// undirected graph.
67.453 ///
67.454 - /// This function count the bi-edge-connected components in an undirected
67.455 - /// graph. The bi-edge-connected components are the classes of an equivalence
67.456 - /// relation on the nodes. Two nodes are in relationship when they are
67.457 - /// connected with at least two edge-disjoint paths.
67.458 + /// This function counts the number of bi-edge-connected components of
67.459 + /// the given undirected graph.
67.460 ///
67.461 - /// \param graph The undirected graph.
67.462 - /// \return The number of components.
67.463 + /// The bi-edge-connected components are the classes of an equivalence
67.464 + /// relation on the nodes of an undirected graph. Two nodes are in the
67.465 + /// same class if they are connected with at least two edge-disjoint
67.466 + /// paths.
67.467 + ///
67.468 + /// \return The number of bi-edge-connected components.
67.469 + ///
67.470 + /// \see biEdgeConnected(), biEdgeConnectedComponents()
67.471 template <typename Graph>
67.472 int countBiEdgeConnectedComponents(const Graph& graph) {
67.473 checkConcept<concepts::Graph, Graph>();
67.474 @@ -1073,22 +1138,29 @@
67.475 return compNum;
67.476 }
67.477
67.478 - /// \ingroup connectivity
67.479 + /// \ingroup graph_properties
67.480 ///
67.481 - /// \brief Find the bi-edge-connected components.
67.482 + /// \brief Find the bi-edge-connected components of an undirected graph.
67.483 ///
67.484 - /// This function finds the bi-edge-connected components in an undirected
67.485 - /// graph. The bi-edge-connected components are the classes of an equivalence
67.486 - /// relation on the nodes. Two nodes are in relationship when they are
67.487 - /// connected at least two edge-disjoint paths.
67.488 + /// This function finds the bi-edge-connected components of the given
67.489 + /// undirected graph.
67.490 ///
67.491 - /// \param graph The graph.
67.492 + /// The bi-edge-connected components are the classes of an equivalence
67.493 + /// relation on the nodes of an undirected graph. Two nodes are in the
67.494 + /// same class if they are connected with at least two edge-disjoint
67.495 + /// paths.
67.496 + ///
67.497 + /// \image html edge_biconnected_components.png
67.498 + /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
67.499 + ///
67.500 + /// \param graph The undirected graph.
67.501 /// \retval compMap A writable node map. The values will be set from 0 to
67.502 - /// the number of the biconnected components minus one. Each values
67.503 - /// of the map will be set exactly once, the values of a certain component
67.504 - /// will be set continuously.
67.505 - /// \return The number of components.
67.506 + /// the number of the bi-edge-connected components minus one. Each value
67.507 + /// of the map will be set exactly once, and the values of a certain
67.508 + /// component will be set continuously.
67.509 + /// \return The number of bi-edge-connected components.
67.510 ///
67.511 + /// \see biEdgeConnected(), countBiEdgeConnectedComponents()
67.512 template <typename Graph, typename NodeMap>
67.513 int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
67.514 checkConcept<concepts::Graph, Graph>();
67.515 @@ -1115,21 +1187,27 @@
67.516 return compNum;
67.517 }
67.518
67.519 - /// \ingroup connectivity
67.520 + /// \ingroup graph_properties
67.521 ///
67.522 - /// \brief Find the bi-edge-connected cut edges.
67.523 + /// \brief Find the bi-edge-connected cut edges in an undirected graph.
67.524 ///
67.525 - /// This function finds the bi-edge-connected components in an undirected
67.526 - /// graph. The bi-edge-connected components are the classes of an equivalence
67.527 - /// relation on the nodes. Two nodes are in relationship when they are
67.528 - /// connected with at least two edge-disjoint paths. The bi-edge-connected
67.529 - /// components are separted by edges which are the cut edges of the
67.530 - /// components.
67.531 + /// This function finds the bi-edge-connected cut edges in the given
67.532 + /// undirected graph.
67.533 ///
67.534 - /// \param graph The graph.
67.535 - /// \retval cutMap A writable node map. The values will be set true when the
67.536 - /// edge is a cut edge.
67.537 + /// The bi-edge-connected components are the classes of an equivalence
67.538 + /// relation on the nodes of an undirected graph. Two nodes are in the
67.539 + /// same class if they are connected with at least two edge-disjoint
67.540 + /// paths.
67.541 + /// The bi-edge-connected components are separted by the cut edges of
67.542 + /// the components.
67.543 + ///
67.544 + /// \param graph The undirected graph.
67.545 + /// \retval cutMap A writable edge map. The values will be set to \c true
67.546 + /// for the cut edges (exactly once for each cut edge), and will not be
67.547 + /// changed for other edges.
67.548 /// \return The number of cut edges.
67.549 + ///
67.550 + /// \see biEdgeConnected(), biEdgeConnectedComponents()
67.551 template <typename Graph, typename EdgeMap>
67.552 int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
67.553 checkConcept<concepts::Graph, Graph>();
67.554 @@ -1179,21 +1257,64 @@
67.555
67.556 }
67.557
67.558 - /// \ingroup connectivity
67.559 + /// \ingroup graph_properties
67.560 + ///
67.561 + /// \brief Check whether a digraph is DAG.
67.562 + ///
67.563 + /// This function checks whether the given digraph is DAG, i.e.
67.564 + /// \e Directed \e Acyclic \e Graph.
67.565 + /// \return \c true if there is no directed cycle in the digraph.
67.566 + /// \see acyclic()
67.567 + template <typename Digraph>
67.568 + bool dag(const Digraph& digraph) {
67.569 +
67.570 + checkConcept<concepts::Digraph, Digraph>();
67.571 +
67.572 + typedef typename Digraph::Node Node;
67.573 + typedef typename Digraph::NodeIt NodeIt;
67.574 + typedef typename Digraph::Arc Arc;
67.575 +
67.576 + typedef typename Digraph::template NodeMap<bool> ProcessedMap;
67.577 +
67.578 + typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
67.579 + Create dfs(digraph);
67.580 +
67.581 + ProcessedMap processed(digraph);
67.582 + dfs.processedMap(processed);
67.583 +
67.584 + dfs.init();
67.585 + for (NodeIt it(digraph); it != INVALID; ++it) {
67.586 + if (!dfs.reached(it)) {
67.587 + dfs.addSource(it);
67.588 + while (!dfs.emptyQueue()) {
67.589 + Arc arc = dfs.nextArc();
67.590 + Node target = digraph.target(arc);
67.591 + if (dfs.reached(target) && !processed[target]) {
67.592 + return false;
67.593 + }
67.594 + dfs.processNextArc();
67.595 + }
67.596 + }
67.597 + }
67.598 + return true;
67.599 + }
67.600 +
67.601 + /// \ingroup graph_properties
67.602 ///
67.603 /// \brief Sort the nodes of a DAG into topolgical order.
67.604 ///
67.605 - /// Sort the nodes of a DAG into topolgical order.
67.606 + /// This function sorts the nodes of the given acyclic digraph (DAG)
67.607 + /// into topolgical order.
67.608 ///
67.609 - /// \param graph The graph. It must be directed and acyclic.
67.610 + /// \param digraph The digraph, which must be DAG.
67.611 /// \retval order A writable node map. The values will be set from 0 to
67.612 - /// the number of the nodes in the graph minus one. Each values of the map
67.613 - /// will be set exactly once, the values will be set descending order.
67.614 + /// the number of the nodes in the digraph minus one. Each value of the
67.615 + /// map will be set exactly once, and the values will be set descending
67.616 + /// order.
67.617 ///
67.618 - /// \see checkedTopologicalSort
67.619 - /// \see dag
67.620 + /// \see dag(), checkedTopologicalSort()
67.621 template <typename Digraph, typename NodeMap>
67.622 - void topologicalSort(const Digraph& graph, NodeMap& order) {
67.623 + void topologicalSort(const Digraph& digraph, NodeMap& order) {
67.624 using namespace _connectivity_bits;
67.625
67.626 checkConcept<concepts::Digraph, Digraph>();
67.627 @@ -1204,13 +1325,13 @@
67.628 typedef typename Digraph::Arc Arc;
67.629
67.630 TopologicalSortVisitor<Digraph, NodeMap>
67.631 - visitor(order, countNodes(graph));
67.632 + visitor(order, countNodes(digraph));
67.633
67.634 DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
67.635 - dfs(graph, visitor);
67.636 + dfs(digraph, visitor);
67.637
67.638 dfs.init();
67.639 - for (NodeIt it(graph); it != INVALID; ++it) {
67.640 + for (NodeIt it(digraph); it != INVALID; ++it) {
67.641 if (!dfs.reached(it)) {
67.642 dfs.addSource(it);
67.643 dfs.start();
67.644 @@ -1218,22 +1339,22 @@
67.645 }
67.646 }
67.647
67.648 - /// \ingroup connectivity
67.649 + /// \ingroup graph_properties
67.650 ///
67.651 /// \brief Sort the nodes of a DAG into topolgical order.
67.652 ///
67.653 - /// Sort the nodes of a DAG into topolgical order. It also checks
67.654 - /// that the given graph is DAG.
67.655 + /// This function sorts the nodes of the given acyclic digraph (DAG)
67.656 + /// into topolgical order and also checks whether the given digraph
67.657 + /// is DAG.
67.658 ///
67.659 - /// \param digraph The graph. It must be directed and acyclic.
67.660 - /// \retval order A readable - writable node map. The values will be set
67.661 - /// from 0 to the number of the nodes in the graph minus one. Each values
67.662 - /// of the map will be set exactly once, the values will be set descending
67.663 - /// order.
67.664 - /// \return %False when the graph is not DAG.
67.665 + /// \param digraph The digraph.
67.666 + /// \retval order A readable and writable node map. The values will be
67.667 + /// set from 0 to the number of the nodes in the digraph minus one.
67.668 + /// Each value of the map will be set exactly once, and the values will
67.669 + /// be set descending order.
67.670 + /// \return \c false if the digraph is not DAG.
67.671 ///
67.672 - /// \see topologicalSort
67.673 - /// \see dag
67.674 + /// \see dag(), topologicalSort()
67.675 template <typename Digraph, typename NodeMap>
67.676 bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
67.677 using namespace _connectivity_bits;
67.678 @@ -1273,56 +1394,13 @@
67.679 return true;
67.680 }
67.681
67.682 - /// \ingroup connectivity
67.683 + /// \ingroup graph_properties
67.684 ///
67.685 - /// \brief Check that the given directed graph is a DAG.
67.686 + /// \brief Check whether an undirected graph is acyclic.
67.687 ///
67.688 - /// Check that the given directed graph is a DAG. The DAG is
67.689 - /// an Directed Acyclic Digraph.
67.690 - /// \return %False when the graph is not DAG.
67.691 - /// \see acyclic
67.692 - template <typename Digraph>
67.693 - bool dag(const Digraph& digraph) {
67.694 -
67.695 - checkConcept<concepts::Digraph, Digraph>();
67.696 -
67.697 - typedef typename Digraph::Node Node;
67.698 - typedef typename Digraph::NodeIt NodeIt;
67.699 - typedef typename Digraph::Arc Arc;
67.700 -
67.701 - typedef typename Digraph::template NodeMap<bool> ProcessedMap;
67.702 -
67.703 - typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
67.704 - Create dfs(digraph);
67.705 -
67.706 - ProcessedMap processed(digraph);
67.707 - dfs.processedMap(processed);
67.708 -
67.709 - dfs.init();
67.710 - for (NodeIt it(digraph); it != INVALID; ++it) {
67.711 - if (!dfs.reached(it)) {
67.712 - dfs.addSource(it);
67.713 - while (!dfs.emptyQueue()) {
67.714 - Arc edge = dfs.nextArc();
67.715 - Node target = digraph.target(edge);
67.716 - if (dfs.reached(target) && !processed[target]) {
67.717 - return false;
67.718 - }
67.719 - dfs.processNextArc();
67.720 - }
67.721 - }
67.722 - }
67.723 - return true;
67.724 - }
67.725 -
67.726 - /// \ingroup connectivity
67.727 - ///
67.728 - /// \brief Check that the given undirected graph is acyclic.
67.729 - ///
67.730 - /// Check that the given undirected graph acyclic.
67.731 - /// \param graph The undirected graph.
67.732 - /// \return %True when there is no circle in the graph.
67.733 - /// \see dag
67.734 + /// This function checks whether the given undirected graph is acyclic.
67.735 + /// \return \c true if there is no cycle in the graph.
67.736 + /// \see dag()
67.737 template <typename Graph>
67.738 bool acyclic(const Graph& graph) {
67.739 checkConcept<concepts::Graph, Graph>();
67.740 @@ -1335,11 +1413,11 @@
67.741 if (!dfs.reached(it)) {
67.742 dfs.addSource(it);
67.743 while (!dfs.emptyQueue()) {
67.744 - Arc edge = dfs.nextArc();
67.745 - Node source = graph.source(edge);
67.746 - Node target = graph.target(edge);
67.747 + Arc arc = dfs.nextArc();
67.748 + Node source = graph.source(arc);
67.749 + Node target = graph.target(arc);
67.750 if (dfs.reached(target) &&
67.751 - dfs.predArc(source) != graph.oppositeArc(edge)) {
67.752 + dfs.predArc(source) != graph.oppositeArc(arc)) {
67.753 return false;
67.754 }
67.755 dfs.processNextArc();
67.756 @@ -1349,28 +1427,29 @@
67.757 return true;
67.758 }
67.759
67.760 - /// \ingroup connectivity
67.761 + /// \ingroup graph_properties
67.762 ///
67.763 - /// \brief Check that the given undirected graph is tree.
67.764 + /// \brief Check whether an undirected graph is tree.
67.765 ///
67.766 - /// Check that the given undirected graph is tree.
67.767 - /// \param graph The undirected graph.
67.768 - /// \return %True when the graph is acyclic and connected.
67.769 + /// This function checks whether the given undirected graph is tree.
67.770 + /// \return \c true if the graph is acyclic and connected.
67.771 + /// \see acyclic(), connected()
67.772 template <typename Graph>
67.773 bool tree(const Graph& graph) {
67.774 checkConcept<concepts::Graph, Graph>();
67.775 typedef typename Graph::Node Node;
67.776 typedef typename Graph::NodeIt NodeIt;
67.777 typedef typename Graph::Arc Arc;
67.778 + if (NodeIt(graph) == INVALID) return true;
67.779 Dfs<Graph> dfs(graph);
67.780 dfs.init();
67.781 dfs.addSource(NodeIt(graph));
67.782 while (!dfs.emptyQueue()) {
67.783 - Arc edge = dfs.nextArc();
67.784 - Node source = graph.source(edge);
67.785 - Node target = graph.target(edge);
67.786 + Arc arc = dfs.nextArc();
67.787 + Node source = graph.source(arc);
67.788 + Node target = graph.target(arc);
67.789 if (dfs.reached(target) &&
67.790 - dfs.predArc(source) != graph.oppositeArc(edge)) {
67.791 + dfs.predArc(source) != graph.oppositeArc(arc)) {
67.792 return false;
67.793 }
67.794 dfs.processNextArc();
67.795 @@ -1441,17 +1520,16 @@
67.796 };
67.797 }
67.798
67.799 - /// \ingroup connectivity
67.800 + /// \ingroup graph_properties
67.801 ///
67.802 - /// \brief Check if the given undirected graph is bipartite or not
67.803 + /// \brief Check whether an undirected graph is bipartite.
67.804 ///
67.805 - /// The function checks if the given undirected \c graph graph is bipartite
67.806 - /// or not. The \ref Bfs algorithm is used to calculate the result.
67.807 - /// \param graph The undirected graph.
67.808 - /// \return %True if \c graph is bipartite, %false otherwise.
67.809 - /// \sa bipartitePartitions
67.810 + /// The function checks whether the given undirected graph is bipartite.
67.811 + /// \return \c true if the graph is bipartite.
67.812 + ///
67.813 + /// \see bipartitePartitions()
67.814 template<typename Graph>
67.815 - inline bool bipartite(const Graph &graph){
67.816 + bool bipartite(const Graph &graph){
67.817 using namespace _connectivity_bits;
67.818
67.819 checkConcept<concepts::Graph, Graph>();
67.820 @@ -1478,23 +1556,29 @@
67.821 return true;
67.822 }
67.823
67.824 - /// \ingroup connectivity
67.825 + /// \ingroup graph_properties
67.826 ///
67.827 - /// \brief Check if the given undirected graph is bipartite or not
67.828 + /// \brief Find the bipartite partitions of an undirected graph.
67.829 ///
67.830 - /// The function checks if the given undirected graph is bipartite
67.831 - /// or not. The \ref Bfs algorithm is used to calculate the result.
67.832 - /// During the execution, the \c partMap will be set as the two
67.833 - /// partitions of the graph.
67.834 + /// This function checks whether the given undirected graph is bipartite
67.835 + /// and gives back the bipartite partitions.
67.836 + ///
67.837 + /// \image html bipartite_partitions.png
67.838 + /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
67.839 + ///
67.840 /// \param graph The undirected graph.
67.841 - /// \retval partMap A writable bool map of nodes. It will be set as the
67.842 - /// two partitions of the graph.
67.843 - /// \return %True if \c graph is bipartite, %false otherwise.
67.844 + /// \retval partMap A writable node map of \c bool (or convertible) value
67.845 + /// type. The values will be set to \c true for one component and
67.846 + /// \c false for the other one.
67.847 + /// \return \c true if the graph is bipartite, \c false otherwise.
67.848 + ///
67.849 + /// \see bipartite()
67.850 template<typename Graph, typename NodeMap>
67.851 - inline bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
67.852 + bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
67.853 using namespace _connectivity_bits;
67.854
67.855 checkConcept<concepts::Graph, Graph>();
67.856 + checkConcept<concepts::WriteMap<typename Graph::Node, bool>, NodeMap>();
67.857
67.858 typedef typename Graph::Node Node;
67.859 typedef typename Graph::NodeIt NodeIt;
67.860 @@ -1519,53 +1603,59 @@
67.861 return true;
67.862 }
67.863
67.864 - /// \brief Returns true when there are not loop edges in the graph.
67.865 + /// \ingroup graph_properties
67.866 ///
67.867 - /// Returns true when there are not loop edges in the graph.
67.868 - template <typename Digraph>
67.869 - bool loopFree(const Digraph& digraph) {
67.870 - for (typename Digraph::ArcIt it(digraph); it != INVALID; ++it) {
67.871 - if (digraph.source(it) == digraph.target(it)) return false;
67.872 + /// \brief Check whether the given graph contains no loop arcs/edges.
67.873 + ///
67.874 + /// This function returns \c true if there are no loop arcs/edges in
67.875 + /// the given graph. It works for both directed and undirected graphs.
67.876 + template <typename Graph>
67.877 + bool loopFree(const Graph& graph) {
67.878 + for (typename Graph::ArcIt it(graph); it != INVALID; ++it) {
67.879 + if (graph.source(it) == graph.target(it)) return false;
67.880 }
67.881 return true;
67.882 }
67.883
67.884 - /// \brief Returns true when there are not parallel edges in the graph.
67.885 + /// \ingroup graph_properties
67.886 ///
67.887 - /// Returns true when there are not parallel edges in the graph.
67.888 - template <typename Digraph>
67.889 - bool parallelFree(const Digraph& digraph) {
67.890 - typename Digraph::template NodeMap<bool> reached(digraph, false);
67.891 - for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
67.892 - for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
67.893 - if (reached[digraph.target(a)]) return false;
67.894 - reached.set(digraph.target(a), true);
67.895 + /// \brief Check whether the given graph contains no parallel arcs/edges.
67.896 + ///
67.897 + /// This function returns \c true if there are no parallel arcs/edges in
67.898 + /// the given graph. It works for both directed and undirected graphs.
67.899 + template <typename Graph>
67.900 + bool parallelFree(const Graph& graph) {
67.901 + typename Graph::template NodeMap<int> reached(graph, 0);
67.902 + int cnt = 1;
67.903 + for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
67.904 + for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
67.905 + if (reached[graph.target(a)] == cnt) return false;
67.906 + reached[graph.target(a)] = cnt;
67.907 }
67.908 - for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
67.909 - reached.set(digraph.target(a), false);
67.910 - }
67.911 + ++cnt;
67.912 }
67.913 return true;
67.914 }
67.915
67.916 - /// \brief Returns true when there are not loop edges and parallel
67.917 - /// edges in the graph.
67.918 + /// \ingroup graph_properties
67.919 ///
67.920 - /// Returns true when there are not loop edges and parallel edges in
67.921 - /// the graph.
67.922 - template <typename Digraph>
67.923 - bool simpleDigraph(const Digraph& digraph) {
67.924 - typename Digraph::template NodeMap<bool> reached(digraph, false);
67.925 - for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
67.926 - reached.set(n, true);
67.927 - for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
67.928 - if (reached[digraph.target(a)]) return false;
67.929 - reached.set(digraph.target(a), true);
67.930 + /// \brief Check whether the given graph is simple.
67.931 + ///
67.932 + /// This function returns \c true if the given graph is simple, i.e.
67.933 + /// it contains no loop arcs/edges and no parallel arcs/edges.
67.934 + /// The function works for both directed and undirected graphs.
67.935 + /// \see loopFree(), parallelFree()
67.936 + template <typename Graph>
67.937 + bool simpleGraph(const Graph& graph) {
67.938 + typename Graph::template NodeMap<int> reached(graph, 0);
67.939 + int cnt = 1;
67.940 + for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
67.941 + reached[n] = cnt;
67.942 + for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
67.943 + if (reached[graph.target(a)] == cnt) return false;
67.944 + reached[graph.target(a)] = cnt;
67.945 }
67.946 - for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
67.947 - reached.set(digraph.target(a), false);
67.948 - }
67.949 - reached.set(n, false);
67.950 + ++cnt;
67.951 }
67.952 return true;
67.953 }
68.1 --- a/lemon/core.h Mon Jan 12 23:11:39 2009 +0100
68.2 +++ b/lemon/core.h Thu Nov 05 15:48:01 2009 +0100
68.3 @@ -22,10 +22,21 @@
68.4 #include <vector>
68.5 #include <algorithm>
68.6
68.7 +#include <lemon/config.h>
68.8 #include <lemon/bits/enable_if.h>
68.9 #include <lemon/bits/traits.h>
68.10 #include <lemon/assert.h>
68.11
68.12 +// Disable the following warnings when compiling with MSVC:
68.13 +// C4250: 'class1' : inherits 'class2::member' via dominance
68.14 +// C4355: 'this' : used in base member initializer list
68.15 +// C4503: 'function' : decorated name length exceeded, name was truncated
68.16 +// C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
68.17 +// C4996: 'function': was declared deprecated
68.18 +#ifdef _MSC_VER
68.19 +#pragma warning( disable : 4250 4355 4503 4800 4996 )
68.20 +#endif
68.21 +
68.22 ///\file
68.23 ///\brief LEMON core utilities.
68.24 ///
68.25 @@ -1033,28 +1044,27 @@
68.26 ///
68.27 ///\sa findArc()
68.28 ///\sa ArcLookUp, AllArcLookUp, DynArcLookUp
68.29 - template <typename _Graph>
68.30 - class ConArcIt : public _Graph::Arc {
68.31 + template <typename GR>
68.32 + class ConArcIt : public GR::Arc {
68.33 + typedef typename GR::Arc Parent;
68.34 +
68.35 public:
68.36
68.37 - typedef _Graph Graph;
68.38 - typedef typename Graph::Arc Parent;
68.39 -
68.40 - typedef typename Graph::Arc Arc;
68.41 - typedef typename Graph::Node Node;
68.42 + typedef typename GR::Arc Arc;
68.43 + typedef typename GR::Node Node;
68.44
68.45 /// \brief Constructor.
68.46 ///
68.47 /// Construct a new ConArcIt iterating on the arcs that
68.48 /// connects nodes \c u and \c v.
68.49 - ConArcIt(const Graph& g, Node u, Node v) : _graph(g) {
68.50 + ConArcIt(const GR& g, Node u, Node v) : _graph(g) {
68.51 Parent::operator=(findArc(_graph, u, v));
68.52 }
68.53
68.54 /// \brief Constructor.
68.55 ///
68.56 /// Construct a new ConArcIt that continues the iterating from arc \c a.
68.57 - ConArcIt(const Graph& g, Arc a) : Parent(a), _graph(g) {}
68.58 + ConArcIt(const GR& g, Arc a) : Parent(a), _graph(g) {}
68.59
68.60 /// \brief Increment operator.
68.61 ///
68.62 @@ -1065,7 +1075,7 @@
68.63 return *this;
68.64 }
68.65 private:
68.66 - const Graph& _graph;
68.67 + const GR& _graph;
68.68 };
68.69
68.70 namespace _core_bits {
68.71 @@ -1156,28 +1166,27 @@
68.72 ///\endcode
68.73 ///
68.74 ///\sa findEdge()
68.75 - template <typename _Graph>
68.76 - class ConEdgeIt : public _Graph::Edge {
68.77 + template <typename GR>
68.78 + class ConEdgeIt : public GR::Edge {
68.79 + typedef typename GR::Edge Parent;
68.80 +
68.81 public:
68.82
68.83 - typedef _Graph Graph;
68.84 - typedef typename Graph::Edge Parent;
68.85 -
68.86 - typedef typename Graph::Edge Edge;
68.87 - typedef typename Graph::Node Node;
68.88 + typedef typename GR::Edge Edge;
68.89 + typedef typename GR::Node Node;
68.90
68.91 /// \brief Constructor.
68.92 ///
68.93 /// Construct a new ConEdgeIt iterating on the edges that
68.94 /// connects nodes \c u and \c v.
68.95 - ConEdgeIt(const Graph& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
68.96 + ConEdgeIt(const GR& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
68.97 Parent::operator=(findEdge(_graph, _u, _v));
68.98 }
68.99
68.100 /// \brief Constructor.
68.101 ///
68.102 /// Construct a new ConEdgeIt that continues iterating from edge \c e.
68.103 - ConEdgeIt(const Graph& g, Edge e) : Parent(e), _graph(g) {}
68.104 + ConEdgeIt(const GR& g, Edge e) : Parent(e), _graph(g) {}
68.105
68.106 /// \brief Increment operator.
68.107 ///
68.108 @@ -1187,7 +1196,7 @@
68.109 return *this;
68.110 }
68.111 private:
68.112 - const Graph& _graph;
68.113 + const GR& _graph;
68.114 Node _u, _v;
68.115 };
68.116
68.117 @@ -1210,29 +1219,32 @@
68.118 ///optimal time bound in a constant factor for any distribution of
68.119 ///queries.
68.120 ///
68.121 - ///\tparam G The type of the underlying digraph.
68.122 + ///\tparam GR The type of the underlying digraph.
68.123 ///
68.124 ///\sa ArcLookUp
68.125 ///\sa AllArcLookUp
68.126 - template<class G>
68.127 + template <typename GR>
68.128 class DynArcLookUp
68.129 - : protected ItemSetTraits<G, typename G::Arc>::ItemNotifier::ObserverBase
68.130 + : protected ItemSetTraits<GR, typename GR::Arc>::ItemNotifier::ObserverBase
68.131 {
68.132 - public:
68.133 - typedef typename ItemSetTraits<G, typename G::Arc>
68.134 + typedef typename ItemSetTraits<GR, typename GR::Arc>
68.135 ::ItemNotifier::ObserverBase Parent;
68.136
68.137 - TEMPLATE_DIGRAPH_TYPEDEFS(G);
68.138 - typedef G Digraph;
68.139 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
68.140 +
68.141 + public:
68.142 +
68.143 + /// The Digraph type
68.144 + typedef GR Digraph;
68.145
68.146 protected:
68.147
68.148 - class AutoNodeMap : public ItemSetTraits<G, Node>::template Map<Arc>::Type {
68.149 + class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type {
68.150 + typedef typename ItemSetTraits<GR, Node>::template Map<Arc>::Type Parent;
68.151 +
68.152 public:
68.153
68.154 - typedef typename ItemSetTraits<G, Node>::template Map<Arc>::Type Parent;
68.155 -
68.156 - AutoNodeMap(const G& digraph) : Parent(digraph, INVALID) {}
68.157 + AutoNodeMap(const GR& digraph) : Parent(digraph, INVALID) {}
68.158
68.159 virtual void add(const Node& node) {
68.160 Parent::add(node);
68.161 @@ -1256,12 +1268,6 @@
68.162 }
68.163 };
68.164
68.165 - const Digraph &_g;
68.166 - AutoNodeMap _head;
68.167 - typename Digraph::template ArcMap<Arc> _parent;
68.168 - typename Digraph::template ArcMap<Arc> _left;
68.169 - typename Digraph::template ArcMap<Arc> _right;
68.170 -
68.171 class ArcLess {
68.172 const Digraph &g;
68.173 public:
68.174 @@ -1272,6 +1278,14 @@
68.175 }
68.176 };
68.177
68.178 + protected:
68.179 +
68.180 + const Digraph &_g;
68.181 + AutoNodeMap _head;
68.182 + typename Digraph::template ArcMap<Arc> _parent;
68.183 + typename Digraph::template ArcMap<Arc> _left;
68.184 + typename Digraph::template ArcMap<Arc> _right;
68.185 +
68.186 public:
68.187
68.188 ///Constructor
68.189 @@ -1314,27 +1328,27 @@
68.190
68.191 virtual void clear() {
68.192 for(NodeIt n(_g);n!=INVALID;++n) {
68.193 - _head.set(n, INVALID);
68.194 + _head[n] = INVALID;
68.195 }
68.196 }
68.197
68.198 void insert(Arc arc) {
68.199 Node s = _g.source(arc);
68.200 Node t = _g.target(arc);
68.201 - _left.set(arc, INVALID);
68.202 - _right.set(arc, INVALID);
68.203 + _left[arc] = INVALID;
68.204 + _right[arc] = INVALID;
68.205
68.206 Arc e = _head[s];
68.207 if (e == INVALID) {
68.208 - _head.set(s, arc);
68.209 - _parent.set(arc, INVALID);
68.210 + _head[s] = arc;
68.211 + _parent[arc] = INVALID;
68.212 return;
68.213 }
68.214 while (true) {
68.215 if (t < _g.target(e)) {
68.216 if (_left[e] == INVALID) {
68.217 - _left.set(e, arc);
68.218 - _parent.set(arc, e);
68.219 + _left[e] = arc;
68.220 + _parent[arc] = e;
68.221 splay(arc);
68.222 return;
68.223 } else {
68.224 @@ -1342,8 +1356,8 @@
68.225 }
68.226 } else {
68.227 if (_right[e] == INVALID) {
68.228 - _right.set(e, arc);
68.229 - _parent.set(arc, e);
68.230 + _right[e] = arc;
68.231 + _parent[arc] = e;
68.232 splay(arc);
68.233 return;
68.234 } else {
68.235 @@ -1356,27 +1370,27 @@
68.236 void remove(Arc arc) {
68.237 if (_left[arc] == INVALID) {
68.238 if (_right[arc] != INVALID) {
68.239 - _parent.set(_right[arc], _parent[arc]);
68.240 + _parent[_right[arc]] = _parent[arc];
68.241 }
68.242 if (_parent[arc] != INVALID) {
68.243 if (_left[_parent[arc]] == arc) {
68.244 - _left.set(_parent[arc], _right[arc]);
68.245 + _left[_parent[arc]] = _right[arc];
68.246 } else {
68.247 - _right.set(_parent[arc], _right[arc]);
68.248 + _right[_parent[arc]] = _right[arc];
68.249 }
68.250 } else {
68.251 - _head.set(_g.source(arc), _right[arc]);
68.252 + _head[_g.source(arc)] = _right[arc];
68.253 }
68.254 } else if (_right[arc] == INVALID) {
68.255 - _parent.set(_left[arc], _parent[arc]);
68.256 + _parent[_left[arc]] = _parent[arc];
68.257 if (_parent[arc] != INVALID) {
68.258 if (_left[_parent[arc]] == arc) {
68.259 - _left.set(_parent[arc], _left[arc]);
68.260 + _left[_parent[arc]] = _left[arc];
68.261 } else {
68.262 - _right.set(_parent[arc], _left[arc]);
68.263 + _right[_parent[arc]] = _left[arc];
68.264 }
68.265 } else {
68.266 - _head.set(_g.source(arc), _left[arc]);
68.267 + _head[_g.source(arc)] = _left[arc];
68.268 }
68.269 } else {
68.270 Arc e = _left[arc];
68.271 @@ -1386,38 +1400,38 @@
68.272 e = _right[e];
68.273 }
68.274 Arc s = _parent[e];
68.275 - _right.set(_parent[e], _left[e]);
68.276 + _right[_parent[e]] = _left[e];
68.277 if (_left[e] != INVALID) {
68.278 - _parent.set(_left[e], _parent[e]);
68.279 + _parent[_left[e]] = _parent[e];
68.280 }
68.281
68.282 - _left.set(e, _left[arc]);
68.283 - _parent.set(_left[arc], e);
68.284 - _right.set(e, _right[arc]);
68.285 - _parent.set(_right[arc], e);
68.286 + _left[e] = _left[arc];
68.287 + _parent[_left[arc]] = e;
68.288 + _right[e] = _right[arc];
68.289 + _parent[_right[arc]] = e;
68.290
68.291 - _parent.set(e, _parent[arc]);
68.292 + _parent[e] = _parent[arc];
68.293 if (_parent[arc] != INVALID) {
68.294 if (_left[_parent[arc]] == arc) {
68.295 - _left.set(_parent[arc], e);
68.296 + _left[_parent[arc]] = e;
68.297 } else {
68.298 - _right.set(_parent[arc], e);
68.299 + _right[_parent[arc]] = e;
68.300 }
68.301 }
68.302 splay(s);
68.303 } else {
68.304 - _right.set(e, _right[arc]);
68.305 - _parent.set(_right[arc], e);
68.306 - _parent.set(e, _parent[arc]);
68.307 + _right[e] = _right[arc];
68.308 + _parent[_right[arc]] = e;
68.309 + _parent[e] = _parent[arc];
68.310
68.311 if (_parent[arc] != INVALID) {
68.312 if (_left[_parent[arc]] == arc) {
68.313 - _left.set(_parent[arc], e);
68.314 + _left[_parent[arc]] = e;
68.315 } else {
68.316 - _right.set(_parent[arc], e);
68.317 + _right[_parent[arc]] = e;
68.318 }
68.319 } else {
68.320 - _head.set(_g.source(arc), e);
68.321 + _head[_g.source(arc)] = e;
68.322 }
68.323 }
68.324 }
68.325 @@ -1429,17 +1443,17 @@
68.326 Arc me=v[m];
68.327 if (a < m) {
68.328 Arc left = refreshRec(v,a,m-1);
68.329 - _left.set(me, left);
68.330 - _parent.set(left, me);
68.331 + _left[me] = left;
68.332 + _parent[left] = me;
68.333 } else {
68.334 - _left.set(me, INVALID);
68.335 + _left[me] = INVALID;
68.336 }
68.337 if (m < b) {
68.338 Arc right = refreshRec(v,m+1,b);
68.339 - _right.set(me, right);
68.340 - _parent.set(right, me);
68.341 + _right[me] = right;
68.342 + _parent[right] = me;
68.343 } else {
68.344 - _right.set(me, INVALID);
68.345 + _right[me] = INVALID;
68.346 }
68.347 return me;
68.348 }
68.349 @@ -1451,46 +1465,46 @@
68.350 if (!v.empty()) {
68.351 std::sort(v.begin(),v.end(),ArcLess(_g));
68.352 Arc head = refreshRec(v,0,v.size()-1);
68.353 - _head.set(n, head);
68.354 - _parent.set(head, INVALID);
68.355 + _head[n] = head;
68.356 + _parent[head] = INVALID;
68.357 }
68.358 - else _head.set(n, INVALID);
68.359 + else _head[n] = INVALID;
68.360 }
68.361 }
68.362
68.363 void zig(Arc v) {
68.364 Arc w = _parent[v];
68.365 - _parent.set(v, _parent[w]);
68.366 - _parent.set(w, v);
68.367 - _left.set(w, _right[v]);
68.368 - _right.set(v, w);
68.369 + _parent[v] = _parent[w];
68.370 + _parent[w] = v;
68.371 + _left[w] = _right[v];
68.372 + _right[v] = w;
68.373 if (_parent[v] != INVALID) {
68.374 if (_right[_parent[v]] == w) {
68.375 - _right.set(_parent[v], v);
68.376 + _right[_parent[v]] = v;
68.377 } else {
68.378 - _left.set(_parent[v], v);
68.379 + _left[_parent[v]] = v;
68.380 }
68.381 }
68.382 if (_left[w] != INVALID){
68.383 - _parent.set(_left[w], w);
68.384 + _parent[_left[w]] = w;
68.385 }
68.386 }
68.387
68.388 void zag(Arc v) {
68.389 Arc w = _parent[v];
68.390 - _parent.set(v, _parent[w]);
68.391 - _parent.set(w, v);
68.392 - _right.set(w, _left[v]);
68.393 - _left.set(v, w);
68.394 + _parent[v] = _parent[w];
68.395 + _parent[w] = v;
68.396 + _right[w] = _left[v];
68.397 + _left[v] = w;
68.398 if (_parent[v] != INVALID){
68.399 if (_left[_parent[v]] == w) {
68.400 - _left.set(_parent[v], v);
68.401 + _left[_parent[v]] = v;
68.402 } else {
68.403 - _right.set(_parent[v], v);
68.404 + _right[_parent[v]] = v;
68.405 }
68.406 }
68.407 if (_right[w] != INVALID){
68.408 - _parent.set(_right[w], w);
68.409 + _parent[_right[w]] = w;
68.410 }
68.411 }
68.412
68.413 @@ -1622,16 +1636,19 @@
68.414 ///digraph changes. This is a time consuming (superlinearly proportional
68.415 ///(<em>O</em>(<em>m</em> log<em>m</em>)) to the number of arcs).
68.416 ///
68.417 - ///\tparam G The type of the underlying digraph.
68.418 + ///\tparam GR The type of the underlying digraph.
68.419 ///
68.420 ///\sa DynArcLookUp
68.421 ///\sa AllArcLookUp
68.422 - template<class G>
68.423 + template<class GR>
68.424 class ArcLookUp
68.425 {
68.426 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
68.427 +
68.428 public:
68.429 - TEMPLATE_DIGRAPH_TYPEDEFS(G);
68.430 - typedef G Digraph;
68.431 +
68.432 + /// The Digraph type
68.433 + typedef GR Digraph;
68.434
68.435 protected:
68.436 const Digraph &_g;
68.437 @@ -1732,22 +1749,21 @@
68.438 ///digraph changes. This is a time consuming (superlinearly proportional
68.439 ///(<em>O</em>(<em>m</em> log<em>m</em>)) to the number of arcs).
68.440 ///
68.441 - ///\tparam G The type of the underlying digraph.
68.442 + ///\tparam GR The type of the underlying digraph.
68.443 ///
68.444 ///\sa DynArcLookUp
68.445 ///\sa ArcLookUp
68.446 - template<class G>
68.447 - class AllArcLookUp : public ArcLookUp<G>
68.448 + template<class GR>
68.449 + class AllArcLookUp : public ArcLookUp<GR>
68.450 {
68.451 - using ArcLookUp<G>::_g;
68.452 - using ArcLookUp<G>::_right;
68.453 - using ArcLookUp<G>::_left;
68.454 - using ArcLookUp<G>::_head;
68.455 + using ArcLookUp<GR>::_g;
68.456 + using ArcLookUp<GR>::_right;
68.457 + using ArcLookUp<GR>::_left;
68.458 + using ArcLookUp<GR>::_head;
68.459
68.460 - TEMPLATE_DIGRAPH_TYPEDEFS(G);
68.461 - typedef G Digraph;
68.462 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
68.463
68.464 - typename Digraph::template ArcMap<Arc> _next;
68.465 + typename GR::template ArcMap<Arc> _next;
68.466
68.467 Arc refreshNext(Arc head,Arc next=INVALID)
68.468 {
68.469 @@ -1766,13 +1782,17 @@
68.470 }
68.471
68.472 public:
68.473 +
68.474 + /// The Digraph type
68.475 + typedef GR Digraph;
68.476 +
68.477 ///Constructor
68.478
68.479 ///Constructor.
68.480 ///
68.481 ///It builds up the search database, which remains valid until the digraph
68.482 ///changes.
68.483 - AllArcLookUp(const Digraph &g) : ArcLookUp<G>(g), _next(g) {refreshNext();}
68.484 + AllArcLookUp(const Digraph &g) : ArcLookUp<GR>(g), _next(g) {refreshNext();}
68.485
68.486 ///Refresh the data structure at a node.
68.487
68.488 @@ -1782,7 +1802,7 @@
68.489 ///the number of the outgoing arcs of \c n.
68.490 void refresh(Node n)
68.491 {
68.492 - ArcLookUp<G>::refresh(n);
68.493 + ArcLookUp<GR>::refresh(n);
68.494 refreshNext(_head[n]);
68.495 }
68.496
68.497 @@ -1829,7 +1849,7 @@
68.498 #ifdef DOXYGEN
68.499 Arc operator()(Node s, Node t, Arc prev=INVALID) const {}
68.500 #else
68.501 - using ArcLookUp<G>::operator() ;
68.502 + using ArcLookUp<GR>::operator() ;
68.503 Arc operator()(Node s, Node t, Arc prev) const
68.504 {
68.505 return prev==INVALID?(*this)(s,t):_next[prev];
69.1 --- a/lemon/cplex.cc Mon Jan 12 23:11:39 2009 +0100
69.2 +++ b/lemon/cplex.cc Thu Nov 05 15:48:01 2009 +0100
69.3 @@ -2,7 +2,7 @@
69.4 *
69.5 * This file is a part of LEMON, a generic C++ optimization library.
69.6 *
69.7 - * Copyright (C) 2003-2008
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 @@ -72,12 +72,14 @@
69.13 CplexBase::CplexBase() : LpBase() {
69.14 int status;
69.15 _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
69.16 + messageLevel(MESSAGE_NOTHING);
69.17 }
69.18
69.19 CplexBase::CplexBase(const CplexEnv& env)
69.20 : LpBase(), _env(env) {
69.21 int status;
69.22 _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
69.23 + messageLevel(MESSAGE_NOTHING);
69.24 }
69.25
69.26 CplexBase::CplexBase(const CplexBase& cplex)
69.27 @@ -86,6 +88,7 @@
69.28 _prob = CPXcloneprob(cplexEnv(), cplex._prob, &status);
69.29 rows = cplex.rows;
69.30 cols = cplex.cols;
69.31 + messageLevel(MESSAGE_NOTHING);
69.32 }
69.33
69.34 CplexBase::~CplexBase() {
69.35 @@ -108,6 +111,39 @@
69.36 return i;
69.37 }
69.38
69.39 + int CplexBase::_addRow(Value lb, ExprIterator b,
69.40 + ExprIterator e, Value ub) {
69.41 + int i = CPXgetnumrows(cplexEnv(), _prob);
69.42 + if (lb == -INF) {
69.43 + const char s = 'L';
69.44 + CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
69.45 + } else if (ub == INF) {
69.46 + const char s = 'G';
69.47 + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
69.48 + } else if (lb == ub){
69.49 + const char s = 'E';
69.50 + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
69.51 + } else {
69.52 + const char s = 'R';
69.53 + double len = ub - lb;
69.54 + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0);
69.55 + }
69.56 +
69.57 + std::vector<int> indices;
69.58 + std::vector<int> rowlist;
69.59 + std::vector<Value> values;
69.60 +
69.61 + for(ExprIterator it=b; it!=e; ++it) {
69.62 + indices.push_back(it->first);
69.63 + values.push_back(it->second);
69.64 + rowlist.push_back(i);
69.65 + }
69.66 +
69.67 + CPXchgcoeflist(cplexEnv(), _prob, values.size(),
69.68 + &rowlist.front(), &indices.front(), &values.front());
69.69 +
69.70 + return i;
69.71 + }
69.72
69.73 void CplexBase::_eraseCol(int i) {
69.74 CPXdelcols(cplexEnv(), _prob, i, i);
69.75 @@ -438,21 +474,40 @@
69.76 cols.clear();
69.77 }
69.78
69.79 + void CplexBase::_messageLevel(MessageLevel level) {
69.80 + switch (level) {
69.81 + case MESSAGE_NOTHING:
69.82 + _message_enabled = false;
69.83 + break;
69.84 + case MESSAGE_ERROR:
69.85 + case MESSAGE_WARNING:
69.86 + case MESSAGE_NORMAL:
69.87 + case MESSAGE_VERBOSE:
69.88 + _message_enabled = true;
69.89 + break;
69.90 + }
69.91 + }
69.92 +
69.93 + void CplexBase::_applyMessageLevel() {
69.94 + CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND,
69.95 + _message_enabled ? CPX_ON : CPX_OFF);
69.96 + }
69.97 +
69.98 // CplexLp members
69.99
69.100 CplexLp::CplexLp()
69.101 - : LpBase(), CplexBase(), LpSolver() {}
69.102 + : LpBase(), LpSolver(), CplexBase() {}
69.103
69.104 CplexLp::CplexLp(const CplexEnv& env)
69.105 - : LpBase(), CplexBase(env), LpSolver() {}
69.106 + : LpBase(), LpSolver(), CplexBase(env) {}
69.107
69.108 CplexLp::CplexLp(const CplexLp& other)
69.109 - : LpBase(), CplexBase(other), LpSolver() {}
69.110 + : LpBase(), LpSolver(), CplexBase(other) {}
69.111
69.112 CplexLp::~CplexLp() {}
69.113
69.114 - CplexLp* CplexLp::_newSolver() const { return new CplexLp; }
69.115 - CplexLp* CplexLp::_cloneSolver() const {return new CplexLp(*this); }
69.116 + CplexLp* CplexLp::newSolver() const { return new CplexLp; }
69.117 + CplexLp* CplexLp::cloneSolver() const {return new CplexLp(*this); }
69.118
69.119 const char* CplexLp::_solverName() const { return "CplexLp"; }
69.120
69.121 @@ -507,21 +562,25 @@
69.122
69.123 CplexLp::SolveExitStatus CplexLp::_solve() {
69.124 _clear_temporals();
69.125 + _applyMessageLevel();
69.126 return convertStatus(CPXlpopt(cplexEnv(), _prob));
69.127 }
69.128
69.129 CplexLp::SolveExitStatus CplexLp::solvePrimal() {
69.130 _clear_temporals();
69.131 + _applyMessageLevel();
69.132 return convertStatus(CPXprimopt(cplexEnv(), _prob));
69.133 }
69.134
69.135 CplexLp::SolveExitStatus CplexLp::solveDual() {
69.136 _clear_temporals();
69.137 + _applyMessageLevel();
69.138 return convertStatus(CPXdualopt(cplexEnv(), _prob));
69.139 }
69.140
69.141 CplexLp::SolveExitStatus CplexLp::solveBarrier() {
69.142 _clear_temporals();
69.143 + _applyMessageLevel();
69.144 return convertStatus(CPXbaropt(cplexEnv(), _prob));
69.145 }
69.146
69.147 @@ -600,7 +659,7 @@
69.148 return _dual_ray[i];
69.149 }
69.150
69.151 - //7.5-os cplex statusai (Vigyazat: a 9.0-asei masok!)
69.152 + // Cplex 7.0 status values
69.153 // This table lists the statuses, returned by the CPXgetstat()
69.154 // routine, for solutions to LP problems or mixed integer problems. If
69.155 // no solution exists, the return value is zero.
69.156 @@ -647,7 +706,7 @@
69.157 // 20 CPX_PIVOT
69.158 // User pivot used
69.159 //
69.160 - // Ezeket hova tegyem:
69.161 + // Pending return values
69.162 // ??case CPX_ABORT_DUAL_INFEAS
69.163 // ??case CPX_ABORT_CROSSOVER
69.164 // ??case CPX_INForUNBD
69.165 @@ -718,7 +777,6 @@
69.166 #else
69.167 statusSwitch(cplexEnv(),stat);
69.168 //CPXgetstat(cplexEnv(), _prob);
69.169 - //printf("A primal status: %d, CPX_OPTIMAL=%d \n",stat,CPX_OPTIMAL);
69.170 switch (stat) {
69.171 case 0:
69.172 return UNDEFINED; //Undefined
69.173 @@ -751,7 +809,7 @@
69.174 #endif
69.175 }
69.176
69.177 - //9.0-as cplex verzio statusai
69.178 + // Cplex 9.0 status values
69.179 // CPX_STAT_ABORT_DUAL_OBJ_LIM
69.180 // CPX_STAT_ABORT_IT_LIM
69.181 // CPX_STAT_ABORT_OBJ_LIM
69.182 @@ -798,7 +856,7 @@
69.183 // CplexMip members
69.184
69.185 CplexMip::CplexMip()
69.186 - : LpBase(), CplexBase(), MipSolver() {
69.187 + : LpBase(), MipSolver(), CplexBase() {
69.188
69.189 #if CPX_VERSION < 800
69.190 CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MIP);
69.191 @@ -808,7 +866,7 @@
69.192 }
69.193
69.194 CplexMip::CplexMip(const CplexEnv& env)
69.195 - : LpBase(), CplexBase(env), MipSolver() {
69.196 + : LpBase(), MipSolver(), CplexBase(env) {
69.197
69.198 #if CPX_VERSION < 800
69.199 CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MIP);
69.200 @@ -819,12 +877,12 @@
69.201 }
69.202
69.203 CplexMip::CplexMip(const CplexMip& other)
69.204 - : LpBase(), CplexBase(other), MipSolver() {}
69.205 + : LpBase(), MipSolver(), CplexBase(other) {}
69.206
69.207 CplexMip::~CplexMip() {}
69.208
69.209 - CplexMip* CplexMip::_newSolver() const { return new CplexMip; }
69.210 - CplexMip* CplexMip::_cloneSolver() const {return new CplexMip(*this); }
69.211 + CplexMip* CplexMip::newSolver() const { return new CplexMip; }
69.212 + CplexMip* CplexMip::cloneSolver() const {return new CplexMip(*this); }
69.213
69.214 const char* CplexMip::_solverName() const { return "CplexMip"; }
69.215
69.216 @@ -864,6 +922,7 @@
69.217
69.218 CplexMip::SolveExitStatus CplexMip::_solve() {
69.219 int status;
69.220 + _applyMessageLevel();
69.221 status = CPXmipopt (cplexEnv(), _prob);
69.222 if (status==0)
69.223 return SOLVED;
70.1 --- a/lemon/cplex.h Mon Jan 12 23:11:39 2009 +0100
70.2 +++ b/lemon/cplex.h Thu Nov 05 15:48:01 2009 +0100
70.3 @@ -2,7 +2,7 @@
70.4 *
70.5 * This file is a part of LEMON, a generic C++ optimization library.
70.6 *
70.7 - * Copyright (C) 2003-2008
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 @@ -78,7 +78,7 @@
70.13 /// \brief Base interface for the CPLEX LP and MIP solver
70.14 ///
70.15 /// This class implements the common interface of the CPLEX LP and
70.16 - /// MIP solvers.
70.17 + /// MIP solvers.
70.18 /// \ingroup lp_group
70.19 class CplexBase : virtual public LpBase {
70.20 protected:
70.21 @@ -93,6 +93,7 @@
70.22
70.23 virtual int _addCol();
70.24 virtual int _addRow();
70.25 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
70.26
70.27 virtual void _eraseCol(int i);
70.28 virtual void _eraseRow(int i);
70.29 @@ -144,14 +145,29 @@
70.30
70.31 virtual void _clear();
70.32
70.33 + virtual void _messageLevel(MessageLevel level);
70.34 + void _applyMessageLevel();
70.35 +
70.36 + bool _message_enabled;
70.37 +
70.38 public:
70.39
70.40 /// Returns the used \c CplexEnv instance
70.41 const CplexEnv& env() const { return _env; }
70.42 +
70.43 + /// \brief Returns the const cpxenv pointer
70.44 ///
70.45 + /// \note The cpxenv might be destructed with the solver.
70.46 const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
70.47
70.48 + /// \brief Returns the const cpxenv pointer
70.49 + ///
70.50 + /// \note The cpxenv might be destructed with the solver.
70.51 + cpxenv* cplexEnv() { return _env.cplexEnv(); }
70.52 +
70.53 + /// Returns the cplex problem object
70.54 cpxlp* cplexLp() { return _prob; }
70.55 + /// Returns the cplex problem object
70.56 const cpxlp* cplexLp() const { return _prob; }
70.57
70.58 };
70.59 @@ -160,7 +176,7 @@
70.60 ///
70.61 /// This class implements an interface for the CPLEX LP solver.
70.62 ///\ingroup lp_group
70.63 - class CplexLp : public CplexBase, public LpSolver {
70.64 + class CplexLp : public LpSolver, public CplexBase {
70.65 public:
70.66 /// \e
70.67 CplexLp();
70.68 @@ -171,6 +187,11 @@
70.69 /// \e
70.70 virtual ~CplexLp();
70.71
70.72 + /// \e
70.73 + virtual CplexLp* cloneSolver() const;
70.74 + /// \e
70.75 + virtual CplexLp* newSolver() const;
70.76 +
70.77 private:
70.78
70.79 // these values cannot retrieved element by element
70.80 @@ -186,9 +207,6 @@
70.81
70.82 protected:
70.83
70.84 - virtual CplexLp* _cloneSolver() const;
70.85 - virtual CplexLp* _newSolver() const;
70.86 -
70.87 virtual const char* _solverName() const;
70.88
70.89 virtual SolveExitStatus _solve();
70.90 @@ -222,7 +240,7 @@
70.91 ///
70.92 /// This class implements an interface for the CPLEX MIP solver.
70.93 ///\ingroup lp_group
70.94 - class CplexMip : public CplexBase, public MipSolver {
70.95 + class CplexMip : public MipSolver, public CplexBase {
70.96 public:
70.97 /// \e
70.98 CplexMip();
70.99 @@ -233,10 +251,13 @@
70.100 /// \e
70.101 virtual ~CplexMip();
70.102
70.103 + /// \e
70.104 + virtual CplexMip* cloneSolver() const;
70.105 + /// \e
70.106 + virtual CplexMip* newSolver() const;
70.107 +
70.108 protected:
70.109
70.110 - virtual CplexMip* _cloneSolver() const;
70.111 - virtual CplexMip* _newSolver() const;
70.112
70.113 virtual const char* _solverName() const;
70.114
71.1 --- a/lemon/dfs.h Mon Jan 12 23:11:39 2009 +0100
71.2 +++ b/lemon/dfs.h Thu Nov 05 15:48:01 2009 +0100
71.3 @@ -47,13 +47,13 @@
71.4 ///
71.5 ///The type of the map that stores the predecessor
71.6 ///arcs of the %DFS paths.
71.7 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
71.8 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
71.9 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
71.10 - ///Instantiates a PredMap.
71.11 + ///Instantiates a \c PredMap.
71.12
71.13 - ///This function instantiates a PredMap.
71.14 + ///This function instantiates a \ref PredMap.
71.15 ///\param g is the digraph, to which we would like to define the
71.16 - ///PredMap.
71.17 + ///\ref PredMap.
71.18 static PredMap *createPredMap(const Digraph &g)
71.19 {
71.20 return new PredMap(g);
71.21 @@ -62,13 +62,14 @@
71.22 ///The type of the map that indicates which nodes are processed.
71.23
71.24 ///The type of the map that indicates which nodes are processed.
71.25 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
71.26 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
71.27 + ///By default it is a NullMap.
71.28 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
71.29 - ///Instantiates a ProcessedMap.
71.30 + ///Instantiates a \c ProcessedMap.
71.31
71.32 - ///This function instantiates a ProcessedMap.
71.33 + ///This function instantiates a \ref ProcessedMap.
71.34 ///\param g is the digraph, to which
71.35 - ///we would like to define the ProcessedMap
71.36 + ///we would like to define the \ref ProcessedMap.
71.37 #ifdef DOXYGEN
71.38 static ProcessedMap *createProcessedMap(const Digraph &g)
71.39 #else
71.40 @@ -81,13 +82,13 @@
71.41 ///The type of the map that indicates which nodes are reached.
71.42
71.43 ///The type of the map that indicates which nodes are reached.
71.44 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
71.45 + ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
71.46 typedef typename Digraph::template NodeMap<bool> ReachedMap;
71.47 - ///Instantiates a ReachedMap.
71.48 + ///Instantiates a \c ReachedMap.
71.49
71.50 - ///This function instantiates a ReachedMap.
71.51 + ///This function instantiates a \ref ReachedMap.
71.52 ///\param g is the digraph, to which
71.53 - ///we would like to define the ReachedMap.
71.54 + ///we would like to define the \ref ReachedMap.
71.55 static ReachedMap *createReachedMap(const Digraph &g)
71.56 {
71.57 return new ReachedMap(g);
71.58 @@ -96,13 +97,13 @@
71.59 ///The type of the map that stores the distances of the nodes.
71.60
71.61 ///The type of the map that stores the distances of the nodes.
71.62 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
71.63 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
71.64 typedef typename Digraph::template NodeMap<int> DistMap;
71.65 - ///Instantiates a DistMap.
71.66 + ///Instantiates a \c DistMap.
71.67
71.68 - ///This function instantiates a DistMap.
71.69 + ///This function instantiates a \ref DistMap.
71.70 ///\param g is the digraph, to which we would like to define the
71.71 - ///DistMap.
71.72 + ///\ref DistMap.
71.73 static DistMap *createDistMap(const Digraph &g)
71.74 {
71.75 return new DistMap(g);
71.76 @@ -206,7 +207,7 @@
71.77
71.78 typedef Dfs Create;
71.79
71.80 - ///\name Named template parameters
71.81 + ///\name Named Template Parameters
71.82
71.83 ///@{
71.84
71.85 @@ -220,11 +221,11 @@
71.86 }
71.87 };
71.88 ///\brief \ref named-templ-param "Named parameter" for setting
71.89 - ///PredMap type.
71.90 + ///\c PredMap type.
71.91 ///
71.92 ///\ref named-templ-param "Named parameter" for setting
71.93 - ///PredMap type.
71.94 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
71.95 + ///\c PredMap type.
71.96 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
71.97 template <class T>
71.98 struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
71.99 typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
71.100 @@ -240,11 +241,11 @@
71.101 }
71.102 };
71.103 ///\brief \ref named-templ-param "Named parameter" for setting
71.104 - ///DistMap type.
71.105 + ///\c DistMap type.
71.106 ///
71.107 ///\ref named-templ-param "Named parameter" for setting
71.108 - ///DistMap type.
71.109 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
71.110 + ///\c DistMap type.
71.111 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
71.112 template <class T>
71.113 struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
71.114 typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
71.115 @@ -260,11 +261,11 @@
71.116 }
71.117 };
71.118 ///\brief \ref named-templ-param "Named parameter" for setting
71.119 - ///ReachedMap type.
71.120 + ///\c ReachedMap type.
71.121 ///
71.122 ///\ref named-templ-param "Named parameter" for setting
71.123 - ///ReachedMap type.
71.124 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
71.125 + ///\c ReachedMap type.
71.126 + ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
71.127 template <class T>
71.128 struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
71.129 typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
71.130 @@ -280,11 +281,11 @@
71.131 }
71.132 };
71.133 ///\brief \ref named-templ-param "Named parameter" for setting
71.134 - ///ProcessedMap type.
71.135 + ///\c ProcessedMap type.
71.136 ///
71.137 ///\ref named-templ-param "Named parameter" for setting
71.138 - ///ProcessedMap type.
71.139 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
71.140 + ///\c ProcessedMap type.
71.141 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
71.142 template <class T>
71.143 struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
71.144 typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
71.145 @@ -298,10 +299,10 @@
71.146 }
71.147 };
71.148 ///\brief \ref named-templ-param "Named parameter" for setting
71.149 - ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
71.150 + ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
71.151 ///
71.152 ///\ref named-templ-param "Named parameter" for setting
71.153 - ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
71.154 + ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
71.155 ///If you don't set it explicitly, it will be automatically allocated.
71.156 struct SetStandardProcessedMap :
71.157 public Dfs< Digraph, SetStandardProcessedMapTraits > {
71.158 @@ -411,8 +412,8 @@
71.159 ///\name Execution Control
71.160 ///The simplest way to execute the DFS algorithm is to use one of the
71.161 ///member functions called \ref run(Node) "run()".\n
71.162 - ///If you need more control on the execution, first you have to call
71.163 - ///\ref init(), then you can add a source node with \ref addSource()
71.164 + ///If you need better control on the execution, you have to call
71.165 + ///\ref init() first, then you can add a source node with \ref addSource()
71.166 ///and perform the actual computation with \ref start().
71.167 ///This procedure can be repeated if there are nodes that have not
71.168 ///been reached.
71.169 @@ -669,9 +670,9 @@
71.170
71.171 ///@{
71.172
71.173 - ///The DFS path to a node.
71.174 + ///The DFS path to the given node.
71.175
71.176 - ///Returns the DFS path to a node.
71.177 + ///Returns the DFS path to the given node from the root(s).
71.178 ///
71.179 ///\warning \c t should be reached from the root(s).
71.180 ///
71.181 @@ -679,9 +680,9 @@
71.182 ///must be called before using this function.
71.183 Path path(Node t) const { return Path(*G, *_pred, t); }
71.184
71.185 - ///The distance of a node from the root(s).
71.186 + ///The distance of the given node from the root(s).
71.187
71.188 - ///Returns the distance of a node from the root(s).
71.189 + ///Returns the distance of the given node from the root(s).
71.190 ///
71.191 ///\warning If node \c v is not reached from the root(s), then
71.192 ///the return value of this function is undefined.
71.193 @@ -690,7 +691,7 @@
71.194 ///must be called before using this function.
71.195 int dist(Node v) const { return (*_dist)[v]; }
71.196
71.197 - ///Returns the 'previous arc' of the %DFS tree for a node.
71.198 + ///Returns the 'previous arc' of the %DFS tree for the given node.
71.199
71.200 ///This function returns the 'previous arc' of the %DFS tree for the
71.201 ///node \c v, i.e. it returns the last arc of a %DFS path from a
71.202 @@ -698,21 +699,21 @@
71.203 ///root(s) or if \c v is a root.
71.204 ///
71.205 ///The %DFS tree used here is equal to the %DFS tree used in
71.206 - ///\ref predNode().
71.207 + ///\ref predNode() and \ref predMap().
71.208 ///
71.209 ///\pre Either \ref run(Node) "run()" or \ref init()
71.210 ///must be called before using this function.
71.211 Arc predArc(Node v) const { return (*_pred)[v];}
71.212
71.213 - ///Returns the 'previous node' of the %DFS tree.
71.214 + ///Returns the 'previous node' of the %DFS tree for the given node.
71.215
71.216 ///This function returns the 'previous node' of the %DFS
71.217 ///tree for the node \c v, i.e. it returns the last but one node
71.218 - ///from a %DFS path from a root to \c v. It is \c INVALID
71.219 + ///of a %DFS path from a root to \c v. It is \c INVALID
71.220 ///if \c v is not reached from the root(s) or if \c v is a root.
71.221 ///
71.222 ///The %DFS tree used here is equal to the %DFS tree used in
71.223 - ///\ref predArc().
71.224 + ///\ref predArc() and \ref predMap().
71.225 ///
71.226 ///\pre Either \ref run(Node) "run()" or \ref init()
71.227 ///must be called before using this function.
71.228 @@ -733,13 +734,13 @@
71.229 ///predecessor arcs.
71.230 ///
71.231 ///Returns a const reference to the node map that stores the predecessor
71.232 - ///arcs, which form the DFS tree.
71.233 + ///arcs, which form the DFS tree (forest).
71.234 ///
71.235 ///\pre Either \ref run(Node) "run()" or \ref init()
71.236 ///must be called before using this function.
71.237 const PredMap &predMap() const { return *_pred;}
71.238
71.239 - ///Checks if a node is reached from the root(s).
71.240 + ///Checks if the given node. node is reached from the root(s).
71.241
71.242 ///Returns \c true if \c v is reached from the root(s).
71.243 ///
71.244 @@ -765,7 +766,7 @@
71.245 ///
71.246 ///The type of the map that stores the predecessor
71.247 ///arcs of the %DFS paths.
71.248 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
71.249 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
71.250 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
71.251 ///Instantiates a PredMap.
71.252
71.253 @@ -780,7 +781,7 @@
71.254 ///The type of the map that indicates which nodes are processed.
71.255
71.256 ///The type of the map that indicates which nodes are processed.
71.257 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
71.258 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
71.259 ///By default it is a NullMap.
71.260 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
71.261 ///Instantiates a ProcessedMap.
71.262 @@ -800,7 +801,7 @@
71.263 ///The type of the map that indicates which nodes are reached.
71.264
71.265 ///The type of the map that indicates which nodes are reached.
71.266 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
71.267 + ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
71.268 typedef typename Digraph::template NodeMap<bool> ReachedMap;
71.269 ///Instantiates a ReachedMap.
71.270
71.271 @@ -815,7 +816,7 @@
71.272 ///The type of the map that stores the distances of the nodes.
71.273
71.274 ///The type of the map that stores the distances of the nodes.
71.275 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
71.276 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
71.277 typedef typename Digraph::template NodeMap<int> DistMap;
71.278 ///Instantiates a DistMap.
71.279
71.280 @@ -830,18 +831,14 @@
71.281 ///The type of the DFS paths.
71.282
71.283 ///The type of the DFS paths.
71.284 - ///It must meet the \ref concepts::Path "Path" concept.
71.285 + ///It must conform to the \ref concepts::Path "Path" concept.
71.286 typedef lemon::Path<Digraph> Path;
71.287 };
71.288
71.289 /// Default traits class used by DfsWizard
71.290
71.291 - /// To make it easier to use Dfs algorithm
71.292 - /// we have created a wizard class.
71.293 - /// This \ref DfsWizard class needs default traits,
71.294 - /// as well as the \ref Dfs class.
71.295 - /// The \ref DfsWizardBase is a class to be the default traits of the
71.296 - /// \ref DfsWizard class.
71.297 + /// Default traits class used by DfsWizard.
71.298 + /// \tparam GR The type of the digraph.
71.299 template<class GR>
71.300 class DfsWizardBase : public DfsWizardDefaultTraits<GR>
71.301 {
71.302 @@ -869,7 +866,7 @@
71.303 public:
71.304 /// Constructor.
71.305
71.306 - /// This constructor does not require parameters, therefore it initiates
71.307 + /// This constructor does not require parameters, it initiates
71.308 /// all of the attributes to \c 0.
71.309 DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
71.310 _dist(0), _path(0), _di(0) {}
71.311 @@ -899,7 +896,6 @@
71.312 {
71.313 typedef TR Base;
71.314
71.315 - ///The type of the digraph the algorithm runs on.
71.316 typedef typename TR::Digraph Digraph;
71.317
71.318 typedef typename Digraph::Node Node;
71.319 @@ -907,16 +903,10 @@
71.320 typedef typename Digraph::Arc Arc;
71.321 typedef typename Digraph::OutArcIt OutArcIt;
71.322
71.323 - ///\brief The type of the map that stores the predecessor
71.324 - ///arcs of the DFS paths.
71.325 typedef typename TR::PredMap PredMap;
71.326 - ///\brief The type of the map that stores the distances of the nodes.
71.327 typedef typename TR::DistMap DistMap;
71.328 - ///\brief The type of the map that indicates which nodes are reached.
71.329 typedef typename TR::ReachedMap ReachedMap;
71.330 - ///\brief The type of the map that indicates which nodes are processed.
71.331 typedef typename TR::ProcessedMap ProcessedMap;
71.332 - ///The type of the DFS paths
71.333 typedef typename TR::Path Path;
71.334
71.335 public:
71.336 @@ -999,11 +989,12 @@
71.337 static PredMap *createPredMap(const Digraph &) { return 0; };
71.338 SetPredMapBase(const TR &b) : TR(b) {}
71.339 };
71.340 - ///\brief \ref named-func-param "Named parameter"
71.341 - ///for setting PredMap object.
71.342 +
71.343 + ///\brief \ref named-templ-param "Named parameter" for setting
71.344 + ///the predecessor map.
71.345 ///
71.346 - ///\ref named-func-param "Named parameter"
71.347 - ///for setting PredMap object.
71.348 + ///\ref named-templ-param "Named parameter" function for setting
71.349 + ///the map that stores the predecessor arcs of the nodes.
71.350 template<class T>
71.351 DfsWizard<SetPredMapBase<T> > predMap(const T &t)
71.352 {
71.353 @@ -1017,11 +1008,12 @@
71.354 static ReachedMap *createReachedMap(const Digraph &) { return 0; };
71.355 SetReachedMapBase(const TR &b) : TR(b) {}
71.356 };
71.357 - ///\brief \ref named-func-param "Named parameter"
71.358 - ///for setting ReachedMap object.
71.359 +
71.360 + ///\brief \ref named-templ-param "Named parameter" for setting
71.361 + ///the reached map.
71.362 ///
71.363 - /// \ref named-func-param "Named parameter"
71.364 - ///for setting ReachedMap object.
71.365 + ///\ref named-templ-param "Named parameter" function for setting
71.366 + ///the map that indicates which nodes are reached.
71.367 template<class T>
71.368 DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
71.369 {
71.370 @@ -1035,11 +1027,13 @@
71.371 static DistMap *createDistMap(const Digraph &) { return 0; };
71.372 SetDistMapBase(const TR &b) : TR(b) {}
71.373 };
71.374 - ///\brief \ref named-func-param "Named parameter"
71.375 - ///for setting DistMap object.
71.376 +
71.377 + ///\brief \ref named-templ-param "Named parameter" for setting
71.378 + ///the distance map.
71.379 ///
71.380 - /// \ref named-func-param "Named parameter"
71.381 - ///for setting DistMap object.
71.382 + ///\ref named-templ-param "Named parameter" function for setting
71.383 + ///the map that stores the distances of the nodes calculated
71.384 + ///by the algorithm.
71.385 template<class T>
71.386 DfsWizard<SetDistMapBase<T> > distMap(const T &t)
71.387 {
71.388 @@ -1053,11 +1047,12 @@
71.389 static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
71.390 SetProcessedMapBase(const TR &b) : TR(b) {}
71.391 };
71.392 - ///\brief \ref named-func-param "Named parameter"
71.393 - ///for setting ProcessedMap object.
71.394 +
71.395 + ///\brief \ref named-func-param "Named parameter" for setting
71.396 + ///the processed map.
71.397 ///
71.398 - /// \ref named-func-param "Named parameter"
71.399 - ///for setting ProcessedMap object.
71.400 + ///\ref named-templ-param "Named parameter" function for setting
71.401 + ///the map that indicates which nodes are processed.
71.402 template<class T>
71.403 DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
71.404 {
71.405 @@ -1126,9 +1121,9 @@
71.406 ///
71.407 /// This class defines the interface of the DfsVisit events, and
71.408 /// it could be the base of a real visitor class.
71.409 - template <typename _Digraph>
71.410 + template <typename GR>
71.411 struct DfsVisitor {
71.412 - typedef _Digraph Digraph;
71.413 + typedef GR Digraph;
71.414 typedef typename Digraph::Arc Arc;
71.415 typedef typename Digraph::Node Node;
71.416 /// \brief Called for the source node of the DFS.
71.417 @@ -1164,9 +1159,9 @@
71.418 void backtrack(const Arc& arc) {}
71.419 };
71.420 #else
71.421 - template <typename _Digraph>
71.422 + template <typename GR>
71.423 struct DfsVisitor {
71.424 - typedef _Digraph Digraph;
71.425 + typedef GR Digraph;
71.426 typedef typename Digraph::Arc Arc;
71.427 typedef typename Digraph::Node Node;
71.428 void start(const Node&) {}
71.429 @@ -1199,16 +1194,16 @@
71.430 ///
71.431 /// Default traits class of DfsVisit class.
71.432 /// \tparam _Digraph The type of the digraph the algorithm runs on.
71.433 - template<class _Digraph>
71.434 + template<class GR>
71.435 struct DfsVisitDefaultTraits {
71.436
71.437 /// \brief The type of the digraph the algorithm runs on.
71.438 - typedef _Digraph Digraph;
71.439 + typedef GR Digraph;
71.440
71.441 /// \brief The type of the map that indicates which nodes are reached.
71.442 ///
71.443 /// The type of the map that indicates which nodes are reached.
71.444 - /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
71.445 + /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
71.446 typedef typename Digraph::template NodeMap<bool> ReachedMap;
71.447
71.448 /// \brief Instantiates a ReachedMap.
71.449 @@ -1224,12 +1219,12 @@
71.450
71.451 /// \ingroup search
71.452 ///
71.453 - /// \brief %DFS algorithm class with visitor interface.
71.454 + /// \brief DFS algorithm class with visitor interface.
71.455 ///
71.456 - /// This class provides an efficient implementation of the %DFS algorithm
71.457 + /// This class provides an efficient implementation of the DFS algorithm
71.458 /// with visitor interface.
71.459 ///
71.460 - /// The %DfsVisit class provides an alternative interface to the Dfs
71.461 + /// The DfsVisit class provides an alternative interface to the Dfs
71.462 /// class. It works with callback mechanism, the DfsVisit object calls
71.463 /// the member functions of the \c Visitor class on every DFS event.
71.464 ///
71.465 @@ -1238,37 +1233,37 @@
71.466 /// events of the DFS algorithm. Otherwise consider to use Dfs or dfs()
71.467 /// instead.
71.468 ///
71.469 - /// \tparam _Digraph The type of the digraph the algorithm runs on.
71.470 - /// The default value is
71.471 - /// \ref ListDigraph. The value of _Digraph is not used directly by
71.472 - /// \ref DfsVisit, it is only passed to \ref DfsVisitDefaultTraits.
71.473 - /// \tparam _Visitor The Visitor type that is used by the algorithm.
71.474 - /// \ref DfsVisitor "DfsVisitor<_Digraph>" is an empty visitor, which
71.475 + /// \tparam GR The type of the digraph the algorithm runs on.
71.476 + /// The default type is \ref ListDigraph.
71.477 + /// The value of GR is not used directly by \ref DfsVisit,
71.478 + /// it is only passed to \ref DfsVisitDefaultTraits.
71.479 + /// \tparam VS The Visitor type that is used by the algorithm.
71.480 + /// \ref DfsVisitor "DfsVisitor<GR>" is an empty visitor, which
71.481 /// does not observe the DFS events. If you want to observe the DFS
71.482 /// events, you should implement your own visitor class.
71.483 - /// \tparam _Traits Traits class to set various data types used by the
71.484 + /// \tparam TR Traits class to set various data types used by the
71.485 /// algorithm. The default traits class is
71.486 - /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<_Digraph>".
71.487 + /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<GR>".
71.488 /// See \ref DfsVisitDefaultTraits for the documentation of
71.489 /// a DFS visit traits class.
71.490 #ifdef DOXYGEN
71.491 - template <typename _Digraph, typename _Visitor, typename _Traits>
71.492 + template <typename GR, typename VS, typename TR>
71.493 #else
71.494 - template <typename _Digraph = ListDigraph,
71.495 - typename _Visitor = DfsVisitor<_Digraph>,
71.496 - typename _Traits = DfsVisitDefaultTraits<_Digraph> >
71.497 + template <typename GR = ListDigraph,
71.498 + typename VS = DfsVisitor<GR>,
71.499 + typename TR = DfsVisitDefaultTraits<GR> >
71.500 #endif
71.501 class DfsVisit {
71.502 public:
71.503
71.504 ///The traits class.
71.505 - typedef _Traits Traits;
71.506 + typedef TR Traits;
71.507
71.508 ///The type of the digraph the algorithm runs on.
71.509 typedef typename Traits::Digraph Digraph;
71.510
71.511 ///The visitor type used by the algorithm.
71.512 - typedef _Visitor Visitor;
71.513 + typedef VS Visitor;
71.514
71.515 ///The type of the map that indicates which nodes are reached.
71.516 typedef typename Traits::ReachedMap ReachedMap;
71.517 @@ -1369,8 +1364,8 @@
71.518 /// \name Execution Control
71.519 /// The simplest way to execute the DFS algorithm is to use one of the
71.520 /// member functions called \ref run(Node) "run()".\n
71.521 - /// If you need more control on the execution, first you have to call
71.522 - /// \ref init(), then you can add a source node with \ref addSource()
71.523 + /// If you need better control on the execution, you have to call
71.524 + /// \ref init() first, then you can add a source node with \ref addSource()
71.525 /// and perform the actual computation with \ref start().
71.526 /// This procedure can be repeated if there are nodes that have not
71.527 /// been reached.
71.528 @@ -1620,7 +1615,7 @@
71.529
71.530 ///@{
71.531
71.532 - /// \brief Checks if a node is reached from the root(s).
71.533 + /// \brief Checks if the given node is reached from the root(s).
71.534 ///
71.535 /// Returns \c true if \c v is reached from the root(s).
71.536 ///
72.1 --- a/lemon/dijkstra.h Mon Jan 12 23:11:39 2009 +0100
72.2 +++ b/lemon/dijkstra.h Thu Nov 05 15:48:01 2009 +0100
72.3 @@ -38,8 +38,10 @@
72.4 ///
72.5 /// This operation traits class defines all computational operations and
72.6 /// constants which are used in the Dijkstra algorithm.
72.7 - template <typename Value>
72.8 + template <typename V>
72.9 struct DijkstraDefaultOperationTraits {
72.10 + /// \e
72.11 + typedef V Value;
72.12 /// \brief Gives back the zero value of the type.
72.13 static Value zero() {
72.14 return static_cast<Value>(0);
72.15 @@ -58,8 +60,8 @@
72.16
72.17 ///Default traits class of Dijkstra class.
72.18 ///\tparam GR The type of the digraph.
72.19 - ///\tparam LM The type of the length map.
72.20 - template<class GR, class LM>
72.21 + ///\tparam LEN The type of the length map.
72.22 + template<typename GR, typename LEN>
72.23 struct DijkstraDefaultTraits
72.24 {
72.25 ///The type of the digraph the algorithm runs on.
72.26 @@ -68,12 +70,12 @@
72.27 ///The type of the map that stores the arc lengths.
72.28
72.29 ///The type of the map that stores the arc lengths.
72.30 - ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
72.31 - typedef LM LengthMap;
72.32 - ///The type of the length of the arcs.
72.33 - typedef typename LM::Value Value;
72.34 + ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
72.35 + typedef LEN LengthMap;
72.36 + ///The type of the arc lengths.
72.37 + typedef typename LEN::Value Value;
72.38
72.39 - /// Operation traits for Dijkstra algorithm.
72.40 + /// Operation traits for %Dijkstra algorithm.
72.41
72.42 /// This class defines the operations that are used in the algorithm.
72.43 /// \see DijkstraDefaultOperationTraits
72.44 @@ -84,7 +86,7 @@
72.45 /// The cross reference type used by the heap.
72.46 /// Usually it is \c Digraph::NodeMap<int>.
72.47 typedef typename Digraph::template NodeMap<int> HeapCrossRef;
72.48 - ///Instantiates a \ref HeapCrossRef.
72.49 + ///Instantiates a \c HeapCrossRef.
72.50
72.51 ///This function instantiates a \ref HeapCrossRef.
72.52 /// \param g is the digraph, to which we would like to define the
72.53 @@ -94,14 +96,14 @@
72.54 return new HeapCrossRef(g);
72.55 }
72.56
72.57 - ///The heap type used by the Dijkstra algorithm.
72.58 + ///The heap type used by the %Dijkstra algorithm.
72.59
72.60 ///The heap type used by the Dijkstra algorithm.
72.61 ///
72.62 ///\sa BinHeap
72.63 ///\sa Dijkstra
72.64 - typedef BinHeap<typename LM::Value, HeapCrossRef, std::less<Value> > Heap;
72.65 - ///Instantiates a \ref Heap.
72.66 + typedef BinHeap<typename LEN::Value, HeapCrossRef, std::less<Value> > Heap;
72.67 + ///Instantiates a \c Heap.
72.68
72.69 ///This function instantiates a \ref Heap.
72.70 static Heap *createHeap(HeapCrossRef& r)
72.71 @@ -114,13 +116,13 @@
72.72 ///
72.73 ///The type of the map that stores the predecessor
72.74 ///arcs of the shortest paths.
72.75 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
72.76 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
72.77 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
72.78 - ///Instantiates a PredMap.
72.79 + ///Instantiates a \c PredMap.
72.80
72.81 - ///This function instantiates a PredMap.
72.82 + ///This function instantiates a \ref PredMap.
72.83 ///\param g is the digraph, to which we would like to define the
72.84 - ///PredMap.
72.85 + ///\ref PredMap.
72.86 static PredMap *createPredMap(const Digraph &g)
72.87 {
72.88 return new PredMap(g);
72.89 @@ -129,14 +131,14 @@
72.90 ///The type of the map that indicates which nodes are processed.
72.91
72.92 ///The type of the map that indicates which nodes are processed.
72.93 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
72.94 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
72.95 ///By default it is a NullMap.
72.96 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
72.97 - ///Instantiates a ProcessedMap.
72.98 + ///Instantiates a \c ProcessedMap.
72.99
72.100 - ///This function instantiates a ProcessedMap.
72.101 + ///This function instantiates a \ref ProcessedMap.
72.102 ///\param g is the digraph, to which
72.103 - ///we would like to define the ProcessedMap
72.104 + ///we would like to define the \ref ProcessedMap.
72.105 #ifdef DOXYGEN
72.106 static ProcessedMap *createProcessedMap(const Digraph &g)
72.107 #else
72.108 @@ -149,13 +151,13 @@
72.109 ///The type of the map that stores the distances of the nodes.
72.110
72.111 ///The type of the map that stores the distances of the nodes.
72.112 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
72.113 - typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
72.114 - ///Instantiates a DistMap.
72.115 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
72.116 + typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
72.117 + ///Instantiates a \c DistMap.
72.118
72.119 - ///This function instantiates a DistMap.
72.120 + ///This function instantiates a \ref DistMap.
72.121 ///\param g is the digraph, to which we would like to define
72.122 - ///the DistMap
72.123 + ///the \ref DistMap.
72.124 static DistMap *createDistMap(const Digraph &g)
72.125 {
72.126 return new DistMap(g);
72.127 @@ -167,6 +169,10 @@
72.128 /// \ingroup shortest_path
72.129 ///This class provides an efficient implementation of the %Dijkstra algorithm.
72.130 ///
72.131 + ///The %Dijkstra algorithm solves the single-source shortest path problem
72.132 + ///when all arc lengths are non-negative. If there are negative lengths,
72.133 + ///the BellmanFord algorithm should be used instead.
72.134 + ///
72.135 ///The arc lengths are passed to the algorithm using a
72.136 ///\ref concepts::ReadMap "ReadMap",
72.137 ///so it is easy to change it to any kind of length.
72.138 @@ -180,18 +186,18 @@
72.139 ///
72.140 ///\tparam GR The type of the digraph the algorithm runs on.
72.141 ///The default type is \ref ListDigraph.
72.142 - ///\tparam LM A \ref concepts::ReadMap "readable" arc map that specifies
72.143 + ///\tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
72.144 ///the lengths of the arcs.
72.145 ///It is read once for each arc, so the map may involve in
72.146 ///relatively time consuming process to compute the arc lengths if
72.147 ///it is necessary. The default map type is \ref
72.148 ///concepts::Digraph::ArcMap "GR::ArcMap<int>".
72.149 #ifdef DOXYGEN
72.150 - template <typename GR, typename LM, typename TR>
72.151 + template <typename GR, typename LEN, typename TR>
72.152 #else
72.153 template <typename GR=ListDigraph,
72.154 - typename LM=typename GR::template ArcMap<int>,
72.155 - typename TR=DijkstraDefaultTraits<GR,LM> >
72.156 + typename LEN=typename GR::template ArcMap<int>,
72.157 + typename TR=DijkstraDefaultTraits<GR,LEN> >
72.158 #endif
72.159 class Dijkstra {
72.160 public:
72.161 @@ -199,7 +205,7 @@
72.162 ///The type of the digraph the algorithm runs on.
72.163 typedef typename TR::Digraph Digraph;
72.164
72.165 - ///The type of the length of the arcs.
72.166 + ///The type of the arc lengths.
72.167 typedef typename TR::LengthMap::Value Value;
72.168 ///The type of the map that stores the arc lengths.
72.169 typedef typename TR::LengthMap LengthMap;
72.170 @@ -216,7 +222,8 @@
72.171 typedef typename TR::HeapCrossRef HeapCrossRef;
72.172 ///The heap type used by the algorithm.
72.173 typedef typename TR::Heap Heap;
72.174 - ///The operation traits class.
72.175 + ///\brief The \ref DijkstraDefaultOperationTraits "operation traits class"
72.176 + ///of the algorithm.
72.177 typedef typename TR::OperationTraits OperationTraits;
72.178
72.179 ///The \ref DijkstraDefaultTraits "traits class" of the algorithm.
72.180 @@ -232,7 +239,7 @@
72.181 //Pointer to the underlying digraph.
72.182 const Digraph *G;
72.183 //Pointer to the length map.
72.184 - const LengthMap *length;
72.185 + const LengthMap *_length;
72.186 //Pointer to the map of predecessors arcs.
72.187 PredMap *_pred;
72.188 //Indicates if _pred is locally allocated (true) or not.
72.189 @@ -283,7 +290,7 @@
72.190
72.191 typedef Dijkstra Create;
72.192
72.193 - ///\name Named template parameters
72.194 + ///\name Named Template Parameters
72.195
72.196 ///@{
72.197
72.198 @@ -297,11 +304,11 @@
72.199 }
72.200 };
72.201 ///\brief \ref named-templ-param "Named parameter" for setting
72.202 - ///PredMap type.
72.203 + ///\c PredMap type.
72.204 ///
72.205 ///\ref named-templ-param "Named parameter" for setting
72.206 - ///PredMap type.
72.207 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
72.208 + ///\c PredMap type.
72.209 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
72.210 template <class T>
72.211 struct SetPredMap
72.212 : public Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > {
72.213 @@ -318,11 +325,11 @@
72.214 }
72.215 };
72.216 ///\brief \ref named-templ-param "Named parameter" for setting
72.217 - ///DistMap type.
72.218 + ///\c DistMap type.
72.219 ///
72.220 ///\ref named-templ-param "Named parameter" for setting
72.221 - ///DistMap type.
72.222 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
72.223 + ///\c DistMap type.
72.224 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
72.225 template <class T>
72.226 struct SetDistMap
72.227 : public Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > {
72.228 @@ -339,11 +346,11 @@
72.229 }
72.230 };
72.231 ///\brief \ref named-templ-param "Named parameter" for setting
72.232 - ///ProcessedMap type.
72.233 + ///\c ProcessedMap type.
72.234 ///
72.235 ///\ref named-templ-param "Named parameter" for setting
72.236 - ///ProcessedMap type.
72.237 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
72.238 + ///\c ProcessedMap type.
72.239 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
72.240 template <class T>
72.241 struct SetProcessedMap
72.242 : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > {
72.243 @@ -358,10 +365,10 @@
72.244 }
72.245 };
72.246 ///\brief \ref named-templ-param "Named parameter" for setting
72.247 - ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
72.248 + ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
72.249 ///
72.250 ///\ref named-templ-param "Named parameter" for setting
72.251 - ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
72.252 + ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
72.253 ///If you don't set it explicitly, it will be automatically allocated.
72.254 struct SetStandardProcessedMap
72.255 : public Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits > {
72.256 @@ -439,7 +446,8 @@
72.257 ///\c OperationTraits type
72.258 ///
72.259 ///\ref named-templ-param "Named parameter" for setting
72.260 - ///\ref OperationTraits type.
72.261 + ///\c OperationTraits type.
72.262 + /// For more information see \ref DijkstraDefaultOperationTraits.
72.263 template <class T>
72.264 struct SetOperationTraits
72.265 : public Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> > {
72.266 @@ -458,10 +466,10 @@
72.267 ///Constructor.
72.268
72.269 ///Constructor.
72.270 - ///\param _g The digraph the algorithm runs on.
72.271 - ///\param _length The length map used by the algorithm.
72.272 - Dijkstra(const Digraph& _g, const LengthMap& _length) :
72.273 - G(&_g), length(&_length),
72.274 + ///\param g The digraph the algorithm runs on.
72.275 + ///\param length The length map used by the algorithm.
72.276 + Dijkstra(const Digraph& g, const LengthMap& length) :
72.277 + G(&g), _length(&length),
72.278 _pred(NULL), local_pred(false),
72.279 _dist(NULL), local_dist(false),
72.280 _processed(NULL), local_processed(false),
72.281 @@ -485,7 +493,7 @@
72.282 ///\return <tt> (*this) </tt>
72.283 Dijkstra &lengthMap(const LengthMap &m)
72.284 {
72.285 - length = &m;
72.286 + _length = &m;
72.287 return *this;
72.288 }
72.289
72.290 @@ -581,8 +589,8 @@
72.291 ///\name Execution Control
72.292 ///The simplest way to execute the %Dijkstra algorithm is to use
72.293 ///one of the member functions called \ref run(Node) "run()".\n
72.294 - ///If you need more control on the execution, first you have to call
72.295 - ///\ref init(), then you can add several source nodes with
72.296 + ///If you need better control on the execution, you have to call
72.297 + ///\ref init() first, then you can add several source nodes with
72.298 ///\ref addSource(). Finally the actual path computation can be
72.299 ///performed with one of the \ref start() functions.
72.300
72.301 @@ -638,12 +646,12 @@
72.302 Node w=G->target(e);
72.303 switch(_heap->state(w)) {
72.304 case Heap::PRE_HEAP:
72.305 - _heap->push(w,OperationTraits::plus(oldvalue, (*length)[e]));
72.306 + _heap->push(w,OperationTraits::plus(oldvalue, (*_length)[e]));
72.307 _pred->set(w,e);
72.308 break;
72.309 case Heap::IN_HEAP:
72.310 {
72.311 - Value newvalue = OperationTraits::plus(oldvalue, (*length)[e]);
72.312 + Value newvalue = OperationTraits::plus(oldvalue, (*_length)[e]);
72.313 if ( OperationTraits::less(newvalue, (*_heap)[w]) ) {
72.314 _heap->decrease(w, newvalue);
72.315 _pred->set(w,e);
72.316 @@ -798,14 +806,14 @@
72.317 ///\name Query Functions
72.318 ///The results of the %Dijkstra algorithm can be obtained using these
72.319 ///functions.\n
72.320 - ///Either \ref run(Node) "run()" or \ref start() should be called
72.321 + ///Either \ref run(Node) "run()" or \ref init() should be called
72.322 ///before using them.
72.323
72.324 ///@{
72.325
72.326 - ///The shortest path to a node.
72.327 + ///The shortest path to the given node.
72.328
72.329 - ///Returns the shortest path to a node.
72.330 + ///Returns the shortest path to the given node from the root(s).
72.331 ///
72.332 ///\warning \c t should be reached from the root(s).
72.333 ///
72.334 @@ -813,9 +821,9 @@
72.335 ///must be called before using this function.
72.336 Path path(Node t) const { return Path(*G, *_pred, t); }
72.337
72.338 - ///The distance of a node from the root(s).
72.339 + ///The distance of the given node from the root(s).
72.340
72.341 - ///Returns the distance of a node from the root(s).
72.342 + ///Returns the distance of the given node from the root(s).
72.343 ///
72.344 ///\warning If node \c v is not reached from the root(s), then
72.345 ///the return value of this function is undefined.
72.346 @@ -824,29 +832,31 @@
72.347 ///must be called before using this function.
72.348 Value dist(Node v) const { return (*_dist)[v]; }
72.349
72.350 - ///Returns the 'previous arc' of the shortest path tree for a node.
72.351 -
72.352 + ///\brief Returns the 'previous arc' of the shortest path tree for
72.353 + ///the given node.
72.354 + ///
72.355 ///This function returns the 'previous arc' of the shortest path
72.356 ///tree for the node \c v, i.e. it returns the last arc of a
72.357 ///shortest path from a root to \c v. It is \c INVALID if \c v
72.358 ///is not reached from the root(s) or if \c v is a root.
72.359 ///
72.360 ///The shortest path tree used here is equal to the shortest path
72.361 - ///tree used in \ref predNode().
72.362 + ///tree used in \ref predNode() and \ref predMap().
72.363 ///
72.364 ///\pre Either \ref run(Node) "run()" or \ref init()
72.365 ///must be called before using this function.
72.366 Arc predArc(Node v) const { return (*_pred)[v]; }
72.367
72.368 - ///Returns the 'previous node' of the shortest path tree for a node.
72.369 -
72.370 + ///\brief Returns the 'previous node' of the shortest path tree for
72.371 + ///the given node.
72.372 + ///
72.373 ///This function returns the 'previous node' of the shortest path
72.374 ///tree for the node \c v, i.e. it returns the last but one node
72.375 - ///from a shortest path from a root to \c v. It is \c INVALID
72.376 + ///of a shortest path from a root to \c v. It is \c INVALID
72.377 ///if \c v is not reached from the root(s) or if \c v is a root.
72.378 ///
72.379 ///The shortest path tree used here is equal to the shortest path
72.380 - ///tree used in \ref predArc().
72.381 + ///tree used in \ref predArc() and \ref predMap().
72.382 ///
72.383 ///\pre Either \ref run(Node) "run()" or \ref init()
72.384 ///must be called before using this function.
72.385 @@ -867,13 +877,13 @@
72.386 ///predecessor arcs.
72.387 ///
72.388 ///Returns a const reference to the node map that stores the predecessor
72.389 - ///arcs, which form the shortest path tree.
72.390 + ///arcs, which form the shortest path tree (forest).
72.391 ///
72.392 ///\pre Either \ref run(Node) "run()" or \ref init()
72.393 ///must be called before using this function.
72.394 const PredMap &predMap() const { return *_pred;}
72.395
72.396 - ///Checks if a node is reached from the root(s).
72.397 + ///Checks if the given node is reached from the root(s).
72.398
72.399 ///Returns \c true if \c v is reached from the root(s).
72.400 ///
72.401 @@ -892,9 +902,9 @@
72.402 bool processed(Node v) const { return (*_heap_cross_ref)[v] ==
72.403 Heap::POST_HEAP; }
72.404
72.405 - ///The current distance of a node from the root(s).
72.406 + ///The current distance of the given node from the root(s).
72.407
72.408 - ///Returns the current distance of a node from the root(s).
72.409 + ///Returns the current distance of the given node from the root(s).
72.410 ///It may be decreased in the following processes.
72.411 ///
72.412 ///\pre Either \ref run(Node) "run()" or \ref init()
72.413 @@ -912,8 +922,8 @@
72.414
72.415 ///Default traits class of dijkstra() function.
72.416 ///\tparam GR The type of the digraph.
72.417 - ///\tparam LM The type of the length map.
72.418 - template<class GR, class LM>
72.419 + ///\tparam LEN The type of the length map.
72.420 + template<class GR, class LEN>
72.421 struct DijkstraWizardDefaultTraits
72.422 {
72.423 ///The type of the digraph the algorithm runs on.
72.424 @@ -921,10 +931,10 @@
72.425 ///The type of the map that stores the arc lengths.
72.426
72.427 ///The type of the map that stores the arc lengths.
72.428 - ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
72.429 - typedef LM LengthMap;
72.430 - ///The type of the length of the arcs.
72.431 - typedef typename LM::Value Value;
72.432 + ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
72.433 + typedef LEN LengthMap;
72.434 + ///The type of the arc lengths.
72.435 + typedef typename LEN::Value Value;
72.436
72.437 /// Operation traits for Dijkstra algorithm.
72.438
72.439 @@ -970,7 +980,7 @@
72.440 ///
72.441 ///The type of the map that stores the predecessor
72.442 ///arcs of the shortest paths.
72.443 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
72.444 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
72.445 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
72.446 ///Instantiates a PredMap.
72.447
72.448 @@ -985,7 +995,7 @@
72.449 ///The type of the map that indicates which nodes are processed.
72.450
72.451 ///The type of the map that indicates which nodes are processed.
72.452 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
72.453 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
72.454 ///By default it is a NullMap.
72.455 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
72.456 ///Instantiates a ProcessedMap.
72.457 @@ -1005,8 +1015,8 @@
72.458 ///The type of the map that stores the distances of the nodes.
72.459
72.460 ///The type of the map that stores the distances of the nodes.
72.461 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
72.462 - typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
72.463 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
72.464 + typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
72.465 ///Instantiates a DistMap.
72.466
72.467 ///This function instantiates a DistMap.
72.468 @@ -1020,22 +1030,19 @@
72.469 ///The type of the shortest paths.
72.470
72.471 ///The type of the shortest paths.
72.472 - ///It must meet the \ref concepts::Path "Path" concept.
72.473 + ///It must conform to the \ref concepts::Path "Path" concept.
72.474 typedef lemon::Path<Digraph> Path;
72.475 };
72.476
72.477 /// Default traits class used by DijkstraWizard
72.478
72.479 - /// To make it easier to use Dijkstra algorithm
72.480 - /// we have created a wizard class.
72.481 - /// This \ref DijkstraWizard class needs default traits,
72.482 - /// as well as the \ref Dijkstra class.
72.483 - /// The \ref DijkstraWizardBase is a class to be the default traits of the
72.484 - /// \ref DijkstraWizard class.
72.485 - template<class GR,class LM>
72.486 - class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LM>
72.487 + /// Default traits class used by DijkstraWizard.
72.488 + /// \tparam GR The type of the digraph.
72.489 + /// \tparam LEN The type of the length map.
72.490 + template<typename GR, typename LEN>
72.491 + class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LEN>
72.492 {
72.493 - typedef DijkstraWizardDefaultTraits<GR,LM> Base;
72.494 + typedef DijkstraWizardDefaultTraits<GR,LEN> Base;
72.495 protected:
72.496 //The type of the nodes in the digraph.
72.497 typedef typename Base::Digraph::Node Node;
72.498 @@ -1069,9 +1076,9 @@
72.499 /// others are initiated to \c 0.
72.500 /// \param g The digraph the algorithm runs on.
72.501 /// \param l The length map.
72.502 - DijkstraWizardBase(const GR &g,const LM &l) :
72.503 + DijkstraWizardBase(const GR &g,const LEN &l) :
72.504 _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
72.505 - _length(reinterpret_cast<void*>(const_cast<LM*>(&l))),
72.506 + _length(reinterpret_cast<void*>(const_cast<LEN*>(&l))),
72.507 _processed(0), _pred(0), _dist(0), _path(0), _di(0) {}
72.508
72.509 };
72.510 @@ -1090,7 +1097,6 @@
72.511 {
72.512 typedef TR Base;
72.513
72.514 - ///The type of the digraph the algorithm runs on.
72.515 typedef typename TR::Digraph Digraph;
72.516
72.517 typedef typename Digraph::Node Node;
72.518 @@ -1098,20 +1104,12 @@
72.519 typedef typename Digraph::Arc Arc;
72.520 typedef typename Digraph::OutArcIt OutArcIt;
72.521
72.522 - ///The type of the map that stores the arc lengths.
72.523 typedef typename TR::LengthMap LengthMap;
72.524 - ///The type of the length of the arcs.
72.525 typedef typename LengthMap::Value Value;
72.526 - ///\brief The type of the map that stores the predecessor
72.527 - ///arcs of the shortest paths.
72.528 typedef typename TR::PredMap PredMap;
72.529 - ///The type of the map that stores the distances of the nodes.
72.530 typedef typename TR::DistMap DistMap;
72.531 - ///The type of the map that indicates which nodes are processed.
72.532 typedef typename TR::ProcessedMap ProcessedMap;
72.533 - ///The type of the shortest paths
72.534 typedef typename TR::Path Path;
72.535 - ///The heap type used by the dijkstra algorithm.
72.536 typedef typename TR::Heap Heap;
72.537
72.538 public:
72.539 @@ -1183,11 +1181,12 @@
72.540 static PredMap *createPredMap(const Digraph &) { return 0; };
72.541 SetPredMapBase(const TR &b) : TR(b) {}
72.542 };
72.543 - ///\brief \ref named-func-param "Named parameter"
72.544 - ///for setting PredMap object.
72.545 +
72.546 + ///\brief \ref named-templ-param "Named parameter" for setting
72.547 + ///the predecessor map.
72.548 ///
72.549 - ///\ref named-func-param "Named parameter"
72.550 - ///for setting PredMap object.
72.551 + ///\ref named-templ-param "Named parameter" function for setting
72.552 + ///the map that stores the predecessor arcs of the nodes.
72.553 template<class T>
72.554 DijkstraWizard<SetPredMapBase<T> > predMap(const T &t)
72.555 {
72.556 @@ -1201,11 +1200,13 @@
72.557 static DistMap *createDistMap(const Digraph &) { return 0; };
72.558 SetDistMapBase(const TR &b) : TR(b) {}
72.559 };
72.560 - ///\brief \ref named-func-param "Named parameter"
72.561 - ///for setting DistMap object.
72.562 +
72.563 + ///\brief \ref named-templ-param "Named parameter" for setting
72.564 + ///the distance map.
72.565 ///
72.566 - ///\ref named-func-param "Named parameter"
72.567 - ///for setting DistMap object.
72.568 + ///\ref named-templ-param "Named parameter" function for setting
72.569 + ///the map that stores the distances of the nodes calculated
72.570 + ///by the algorithm.
72.571 template<class T>
72.572 DijkstraWizard<SetDistMapBase<T> > distMap(const T &t)
72.573 {
72.574 @@ -1219,11 +1220,12 @@
72.575 static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
72.576 SetProcessedMapBase(const TR &b) : TR(b) {}
72.577 };
72.578 - ///\brief \ref named-func-param "Named parameter"
72.579 - ///for setting ProcessedMap object.
72.580 +
72.581 + ///\brief \ref named-func-param "Named parameter" for setting
72.582 + ///the processed map.
72.583 ///
72.584 - /// \ref named-func-param "Named parameter"
72.585 - ///for setting ProcessedMap object.
72.586 + ///\ref named-templ-param "Named parameter" function for setting
72.587 + ///the map that indicates which nodes are processed.
72.588 template<class T>
72.589 DijkstraWizard<SetProcessedMapBase<T> > processedMap(const T &t)
72.590 {
72.591 @@ -1236,6 +1238,7 @@
72.592 typedef T Path;
72.593 SetPathBase(const TR &b) : TR(b) {}
72.594 };
72.595 +
72.596 ///\brief \ref named-func-param "Named parameter"
72.597 ///for getting the shortest path to the target node.
72.598 ///
72.599 @@ -1280,11 +1283,11 @@
72.600 ///to the end of the parameter list.
72.601 ///\sa DijkstraWizard
72.602 ///\sa Dijkstra
72.603 - template<class GR, class LM>
72.604 - DijkstraWizard<DijkstraWizardBase<GR,LM> >
72.605 - dijkstra(const GR &digraph, const LM &length)
72.606 + template<typename GR, typename LEN>
72.607 + DijkstraWizard<DijkstraWizardBase<GR,LEN> >
72.608 + dijkstra(const GR &digraph, const LEN &length)
72.609 {
72.610 - return DijkstraWizard<DijkstraWizardBase<GR,LM> >(digraph,length);
72.611 + return DijkstraWizard<DijkstraWizardBase<GR,LEN> >(digraph,length);
72.612 }
72.613
72.614 } //END OF NAMESPACE LEMON
73.1 --- a/lemon/dim2.h Mon Jan 12 23:11:39 2009 +0100
73.2 +++ b/lemon/dim2.h Thu Nov 05 15:48:01 2009 +0100
73.3 @@ -21,16 +21,9 @@
73.4
73.5 #include <iostream>
73.6
73.7 -///\ingroup misc
73.8 +///\ingroup geomdat
73.9 ///\file
73.10 ///\brief A simple two dimensional vector and a bounding box implementation
73.11 -///
73.12 -/// The class \ref lemon::dim2::Point "dim2::Point" implements
73.13 -/// a two dimensional vector with the usual operations.
73.14 -///
73.15 -/// The class \ref lemon::dim2::Box "dim2::Box" can be used to determine
73.16 -/// the rectangular bounding box of a set of
73.17 -/// \ref lemon::dim2::Point "dim2::Point"'s.
73.18
73.19 namespace lemon {
73.20
73.21 @@ -40,7 +33,7 @@
73.22 ///tools for handling two dimensional coordinates
73.23 namespace dim2 {
73.24
73.25 - /// \addtogroup misc
73.26 + /// \addtogroup geomdat
73.27 /// @{
73.28
73.29 /// Two dimensional vector (plain vector)
74.1 --- a/lemon/dimacs.h Mon Jan 12 23:11:39 2009 +0100
74.2 +++ b/lemon/dimacs.h Thu Nov 05 15:48:01 2009 +0100
74.3 @@ -22,9 +22,9 @@
74.4 #include <iostream>
74.5 #include <string>
74.6 #include <vector>
74.7 +#include <limits>
74.8 #include <lemon/maps.h>
74.9 #include <lemon/error.h>
74.10 -
74.11 /// \ingroup dimacs_group
74.12 /// \file
74.13 /// \brief DIMACS file format reader.
74.14 @@ -37,11 +37,16 @@
74.15 /// DIMACS file type descriptor.
74.16 struct DimacsDescriptor
74.17 {
74.18 - ///File type enum
74.19 - enum Type
74.20 - {
74.21 - NONE, MIN, MAX, SP, MAT
74.22 - };
74.23 + ///\brief DIMACS file type enum
74.24 + ///
74.25 + ///DIMACS file type enum.
74.26 + enum Type {
74.27 + NONE, ///< Undefined type.
74.28 + MIN, ///< DIMACS file type for minimum cost flow problems.
74.29 + MAX, ///< DIMACS file type for maximum flow problems.
74.30 + SP, ///< DIMACS file type for shostest path problems.
74.31 + MAT ///< DIMACS file type for plain graphs and matching problems.
74.32 + };
74.33 ///The file type
74.34 Type type;
74.35 ///The number of nodes in the graph
74.36 @@ -49,16 +54,16 @@
74.37 ///The number of edges in the graph
74.38 int edgeNum;
74.39 int lineShift;
74.40 - /// Constructor. Sets the type to NONE.
74.41 + ///Constructor. It sets the type to \c NONE.
74.42 DimacsDescriptor() : type(NONE) {}
74.43 };
74.44
74.45 ///Discover the type of a DIMACS file
74.46
74.47 - ///It starts seeking the begining of the file for the problem type
74.48 - ///and size info. The found data is returned in a special struct
74.49 - ///that can be evaluated and passed to the appropriate reader
74.50 - ///function.
74.51 + ///This function starts seeking the beginning of the given file for the
74.52 + ///problem type and size info.
74.53 + ///The found data is returned in a special struct that can be evaluated
74.54 + ///and passed to the appropriate reader function.
74.55 DimacsDescriptor dimacsType(std::istream& is)
74.56 {
74.57 DimacsDescriptor r;
74.58 @@ -96,8 +101,7 @@
74.59 }
74.60
74.61
74.62 -
74.63 - /// DIMACS minimum cost flow reader function.
74.64 + /// \brief DIMACS minimum cost flow reader function.
74.65 ///
74.66 /// This function reads a minimum cost flow instance from DIMACS format,
74.67 /// i.e. from a DIMACS file having a line starting with
74.68 @@ -105,9 +109,17 @@
74.69 /// p min
74.70 /// \endcode
74.71 /// At the beginning, \c g is cleared by \c g.clear(). The supply
74.72 - /// amount of the nodes are written to \c supply (signed). The
74.73 - /// lower bounds, capacities and costs of the arcs are written to
74.74 - /// \c lower, \c capacity and \c cost.
74.75 + /// amount of the nodes are written to the \c supply node map
74.76 + /// (they are signed values). The lower bounds, capacities and costs
74.77 + /// of the arcs are written to the \c lower, \c capacity and \c cost
74.78 + /// arc maps.
74.79 + ///
74.80 + /// If the capacity of an arc is less than the lower bound, it will
74.81 + /// be set to "infinite" instead. The actual value of "infinite" is
74.82 + /// contolled by the \c infty parameter. If it is 0 (the default value),
74.83 + /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
74.84 + /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
74.85 + /// a non-zero value, that value will be used as "infinite".
74.86 ///
74.87 /// If the file type was previously evaluated by dimacsType(), then
74.88 /// the descriptor struct should be given by the \c dest parameter.
74.89 @@ -120,6 +132,7 @@
74.90 CapacityMap& capacity,
74.91 CostMap& cost,
74.92 SupplyMap& supply,
74.93 + typename CapacityMap::Value infty = 0,
74.94 DimacsDescriptor desc=DimacsDescriptor())
74.95 {
74.96 g.clear();
74.97 @@ -142,6 +155,12 @@
74.98 typename CapacityMap::Value low;
74.99 typename CapacityMap::Value cap;
74.100 typename CostMap::Value co;
74.101 + typedef typename CapacityMap::Value Capacity;
74.102 + if(infty==0)
74.103 + infty = std::numeric_limits<Capacity>::has_infinity ?
74.104 + std::numeric_limits<Capacity>::infinity() :
74.105 + std::numeric_limits<Capacity>::max();
74.106 +
74.107 while (is >> c) {
74.108 switch (c) {
74.109 case 'c': // comment line
74.110 @@ -152,15 +171,15 @@
74.111 getline(is, str);
74.112 supply.set(nodes[i], sup);
74.113 break;
74.114 - case 'a': // arc (arc) definition line
74.115 + case 'a': // arc definition line
74.116 is >> i >> j >> low >> cap >> co;
74.117 getline(is, str);
74.118 e = g.addArc(nodes[i], nodes[j]);
74.119 lower.set(e, low);
74.120 - if (cap >= 0)
74.121 + if (cap >= low)
74.122 capacity.set(e, cap);
74.123 else
74.124 - capacity.set(e, -1);
74.125 + capacity.set(e, infty);
74.126 cost.set(e, co);
74.127 break;
74.128 }
74.129 @@ -173,6 +192,7 @@
74.130 CapacityMap& capacity,
74.131 typename Digraph::Node &s,
74.132 typename Digraph::Node &t,
74.133 + typename CapacityMap::Value infty = 0,
74.134 DimacsDescriptor desc=DimacsDescriptor()) {
74.135 g.clear();
74.136 s=t=INVALID;
74.137 @@ -186,7 +206,13 @@
74.138 for (int k = 1; k <= desc.nodeNum; ++k) {
74.139 nodes[k] = g.addNode();
74.140 }
74.141 + typedef typename CapacityMap::Value Capacity;
74.142
74.143 + if(infty==0)
74.144 + infty = std::numeric_limits<Capacity>::has_infinity ?
74.145 + std::numeric_limits<Capacity>::infinity() :
74.146 + std::numeric_limits<Capacity>::max();
74.147 +
74.148 while (is >> c) {
74.149 switch (c) {
74.150 case 'c': // comment line
74.151 @@ -205,14 +231,23 @@
74.152 if (d == 't') t = nodes[i];
74.153 }
74.154 break;
74.155 - case 'a': // arc (arc) definition line
74.156 - if (desc.type==DimacsDescriptor::SP ||
74.157 - desc.type==DimacsDescriptor::MAX) {
74.158 + case 'a': // arc definition line
74.159 + if (desc.type==DimacsDescriptor::SP) {
74.160 is >> i >> j >> _cap;
74.161 getline(is, str);
74.162 e = g.addArc(nodes[i], nodes[j]);
74.163 capacity.set(e, _cap);
74.164 - } else {
74.165 + }
74.166 + else if (desc.type==DimacsDescriptor::MAX) {
74.167 + is >> i >> j >> _cap;
74.168 + getline(is, str);
74.169 + e = g.addArc(nodes[i], nodes[j]);
74.170 + if (_cap >= 0)
74.171 + capacity.set(e, _cap);
74.172 + else
74.173 + capacity.set(e, infty);
74.174 + }
74.175 + else {
74.176 is >> i >> j;
74.177 getline(is, str);
74.178 g.addArc(nodes[i], nodes[j]);
74.179 @@ -222,7 +257,7 @@
74.180 }
74.181 }
74.182
74.183 - /// DIMACS maximum flow reader function.
74.184 + /// \brief DIMACS maximum flow reader function.
74.185 ///
74.186 /// This function reads a maximum flow instance from DIMACS format,
74.187 /// i.e. from a DIMACS file having a line starting with
74.188 @@ -230,8 +265,15 @@
74.189 /// p max
74.190 /// \endcode
74.191 /// At the beginning, \c g is cleared by \c g.clear(). The arc
74.192 - /// capacities are written to \c capacity and \c s and \c t are
74.193 - /// set to the source and the target nodes.
74.194 + /// capacities are written to the \c capacity arc map and \c s and
74.195 + /// \c t are set to the source and the target nodes.
74.196 + ///
74.197 + /// If the capacity of an arc is negative, it will
74.198 + /// be set to "infinite" instead. The actual value of "infinite" is
74.199 + /// contolled by the \c infty parameter. If it is 0 (the default value),
74.200 + /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
74.201 + /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
74.202 + /// a non-zero value, that value will be used as "infinite".
74.203 ///
74.204 /// If the file type was previously evaluated by dimacsType(), then
74.205 /// the descriptor struct should be given by the \c dest parameter.
74.206 @@ -241,14 +283,15 @@
74.207 CapacityMap& capacity,
74.208 typename Digraph::Node &s,
74.209 typename Digraph::Node &t,
74.210 + typename CapacityMap::Value infty = 0,
74.211 DimacsDescriptor desc=DimacsDescriptor()) {
74.212 if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
74.213 if(desc.type!=DimacsDescriptor::MAX)
74.214 throw FormatError("Problem type mismatch");
74.215 - _readDimacs(is,g,capacity,s,t,desc);
74.216 + _readDimacs(is,g,capacity,s,t,infty,desc);
74.217 }
74.218
74.219 - /// DIMACS shortest path reader function.
74.220 + /// \brief DIMACS shortest path reader function.
74.221 ///
74.222 /// This function reads a shortest path instance from DIMACS format,
74.223 /// i.e. from a DIMACS file having a line starting with
74.224 @@ -256,7 +299,7 @@
74.225 /// p sp
74.226 /// \endcode
74.227 /// At the beginning, \c g is cleared by \c g.clear(). The arc
74.228 - /// lengths are written to \c length and \c s is set to the
74.229 + /// lengths are written to the \c length arc map and \c s is set to the
74.230 /// source node.
74.231 ///
74.232 /// If the file type was previously evaluated by dimacsType(), then
74.233 @@ -271,15 +314,24 @@
74.234 if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
74.235 if(desc.type!=DimacsDescriptor::SP)
74.236 throw FormatError("Problem type mismatch");
74.237 - _readDimacs(is, g, length, s, t,desc);
74.238 + _readDimacs(is, g, length, s, t, 0, desc);
74.239 }
74.240
74.241 - /// DIMACS capacitated digraph reader function.
74.242 + /// \brief DIMACS capacitated digraph reader function.
74.243 ///
74.244 /// This function reads an arc capacitated digraph instance from
74.245 - /// DIMACS 'mat' or 'sp' format.
74.246 + /// DIMACS 'max' or 'sp' format.
74.247 /// At the beginning, \c g is cleared by \c g.clear()
74.248 - /// and the arc capacities/lengths are written to \c capacity.
74.249 + /// and the arc capacities/lengths are written to the \c capacity
74.250 + /// arc map.
74.251 + ///
74.252 + /// In case of the 'max' format, if the capacity of an arc is negative,
74.253 + /// it will
74.254 + /// be set to "infinite" instead. The actual value of "infinite" is
74.255 + /// contolled by the \c infty parameter. If it is 0 (the default value),
74.256 + /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
74.257 + /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
74.258 + /// a non-zero value, that value will be used as "infinite".
74.259 ///
74.260 /// If the file type was previously evaluated by dimacsType(), then
74.261 /// the descriptor struct should be given by the \c dest parameter.
74.262 @@ -287,19 +339,35 @@
74.263 void readDimacsCap(std::istream& is,
74.264 Digraph &g,
74.265 CapacityMap& capacity,
74.266 + typename CapacityMap::Value infty = 0,
74.267 DimacsDescriptor desc=DimacsDescriptor()) {
74.268 typename Digraph::Node u,v;
74.269 if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
74.270 if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
74.271 throw FormatError("Problem type mismatch");
74.272 - _readDimacs(is, g, capacity, u, v, desc);
74.273 + _readDimacs(is, g, capacity, u, v, infty, desc);
74.274 }
74.275
74.276 - /// DIMACS plain digraph reader function.
74.277 + template<typename Graph>
74.278 + typename enable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
74.279 + _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
74.280 + dummy<0> = 0)
74.281 + {
74.282 + g.addEdge(s,t);
74.283 + }
74.284 + template<typename Graph>
74.285 + typename disable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
74.286 + _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
74.287 + dummy<1> = 1)
74.288 + {
74.289 + g.addArc(s,t);
74.290 + }
74.291 +
74.292 + /// \brief DIMACS plain (di)graph reader function.
74.293 ///
74.294 - /// This function reads a digraph without any designated nodes and
74.295 - /// maps from DIMACS format, i.e. from DIMACS files having a line
74.296 - /// starting with
74.297 + /// This function reads a plain (di)graph without any designated nodes
74.298 + /// and maps (e.g. a matching instance) from DIMACS format, i.e. from
74.299 + /// DIMACS files having a line starting with
74.300 /// \code
74.301 /// p mat
74.302 /// \endcode
74.303 @@ -307,15 +375,38 @@
74.304 ///
74.305 /// If the file type was previously evaluated by dimacsType(), then
74.306 /// the descriptor struct should be given by the \c dest parameter.
74.307 - template<typename Digraph>
74.308 - void readDimacsMat(std::istream& is, Digraph &g,
74.309 - DimacsDescriptor desc=DimacsDescriptor()) {
74.310 - typename Digraph::Node u,v;
74.311 - NullMap<typename Digraph::Arc, int> n;
74.312 + template<typename Graph>
74.313 + void readDimacsMat(std::istream& is, Graph &g,
74.314 + DimacsDescriptor desc=DimacsDescriptor())
74.315 + {
74.316 if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
74.317 if(desc.type!=DimacsDescriptor::MAT)
74.318 throw FormatError("Problem type mismatch");
74.319 - _readDimacs(is, g, n, u, v, desc);
74.320 +
74.321 + g.clear();
74.322 + std::vector<typename Graph::Node> nodes;
74.323 + char c;
74.324 + int i, j;
74.325 + std::string str;
74.326 + nodes.resize(desc.nodeNum + 1);
74.327 + for (int k = 1; k <= desc.nodeNum; ++k) {
74.328 + nodes[k] = g.addNode();
74.329 + }
74.330 +
74.331 + while (is >> c) {
74.332 + switch (c) {
74.333 + case 'c': // comment line
74.334 + getline(is, str);
74.335 + break;
74.336 + case 'n': // node definition line
74.337 + break;
74.338 + case 'a': // arc definition line
74.339 + is >> i >> j;
74.340 + getline(is, str);
74.341 + _addArcEdge(g,nodes[i], nodes[j]);
74.342 + break;
74.343 + }
74.344 + }
74.345 }
74.346
74.347 /// DIMACS plain digraph writer function.
75.1 --- a/lemon/edge_set.h Mon Jan 12 23:11:39 2009 +0100
75.2 +++ b/lemon/edge_set.h Thu Nov 05 15:48:01 2009 +0100
75.3 @@ -22,20 +22,19 @@
75.4 #include <lemon/core.h>
75.5 #include <lemon/bits/edge_set_extender.h>
75.6
75.7 -/// \ingroup semi_adaptors
75.8 +/// \ingroup graphs
75.9 /// \file
75.10 /// \brief ArcSet and EdgeSet classes.
75.11 ///
75.12 /// Graphs which use another graph's node-set as own.
75.13 namespace lemon {
75.14
75.15 - template <typename _Graph>
75.16 + template <typename GR>
75.17 class ListArcSetBase {
75.18 public:
75.19
75.20 - typedef _Graph Graph;
75.21 - typedef typename Graph::Node Node;
75.22 - typedef typename Graph::NodeIt NodeIt;
75.23 + typedef typename GR::Node Node;
75.24 + typedef typename GR::NodeIt NodeIt;
75.25
75.26 protected:
75.27
75.28 @@ -44,10 +43,10 @@
75.29 NodeT() : first_out(-1), first_in(-1) {}
75.30 };
75.31
75.32 - typedef typename ItemSetTraits<Graph, Node>::
75.33 + typedef typename ItemSetTraits<GR, Node>::
75.34 template Map<NodeT>::Type NodesImplBase;
75.35
75.36 - NodesImplBase* nodes;
75.37 + NodesImplBase* _nodes;
75.38
75.39 struct ArcT {
75.40 Node source, target;
75.41 @@ -61,17 +60,17 @@
75.42 int first_arc;
75.43 int first_free_arc;
75.44
75.45 - const Graph* graph;
75.46 + const GR* _graph;
75.47
75.48 - void initalize(const Graph& _graph, NodesImplBase& _nodes) {
75.49 - graph = &_graph;
75.50 - nodes = &_nodes;
75.51 + void initalize(const GR& graph, NodesImplBase& nodes) {
75.52 + _graph = &graph;
75.53 + _nodes = &nodes;
75.54 }
75.55
75.56 public:
75.57
75.58 class Arc {
75.59 - friend class ListArcSetBase<Graph>;
75.60 + friend class ListArcSetBase<GR>;
75.61 protected:
75.62 Arc(int _id) : id(_id) {}
75.63 int id;
75.64 @@ -85,6 +84,12 @@
75.65
75.66 ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
75.67
75.68 + Node addNode() {
75.69 + LEMON_ASSERT(false,
75.70 + "This graph structure does not support node insertion");
75.71 + return INVALID; // avoid warning
75.72 + }
75.73 +
75.74 Arc addArc(const Node& u, const Node& v) {
75.75 int n;
75.76 if (first_free_arc == -1) {
75.77 @@ -94,16 +99,16 @@
75.78 n = first_free_arc;
75.79 first_free_arc = arcs[first_free_arc].next_in;
75.80 }
75.81 - arcs[n].next_in = (*nodes)[v].first_in;
75.82 - if ((*nodes)[v].first_in != -1) {
75.83 - arcs[(*nodes)[v].first_in].prev_in = n;
75.84 + arcs[n].next_in = (*_nodes)[v].first_in;
75.85 + if ((*_nodes)[v].first_in != -1) {
75.86 + arcs[(*_nodes)[v].first_in].prev_in = n;
75.87 }
75.88 - (*nodes)[v].first_in = n;
75.89 - arcs[n].next_out = (*nodes)[u].first_out;
75.90 - if ((*nodes)[u].first_out != -1) {
75.91 - arcs[(*nodes)[u].first_out].prev_out = n;
75.92 + (*_nodes)[v].first_in = n;
75.93 + arcs[n].next_out = (*_nodes)[u].first_out;
75.94 + if ((*_nodes)[u].first_out != -1) {
75.95 + arcs[(*_nodes)[u].first_out].prev_out = n;
75.96 }
75.97 - (*nodes)[u].first_out = n;
75.98 + (*_nodes)[u].first_out = n;
75.99 arcs[n].source = u;
75.100 arcs[n].target = v;
75.101 return Arc(n);
75.102 @@ -114,7 +119,7 @@
75.103 if (arcs[n].prev_in != -1) {
75.104 arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
75.105 } else {
75.106 - (*nodes)[arcs[n].target].first_in = arcs[n].next_in;
75.107 + (*_nodes)[arcs[n].target].first_in = arcs[n].next_in;
75.108 }
75.109 if (arcs[n].next_in != -1) {
75.110 arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
75.111 @@ -123,7 +128,7 @@
75.112 if (arcs[n].prev_out != -1) {
75.113 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
75.114 } else {
75.115 - (*nodes)[arcs[n].source].first_out = arcs[n].next_out;
75.116 + (*_nodes)[arcs[n].source].first_out = arcs[n].next_out;
75.117 }
75.118 if (arcs[n].next_out != -1) {
75.119 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
75.120 @@ -134,8 +139,8 @@
75.121 void clear() {
75.122 Node node;
75.123 for (first(node); node != INVALID; next(node)) {
75.124 - (*nodes)[node].first_in = -1;
75.125 - (*nodes)[node].first_out = -1;
75.126 + (*_nodes)[node].first_in = -1;
75.127 + (*_nodes)[node].first_out = -1;
75.128 }
75.129 arcs.clear();
75.130 first_arc = -1;
75.131 @@ -143,20 +148,20 @@
75.132 }
75.133
75.134 void first(Node& node) const {
75.135 - graph->first(node);
75.136 + _graph->first(node);
75.137 }
75.138
75.139 void next(Node& node) const {
75.140 - graph->next(node);
75.141 + _graph->next(node);
75.142 }
75.143
75.144 void first(Arc& arc) const {
75.145 Node node;
75.146 first(node);
75.147 - while (node != INVALID && (*nodes)[node].first_in == -1) {
75.148 + while (node != INVALID && (*_nodes)[node].first_in == -1) {
75.149 next(node);
75.150 }
75.151 - arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
75.152 + arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
75.153 }
75.154
75.155 void next(Arc& arc) const {
75.156 @@ -165,15 +170,15 @@
75.157 } else {
75.158 Node node = arcs[arc.id].target;
75.159 next(node);
75.160 - while (node != INVALID && (*nodes)[node].first_in == -1) {
75.161 + while (node != INVALID && (*_nodes)[node].first_in == -1) {
75.162 next(node);
75.163 }
75.164 - arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
75.165 + arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
75.166 }
75.167 }
75.168
75.169 void firstOut(Arc& arc, const Node& node) const {
75.170 - arc.id = (*nodes)[node].first_out;
75.171 + arc.id = (*_nodes)[node].first_out;
75.172 }
75.173
75.174 void nextOut(Arc& arc) const {
75.175 @@ -181,42 +186,42 @@
75.176 }
75.177
75.178 void firstIn(Arc& arc, const Node& node) const {
75.179 - arc.id = (*nodes)[node].first_in;
75.180 + arc.id = (*_nodes)[node].first_in;
75.181 }
75.182
75.183 void nextIn(Arc& arc) const {
75.184 arc.id = arcs[arc.id].next_in;
75.185 }
75.186
75.187 - int id(const Node& node) const { return graph->id(node); }
75.188 + int id(const Node& node) const { return _graph->id(node); }
75.189 int id(const Arc& arc) const { return arc.id; }
75.190
75.191 - Node nodeFromId(int ix) const { return graph->nodeFromId(ix); }
75.192 + Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
75.193 Arc arcFromId(int ix) const { return Arc(ix); }
75.194
75.195 - int maxNodeId() const { return graph->maxNodeId(); };
75.196 + int maxNodeId() const { return _graph->maxNodeId(); };
75.197 int maxArcId() const { return arcs.size() - 1; }
75.198
75.199 Node source(const Arc& arc) const { return arcs[arc.id].source;}
75.200 Node target(const Arc& arc) const { return arcs[arc.id].target;}
75.201
75.202 - typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
75.203 + typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
75.204
75.205 NodeNotifier& notifier(Node) const {
75.206 - return graph->notifier(Node());
75.207 + return _graph->notifier(Node());
75.208 }
75.209
75.210 - template <typename _Value>
75.211 - class NodeMap : public Graph::template NodeMap<_Value> {
75.212 + template <typename V>
75.213 + class NodeMap : public GR::template NodeMap<V> {
75.214 + typedef typename GR::template NodeMap<V> Parent;
75.215 +
75.216 public:
75.217
75.218 - typedef typename _Graph::template NodeMap<_Value> Parent;
75.219 + explicit NodeMap(const ListArcSetBase<GR>& arcset)
75.220 + : Parent(*arcset._graph) {}
75.221
75.222 - explicit NodeMap(const ListArcSetBase<Graph>& arcset)
75.223 - : Parent(*arcset.graph) {}
75.224 -
75.225 - NodeMap(const ListArcSetBase<Graph>& arcset, const _Value& value)
75.226 - : Parent(*arcset.graph, value) {}
75.227 + NodeMap(const ListArcSetBase<GR>& arcset, const V& value)
75.228 + : Parent(*arcset._graph, value) {}
75.229
75.230 NodeMap& operator=(const NodeMap& cmap) {
75.231 return operator=<NodeMap>(cmap);
75.232 @@ -231,7 +236,7 @@
75.233
75.234 };
75.235
75.236 - /// \ingroup semi_adaptors
75.237 + /// \ingroup graphs
75.238 ///
75.239 /// \brief Digraph using a node set of another digraph or graph and
75.240 /// an own arc set.
75.241 @@ -250,26 +255,22 @@
75.242 /// that node can be removed from the underlying graph, in this case
75.243 /// all arcs incident to the given node is erased from the arc set.
75.244 ///
75.245 - /// \param _Graph The type of the graph which shares its node set with
75.246 + /// \param GR The type of the graph which shares its node set with
75.247 /// this class. Its interface must conform to the
75.248 /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
75.249 /// concept.
75.250 ///
75.251 - /// This class is fully conform to the \ref concepts::Digraph
75.252 + /// This class fully conforms to the \ref concepts::Digraph
75.253 /// "Digraph" concept.
75.254 - template <typename _Graph>
75.255 - class ListArcSet : public ArcSetExtender<ListArcSetBase<_Graph> > {
75.256 + template <typename GR>
75.257 + class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
75.258 + typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
75.259
75.260 public:
75.261
75.262 - typedef ArcSetExtender<ListArcSetBase<_Graph> > Parent;
75.263 -
75.264 typedef typename Parent::Node Node;
75.265 typedef typename Parent::Arc Arc;
75.266
75.267 - typedef _Graph Graph;
75.268 -
75.269 -
75.270 typedef typename Parent::NodesImplBase NodesImplBase;
75.271
75.272 void eraseNode(const Node& node) {
75.273 @@ -292,10 +293,10 @@
75.274 }
75.275
75.276 class NodesImpl : public NodesImplBase {
75.277 - public:
75.278 typedef NodesImplBase Parent;
75.279
75.280 - NodesImpl(const Graph& graph, ListArcSet& arcset)
75.281 + public:
75.282 + NodesImpl(const GR& graph, ListArcSet& arcset)
75.283 : Parent(graph), _arcset(arcset) {}
75.284
75.285 virtual ~NodesImpl() {}
75.286 @@ -321,22 +322,22 @@
75.287 ListArcSet& _arcset;
75.288 };
75.289
75.290 - NodesImpl nodes;
75.291 + NodesImpl _nodes;
75.292
75.293 public:
75.294
75.295 /// \brief Constructor of the ArcSet.
75.296 ///
75.297 /// Constructor of the ArcSet.
75.298 - ListArcSet(const Graph& graph) : nodes(graph, *this) {
75.299 - Parent::initalize(graph, nodes);
75.300 + ListArcSet(const GR& graph) : _nodes(graph, *this) {
75.301 + Parent::initalize(graph, _nodes);
75.302 }
75.303
75.304 /// \brief Add a new arc to the digraph.
75.305 ///
75.306 /// Add a new arc to the digraph with source node \c s
75.307 /// and target node \c t.
75.308 - /// \return the new arc.
75.309 + /// \return The new arc.
75.310 Arc addArc(const Node& s, const Node& t) {
75.311 return Parent::addArc(s, t);
75.312 }
75.313 @@ -350,13 +351,12 @@
75.314
75.315 };
75.316
75.317 - template <typename _Graph>
75.318 + template <typename GR>
75.319 class ListEdgeSetBase {
75.320 public:
75.321
75.322 - typedef _Graph Graph;
75.323 - typedef typename Graph::Node Node;
75.324 - typedef typename Graph::NodeIt NodeIt;
75.325 + typedef typename GR::Node Node;
75.326 + typedef typename GR::NodeIt NodeIt;
75.327
75.328 protected:
75.329
75.330 @@ -365,10 +365,10 @@
75.331 NodeT() : first_out(-1) {}
75.332 };
75.333
75.334 - typedef typename ItemSetTraits<Graph, Node>::
75.335 + typedef typename ItemSetTraits<GR, Node>::
75.336 template Map<NodeT>::Type NodesImplBase;
75.337
75.338 - NodesImplBase* nodes;
75.339 + NodesImplBase* _nodes;
75.340
75.341 struct ArcT {
75.342 Node target;
75.343 @@ -381,11 +381,11 @@
75.344 int first_arc;
75.345 int first_free_arc;
75.346
75.347 - const Graph* graph;
75.348 + const GR* _graph;
75.349
75.350 - void initalize(const Graph& _graph, NodesImplBase& _nodes) {
75.351 - graph = &_graph;
75.352 - nodes = &_nodes;
75.353 + void initalize(const GR& graph, NodesImplBase& nodes) {
75.354 + _graph = &graph;
75.355 + _nodes = &nodes;
75.356 }
75.357
75.358 public:
75.359 @@ -422,6 +422,12 @@
75.360
75.361 ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
75.362
75.363 + Node addNode() {
75.364 + LEMON_ASSERT(false,
75.365 + "This graph structure does not support node insertion");
75.366 + return INVALID; // avoid warning
75.367 + }
75.368 +
75.369 Edge addEdge(const Node& u, const Node& v) {
75.370 int n;
75.371
75.372 @@ -437,18 +443,18 @@
75.373 arcs[n].target = u;
75.374 arcs[n | 1].target = v;
75.375
75.376 - arcs[n].next_out = (*nodes)[v].first_out;
75.377 - if ((*nodes)[v].first_out != -1) {
75.378 - arcs[(*nodes)[v].first_out].prev_out = n;
75.379 + arcs[n].next_out = (*_nodes)[v].first_out;
75.380 + if ((*_nodes)[v].first_out != -1) {
75.381 + arcs[(*_nodes)[v].first_out].prev_out = n;
75.382 }
75.383 - (*nodes)[v].first_out = n;
75.384 + (*_nodes)[v].first_out = n;
75.385 arcs[n].prev_out = -1;
75.386
75.387 - if ((*nodes)[u].first_out != -1) {
75.388 - arcs[(*nodes)[u].first_out].prev_out = (n | 1);
75.389 + if ((*_nodes)[u].first_out != -1) {
75.390 + arcs[(*_nodes)[u].first_out].prev_out = (n | 1);
75.391 }
75.392 - arcs[n | 1].next_out = (*nodes)[u].first_out;
75.393 - (*nodes)[u].first_out = (n | 1);
75.394 + arcs[n | 1].next_out = (*_nodes)[u].first_out;
75.395 + (*_nodes)[u].first_out = (n | 1);
75.396 arcs[n | 1].prev_out = -1;
75.397
75.398 return Edge(n / 2);
75.399 @@ -464,7 +470,7 @@
75.400 if (arcs[n].prev_out != -1) {
75.401 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
75.402 } else {
75.403 - (*nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
75.404 + (*_nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
75.405 }
75.406
75.407 if (arcs[n | 1].next_out != -1) {
75.408 @@ -474,7 +480,7 @@
75.409 if (arcs[n | 1].prev_out != -1) {
75.410 arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
75.411 } else {
75.412 - (*nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
75.413 + (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
75.414 }
75.415
75.416 arcs[n].next_out = first_free_arc;
75.417 @@ -485,7 +491,7 @@
75.418 void clear() {
75.419 Node node;
75.420 for (first(node); node != INVALID; next(node)) {
75.421 - (*nodes)[node].first_out = -1;
75.422 + (*_nodes)[node].first_out = -1;
75.423 }
75.424 arcs.clear();
75.425 first_arc = -1;
75.426 @@ -493,20 +499,20 @@
75.427 }
75.428
75.429 void first(Node& node) const {
75.430 - graph->first(node);
75.431 + _graph->first(node);
75.432 }
75.433
75.434 void next(Node& node) const {
75.435 - graph->next(node);
75.436 + _graph->next(node);
75.437 }
75.438
75.439 void first(Arc& arc) const {
75.440 Node node;
75.441 first(node);
75.442 - while (node != INVALID && (*nodes)[node].first_out == -1) {
75.443 + while (node != INVALID && (*_nodes)[node].first_out == -1) {
75.444 next(node);
75.445 }
75.446 - arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_out;
75.447 + arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
75.448 }
75.449
75.450 void next(Arc& arc) const {
75.451 @@ -515,10 +521,10 @@
75.452 } else {
75.453 Node node = arcs[arc.id ^ 1].target;
75.454 next(node);
75.455 - while(node != INVALID && (*nodes)[node].first_out == -1) {
75.456 + while(node != INVALID && (*_nodes)[node].first_out == -1) {
75.457 next(node);
75.458 }
75.459 - arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_out;
75.460 + arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
75.461 }
75.462 }
75.463
75.464 @@ -526,7 +532,7 @@
75.465 Node node;
75.466 first(node);
75.467 while (node != INVALID) {
75.468 - edge.id = (*nodes)[node].first_out;
75.469 + edge.id = (*_nodes)[node].first_out;
75.470 while ((edge.id & 1) != 1) {
75.471 edge.id = arcs[edge.id].next_out;
75.472 }
75.473 @@ -551,7 +557,7 @@
75.474 }
75.475 next(node);
75.476 while (node != INVALID) {
75.477 - edge.id = (*nodes)[node].first_out;
75.478 + edge.id = (*_nodes)[node].first_out;
75.479 while ((edge.id & 1) != 1) {
75.480 edge.id = arcs[edge.id].next_out;
75.481 }
75.482 @@ -565,7 +571,7 @@
75.483 }
75.484
75.485 void firstOut(Arc& arc, const Node& node) const {
75.486 - arc.id = (*nodes)[node].first_out;
75.487 + arc.id = (*_nodes)[node].first_out;
75.488 }
75.489
75.490 void nextOut(Arc& arc) const {
75.491 @@ -573,7 +579,7 @@
75.492 }
75.493
75.494 void firstIn(Arc& arc, const Node& node) const {
75.495 - arc.id = (((*nodes)[node].first_out) ^ 1);
75.496 + arc.id = (((*_nodes)[node].first_out) ^ 1);
75.497 if (arc.id == -2) arc.id = -1;
75.498 }
75.499
75.500 @@ -583,7 +589,7 @@
75.501 }
75.502
75.503 void firstInc(Edge &arc, bool& dir, const Node& node) const {
75.504 - int de = (*nodes)[node].first_out;
75.505 + int de = (*_nodes)[node].first_out;
75.506 if (de != -1 ) {
75.507 arc.id = de / 2;
75.508 dir = ((de & 1) == 1);
75.509 @@ -611,15 +617,15 @@
75.510 return Arc(edge.id * 2 + (dir ? 1 : 0));
75.511 }
75.512
75.513 - int id(const Node& node) const { return graph->id(node); }
75.514 + int id(const Node& node) const { return _graph->id(node); }
75.515 static int id(Arc e) { return e.id; }
75.516 static int id(Edge e) { return e.id; }
75.517
75.518 - Node nodeFromId(int id) const { return graph->nodeFromId(id); }
75.519 + Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
75.520 static Arc arcFromId(int id) { return Arc(id);}
75.521 static Edge edgeFromId(int id) { return Edge(id);}
75.522
75.523 - int maxNodeId() const { return graph->maxNodeId(); };
75.524 + int maxNodeId() const { return _graph->maxNodeId(); };
75.525 int maxEdgeId() const { return arcs.size() / 2 - 1; }
75.526 int maxArcId() const { return arcs.size()-1; }
75.527
75.528 @@ -629,23 +635,23 @@
75.529 Node u(Edge e) const { return arcs[2 * e.id].target; }
75.530 Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
75.531
75.532 - typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
75.533 + typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
75.534
75.535 NodeNotifier& notifier(Node) const {
75.536 - return graph->notifier(Node());
75.537 + return _graph->notifier(Node());
75.538 }
75.539
75.540 - template <typename _Value>
75.541 - class NodeMap : public Graph::template NodeMap<_Value> {
75.542 + template <typename V>
75.543 + class NodeMap : public GR::template NodeMap<V> {
75.544 + typedef typename GR::template NodeMap<V> Parent;
75.545 +
75.546 public:
75.547
75.548 - typedef typename _Graph::template NodeMap<_Value> Parent;
75.549 + explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
75.550 + : Parent(*arcset._graph) {}
75.551
75.552 - explicit NodeMap(const ListEdgeSetBase<Graph>& arcset)
75.553 - : Parent(*arcset.graph) {}
75.554 -
75.555 - NodeMap(const ListEdgeSetBase<Graph>& arcset, const _Value& value)
75.556 - : Parent(*arcset.graph, value) {}
75.557 + NodeMap(const ListEdgeSetBase<GR>& arcset, const V& value)
75.558 + : Parent(*arcset._graph, value) {}
75.559
75.560 NodeMap& operator=(const NodeMap& cmap) {
75.561 return operator=<NodeMap>(cmap);
75.562 @@ -660,7 +666,7 @@
75.563
75.564 };
75.565
75.566 - /// \ingroup semi_adaptors
75.567 + /// \ingroup graphs
75.568 ///
75.569 /// \brief Graph using a node set of another digraph or graph and an
75.570 /// own edge set.
75.571 @@ -679,27 +685,23 @@
75.572 /// be removed from the underlying graph, in this case all edges
75.573 /// incident to the given node is erased from the arc set.
75.574 ///
75.575 - /// \param _Graph The type of the graph which shares its node set
75.576 + /// \param GR The type of the graph which shares its node set
75.577 /// with this class. Its interface must conform to the
75.578 /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
75.579 /// concept.
75.580 ///
75.581 - /// This class is fully conform to the \ref concepts::Graph "Graph"
75.582 + /// This class fully conforms to the \ref concepts::Graph "Graph"
75.583 /// concept.
75.584 - template <typename _Graph>
75.585 - class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<_Graph> > {
75.586 + template <typename GR>
75.587 + class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
75.588 + typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
75.589
75.590 public:
75.591
75.592 - typedef EdgeSetExtender<ListEdgeSetBase<_Graph> > Parent;
75.593 -
75.594 typedef typename Parent::Node Node;
75.595 typedef typename Parent::Arc Arc;
75.596 typedef typename Parent::Edge Edge;
75.597
75.598 - typedef _Graph Graph;
75.599 -
75.600 -
75.601 typedef typename Parent::NodesImplBase NodesImplBase;
75.602
75.603 void eraseNode(const Node& node) {
75.604 @@ -717,10 +719,10 @@
75.605 }
75.606
75.607 class NodesImpl : public NodesImplBase {
75.608 - public:
75.609 typedef NodesImplBase Parent;
75.610
75.611 - NodesImpl(const Graph& graph, ListEdgeSet& arcset)
75.612 + public:
75.613 + NodesImpl(const GR& graph, ListEdgeSet& arcset)
75.614 : Parent(graph), _arcset(arcset) {}
75.615
75.616 virtual ~NodesImpl() {}
75.617 @@ -746,22 +748,22 @@
75.618 ListEdgeSet& _arcset;
75.619 };
75.620
75.621 - NodesImpl nodes;
75.622 + NodesImpl _nodes;
75.623
75.624 public:
75.625
75.626 /// \brief Constructor of the EdgeSet.
75.627 ///
75.628 /// Constructor of the EdgeSet.
75.629 - ListEdgeSet(const Graph& graph) : nodes(graph, *this) {
75.630 - Parent::initalize(graph, nodes);
75.631 + ListEdgeSet(const GR& graph) : _nodes(graph, *this) {
75.632 + Parent::initalize(graph, _nodes);
75.633 }
75.634
75.635 /// \brief Add a new edge to the graph.
75.636 ///
75.637 /// Add a new edge to the graph with node \c u
75.638 /// and node \c v endpoints.
75.639 - /// \return the new edge.
75.640 + /// \return The new edge.
75.641 Edge addEdge(const Node& u, const Node& v) {
75.642 return Parent::addEdge(u, v);
75.643 }
75.644 @@ -775,13 +777,12 @@
75.645
75.646 };
75.647
75.648 - template <typename _Graph>
75.649 + template <typename GR>
75.650 class SmartArcSetBase {
75.651 public:
75.652
75.653 - typedef _Graph Graph;
75.654 - typedef typename Graph::Node Node;
75.655 - typedef typename Graph::NodeIt NodeIt;
75.656 + typedef typename GR::Node Node;
75.657 + typedef typename GR::NodeIt NodeIt;
75.658
75.659 protected:
75.660
75.661 @@ -790,10 +791,10 @@
75.662 NodeT() : first_out(-1), first_in(-1) {}
75.663 };
75.664
75.665 - typedef typename ItemSetTraits<Graph, Node>::
75.666 + typedef typename ItemSetTraits<GR, Node>::
75.667 template Map<NodeT>::Type NodesImplBase;
75.668
75.669 - NodesImplBase* nodes;
75.670 + NodesImplBase* _nodes;
75.671
75.672 struct ArcT {
75.673 Node source, target;
75.674 @@ -803,17 +804,17 @@
75.675
75.676 std::vector<ArcT> arcs;
75.677
75.678 - const Graph* graph;
75.679 + const GR* _graph;
75.680
75.681 - void initalize(const Graph& _graph, NodesImplBase& _nodes) {
75.682 - graph = &_graph;
75.683 - nodes = &_nodes;
75.684 + void initalize(const GR& graph, NodesImplBase& nodes) {
75.685 + _graph = &graph;
75.686 + _nodes = &nodes;
75.687 }
75.688
75.689 public:
75.690
75.691 class Arc {
75.692 - friend class SmartArcSetBase<Graph>;
75.693 + friend class SmartArcSetBase<GR>;
75.694 protected:
75.695 Arc(int _id) : id(_id) {}
75.696 int id;
75.697 @@ -827,13 +828,19 @@
75.698
75.699 SmartArcSetBase() {}
75.700
75.701 + Node addNode() {
75.702 + LEMON_ASSERT(false,
75.703 + "This graph structure does not support node insertion");
75.704 + return INVALID; // avoid warning
75.705 + }
75.706 +
75.707 Arc addArc(const Node& u, const Node& v) {
75.708 int n = arcs.size();
75.709 arcs.push_back(ArcT());
75.710 - arcs[n].next_in = (*nodes)[v].first_in;
75.711 - (*nodes)[v].first_in = n;
75.712 - arcs[n].next_out = (*nodes)[u].first_out;
75.713 - (*nodes)[u].first_out = n;
75.714 + arcs[n].next_in = (*_nodes)[v].first_in;
75.715 + (*_nodes)[v].first_in = n;
75.716 + arcs[n].next_out = (*_nodes)[u].first_out;
75.717 + (*_nodes)[u].first_out = n;
75.718 arcs[n].source = u;
75.719 arcs[n].target = v;
75.720 return Arc(n);
75.721 @@ -842,30 +849,30 @@
75.722 void clear() {
75.723 Node node;
75.724 for (first(node); node != INVALID; next(node)) {
75.725 - (*nodes)[node].first_in = -1;
75.726 - (*nodes)[node].first_out = -1;
75.727 + (*_nodes)[node].first_in = -1;
75.728 + (*_nodes)[node].first_out = -1;
75.729 }
75.730 arcs.clear();
75.731 }
75.732
75.733 void first(Node& node) const {
75.734 - graph->first(node);
75.735 + _graph->first(node);
75.736 }
75.737
75.738 void next(Node& node) const {
75.739 - graph->next(node);
75.740 + _graph->next(node);
75.741 }
75.742
75.743 void first(Arc& arc) const {
75.744 arc.id = arcs.size() - 1;
75.745 }
75.746
75.747 - void next(Arc& arc) const {
75.748 + static void next(Arc& arc) {
75.749 --arc.id;
75.750 }
75.751
75.752 void firstOut(Arc& arc, const Node& node) const {
75.753 - arc.id = (*nodes)[node].first_out;
75.754 + arc.id = (*_nodes)[node].first_out;
75.755 }
75.756
75.757 void nextOut(Arc& arc) const {
75.758 @@ -873,42 +880,42 @@
75.759 }
75.760
75.761 void firstIn(Arc& arc, const Node& node) const {
75.762 - arc.id = (*nodes)[node].first_in;
75.763 + arc.id = (*_nodes)[node].first_in;
75.764 }
75.765
75.766 void nextIn(Arc& arc) const {
75.767 arc.id = arcs[arc.id].next_in;
75.768 }
75.769
75.770 - int id(const Node& node) const { return graph->id(node); }
75.771 + int id(const Node& node) const { return _graph->id(node); }
75.772 int id(const Arc& arc) const { return arc.id; }
75.773
75.774 - Node nodeFromId(int ix) const { return graph->nodeFromId(ix); }
75.775 + Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
75.776 Arc arcFromId(int ix) const { return Arc(ix); }
75.777
75.778 - int maxNodeId() const { return graph->maxNodeId(); };
75.779 + int maxNodeId() const { return _graph->maxNodeId(); };
75.780 int maxArcId() const { return arcs.size() - 1; }
75.781
75.782 Node source(const Arc& arc) const { return arcs[arc.id].source;}
75.783 Node target(const Arc& arc) const { return arcs[arc.id].target;}
75.784
75.785 - typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
75.786 + typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
75.787
75.788 NodeNotifier& notifier(Node) const {
75.789 - return graph->notifier(Node());
75.790 + return _graph->notifier(Node());
75.791 }
75.792
75.793 - template <typename _Value>
75.794 - class NodeMap : public Graph::template NodeMap<_Value> {
75.795 + template <typename V>
75.796 + class NodeMap : public GR::template NodeMap<V> {
75.797 + typedef typename GR::template NodeMap<V> Parent;
75.798 +
75.799 public:
75.800
75.801 - typedef typename _Graph::template NodeMap<_Value> Parent;
75.802 + explicit NodeMap(const SmartArcSetBase<GR>& arcset)
75.803 + : Parent(*arcset._graph) { }
75.804
75.805 - explicit NodeMap(const SmartArcSetBase<Graph>& arcset)
75.806 - : Parent(*arcset.graph) { }
75.807 -
75.808 - NodeMap(const SmartArcSetBase<Graph>& arcset, const _Value& value)
75.809 - : Parent(*arcset.graph, value) { }
75.810 + NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
75.811 + : Parent(*arcset._graph, value) { }
75.812
75.813 NodeMap& operator=(const NodeMap& cmap) {
75.814 return operator=<NodeMap>(cmap);
75.815 @@ -924,7 +931,7 @@
75.816 };
75.817
75.818
75.819 - /// \ingroup semi_adaptors
75.820 + /// \ingroup graphs
75.821 ///
75.822 /// \brief Digraph using a node set of another digraph or graph and
75.823 /// an own arc set.
75.824 @@ -937,7 +944,7 @@
75.825 /// class. The node handling functions (id handling, observing, and
75.826 /// iterators) works equivalently as in the original graph.
75.827 ///
75.828 - /// \param _Graph The type of the graph which shares its node set with
75.829 + /// \param GR The type of the graph which shares its node set with
75.830 /// this class. Its interface must conform to the
75.831 /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
75.832 /// concept.
75.833 @@ -952,20 +959,17 @@
75.834 /// the arc set is invalidated, and it cannot be used anymore. The
75.835 /// validity can be checked with the \c valid() member function.
75.836 ///
75.837 - /// This class is fully conform to the \ref concepts::Digraph
75.838 + /// This class fully conforms to the \ref concepts::Digraph
75.839 /// "Digraph" concept.
75.840 - template <typename _Graph>
75.841 - class SmartArcSet : public ArcSetExtender<SmartArcSetBase<_Graph> > {
75.842 + template <typename GR>
75.843 + class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
75.844 + typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
75.845
75.846 public:
75.847
75.848 - typedef ArcSetExtender<SmartArcSetBase<_Graph> > Parent;
75.849 -
75.850 typedef typename Parent::Node Node;
75.851 typedef typename Parent::Arc Arc;
75.852
75.853 - typedef _Graph Graph;
75.854 -
75.855 protected:
75.856
75.857 typedef typename Parent::NodesImplBase NodesImplBase;
75.858 @@ -983,10 +987,10 @@
75.859 }
75.860
75.861 class NodesImpl : public NodesImplBase {
75.862 - public:
75.863 typedef NodesImplBase Parent;
75.864
75.865 - NodesImpl(const Graph& graph, SmartArcSet& arcset)
75.866 + public:
75.867 + NodesImpl(const GR& graph, SmartArcSet& arcset)
75.868 : Parent(graph), _arcset(arcset) {}
75.869
75.870 virtual ~NodesImpl() {}
75.871 @@ -1026,22 +1030,22 @@
75.872 SmartArcSet& _arcset;
75.873 };
75.874
75.875 - NodesImpl nodes;
75.876 + NodesImpl _nodes;
75.877
75.878 public:
75.879
75.880 /// \brief Constructor of the ArcSet.
75.881 ///
75.882 /// Constructor of the ArcSet.
75.883 - SmartArcSet(const Graph& graph) : nodes(graph, *this) {
75.884 - Parent::initalize(graph, nodes);
75.885 + SmartArcSet(const GR& graph) : _nodes(graph, *this) {
75.886 + Parent::initalize(graph, _nodes);
75.887 }
75.888
75.889 /// \brief Add a new arc to the digraph.
75.890 ///
75.891 /// Add a new arc to the digraph with source node \c s
75.892 /// and target node \c t.
75.893 - /// \return the new arc.
75.894 + /// \return The new arc.
75.895 Arc addArc(const Node& s, const Node& t) {
75.896 return Parent::addArc(s, t);
75.897 }
75.898 @@ -1052,19 +1056,18 @@
75.899 /// invalidated. It occurs when a node in the underlying graph is
75.900 /// erased and it is not isolated in the ArcSet.
75.901 bool valid() const {
75.902 - return nodes.attached();
75.903 + return _nodes.attached();
75.904 }
75.905
75.906 };
75.907
75.908
75.909 - template <typename _Graph>
75.910 + template <typename GR>
75.911 class SmartEdgeSetBase {
75.912 public:
75.913
75.914 - typedef _Graph Graph;
75.915 - typedef typename Graph::Node Node;
75.916 - typedef typename Graph::NodeIt NodeIt;
75.917 + typedef typename GR::Node Node;
75.918 + typedef typename GR::NodeIt NodeIt;
75.919
75.920 protected:
75.921
75.922 @@ -1073,10 +1076,10 @@
75.923 NodeT() : first_out(-1) {}
75.924 };
75.925
75.926 - typedef typename ItemSetTraits<Graph, Node>::
75.927 + typedef typename ItemSetTraits<GR, Node>::
75.928 template Map<NodeT>::Type NodesImplBase;
75.929
75.930 - NodesImplBase* nodes;
75.931 + NodesImplBase* _nodes;
75.932
75.933 struct ArcT {
75.934 Node target;
75.935 @@ -1086,11 +1089,11 @@
75.936
75.937 std::vector<ArcT> arcs;
75.938
75.939 - const Graph* graph;
75.940 + const GR* _graph;
75.941
75.942 - void initalize(const Graph& _graph, NodesImplBase& _nodes) {
75.943 - graph = &_graph;
75.944 - nodes = &_nodes;
75.945 + void initalize(const GR& graph, NodesImplBase& nodes) {
75.946 + _graph = &graph;
75.947 + _nodes = &nodes;
75.948 }
75.949
75.950 public:
75.951 @@ -1127,6 +1130,12 @@
75.952
75.953 SmartEdgeSetBase() {}
75.954
75.955 + Node addNode() {
75.956 + LEMON_ASSERT(false,
75.957 + "This graph structure does not support node insertion");
75.958 + return INVALID; // avoid warning
75.959 + }
75.960 +
75.961 Edge addEdge(const Node& u, const Node& v) {
75.962 int n = arcs.size();
75.963 arcs.push_back(ArcT());
75.964 @@ -1135,11 +1144,11 @@
75.965 arcs[n].target = u;
75.966 arcs[n | 1].target = v;
75.967
75.968 - arcs[n].next_out = (*nodes)[v].first_out;
75.969 - (*nodes)[v].first_out = n;
75.970 + arcs[n].next_out = (*_nodes)[v].first_out;
75.971 + (*_nodes)[v].first_out = n;
75.972
75.973 - arcs[n | 1].next_out = (*nodes)[u].first_out;
75.974 - (*nodes)[u].first_out = (n | 1);
75.975 + arcs[n | 1].next_out = (*_nodes)[u].first_out;
75.976 + (*_nodes)[u].first_out = (n | 1);
75.977
75.978 return Edge(n / 2);
75.979 }
75.980 @@ -1147,24 +1156,24 @@
75.981 void clear() {
75.982 Node node;
75.983 for (first(node); node != INVALID; next(node)) {
75.984 - (*nodes)[node].first_out = -1;
75.985 + (*_nodes)[node].first_out = -1;
75.986 }
75.987 arcs.clear();
75.988 }
75.989
75.990 void first(Node& node) const {
75.991 - graph->first(node);
75.992 + _graph->first(node);
75.993 }
75.994
75.995 void next(Node& node) const {
75.996 - graph->next(node);
75.997 + _graph->next(node);
75.998 }
75.999
75.1000 void first(Arc& arc) const {
75.1001 arc.id = arcs.size() - 1;
75.1002 }
75.1003
75.1004 - void next(Arc& arc) const {
75.1005 + static void next(Arc& arc) {
75.1006 --arc.id;
75.1007 }
75.1008
75.1009 @@ -1172,12 +1181,12 @@
75.1010 arc.id = arcs.size() / 2 - 1;
75.1011 }
75.1012
75.1013 - void next(Edge& arc) const {
75.1014 + static void next(Edge& arc) {
75.1015 --arc.id;
75.1016 }
75.1017
75.1018 void firstOut(Arc& arc, const Node& node) const {
75.1019 - arc.id = (*nodes)[node].first_out;
75.1020 + arc.id = (*_nodes)[node].first_out;
75.1021 }
75.1022
75.1023 void nextOut(Arc& arc) const {
75.1024 @@ -1185,7 +1194,7 @@
75.1025 }
75.1026
75.1027 void firstIn(Arc& arc, const Node& node) const {
75.1028 - arc.id = (((*nodes)[node].first_out) ^ 1);
75.1029 + arc.id = (((*_nodes)[node].first_out) ^ 1);
75.1030 if (arc.id == -2) arc.id = -1;
75.1031 }
75.1032
75.1033 @@ -1195,7 +1204,7 @@
75.1034 }
75.1035
75.1036 void firstInc(Edge &arc, bool& dir, const Node& node) const {
75.1037 - int de = (*nodes)[node].first_out;
75.1038 + int de = (*_nodes)[node].first_out;
75.1039 if (de != -1 ) {
75.1040 arc.id = de / 2;
75.1041 dir = ((de & 1) == 1);
75.1042 @@ -1223,15 +1232,15 @@
75.1043 return Arc(edge.id * 2 + (dir ? 1 : 0));
75.1044 }
75.1045
75.1046 - int id(Node node) const { return graph->id(node); }
75.1047 + int id(Node node) const { return _graph->id(node); }
75.1048 static int id(Arc arc) { return arc.id; }
75.1049 static int id(Edge arc) { return arc.id; }
75.1050
75.1051 - Node nodeFromId(int id) const { return graph->nodeFromId(id); }
75.1052 + Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
75.1053 static Arc arcFromId(int id) { return Arc(id); }
75.1054 static Edge edgeFromId(int id) { return Edge(id);}
75.1055
75.1056 - int maxNodeId() const { return graph->maxNodeId(); };
75.1057 + int maxNodeId() const { return _graph->maxNodeId(); };
75.1058 int maxArcId() const { return arcs.size() - 1; }
75.1059 int maxEdgeId() const { return arcs.size() / 2 - 1; }
75.1060
75.1061 @@ -1241,23 +1250,23 @@
75.1062 Node u(Edge e) const { return arcs[2 * e.id].target; }
75.1063 Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
75.1064
75.1065 - typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
75.1066 + typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
75.1067
75.1068 NodeNotifier& notifier(Node) const {
75.1069 - return graph->notifier(Node());
75.1070 + return _graph->notifier(Node());
75.1071 }
75.1072
75.1073 - template <typename _Value>
75.1074 - class NodeMap : public Graph::template NodeMap<_Value> {
75.1075 + template <typename V>
75.1076 + class NodeMap : public GR::template NodeMap<V> {
75.1077 + typedef typename GR::template NodeMap<V> Parent;
75.1078 +
75.1079 public:
75.1080
75.1081 - typedef typename _Graph::template NodeMap<_Value> Parent;
75.1082 + explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
75.1083 + : Parent(*arcset._graph) { }
75.1084
75.1085 - explicit NodeMap(const SmartEdgeSetBase<Graph>& arcset)
75.1086 - : Parent(*arcset.graph) { }
75.1087 -
75.1088 - NodeMap(const SmartEdgeSetBase<Graph>& arcset, const _Value& value)
75.1089 - : Parent(*arcset.graph, value) { }
75.1090 + NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& value)
75.1091 + : Parent(*arcset._graph, value) { }
75.1092
75.1093 NodeMap& operator=(const NodeMap& cmap) {
75.1094 return operator=<NodeMap>(cmap);
75.1095 @@ -1272,7 +1281,7 @@
75.1096
75.1097 };
75.1098
75.1099 - /// \ingroup semi_adaptors
75.1100 + /// \ingroup graphs
75.1101 ///
75.1102 /// \brief Graph using a node set of another digraph or graph and an
75.1103 /// own edge set.
75.1104 @@ -1285,7 +1294,7 @@
75.1105 /// node handling functions (id handling, observing, and iterators)
75.1106 /// works equivalently as in the original graph.
75.1107 ///
75.1108 - /// \param _Graph The type of the graph which shares its node set
75.1109 + /// \param GR The type of the graph which shares its node set
75.1110 /// with this class. Its interface must conform to the
75.1111 /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
75.1112 /// concept.
75.1113 @@ -1300,21 +1309,18 @@
75.1114 /// is invalidated, and it cannot be used anymore. The validity can
75.1115 /// be checked with the \c valid() member function.
75.1116 ///
75.1117 - /// This class is fully conform to the \ref concepts::Graph
75.1118 + /// This class fully conforms to the \ref concepts::Graph
75.1119 /// "Graph" concept.
75.1120 - template <typename _Graph>
75.1121 - class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<_Graph> > {
75.1122 + template <typename GR>
75.1123 + class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
75.1124 + typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
75.1125
75.1126 public:
75.1127
75.1128 - typedef EdgeSetExtender<SmartEdgeSetBase<_Graph> > Parent;
75.1129 -
75.1130 typedef typename Parent::Node Node;
75.1131 typedef typename Parent::Arc Arc;
75.1132 typedef typename Parent::Edge Edge;
75.1133
75.1134 - typedef _Graph Graph;
75.1135 -
75.1136 protected:
75.1137
75.1138 typedef typename Parent::NodesImplBase NodesImplBase;
75.1139 @@ -1331,10 +1337,10 @@
75.1140 }
75.1141
75.1142 class NodesImpl : public NodesImplBase {
75.1143 - public:
75.1144 typedef NodesImplBase Parent;
75.1145
75.1146 - NodesImpl(const Graph& graph, SmartEdgeSet& arcset)
75.1147 + public:
75.1148 + NodesImpl(const GR& graph, SmartEdgeSet& arcset)
75.1149 : Parent(graph), _arcset(arcset) {}
75.1150
75.1151 virtual ~NodesImpl() {}
75.1152 @@ -1374,22 +1380,22 @@
75.1153 SmartEdgeSet& _arcset;
75.1154 };
75.1155
75.1156 - NodesImpl nodes;
75.1157 + NodesImpl _nodes;
75.1158
75.1159 public:
75.1160
75.1161 /// \brief Constructor of the EdgeSet.
75.1162 ///
75.1163 /// Constructor of the EdgeSet.
75.1164 - SmartEdgeSet(const Graph& graph) : nodes(graph, *this) {
75.1165 - Parent::initalize(graph, nodes);
75.1166 + SmartEdgeSet(const GR& graph) : _nodes(graph, *this) {
75.1167 + Parent::initalize(graph, _nodes);
75.1168 }
75.1169
75.1170 /// \brief Add a new edge to the graph.
75.1171 ///
75.1172 /// Add a new edge to the graph with node \c u
75.1173 /// and node \c v endpoints.
75.1174 - /// \return the new edge.
75.1175 + /// \return The new edge.
75.1176 Edge addEdge(const Node& u, const Node& v) {
75.1177 return Parent::addEdge(u, v);
75.1178 }
75.1179 @@ -1400,7 +1406,7 @@
75.1180 /// invalidated. It occurs when a node in the underlying graph is
75.1181 /// erased and it is not isolated in the EdgeSet.
75.1182 bool valid() const {
75.1183 - return nodes.attached();
75.1184 + return _nodes.attached();
75.1185 }
75.1186
75.1187 };
76.1 --- a/lemon/elevator.h Mon Jan 12 23:11:39 2009 +0100
76.2 +++ b/lemon/elevator.h Thu Nov 05 15:48:01 2009 +0100
76.3 @@ -27,6 +27,7 @@
76.4 ///for labeling items in push-relabel type algorithms.
76.5 ///
76.6
76.7 +#include <lemon/core.h>
76.8 #include <lemon/bits/traits.h>
76.9
76.10 namespace lemon {
76.11 @@ -45,10 +46,10 @@
76.12 ///
76.13 ///\sa LinkedElevator
76.14 ///
76.15 - ///\param Graph Type of the underlying graph.
76.16 - ///\param Item Type of the items the data is assigned to (Graph::Node,
76.17 - ///Graph::Arc, Graph::Edge).
76.18 - template<class Graph, class Item>
76.19 + ///\param GR Type of the underlying graph.
76.20 + ///\param Item Type of the items the data is assigned to (\c GR::Node,
76.21 + ///\c GR::Arc or \c GR::Edge).
76.22 + template<class GR, class Item>
76.23 class Elevator
76.24 {
76.25 public:
76.26 @@ -59,10 +60,10 @@
76.27 private:
76.28
76.29 typedef Item *Vit;
76.30 - typedef typename ItemSetTraits<Graph,Item>::template Map<Vit>::Type VitMap;
76.31 - typedef typename ItemSetTraits<Graph,Item>::template Map<int>::Type IntMap;
76.32 + typedef typename ItemSetTraits<GR,Item>::template Map<Vit>::Type VitMap;
76.33 + typedef typename ItemSetTraits<GR,Item>::template Map<int>::Type IntMap;
76.34
76.35 - const Graph &_g;
76.36 + const GR &_g;
76.37 int _max_level;
76.38 int _item_num;
76.39 VitMap _where;
76.40 @@ -75,7 +76,7 @@
76.41
76.42 void copy(Item i, Vit p)
76.43 {
76.44 - _where.set(*p=i,p);
76.45 + _where[*p=i] = p;
76.46 }
76.47 void copy(Vit s, Vit p)
76.48 {
76.49 @@ -83,15 +84,15 @@
76.50 {
76.51 Item i=*s;
76.52 *p=i;
76.53 - _where.set(i,p);
76.54 + _where[i] = p;
76.55 }
76.56 }
76.57 void swap(Vit i, Vit j)
76.58 {
76.59 Item ti=*i;
76.60 Vit ct = _where[ti];
76.61 - _where.set(ti,_where[*i=*j]);
76.62 - _where.set(*j,ct);
76.63 + _where[ti] = _where[*i=*j];
76.64 + _where[*j] = ct;
76.65 *j=ti;
76.66 }
76.67
76.68 @@ -104,7 +105,7 @@
76.69 ///\param graph The underlying graph.
76.70 ///\param max_level The maximum allowed level.
76.71 ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
76.72 - Elevator(const Graph &graph,int max_level) :
76.73 + Elevator(const GR &graph,int max_level) :
76.74 _g(graph),
76.75 _max_level(max_level),
76.76 _item_num(_max_level),
76.77 @@ -121,9 +122,9 @@
76.78 ///\param graph The underlying graph.
76.79 ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
76.80 ///where \c max_level is equal to the number of labeled items in the graph.
76.81 - Elevator(const Graph &graph) :
76.82 + Elevator(const GR &graph) :
76.83 _g(graph),
76.84 - _max_level(countItems<Graph, Item>(graph)),
76.85 + _max_level(countItems<GR, Item>(graph)),
76.86 _item_num(_max_level),
76.87 _where(graph),
76.88 _level(graph,0),
76.89 @@ -225,7 +226,7 @@
76.90 void liftHighestActive()
76.91 {
76.92 Item it = *_last_active[_highest_active];
76.93 - _level.set(it,_level[it]+1);
76.94 + ++_level[it];
76.95 swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
76.96 --_first[++_highest_active];
76.97 }
76.98 @@ -248,7 +249,7 @@
76.99 --_last_active[l];
76.100 }
76.101 copy(li,_first[new_level]);
76.102 - _level.set(li,new_level);
76.103 + _level[li] = new_level;
76.104 _highest_active=new_level;
76.105 }
76.106
76.107 @@ -268,7 +269,7 @@
76.108 }
76.109 copy(li,_first[_max_level]);
76.110 --_last_active[_max_level];
76.111 - _level.set(li,_max_level);
76.112 + _level[li] = _max_level;
76.113
76.114 while(_highest_active>=0 &&
76.115 _last_active[_highest_active]<_first[_highest_active])
76.116 @@ -298,7 +299,7 @@
76.117 Item liftActiveOn(int level)
76.118 {
76.119 Item it =*_last_active[level];
76.120 - _level.set(it,_level[it]+1);
76.121 + ++_level[it];
76.122 swap(_last_active[level]--, --_first[level+1]);
76.123 if (level+1>_highest_active) ++_highest_active;
76.124 }
76.125 @@ -318,7 +319,7 @@
76.126 copy(--_first[l+1], _last_active[l]--);
76.127 }
76.128 copy(ai,_first[new_level]);
76.129 - _level.set(ai,new_level);
76.130 + _level[ai] = new_level;
76.131 if (new_level>_highest_active) _highest_active=new_level;
76.132 }
76.133
76.134 @@ -338,7 +339,7 @@
76.135 }
76.136 copy(ai,_first[_max_level]);
76.137 --_last_active[_max_level];
76.138 - _level.set(ai,_max_level);
76.139 + _level[ai] = _max_level;
76.140
76.141 if (_highest_active==level) {
76.142 while(_highest_active>=0 &&
76.143 @@ -369,7 +370,7 @@
76.144 copy(--_first[l+1],_last_active[l]--);
76.145 }
76.146 copy(i,_first[new_level]);
76.147 - _level.set(i,new_level);
76.148 + _level[i] = new_level;
76.149 if(new_level>_highest_active) _highest_active=new_level;
76.150 }
76.151
76.152 @@ -381,7 +382,7 @@
76.153 ///only if you really know what it is for.
76.154 ///\pre The item is on the top level.
76.155 void dirtyTopButOne(Item i) {
76.156 - _level.set(i,_max_level - 1);
76.157 + _level[i] = _max_level - 1;
76.158 }
76.159
76.160 ///Lift all items on and above the given level to the top level.
76.161 @@ -393,7 +394,7 @@
76.162 const Vit f=_first[l];
76.163 const Vit tl=_first[_max_level];
76.164 for(Vit i=f;i!=tl;++i)
76.165 - _level.set(*i,_max_level);
76.166 + _level[*i] = _max_level;
76.167 for(int i=l;i<=_max_level;i++)
76.168 {
76.169 _first[i]=f;
76.170 @@ -429,11 +430,11 @@
76.171 _first[0]=&_items[0];
76.172 _last_active[0]=&_items[0]-1;
76.173 Vit n=&_items[0];
76.174 - for(typename ItemSetTraits<Graph,Item>::ItemIt i(_g);i!=INVALID;++i)
76.175 + for(typename ItemSetTraits<GR,Item>::ItemIt i(_g);i!=INVALID;++i)
76.176 {
76.177 *n=i;
76.178 - _where.set(i,n);
76.179 - _level.set(i,_max_level);
76.180 + _where[i] = n;
76.181 + _level[i] = _max_level;
76.182 ++n;
76.183 }
76.184 }
76.185 @@ -442,7 +443,7 @@
76.186 void initAddItem(Item i)
76.187 {
76.188 swap(_where[i],_init_num);
76.189 - _level.set(i,_init_lev);
76.190 + _level[i] = _init_lev;
76.191 ++_init_num;
76.192 }
76.193
76.194 @@ -488,10 +489,10 @@
76.195 ///
76.196 ///\sa Elevator
76.197 ///
76.198 - ///\param Graph Type of the underlying graph.
76.199 - ///\param Item Type of the items the data is assigned to (Graph::Node,
76.200 - ///Graph::Arc, Graph::Edge).
76.201 - template <class Graph, class Item>
76.202 + ///\param GR Type of the underlying graph.
76.203 + ///\param Item Type of the items the data is assigned to (\c GR::Node,
76.204 + ///\c GR::Arc or \c GR::Edge).
76.205 + template <class GR, class Item>
76.206 class LinkedElevator {
76.207 public:
76.208
76.209 @@ -500,14 +501,14 @@
76.210
76.211 private:
76.212
76.213 - typedef typename ItemSetTraits<Graph,Item>::
76.214 + typedef typename ItemSetTraits<GR,Item>::
76.215 template Map<Item>::Type ItemMap;
76.216 - typedef typename ItemSetTraits<Graph,Item>::
76.217 + typedef typename ItemSetTraits<GR,Item>::
76.218 template Map<int>::Type IntMap;
76.219 - typedef typename ItemSetTraits<Graph,Item>::
76.220 + typedef typename ItemSetTraits<GR,Item>::
76.221 template Map<bool>::Type BoolMap;
76.222
76.223 - const Graph &_graph;
76.224 + const GR &_graph;
76.225 int _max_level;
76.226 int _item_num;
76.227 std::vector<Item> _first, _last;
76.228 @@ -524,7 +525,7 @@
76.229 ///\param graph The underlying graph.
76.230 ///\param max_level The maximum allowed level.
76.231 ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
76.232 - LinkedElevator(const Graph& graph, int max_level)
76.233 + LinkedElevator(const GR& graph, int max_level)
76.234 : _graph(graph), _max_level(max_level), _item_num(_max_level),
76.235 _first(_max_level + 1), _last(_max_level + 1),
76.236 _prev(graph), _next(graph),
76.237 @@ -537,8 +538,8 @@
76.238 ///\param graph The underlying graph.
76.239 ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
76.240 ///where \c max_level is equal to the number of labeled items in the graph.
76.241 - LinkedElevator(const Graph& graph)
76.242 - : _graph(graph), _max_level(countItems<Graph, Item>(graph)),
76.243 + LinkedElevator(const GR& graph)
76.244 + : _graph(graph), _max_level(countItems<GR, Item>(graph)),
76.245 _item_num(_max_level),
76.246 _first(_max_level + 1), _last(_max_level + 1),
76.247 _prev(graph, INVALID), _next(graph, INVALID),
76.248 @@ -550,7 +551,7 @@
76.249 ///Activate item \c i.
76.250 ///\pre Item \c i shouldn't be active before.
76.251 void activate(Item i) {
76.252 - _active.set(i, true);
76.253 + _active[i] = true;
76.254
76.255 int level = _level[i];
76.256 if (level > _highest_active) {
76.257 @@ -559,16 +560,16 @@
76.258
76.259 if (_prev[i] == INVALID || _active[_prev[i]]) return;
76.260 //unlace
76.261 - _next.set(_prev[i], _next[i]);
76.262 + _next[_prev[i]] = _next[i];
76.263 if (_next[i] != INVALID) {
76.264 - _prev.set(_next[i], _prev[i]);
76.265 + _prev[_next[i]] = _prev[i];
76.266 } else {
76.267 _last[level] = _prev[i];
76.268 }
76.269 //lace
76.270 - _next.set(i, _first[level]);
76.271 - _prev.set(_first[level], i);
76.272 - _prev.set(i, INVALID);
76.273 + _next[i] = _first[level];
76.274 + _prev[_first[level]] = i;
76.275 + _prev[i] = INVALID;
76.276 _first[level] = i;
76.277
76.278 }
76.279 @@ -578,23 +579,23 @@
76.280 ///Deactivate item \c i.
76.281 ///\pre Item \c i must be active before.
76.282 void deactivate(Item i) {
76.283 - _active.set(i, false);
76.284 + _active[i] = false;
76.285 int level = _level[i];
76.286
76.287 if (_next[i] == INVALID || !_active[_next[i]])
76.288 goto find_highest_level;
76.289
76.290 //unlace
76.291 - _prev.set(_next[i], _prev[i]);
76.292 + _prev[_next[i]] = _prev[i];
76.293 if (_prev[i] != INVALID) {
76.294 - _next.set(_prev[i], _next[i]);
76.295 + _next[_prev[i]] = _next[i];
76.296 } else {
76.297 _first[_level[i]] = _next[i];
76.298 }
76.299 //lace
76.300 - _prev.set(i, _last[level]);
76.301 - _next.set(_last[level], i);
76.302 - _next.set(i, INVALID);
76.303 + _prev[i] = _last[level];
76.304 + _next[_last[level]] = i;
76.305 + _next[i] = INVALID;
76.306 _last[level] = i;
76.307
76.308 find_highest_level:
76.309 @@ -684,21 +685,21 @@
76.310 void liftHighestActive() {
76.311 Item i = _first[_highest_active];
76.312 if (_next[i] != INVALID) {
76.313 - _prev.set(_next[i], INVALID);
76.314 + _prev[_next[i]] = INVALID;
76.315 _first[_highest_active] = _next[i];
76.316 } else {
76.317 _first[_highest_active] = INVALID;
76.318 _last[_highest_active] = INVALID;
76.319 }
76.320 - _level.set(i, ++_highest_active);
76.321 + _level[i] = ++_highest_active;
76.322 if (_first[_highest_active] == INVALID) {
76.323 _first[_highest_active] = i;
76.324 _last[_highest_active] = i;
76.325 - _prev.set(i, INVALID);
76.326 - _next.set(i, INVALID);
76.327 + _prev[i] = INVALID;
76.328 + _next[i] = INVALID;
76.329 } else {
76.330 - _prev.set(_first[_highest_active], i);
76.331 - _next.set(i, _first[_highest_active]);
76.332 + _prev[_first[_highest_active]] = i;
76.333 + _next[i] = _first[_highest_active];
76.334 _first[_highest_active] = i;
76.335 }
76.336 }
76.337 @@ -713,20 +714,20 @@
76.338 void liftHighestActive(int new_level) {
76.339 Item i = _first[_highest_active];
76.340 if (_next[i] != INVALID) {
76.341 - _prev.set(_next[i], INVALID);
76.342 + _prev[_next[i]] = INVALID;
76.343 _first[_highest_active] = _next[i];
76.344 } else {
76.345 _first[_highest_active] = INVALID;
76.346 _last[_highest_active] = INVALID;
76.347 }
76.348 - _level.set(i, _highest_active = new_level);
76.349 + _level[i] = _highest_active = new_level;
76.350 if (_first[_highest_active] == INVALID) {
76.351 _first[_highest_active] = _last[_highest_active] = i;
76.352 - _prev.set(i, INVALID);
76.353 - _next.set(i, INVALID);
76.354 + _prev[i] = INVALID;
76.355 + _next[i] = INVALID;
76.356 } else {
76.357 - _prev.set(_first[_highest_active], i);
76.358 - _next.set(i, _first[_highest_active]);
76.359 + _prev[_first[_highest_active]] = i;
76.360 + _next[i] = _first[_highest_active];
76.361 _first[_highest_active] = i;
76.362 }
76.363 }
76.364 @@ -737,9 +738,9 @@
76.365 ///deactivate it.
76.366 void liftHighestActiveToTop() {
76.367 Item i = _first[_highest_active];
76.368 - _level.set(i, _max_level);
76.369 + _level[i] = _max_level;
76.370 if (_next[i] != INVALID) {
76.371 - _prev.set(_next[i], INVALID);
76.372 + _prev[_next[i]] = INVALID;
76.373 _first[_highest_active] = _next[i];
76.374 } else {
76.375 _first[_highest_active] = INVALID;
76.376 @@ -773,20 +774,20 @@
76.377 {
76.378 Item i = _first[l];
76.379 if (_next[i] != INVALID) {
76.380 - _prev.set(_next[i], INVALID);
76.381 + _prev[_next[i]] = INVALID;
76.382 _first[l] = _next[i];
76.383 } else {
76.384 _first[l] = INVALID;
76.385 _last[l] = INVALID;
76.386 }
76.387 - _level.set(i, ++l);
76.388 + _level[i] = ++l;
76.389 if (_first[l] == INVALID) {
76.390 _first[l] = _last[l] = i;
76.391 - _prev.set(i, INVALID);
76.392 - _next.set(i, INVALID);
76.393 + _prev[i] = INVALID;
76.394 + _next[i] = INVALID;
76.395 } else {
76.396 - _prev.set(_first[l], i);
76.397 - _next.set(i, _first[l]);
76.398 + _prev[_first[l]] = i;
76.399 + _next[i] = _first[l];
76.400 _first[l] = i;
76.401 }
76.402 if (_highest_active < l) {
76.403 @@ -802,20 +803,20 @@
76.404 {
76.405 Item i = _first[l];
76.406 if (_next[i] != INVALID) {
76.407 - _prev.set(_next[i], INVALID);
76.408 + _prev[_next[i]] = INVALID;
76.409 _first[l] = _next[i];
76.410 } else {
76.411 _first[l] = INVALID;
76.412 _last[l] = INVALID;
76.413 }
76.414 - _level.set(i, l = new_level);
76.415 + _level[i] = l = new_level;
76.416 if (_first[l] == INVALID) {
76.417 _first[l] = _last[l] = i;
76.418 - _prev.set(i, INVALID);
76.419 - _next.set(i, INVALID);
76.420 + _prev[i] = INVALID;
76.421 + _next[i] = INVALID;
76.422 } else {
76.423 - _prev.set(_first[l], i);
76.424 - _next.set(i, _first[l]);
76.425 + _prev[_first[l]] = i;
76.426 + _next[i] = _first[l];
76.427 _first[l] = i;
76.428 }
76.429 if (_highest_active < l) {
76.430 @@ -831,13 +832,13 @@
76.431 {
76.432 Item i = _first[l];
76.433 if (_next[i] != INVALID) {
76.434 - _prev.set(_next[i], INVALID);
76.435 + _prev[_next[i]] = INVALID;
76.436 _first[l] = _next[i];
76.437 } else {
76.438 _first[l] = INVALID;
76.439 _last[l] = INVALID;
76.440 }
76.441 - _level.set(i, _max_level);
76.442 + _level[i] = _max_level;
76.443 if (l == _highest_active) {
76.444 while (_highest_active >= 0 && activeFree(_highest_active))
76.445 --_highest_active;
76.446 @@ -855,23 +856,23 @@
76.447 ///
76.448 void lift(Item i, int new_level) {
76.449 if (_next[i] != INVALID) {
76.450 - _prev.set(_next[i], _prev[i]);
76.451 + _prev[_next[i]] = _prev[i];
76.452 } else {
76.453 _last[new_level] = _prev[i];
76.454 }
76.455 if (_prev[i] != INVALID) {
76.456 - _next.set(_prev[i], _next[i]);
76.457 + _next[_prev[i]] = _next[i];
76.458 } else {
76.459 _first[new_level] = _next[i];
76.460 }
76.461 - _level.set(i, new_level);
76.462 + _level[i] = new_level;
76.463 if (_first[new_level] == INVALID) {
76.464 _first[new_level] = _last[new_level] = i;
76.465 - _prev.set(i, INVALID);
76.466 - _next.set(i, INVALID);
76.467 + _prev[i] = INVALID;
76.468 + _next[i] = INVALID;
76.469 } else {
76.470 - _prev.set(_first[new_level], i);
76.471 - _next.set(i, _first[new_level]);
76.472 + _prev[_first[new_level]] = i;
76.473 + _next[i] = _first[new_level];
76.474 _first[new_level] = i;
76.475 }
76.476 if (_highest_active < new_level) {
76.477 @@ -887,7 +888,7 @@
76.478 ///only if you really know what it is for.
76.479 ///\pre The item is on the top level.
76.480 void dirtyTopButOne(Item i) {
76.481 - _level.set(i, _max_level - 1);
76.482 + _level[i] = _max_level - 1;
76.483 }
76.484
76.485 ///Lift all items on and above the given level to the top level.
76.486 @@ -898,7 +899,7 @@
76.487 for (int i = l + 1; _first[i] != INVALID; ++i) {
76.488 Item n = _first[i];
76.489 while (n != INVALID) {
76.490 - _level.set(n, _max_level);
76.491 + _level[n] = _max_level;
76.492 n = _next[n];
76.493 }
76.494 _first[i] = INVALID;
76.495 @@ -934,25 +935,25 @@
76.496 _first[i] = _last[i] = INVALID;
76.497 }
76.498 _init_level = 0;
76.499 - for(typename ItemSetTraits<Graph,Item>::ItemIt i(_graph);
76.500 + for(typename ItemSetTraits<GR,Item>::ItemIt i(_graph);
76.501 i != INVALID; ++i) {
76.502 - _level.set(i, _max_level);
76.503 - _active.set(i, false);
76.504 + _level[i] = _max_level;
76.505 + _active[i] = false;
76.506 }
76.507 }
76.508
76.509 ///Add an item to the current level.
76.510 void initAddItem(Item i) {
76.511 - _level.set(i, _init_level);
76.512 + _level[i] = _init_level;
76.513 if (_last[_init_level] == INVALID) {
76.514 _first[_init_level] = i;
76.515 _last[_init_level] = i;
76.516 - _prev.set(i, INVALID);
76.517 - _next.set(i, INVALID);
76.518 + _prev[i] = INVALID;
76.519 + _next[i] = INVALID;
76.520 } else {
76.521 - _prev.set(i, _last[_init_level]);
76.522 - _next.set(i, INVALID);
76.523 - _next.set(_last[_init_level], i);
76.524 + _prev[i] = _last[_init_level];
76.525 + _next[i] = INVALID;
76.526 + _next[_last[_init_level]] = i;
76.527 _last[_init_level] = i;
76.528 }
76.529 }
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
77.2 +++ b/lemon/euler.h Thu Nov 05 15:48:01 2009 +0100
77.3 @@ -0,0 +1,287 @@
77.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
77.5 + *
77.6 + * This file is a part of LEMON, a generic C++ optimization library.
77.7 + *
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 + * Permission to use, modify and distribute this software is granted
77.13 + * provided that this copyright notice appears in all copies. For
77.14 + * precise terms see the accompanying LICENSE file.
77.15 + *
77.16 + * This software is provided "AS IS" with no warranty of any kind,
77.17 + * express or implied, and with no claim as to its suitability for any
77.18 + * purpose.
77.19 + *
77.20 + */
77.21 +
77.22 +#ifndef LEMON_EULER_H
77.23 +#define LEMON_EULER_H
77.24 +
77.25 +#include<lemon/core.h>
77.26 +#include<lemon/adaptors.h>
77.27 +#include<lemon/connectivity.h>
77.28 +#include <list>
77.29 +
77.30 +/// \ingroup graph_properties
77.31 +/// \file
77.32 +/// \brief Euler tour iterators and a function for checking the \e Eulerian
77.33 +/// property.
77.34 +///
77.35 +///This file provides Euler tour iterators and a function to check
77.36 +///if a (di)graph is \e Eulerian.
77.37 +
77.38 +namespace lemon {
77.39 +
77.40 + ///Euler tour iterator for digraphs.
77.41 +
77.42 + /// \ingroup graph_prop
77.43 + ///This iterator provides an Euler tour (Eulerian circuit) of a \e directed
77.44 + ///graph (if there exists) and it converts to the \c Arc type of the digraph.
77.45 + ///
77.46 + ///For example, if the given digraph has an Euler tour (i.e it has only one
77.47 + ///non-trivial component and the in-degree is equal to the out-degree
77.48 + ///for all nodes), then the following code will put the arcs of \c g
77.49 + ///to the vector \c et according to an Euler tour of \c g.
77.50 + ///\code
77.51 + /// std::vector<ListDigraph::Arc> et;
77.52 + /// for(DiEulerIt<ListDigraph> e(g); e!=INVALID; ++e)
77.53 + /// et.push_back(e);
77.54 + ///\endcode
77.55 + ///If \c g has no Euler tour, then the resulted walk will not be closed
77.56 + ///or not contain all arcs.
77.57 + ///\sa EulerIt
77.58 + template<typename GR>
77.59 + class DiEulerIt
77.60 + {
77.61 + typedef typename GR::Node Node;
77.62 + typedef typename GR::NodeIt NodeIt;
77.63 + typedef typename GR::Arc Arc;
77.64 + typedef typename GR::ArcIt ArcIt;
77.65 + typedef typename GR::OutArcIt OutArcIt;
77.66 + typedef typename GR::InArcIt InArcIt;
77.67 +
77.68 + const GR &g;
77.69 + typename GR::template NodeMap<OutArcIt> narc;
77.70 + std::list<Arc> euler;
77.71 +
77.72 + public:
77.73 +
77.74 + ///Constructor
77.75 +
77.76 + ///Constructor.
77.77 + ///\param gr A digraph.
77.78 + ///\param start The starting point of the tour. If it is not given,
77.79 + ///the tour will start from the first node that has an outgoing arc.
77.80 + DiEulerIt(const GR &gr, typename GR::Node start = INVALID)
77.81 + : g(gr), narc(g)
77.82 + {
77.83 + if (start==INVALID) {
77.84 + NodeIt n(g);
77.85 + while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
77.86 + start=n;
77.87 + }
77.88 + if (start!=INVALID) {
77.89 + for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
77.90 + while (narc[start]!=INVALID) {
77.91 + euler.push_back(narc[start]);
77.92 + Node next=g.target(narc[start]);
77.93 + ++narc[start];
77.94 + start=next;
77.95 + }
77.96 + }
77.97 + }
77.98 +
77.99 + ///Arc conversion
77.100 + operator Arc() { return euler.empty()?INVALID:euler.front(); }
77.101 + ///Compare with \c INVALID
77.102 + bool operator==(Invalid) { return euler.empty(); }
77.103 + ///Compare with \c INVALID
77.104 + bool operator!=(Invalid) { return !euler.empty(); }
77.105 +
77.106 + ///Next arc of the tour
77.107 +
77.108 + ///Next arc of the tour
77.109 + ///
77.110 + DiEulerIt &operator++() {
77.111 + Node s=g.target(euler.front());
77.112 + euler.pop_front();
77.113 + typename std::list<Arc>::iterator next=euler.begin();
77.114 + while(narc[s]!=INVALID) {
77.115 + euler.insert(next,narc[s]);
77.116 + Node n=g.target(narc[s]);
77.117 + ++narc[s];
77.118 + s=n;
77.119 + }
77.120 + return *this;
77.121 + }
77.122 + ///Postfix incrementation
77.123 +
77.124 + /// Postfix incrementation.
77.125 + ///
77.126 + ///\warning This incrementation
77.127 + ///returns an \c Arc, not a \ref DiEulerIt, as one may
77.128 + ///expect.
77.129 + Arc operator++(int)
77.130 + {
77.131 + Arc e=*this;
77.132 + ++(*this);
77.133 + return e;
77.134 + }
77.135 + };
77.136 +
77.137 + ///Euler tour iterator for graphs.
77.138 +
77.139 + /// \ingroup graph_properties
77.140 + ///This iterator provides an Euler tour (Eulerian circuit) of an
77.141 + ///\e undirected graph (if there exists) and it converts to the \c Arc
77.142 + ///and \c Edge types of the graph.
77.143 + ///
77.144 + ///For example, if the given graph has an Euler tour (i.e it has only one
77.145 + ///non-trivial component and the degree of each node is even),
77.146 + ///the following code will print the arc IDs according to an
77.147 + ///Euler tour of \c g.
77.148 + ///\code
77.149 + /// for(EulerIt<ListGraph> e(g); e!=INVALID; ++e) {
77.150 + /// std::cout << g.id(Edge(e)) << std::eol;
77.151 + /// }
77.152 + ///\endcode
77.153 + ///Although this iterator is for undirected graphs, it still returns
77.154 + ///arcs in order to indicate the direction of the tour.
77.155 + ///(But arcs convert to edges, of course.)
77.156 + ///
77.157 + ///If \c g has no Euler tour, then the resulted walk will not be closed
77.158 + ///or not contain all edges.
77.159 + template<typename GR>
77.160 + class EulerIt
77.161 + {
77.162 + typedef typename GR::Node Node;
77.163 + typedef typename GR::NodeIt NodeIt;
77.164 + typedef typename GR::Arc Arc;
77.165 + typedef typename GR::Edge Edge;
77.166 + typedef typename GR::ArcIt ArcIt;
77.167 + typedef typename GR::OutArcIt OutArcIt;
77.168 + typedef typename GR::InArcIt InArcIt;
77.169 +
77.170 + const GR &g;
77.171 + typename GR::template NodeMap<OutArcIt> narc;
77.172 + typename GR::template EdgeMap<bool> visited;
77.173 + std::list<Arc> euler;
77.174 +
77.175 + public:
77.176 +
77.177 + ///Constructor
77.178 +
77.179 + ///Constructor.
77.180 + ///\param gr A graph.
77.181 + ///\param start The starting point of the tour. If it is not given,
77.182 + ///the tour will start from the first node that has an incident edge.
77.183 + EulerIt(const GR &gr, typename GR::Node start = INVALID)
77.184 + : g(gr), narc(g), visited(g, false)
77.185 + {
77.186 + if (start==INVALID) {
77.187 + NodeIt n(g);
77.188 + while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
77.189 + start=n;
77.190 + }
77.191 + if (start!=INVALID) {
77.192 + for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
77.193 + while(narc[start]!=INVALID) {
77.194 + euler.push_back(narc[start]);
77.195 + visited[narc[start]]=true;
77.196 + Node next=g.target(narc[start]);
77.197 + ++narc[start];
77.198 + start=next;
77.199 + while(narc[start]!=INVALID && visited[narc[start]]) ++narc[start];
77.200 + }
77.201 + }
77.202 + }
77.203 +
77.204 + ///Arc conversion
77.205 + operator Arc() const { return euler.empty()?INVALID:euler.front(); }
77.206 + ///Edge conversion
77.207 + operator Edge() const { return euler.empty()?INVALID:euler.front(); }
77.208 + ///Compare with \c INVALID
77.209 + bool operator==(Invalid) const { return euler.empty(); }
77.210 + ///Compare with \c INVALID
77.211 + bool operator!=(Invalid) const { return !euler.empty(); }
77.212 +
77.213 + ///Next arc of the tour
77.214 +
77.215 + ///Next arc of the tour
77.216 + ///
77.217 + EulerIt &operator++() {
77.218 + Node s=g.target(euler.front());
77.219 + euler.pop_front();
77.220 + typename std::list<Arc>::iterator next=euler.begin();
77.221 + while(narc[s]!=INVALID) {
77.222 + while(narc[s]!=INVALID && visited[narc[s]]) ++narc[s];
77.223 + if(narc[s]==INVALID) break;
77.224 + else {
77.225 + euler.insert(next,narc[s]);
77.226 + visited[narc[s]]=true;
77.227 + Node n=g.target(narc[s]);
77.228 + ++narc[s];
77.229 + s=n;
77.230 + }
77.231 + }
77.232 + return *this;
77.233 + }
77.234 +
77.235 + ///Postfix incrementation
77.236 +
77.237 + /// Postfix incrementation.
77.238 + ///
77.239 + ///\warning This incrementation returns an \c Arc (which converts to
77.240 + ///an \c Edge), not an \ref EulerIt, as one may expect.
77.241 + Arc operator++(int)
77.242 + {
77.243 + Arc e=*this;
77.244 + ++(*this);
77.245 + return e;
77.246 + }
77.247 + };
77.248 +
77.249 +
77.250 + ///Check if the given graph is Eulerian
77.251 +
77.252 + /// \ingroup graph_properties
77.253 + ///This function checks if the given graph is Eulerian.
77.254 + ///It works for both directed and undirected graphs.
77.255 + ///
77.256 + ///By definition, a digraph is called \e Eulerian if
77.257 + ///and only if it is connected and the number of incoming and outgoing
77.258 + ///arcs are the same for each node.
77.259 + ///Similarly, an undirected graph is called \e Eulerian if
77.260 + ///and only if it is connected and the number of incident edges is even
77.261 + ///for each node.
77.262 + ///
77.263 + ///\note There are (di)graphs that are not Eulerian, but still have an
77.264 + /// Euler tour, since they may contain isolated nodes.
77.265 + ///
77.266 + ///\sa DiEulerIt, EulerIt
77.267 + template<typename GR>
77.268 +#ifdef DOXYGEN
77.269 + bool
77.270 +#else
77.271 + typename enable_if<UndirectedTagIndicator<GR>,bool>::type
77.272 + eulerian(const GR &g)
77.273 + {
77.274 + for(typename GR::NodeIt n(g);n!=INVALID;++n)
77.275 + if(countIncEdges(g,n)%2) return false;
77.276 + return connected(g);
77.277 + }
77.278 + template<class GR>
77.279 + typename disable_if<UndirectedTagIndicator<GR>,bool>::type
77.280 +#endif
77.281 + eulerian(const GR &g)
77.282 + {
77.283 + for(typename GR::NodeIt n(g);n!=INVALID;++n)
77.284 + if(countInArcs(g,n)!=countOutArcs(g,n)) return false;
77.285 + return connected(undirector(g));
77.286 + }
77.287 +
77.288 +}
77.289 +
77.290 +#endif
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
78.2 +++ b/lemon/fib_heap.h Thu Nov 05 15:48:01 2009 +0100
78.3 @@ -0,0 +1,475 @@
78.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
78.5 + *
78.6 + * This file is a part of LEMON, a generic C++ optimization library.
78.7 + *
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 + * Permission to use, modify and distribute this software is granted
78.13 + * provided that this copyright notice appears in all copies. For
78.14 + * precise terms see the accompanying LICENSE file.
78.15 + *
78.16 + * This software is provided "AS IS" with no warranty of any kind,
78.17 + * express or implied, and with no claim as to its suitability for any
78.18 + * purpose.
78.19 + *
78.20 + */
78.21 +
78.22 +#ifndef LEMON_FIB_HEAP_H
78.23 +#define LEMON_FIB_HEAP_H
78.24 +
78.25 +///\file
78.26 +///\ingroup heaps
78.27 +///\brief Fibonacci heap implementation.
78.28 +
78.29 +#include <vector>
78.30 +#include <utility>
78.31 +#include <functional>
78.32 +#include <lemon/math.h>
78.33 +
78.34 +namespace lemon {
78.35 +
78.36 + /// \ingroup heaps
78.37 + ///
78.38 + /// \brief Fibonacci heap data structure.
78.39 + ///
78.40 + /// This class implements the \e Fibonacci \e heap data structure.
78.41 + /// It fully conforms to the \ref concepts::Heap "heap concept".
78.42 + ///
78.43 + /// The methods \ref increase() and \ref erase() are not efficient in a
78.44 + /// Fibonacci heap. In case of many calls of these operations, it is
78.45 + /// better to use other heap structure, e.g. \ref BinHeap "binary heap".
78.46 + ///
78.47 + /// \tparam PR Type of the priorities of the items.
78.48 + /// \tparam IM A read-writable item map with \c int values, used
78.49 + /// internally to handle the cross references.
78.50 + /// \tparam CMP A functor class for comparing the priorities.
78.51 + /// The default is \c std::less<PR>.
78.52 +#ifdef DOXYGEN
78.53 + template <typename PR, typename IM, typename CMP>
78.54 +#else
78.55 + template <typename PR, typename IM, typename CMP = std::less<PR> >
78.56 +#endif
78.57 + class FibHeap {
78.58 + public:
78.59 +
78.60 + /// Type of the item-int map.
78.61 + typedef IM ItemIntMap;
78.62 + /// Type of the priorities.
78.63 + typedef PR Prio;
78.64 + /// Type of the items stored in the heap.
78.65 + typedef typename ItemIntMap::Key Item;
78.66 + /// Type of the item-priority pairs.
78.67 + typedef std::pair<Item,Prio> Pair;
78.68 + /// Functor type for comparing the priorities.
78.69 + typedef CMP Compare;
78.70 +
78.71 + private:
78.72 + class Store;
78.73 +
78.74 + std::vector<Store> _data;
78.75 + int _minimum;
78.76 + ItemIntMap &_iim;
78.77 + Compare _comp;
78.78 + int _num;
78.79 +
78.80 + public:
78.81 +
78.82 + /// \brief Type to represent the states of the items.
78.83 + ///
78.84 + /// Each item has a state associated to it. It can be "in heap",
78.85 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
78.86 + /// heap's point of view, but may be useful to the user.
78.87 + ///
78.88 + /// The item-int map must be initialized in such way that it assigns
78.89 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
78.90 + enum State {
78.91 + IN_HEAP = 0, ///< = 0.
78.92 + PRE_HEAP = -1, ///< = -1.
78.93 + POST_HEAP = -2 ///< = -2.
78.94 + };
78.95 +
78.96 + /// \brief Constructor.
78.97 + ///
78.98 + /// Constructor.
78.99 + /// \param map A map that assigns \c int values to the items.
78.100 + /// It is used internally to handle the cross references.
78.101 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
78.102 + explicit FibHeap(ItemIntMap &map)
78.103 + : _minimum(0), _iim(map), _num() {}
78.104 +
78.105 + /// \brief Constructor.
78.106 + ///
78.107 + /// Constructor.
78.108 + /// \param map A map that assigns \c int values to the items.
78.109 + /// It is used internally to handle the cross references.
78.110 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
78.111 + /// \param comp The function object used for comparing the priorities.
78.112 + FibHeap(ItemIntMap &map, const Compare &comp)
78.113 + : _minimum(0), _iim(map), _comp(comp), _num() {}
78.114 +
78.115 + /// \brief The number of items stored in the heap.
78.116 + ///
78.117 + /// This function returns the number of items stored in the heap.
78.118 + int size() const { return _num; }
78.119 +
78.120 + /// \brief Check if the heap is empty.
78.121 + ///
78.122 + /// This function returns \c true if the heap is empty.
78.123 + bool empty() const { return _num==0; }
78.124 +
78.125 + /// \brief Make the heap empty.
78.126 + ///
78.127 + /// This functon makes the heap empty.
78.128 + /// It does not change the cross reference map. If you want to reuse
78.129 + /// a heap that is not surely empty, you should first clear it and
78.130 + /// then you should set the cross reference map to \c PRE_HEAP
78.131 + /// for each item.
78.132 + void clear() {
78.133 + _data.clear(); _minimum = 0; _num = 0;
78.134 + }
78.135 +
78.136 + /// \brief Insert an item into the heap with the given priority.
78.137 + ///
78.138 + /// This function inserts the given item into the heap with the
78.139 + /// given priority.
78.140 + /// \param item The item to insert.
78.141 + /// \param prio The priority of the item.
78.142 + /// \pre \e item must not be stored in the heap.
78.143 + void push (const Item& item, const Prio& prio) {
78.144 + int i=_iim[item];
78.145 + if ( i < 0 ) {
78.146 + int s=_data.size();
78.147 + _iim.set( item, s );
78.148 + Store st;
78.149 + st.name=item;
78.150 + _data.push_back(st);
78.151 + i=s;
78.152 + } else {
78.153 + _data[i].parent=_data[i].child=-1;
78.154 + _data[i].degree=0;
78.155 + _data[i].in=true;
78.156 + _data[i].marked=false;
78.157 + }
78.158 +
78.159 + if ( _num ) {
78.160 + _data[_data[_minimum].right_neighbor].left_neighbor=i;
78.161 + _data[i].right_neighbor=_data[_minimum].right_neighbor;
78.162 + _data[_minimum].right_neighbor=i;
78.163 + _data[i].left_neighbor=_minimum;
78.164 + if ( _comp( prio, _data[_minimum].prio) ) _minimum=i;
78.165 + } else {
78.166 + _data[i].right_neighbor=_data[i].left_neighbor=i;
78.167 + _minimum=i;
78.168 + }
78.169 + _data[i].prio=prio;
78.170 + ++_num;
78.171 + }
78.172 +
78.173 + /// \brief Return the item having minimum priority.
78.174 + ///
78.175 + /// This function returns the item having minimum priority.
78.176 + /// \pre The heap must be non-empty.
78.177 + Item top() const { return _data[_minimum].name; }
78.178 +
78.179 + /// \brief The minimum priority.
78.180 + ///
78.181 + /// This function returns the minimum priority.
78.182 + /// \pre The heap must be non-empty.
78.183 + Prio prio() const { return _data[_minimum].prio; }
78.184 +
78.185 + /// \brief Remove the item having minimum priority.
78.186 + ///
78.187 + /// This function removes the item having minimum priority.
78.188 + /// \pre The heap must be non-empty.
78.189 + void pop() {
78.190 + /*The first case is that there are only one root.*/
78.191 + if ( _data[_minimum].left_neighbor==_minimum ) {
78.192 + _data[_minimum].in=false;
78.193 + if ( _data[_minimum].degree!=0 ) {
78.194 + makeRoot(_data[_minimum].child);
78.195 + _minimum=_data[_minimum].child;
78.196 + balance();
78.197 + }
78.198 + } else {
78.199 + int right=_data[_minimum].right_neighbor;
78.200 + unlace(_minimum);
78.201 + _data[_minimum].in=false;
78.202 + if ( _data[_minimum].degree > 0 ) {
78.203 + int left=_data[_minimum].left_neighbor;
78.204 + int child=_data[_minimum].child;
78.205 + int last_child=_data[child].left_neighbor;
78.206 +
78.207 + makeRoot(child);
78.208 +
78.209 + _data[left].right_neighbor=child;
78.210 + _data[child].left_neighbor=left;
78.211 + _data[right].left_neighbor=last_child;
78.212 + _data[last_child].right_neighbor=right;
78.213 + }
78.214 + _minimum=right;
78.215 + balance();
78.216 + } // the case where there are more roots
78.217 + --_num;
78.218 + }
78.219 +
78.220 + /// \brief Remove the given item from the heap.
78.221 + ///
78.222 + /// This function removes the given item from the heap if it is
78.223 + /// already stored.
78.224 + /// \param item The item to delete.
78.225 + /// \pre \e item must be in the heap.
78.226 + void erase (const Item& item) {
78.227 + int i=_iim[item];
78.228 +
78.229 + if ( i >= 0 && _data[i].in ) {
78.230 + if ( _data[i].parent!=-1 ) {
78.231 + int p=_data[i].parent;
78.232 + cut(i,p);
78.233 + cascade(p);
78.234 + }
78.235 + _minimum=i; //As if its prio would be -infinity
78.236 + pop();
78.237 + }
78.238 + }
78.239 +
78.240 + /// \brief The priority of the given item.
78.241 + ///
78.242 + /// This function returns the priority of the given item.
78.243 + /// \param item The item.
78.244 + /// \pre \e item must be in the heap.
78.245 + Prio operator[](const Item& item) const {
78.246 + return _data[_iim[item]].prio;
78.247 + }
78.248 +
78.249 + /// \brief Set the priority of an item or insert it, if it is
78.250 + /// not stored in the heap.
78.251 + ///
78.252 + /// This method sets the priority of the given item if it is
78.253 + /// already stored in the heap. Otherwise it inserts the given
78.254 + /// item into the heap with the given priority.
78.255 + /// \param item The item.
78.256 + /// \param prio The priority.
78.257 + void set (const Item& item, const Prio& prio) {
78.258 + int i=_iim[item];
78.259 + if ( i >= 0 && _data[i].in ) {
78.260 + if ( _comp(prio, _data[i].prio) ) decrease(item, prio);
78.261 + if ( _comp(_data[i].prio, prio) ) increase(item, prio);
78.262 + } else push(item, prio);
78.263 + }
78.264 +
78.265 + /// \brief Decrease the priority of an item to the given value.
78.266 + ///
78.267 + /// This function decreases the priority of an item to the given value.
78.268 + /// \param item The item.
78.269 + /// \param prio The priority.
78.270 + /// \pre \e item must be stored in the heap with priority at least \e prio.
78.271 + void decrease (const Item& item, const Prio& prio) {
78.272 + int i=_iim[item];
78.273 + _data[i].prio=prio;
78.274 + int p=_data[i].parent;
78.275 +
78.276 + if ( p!=-1 && _comp(prio, _data[p].prio) ) {
78.277 + cut(i,p);
78.278 + cascade(p);
78.279 + }
78.280 + if ( _comp(prio, _data[_minimum].prio) ) _minimum=i;
78.281 + }
78.282 +
78.283 + /// \brief Increase the priority of an item to the given value.
78.284 + ///
78.285 + /// This function increases the priority of an item to the given value.
78.286 + /// \param item The item.
78.287 + /// \param prio The priority.
78.288 + /// \pre \e item must be stored in the heap with priority at most \e prio.
78.289 + void increase (const Item& item, const Prio& prio) {
78.290 + erase(item);
78.291 + push(item, prio);
78.292 + }
78.293 +
78.294 + /// \brief Return the state of an item.
78.295 + ///
78.296 + /// This method returns \c PRE_HEAP if the given item has never
78.297 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
78.298 + /// and \c POST_HEAP otherwise.
78.299 + /// In the latter case it is possible that the item will get back
78.300 + /// to the heap again.
78.301 + /// \param item The item.
78.302 + State state(const Item &item) const {
78.303 + int i=_iim[item];
78.304 + if( i>=0 ) {
78.305 + if ( _data[i].in ) i=0;
78.306 + else i=-2;
78.307 + }
78.308 + return State(i);
78.309 + }
78.310 +
78.311 + /// \brief Set the state of an item in the heap.
78.312 + ///
78.313 + /// This function sets the state of the given item in the heap.
78.314 + /// It can be used to manually clear the heap when it is important
78.315 + /// to achive better time complexity.
78.316 + /// \param i The item.
78.317 + /// \param st The state. It should not be \c IN_HEAP.
78.318 + void state(const Item& i, State st) {
78.319 + switch (st) {
78.320 + case POST_HEAP:
78.321 + case PRE_HEAP:
78.322 + if (state(i) == IN_HEAP) {
78.323 + erase(i);
78.324 + }
78.325 + _iim[i] = st;
78.326 + break;
78.327 + case IN_HEAP:
78.328 + break;
78.329 + }
78.330 + }
78.331 +
78.332 + private:
78.333 +
78.334 + void balance() {
78.335 +
78.336 + int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;
78.337 +
78.338 + std::vector<int> A(maxdeg,-1);
78.339 +
78.340 + /*
78.341 + *Recall that now minimum does not point to the minimum prio element.
78.342 + *We set minimum to this during balance().
78.343 + */
78.344 + int anchor=_data[_minimum].left_neighbor;
78.345 + int next=_minimum;
78.346 + bool end=false;
78.347 +
78.348 + do {
78.349 + int active=next;
78.350 + if ( anchor==active ) end=true;
78.351 + int d=_data[active].degree;
78.352 + next=_data[active].right_neighbor;
78.353 +
78.354 + while (A[d]!=-1) {
78.355 + if( _comp(_data[active].prio, _data[A[d]].prio) ) {
78.356 + fuse(active,A[d]);
78.357 + } else {
78.358 + fuse(A[d],active);
78.359 + active=A[d];
78.360 + }
78.361 + A[d]=-1;
78.362 + ++d;
78.363 + }
78.364 + A[d]=active;
78.365 + } while ( !end );
78.366 +
78.367 +
78.368 + while ( _data[_minimum].parent >=0 )
78.369 + _minimum=_data[_minimum].parent;
78.370 + int s=_minimum;
78.371 + int m=_minimum;
78.372 + do {
78.373 + if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
78.374 + s=_data[s].right_neighbor;
78.375 + } while ( s != m );
78.376 + }
78.377 +
78.378 + void makeRoot(int c) {
78.379 + int s=c;
78.380 + do {
78.381 + _data[s].parent=-1;
78.382 + s=_data[s].right_neighbor;
78.383 + } while ( s != c );
78.384 + }
78.385 +
78.386 + void cut(int a, int b) {
78.387 + /*
78.388 + *Replacing a from the children of b.
78.389 + */
78.390 + --_data[b].degree;
78.391 +
78.392 + if ( _data[b].degree !=0 ) {
78.393 + int child=_data[b].child;
78.394 + if ( child==a )
78.395 + _data[b].child=_data[child].right_neighbor;
78.396 + unlace(a);
78.397 + }
78.398 +
78.399 +
78.400 + /*Lacing a to the roots.*/
78.401 + int right=_data[_minimum].right_neighbor;
78.402 + _data[_minimum].right_neighbor=a;
78.403 + _data[a].left_neighbor=_minimum;
78.404 + _data[a].right_neighbor=right;
78.405 + _data[right].left_neighbor=a;
78.406 +
78.407 + _data[a].parent=-1;
78.408 + _data[a].marked=false;
78.409 + }
78.410 +
78.411 + void cascade(int a) {
78.412 + if ( _data[a].parent!=-1 ) {
78.413 + int p=_data[a].parent;
78.414 +
78.415 + if ( _data[a].marked==false ) _data[a].marked=true;
78.416 + else {
78.417 + cut(a,p);
78.418 + cascade(p);
78.419 + }
78.420 + }
78.421 + }
78.422 +
78.423 + void fuse(int a, int b) {
78.424 + unlace(b);
78.425 +
78.426 + /*Lacing b under a.*/
78.427 + _data[b].parent=a;
78.428 +
78.429 + if (_data[a].degree==0) {
78.430 + _data[b].left_neighbor=b;
78.431 + _data[b].right_neighbor=b;
78.432 + _data[a].child=b;
78.433 + } else {
78.434 + int child=_data[a].child;
78.435 + int last_child=_data[child].left_neighbor;
78.436 + _data[child].left_neighbor=b;
78.437 + _data[b].right_neighbor=child;
78.438 + _data[last_child].right_neighbor=b;
78.439 + _data[b].left_neighbor=last_child;
78.440 + }
78.441 +
78.442 + ++_data[a].degree;
78.443 +
78.444 + _data[b].marked=false;
78.445 + }
78.446 +
78.447 + /*
78.448 + *It is invoked only if a has siblings.
78.449 + */
78.450 + void unlace(int a) {
78.451 + int leftn=_data[a].left_neighbor;
78.452 + int rightn=_data[a].right_neighbor;
78.453 + _data[leftn].right_neighbor=rightn;
78.454 + _data[rightn].left_neighbor=leftn;
78.455 + }
78.456 +
78.457 +
78.458 + class Store {
78.459 + friend class FibHeap;
78.460 +
78.461 + Item name;
78.462 + int parent;
78.463 + int left_neighbor;
78.464 + int right_neighbor;
78.465 + int child;
78.466 + int degree;
78.467 + bool marked;
78.468 + bool in;
78.469 + Prio prio;
78.470 +
78.471 + Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
78.472 + };
78.473 + };
78.474 +
78.475 +} //namespace lemon
78.476 +
78.477 +#endif //LEMON_FIB_HEAP_H
78.478 +
79.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
79.2 +++ b/lemon/fourary_heap.h Thu Nov 05 15:48:01 2009 +0100
79.3 @@ -0,0 +1,342 @@
79.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
79.5 + *
79.6 + * This file is a part of LEMON, a generic C++ optimization library.
79.7 + *
79.8 + * Copyright (C) 2003-2009
79.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
79.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
79.11 + *
79.12 + * Permission to use, modify and distribute this software is granted
79.13 + * provided that this copyright notice appears in all copies. For
79.14 + * precise terms see the accompanying LICENSE file.
79.15 + *
79.16 + * This software is provided "AS IS" with no warranty of any kind,
79.17 + * express or implied, and with no claim as to its suitability for any
79.18 + * purpose.
79.19 + *
79.20 + */
79.21 +
79.22 +#ifndef LEMON_FOURARY_HEAP_H
79.23 +#define LEMON_FOURARY_HEAP_H
79.24 +
79.25 +///\ingroup heaps
79.26 +///\file
79.27 +///\brief Fourary heap implementation.
79.28 +
79.29 +#include <vector>
79.30 +#include <utility>
79.31 +#include <functional>
79.32 +
79.33 +namespace lemon {
79.34 +
79.35 + /// \ingroup heaps
79.36 + ///
79.37 + ///\brief Fourary heap data structure.
79.38 + ///
79.39 + /// This class implements the \e fourary \e heap data structure.
79.40 + /// It fully conforms to the \ref concepts::Heap "heap concept".
79.41 + ///
79.42 + /// The fourary heap is a specialization of the \ref KaryHeap "K-ary heap"
79.43 + /// for <tt>K=4</tt>. It is similar to the \ref BinHeap "binary heap",
79.44 + /// but its nodes have at most four children, instead of two.
79.45 + ///
79.46 + /// \tparam PR Type of the priorities of the items.
79.47 + /// \tparam IM A read-writable item map with \c int values, used
79.48 + /// internally to handle the cross references.
79.49 + /// \tparam CMP A functor class for comparing the priorities.
79.50 + /// The default is \c std::less<PR>.
79.51 + ///
79.52 + ///\sa BinHeap
79.53 + ///\sa KaryHeap
79.54 +#ifdef DOXYGEN
79.55 + template <typename PR, typename IM, typename CMP>
79.56 +#else
79.57 + template <typename PR, typename IM, typename CMP = std::less<PR> >
79.58 +#endif
79.59 + class FouraryHeap {
79.60 + public:
79.61 + /// Type of the item-int map.
79.62 + typedef IM ItemIntMap;
79.63 + /// Type of the priorities.
79.64 + typedef PR Prio;
79.65 + /// Type of the items stored in the heap.
79.66 + typedef typename ItemIntMap::Key Item;
79.67 + /// Type of the item-priority pairs.
79.68 + typedef std::pair<Item,Prio> Pair;
79.69 + /// Functor type for comparing the priorities.
79.70 + typedef CMP Compare;
79.71 +
79.72 + /// \brief Type to represent the states of the items.
79.73 + ///
79.74 + /// Each item has a state associated to it. It can be "in heap",
79.75 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
79.76 + /// heap's point of view, but may be useful to the user.
79.77 + ///
79.78 + /// The item-int map must be initialized in such way that it assigns
79.79 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
79.80 + enum State {
79.81 + IN_HEAP = 0, ///< = 0.
79.82 + PRE_HEAP = -1, ///< = -1.
79.83 + POST_HEAP = -2 ///< = -2.
79.84 + };
79.85 +
79.86 + private:
79.87 + std::vector<Pair> _data;
79.88 + Compare _comp;
79.89 + ItemIntMap &_iim;
79.90 +
79.91 + public:
79.92 + /// \brief Constructor.
79.93 + ///
79.94 + /// Constructor.
79.95 + /// \param map A map that assigns \c int values to the items.
79.96 + /// It is used internally to handle the cross references.
79.97 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
79.98 + explicit FouraryHeap(ItemIntMap &map) : _iim(map) {}
79.99 +
79.100 + /// \brief Constructor.
79.101 + ///
79.102 + /// Constructor.
79.103 + /// \param map A map that assigns \c int values to the items.
79.104 + /// It is used internally to handle the cross references.
79.105 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
79.106 + /// \param comp The function object used for comparing the priorities.
79.107 + FouraryHeap(ItemIntMap &map, const Compare &comp)
79.108 + : _iim(map), _comp(comp) {}
79.109 +
79.110 + /// \brief The number of items stored in the heap.
79.111 + ///
79.112 + /// This function returns the number of items stored in the heap.
79.113 + int size() const { return _data.size(); }
79.114 +
79.115 + /// \brief Check if the heap is empty.
79.116 + ///
79.117 + /// This function returns \c true if the heap is empty.
79.118 + bool empty() const { return _data.empty(); }
79.119 +
79.120 + /// \brief Make the heap empty.
79.121 + ///
79.122 + /// This functon makes the heap empty.
79.123 + /// It does not change the cross reference map. If you want to reuse
79.124 + /// a heap that is not surely empty, you should first clear it and
79.125 + /// then you should set the cross reference map to \c PRE_HEAP
79.126 + /// for each item.
79.127 + void clear() { _data.clear(); }
79.128 +
79.129 + private:
79.130 + static int parent(int i) { return (i-1)/4; }
79.131 + static int firstChild(int i) { return 4*i+1; }
79.132 +
79.133 + bool less(const Pair &p1, const Pair &p2) const {
79.134 + return _comp(p1.second, p2.second);
79.135 + }
79.136 +
79.137 + void bubbleUp(int hole, Pair p) {
79.138 + int par = parent(hole);
79.139 + while( hole>0 && less(p,_data[par]) ) {
79.140 + move(_data[par],hole);
79.141 + hole = par;
79.142 + par = parent(hole);
79.143 + }
79.144 + move(p, hole);
79.145 + }
79.146 +
79.147 + void bubbleDown(int hole, Pair p, int length) {
79.148 + if( length>1 ) {
79.149 + int child = firstChild(hole);
79.150 + while( child+3<length ) {
79.151 + int min=child;
79.152 + if( less(_data[++child], _data[min]) ) min=child;
79.153 + if( less(_data[++child], _data[min]) ) min=child;
79.154 + if( less(_data[++child], _data[min]) ) min=child;
79.155 + if( !less(_data[min], p) )
79.156 + goto ok;
79.157 + move(_data[min], hole);
79.158 + hole = min;
79.159 + child = firstChild(hole);
79.160 + }
79.161 + if ( child<length ) {
79.162 + int min = child;
79.163 + if( ++child<length && less(_data[child], _data[min]) ) min=child;
79.164 + if( ++child<length && less(_data[child], _data[min]) ) min=child;
79.165 + if( less(_data[min], p) ) {
79.166 + move(_data[min], hole);
79.167 + hole = min;
79.168 + }
79.169 + }
79.170 + }
79.171 + ok:
79.172 + move(p, hole);
79.173 + }
79.174 +
79.175 + void move(const Pair &p, int i) {
79.176 + _data[i] = p;
79.177 + _iim.set(p.first, i);
79.178 + }
79.179 +
79.180 + public:
79.181 + /// \brief Insert a pair of item and priority into the heap.
79.182 + ///
79.183 + /// This function inserts \c p.first to the heap with priority
79.184 + /// \c p.second.
79.185 + /// \param p The pair to insert.
79.186 + /// \pre \c p.first must not be stored in the heap.
79.187 + void push(const Pair &p) {
79.188 + int n = _data.size();
79.189 + _data.resize(n+1);
79.190 + bubbleUp(n, p);
79.191 + }
79.192 +
79.193 + /// \brief Insert an item into the heap with the given priority.
79.194 + ///
79.195 + /// This function inserts the given item into the heap with the
79.196 + /// given priority.
79.197 + /// \param i The item to insert.
79.198 + /// \param p The priority of the item.
79.199 + /// \pre \e i must not be stored in the heap.
79.200 + void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
79.201 +
79.202 + /// \brief Return the item having minimum priority.
79.203 + ///
79.204 + /// This function returns the item having minimum priority.
79.205 + /// \pre The heap must be non-empty.
79.206 + Item top() const { return _data[0].first; }
79.207 +
79.208 + /// \brief The minimum priority.
79.209 + ///
79.210 + /// This function returns the minimum priority.
79.211 + /// \pre The heap must be non-empty.
79.212 + Prio prio() const { return _data[0].second; }
79.213 +
79.214 + /// \brief Remove the item having minimum priority.
79.215 + ///
79.216 + /// This function removes the item having minimum priority.
79.217 + /// \pre The heap must be non-empty.
79.218 + void pop() {
79.219 + int n = _data.size()-1;
79.220 + _iim.set(_data[0].first, POST_HEAP);
79.221 + if (n>0) bubbleDown(0, _data[n], n);
79.222 + _data.pop_back();
79.223 + }
79.224 +
79.225 + /// \brief Remove the given item from the heap.
79.226 + ///
79.227 + /// This function removes the given item from the heap if it is
79.228 + /// already stored.
79.229 + /// \param i The item to delete.
79.230 + /// \pre \e i must be in the heap.
79.231 + void erase(const Item &i) {
79.232 + int h = _iim[i];
79.233 + int n = _data.size()-1;
79.234 + _iim.set(_data[h].first, POST_HEAP);
79.235 + if( h<n ) {
79.236 + if( less(_data[parent(h)], _data[n]) )
79.237 + bubbleDown(h, _data[n], n);
79.238 + else
79.239 + bubbleUp(h, _data[n]);
79.240 + }
79.241 + _data.pop_back();
79.242 + }
79.243 +
79.244 + /// \brief The priority of the given item.
79.245 + ///
79.246 + /// This function returns the priority of the given item.
79.247 + /// \param i The item.
79.248 + /// \pre \e i must be in the heap.
79.249 + Prio operator[](const Item &i) const {
79.250 + int idx = _iim[i];
79.251 + return _data[idx].second;
79.252 + }
79.253 +
79.254 + /// \brief Set the priority of an item or insert it, if it is
79.255 + /// not stored in the heap.
79.256 + ///
79.257 + /// This method sets the priority of the given item if it is
79.258 + /// already stored in the heap. Otherwise it inserts the given
79.259 + /// item into the heap with the given priority.
79.260 + /// \param i The item.
79.261 + /// \param p The priority.
79.262 + void set(const Item &i, const Prio &p) {
79.263 + int idx = _iim[i];
79.264 + if( idx < 0 )
79.265 + push(i,p);
79.266 + else if( _comp(p, _data[idx].second) )
79.267 + bubbleUp(idx, Pair(i,p));
79.268 + else
79.269 + bubbleDown(idx, Pair(i,p), _data.size());
79.270 + }
79.271 +
79.272 + /// \brief Decrease the priority of an item to the given value.
79.273 + ///
79.274 + /// This function decreases the priority of an item to the given value.
79.275 + /// \param i The item.
79.276 + /// \param p The priority.
79.277 + /// \pre \e i must be stored in the heap with priority at least \e p.
79.278 + void decrease(const Item &i, const Prio &p) {
79.279 + int idx = _iim[i];
79.280 + bubbleUp(idx, Pair(i,p));
79.281 + }
79.282 +
79.283 + /// \brief Increase the priority of an item to the given value.
79.284 + ///
79.285 + /// This function increases the priority of an item to the given value.
79.286 + /// \param i The item.
79.287 + /// \param p The priority.
79.288 + /// \pre \e i must be stored in the heap with priority at most \e p.
79.289 + void increase(const Item &i, const Prio &p) {
79.290 + int idx = _iim[i];
79.291 + bubbleDown(idx, Pair(i,p), _data.size());
79.292 + }
79.293 +
79.294 + /// \brief Return the state of an item.
79.295 + ///
79.296 + /// This method returns \c PRE_HEAP if the given item has never
79.297 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
79.298 + /// and \c POST_HEAP otherwise.
79.299 + /// In the latter case it is possible that the item will get back
79.300 + /// to the heap again.
79.301 + /// \param i The item.
79.302 + State state(const Item &i) const {
79.303 + int s = _iim[i];
79.304 + if (s>=0) s=0;
79.305 + return State(s);
79.306 + }
79.307 +
79.308 + /// \brief Set the state of an item in the heap.
79.309 + ///
79.310 + /// This function sets the state of the given item in the heap.
79.311 + /// It can be used to manually clear the heap when it is important
79.312 + /// to achive better time complexity.
79.313 + /// \param i The item.
79.314 + /// \param st The state. It should not be \c IN_HEAP.
79.315 + void state(const Item& i, State st) {
79.316 + switch (st) {
79.317 + case POST_HEAP:
79.318 + case PRE_HEAP:
79.319 + if (state(i) == IN_HEAP) erase(i);
79.320 + _iim[i] = st;
79.321 + break;
79.322 + case IN_HEAP:
79.323 + break;
79.324 + }
79.325 + }
79.326 +
79.327 + /// \brief Replace an item in the heap.
79.328 + ///
79.329 + /// This function replaces item \c i with item \c j.
79.330 + /// Item \c i must be in the heap, while \c j must be out of the heap.
79.331 + /// After calling this method, item \c i will be out of the
79.332 + /// heap and \c j will be in the heap with the same prioriority
79.333 + /// as item \c i had before.
79.334 + void replace(const Item& i, const Item& j) {
79.335 + int idx = _iim[i];
79.336 + _iim.set(i, _iim[j]);
79.337 + _iim.set(j, idx);
79.338 + _data[idx].first = j;
79.339 + }
79.340 +
79.341 + }; // class FouraryHeap
79.342 +
79.343 +} // namespace lemon
79.344 +
79.345 +#endif // LEMON_FOURARY_HEAP_H
80.1 --- a/lemon/full_graph.h Mon Jan 12 23:11:39 2009 +0100
80.2 +++ b/lemon/full_graph.h Thu Nov 05 15:48:01 2009 +0100
80.3 @@ -24,14 +24,14 @@
80.4
80.5 ///\ingroup graphs
80.6 ///\file
80.7 -///\brief FullGraph and FullDigraph classes.
80.8 +///\brief FullDigraph and FullGraph classes.
80.9
80.10 namespace lemon {
80.11
80.12 class FullDigraphBase {
80.13 public:
80.14
80.15 - typedef FullDigraphBase Graph;
80.16 + typedef FullDigraphBase Digraph;
80.17
80.18 class Node;
80.19 class Arc;
80.20 @@ -51,7 +51,7 @@
80.21 typedef True ArcNumTag;
80.22
80.23 Node operator()(int ix) const { return Node(ix); }
80.24 - int index(const Node& node) const { return node._id; }
80.25 + static int index(const Node& node) { return node._id; }
80.26
80.27 Arc arc(const Node& s, const Node& t) const {
80.28 return Arc(s._id * _node_num + t._id);
80.29 @@ -148,33 +148,36 @@
80.30
80.31 /// \ingroup graphs
80.32 ///
80.33 - /// \brief A full digraph class.
80.34 + /// \brief A directed full graph class.
80.35 ///
80.36 - /// This is a simple and fast directed full graph implementation.
80.37 - /// From each node go arcs to each node (including the source node),
80.38 - /// therefore the number of the arcs in the digraph is the square of
80.39 - /// the node number. This digraph type is completely static, so you
80.40 - /// can neither add nor delete either arcs or nodes, and it needs
80.41 - /// constant space in memory.
80.42 + /// FullDigraph is a simple and fast implmenetation of directed full
80.43 + /// (complete) graphs. It contains an arc from each node to each node
80.44 + /// (including a loop for each node), therefore the number of arcs
80.45 + /// is the square of the number of nodes.
80.46 + /// This class is completely static and it needs constant memory space.
80.47 + /// Thus you can neither add nor delete nodes or arcs, however
80.48 + /// the structure can be resized using resize().
80.49 ///
80.50 - /// This class conforms to the \ref concepts::Digraph "Digraph" concept
80.51 - /// and it also has an important extra feature that its maps are
80.52 - /// real \ref concepts::ReferenceMap "reference map"s.
80.53 + /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
80.54 + /// Most of its member functions and nested classes are documented
80.55 + /// only in the concept class.
80.56 ///
80.57 - /// The \c FullDigraph and \c FullGraph classes are very similar,
80.58 + /// \note FullDigraph and FullGraph classes are very similar,
80.59 /// but there are two differences. While this class conforms only
80.60 - /// to the \ref concepts::Digraph "Digraph" concept, the \c FullGraph
80.61 - /// class conforms to the \ref concepts::Graph "Graph" concept,
80.62 - /// moreover \c FullGraph does not contain a loop arc for each
80.63 - /// node as \c FullDigraph does.
80.64 + /// to the \ref concepts::Digraph "Digraph" concept, FullGraph
80.65 + /// conforms to the \ref concepts::Graph "Graph" concept,
80.66 + /// moreover FullGraph does not contain a loop for each
80.67 + /// node as this class does.
80.68 ///
80.69 /// \sa FullGraph
80.70 class FullDigraph : public ExtendedFullDigraphBase {
80.71 + typedef ExtendedFullDigraphBase Parent;
80.72 +
80.73 public:
80.74
80.75 - typedef ExtendedFullDigraphBase Parent;
80.76 -
80.77 - /// \brief Constructor
80.78 + /// \brief Default constructor.
80.79 + ///
80.80 + /// Default constructor. The number of nodes and arcs will be zero.
80.81 FullDigraph() { construct(0); }
80.82
80.83 /// \brief Constructor
80.84 @@ -185,8 +188,8 @@
80.85
80.86 /// \brief Resizes the digraph
80.87 ///
80.88 - /// Resizes the digraph. The function will fully destroy and
80.89 - /// rebuild the digraph. This cause that the maps of the digraph will
80.90 + /// This function resizes the digraph. It fully destroys and
80.91 + /// rebuilds the structure, therefore the maps of the digraph will be
80.92 /// reallocated automatically and the previous values will be lost.
80.93 void resize(int n) {
80.94 Parent::notifier(Arc()).clear();
80.95 @@ -198,24 +201,24 @@
80.96
80.97 /// \brief Returns the node with the given index.
80.98 ///
80.99 - /// Returns the node with the given index. Since it is a static
80.100 - /// digraph its nodes can be indexed with integers from the range
80.101 - /// <tt>[0..nodeNum()-1]</tt>.
80.102 + /// Returns the node with the given index. Since this structure is
80.103 + /// completely static, the nodes can be indexed with integers from
80.104 + /// the range <tt>[0..nodeNum()-1]</tt>.
80.105 /// \sa index()
80.106 Node operator()(int ix) const { return Parent::operator()(ix); }
80.107
80.108 /// \brief Returns the index of the given node.
80.109 ///
80.110 - /// Returns the index of the given node. Since it is a static
80.111 - /// digraph its nodes can be indexed with integers from the range
80.112 - /// <tt>[0..nodeNum()-1]</tt>.
80.113 - /// \sa operator()
80.114 - int index(const Node& node) const { return Parent::index(node); }
80.115 + /// Returns the index of the given node. Since this structure is
80.116 + /// completely static, the nodes can be indexed with integers from
80.117 + /// the range <tt>[0..nodeNum()-1]</tt>.
80.118 + /// \sa operator()()
80.119 + static int index(const Node& node) { return Parent::index(node); }
80.120
80.121 /// \brief Returns the arc connecting the given nodes.
80.122 ///
80.123 /// Returns the arc connecting the given nodes.
80.124 - Arc arc(const Node& u, const Node& v) const {
80.125 + Arc arc(Node u, Node v) const {
80.126 return Parent::arc(u, v);
80.127 }
80.128
80.129 @@ -227,8 +230,6 @@
80.130
80.131
80.132 class FullGraphBase {
80.133 - int _node_num;
80.134 - int _edge_num;
80.135 public:
80.136
80.137 typedef FullGraphBase Graph;
80.138 @@ -239,6 +240,9 @@
80.139
80.140 protected:
80.141
80.142 + int _node_num;
80.143 + int _edge_num;
80.144 +
80.145 FullGraphBase() {}
80.146
80.147 void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; }
80.148 @@ -283,7 +287,7 @@
80.149 public:
80.150
80.151 Node operator()(int ix) const { return Node(ix); }
80.152 - int index(const Node& node) const { return node._id; }
80.153 + static int index(const Node& node) { return node._id; }
80.154
80.155 Edge edge(const Node& u, const Node& v) const {
80.156 if (u._id < v._id) {
80.157 @@ -520,31 +524,33 @@
80.158 ///
80.159 /// \brief An undirected full graph class.
80.160 ///
80.161 - /// This is a simple and fast undirected full graph
80.162 - /// implementation. From each node go edge to each other node,
80.163 - /// therefore the number of edges in the graph is \f$n(n-1)/2\f$.
80.164 - /// This graph type is completely static, so you can neither
80.165 - /// add nor delete either edges or nodes, and it needs constant
80.166 - /// space in memory.
80.167 + /// FullGraph is a simple and fast implmenetation of undirected full
80.168 + /// (complete) graphs. It contains an edge between every distinct pair
80.169 + /// of nodes, therefore the number of edges is <tt>n(n-1)/2</tt>.
80.170 + /// This class is completely static and it needs constant memory space.
80.171 + /// Thus you can neither add nor delete nodes or edges, however
80.172 + /// the structure can be resized using resize().
80.173 ///
80.174 - /// This class conforms to the \ref concepts::Graph "Graph" concept
80.175 - /// and it also has an important extra feature that its maps are
80.176 - /// real \ref concepts::ReferenceMap "reference map"s.
80.177 + /// This type fully conforms to the \ref concepts::Graph "Graph concept".
80.178 + /// Most of its member functions and nested classes are documented
80.179 + /// only in the concept class.
80.180 ///
80.181 - /// The \c FullGraph and \c FullDigraph classes are very similar,
80.182 - /// but there are two differences. While the \c FullDigraph class
80.183 + /// \note FullDigraph and FullGraph classes are very similar,
80.184 + /// but there are two differences. While FullDigraph
80.185 /// conforms only to the \ref concepts::Digraph "Digraph" concept,
80.186 /// this class conforms to the \ref concepts::Graph "Graph" concept,
80.187 - /// moreover \c FullGraph does not contain a loop arc for each
80.188 - /// node as \c FullDigraph does.
80.189 + /// moreover this class does not contain a loop for each
80.190 + /// node as FullDigraph does.
80.191 ///
80.192 /// \sa FullDigraph
80.193 class FullGraph : public ExtendedFullGraphBase {
80.194 + typedef ExtendedFullGraphBase Parent;
80.195 +
80.196 public:
80.197
80.198 - typedef ExtendedFullGraphBase Parent;
80.199 -
80.200 - /// \brief Constructor
80.201 + /// \brief Default constructor.
80.202 + ///
80.203 + /// Default constructor. The number of nodes and edges will be zero.
80.204 FullGraph() { construct(0); }
80.205
80.206 /// \brief Constructor
80.207 @@ -555,8 +561,8 @@
80.208
80.209 /// \brief Resizes the graph
80.210 ///
80.211 - /// Resizes the graph. The function will fully destroy and
80.212 - /// rebuild the graph. This cause that the maps of the graph will
80.213 + /// This function resizes the graph. It fully destroys and
80.214 + /// rebuilds the structure, therefore the maps of the graph will be
80.215 /// reallocated automatically and the previous values will be lost.
80.216 void resize(int n) {
80.217 Parent::notifier(Arc()).clear();
80.218 @@ -570,31 +576,31 @@
80.219
80.220 /// \brief Returns the node with the given index.
80.221 ///
80.222 - /// Returns the node with the given index. Since it is a static
80.223 - /// graph its nodes can be indexed with integers from the range
80.224 - /// <tt>[0..nodeNum()-1]</tt>.
80.225 + /// Returns the node with the given index. Since this structure is
80.226 + /// completely static, the nodes can be indexed with integers from
80.227 + /// the range <tt>[0..nodeNum()-1]</tt>.
80.228 /// \sa index()
80.229 Node operator()(int ix) const { return Parent::operator()(ix); }
80.230
80.231 /// \brief Returns the index of the given node.
80.232 ///
80.233 - /// Returns the index of the given node. Since it is a static
80.234 - /// graph its nodes can be indexed with integers from the range
80.235 - /// <tt>[0..nodeNum()-1]</tt>.
80.236 - /// \sa operator()
80.237 - int index(const Node& node) const { return Parent::index(node); }
80.238 + /// Returns the index of the given node. Since this structure is
80.239 + /// completely static, the nodes can be indexed with integers from
80.240 + /// the range <tt>[0..nodeNum()-1]</tt>.
80.241 + /// \sa operator()()
80.242 + static int index(const Node& node) { return Parent::index(node); }
80.243
80.244 /// \brief Returns the arc connecting the given nodes.
80.245 ///
80.246 /// Returns the arc connecting the given nodes.
80.247 - Arc arc(const Node& s, const Node& t) const {
80.248 + Arc arc(Node s, Node t) const {
80.249 return Parent::arc(s, t);
80.250 }
80.251
80.252 - /// \brief Returns the edge connects the given nodes.
80.253 + /// \brief Returns the edge connecting the given nodes.
80.254 ///
80.255 - /// Returns the edge connects the given nodes.
80.256 - Edge edge(const Node& u, const Node& v) const {
80.257 + /// Returns the edge connecting the given nodes.
80.258 + Edge edge(Node u, Node v) const {
80.259 return Parent::edge(u, v);
80.260 }
80.261
81.1 --- a/lemon/glpk.cc Mon Jan 12 23:11:39 2009 +0100
81.2 +++ b/lemon/glpk.cc Thu Nov 05 15:48: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 @@ -31,6 +31,7 @@
81.13 GlpkBase::GlpkBase() : LpBase() {
81.14 lp = glp_create_prob();
81.15 glp_create_index(lp);
81.16 + messageLevel(MESSAGE_NOTHING);
81.17 }
81.18
81.19 GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() {
81.20 @@ -39,6 +40,7 @@
81.21 glp_create_index(lp);
81.22 rows = other.rows;
81.23 cols = other.cols;
81.24 + messageLevel(MESSAGE_NOTHING);
81.25 }
81.26
81.27 GlpkBase::~GlpkBase() {
81.28 @@ -57,6 +59,42 @@
81.29 return i;
81.30 }
81.31
81.32 + int GlpkBase::_addRow(Value lo, ExprIterator b,
81.33 + ExprIterator e, Value up) {
81.34 + int i = glp_add_rows(lp, 1);
81.35 +
81.36 + if (lo == -INF) {
81.37 + if (up == INF) {
81.38 + glp_set_row_bnds(lp, i, GLP_FR, lo, up);
81.39 + } else {
81.40 + glp_set_row_bnds(lp, i, GLP_UP, lo, up);
81.41 + }
81.42 + } else {
81.43 + if (up == INF) {
81.44 + glp_set_row_bnds(lp, i, GLP_LO, lo, up);
81.45 + } else if (lo != up) {
81.46 + glp_set_row_bnds(lp, i, GLP_DB, lo, up);
81.47 + } else {
81.48 + glp_set_row_bnds(lp, i, GLP_FX, lo, up);
81.49 + }
81.50 + }
81.51 +
81.52 + std::vector<int> indexes;
81.53 + std::vector<Value> values;
81.54 +
81.55 + indexes.push_back(0);
81.56 + values.push_back(0);
81.57 +
81.58 + for(ExprIterator it = b; it != e; ++it) {
81.59 + indexes.push_back(it->first);
81.60 + values.push_back(it->second);
81.61 + }
81.62 +
81.63 + glp_set_mat_row(lp, i, values.size() - 1,
81.64 + &indexes.front(), &values.front());
81.65 + return i;
81.66 + }
81.67 +
81.68 void GlpkBase::_eraseCol(int i) {
81.69 int ca[2];
81.70 ca[1] = i;
81.71 @@ -522,20 +560,46 @@
81.72 cols.clear();
81.73 }
81.74
81.75 + void GlpkBase::freeEnv() {
81.76 + glp_free_env();
81.77 + }
81.78 +
81.79 + void GlpkBase::_messageLevel(MessageLevel level) {
81.80 + switch (level) {
81.81 + case MESSAGE_NOTHING:
81.82 + _message_level = GLP_MSG_OFF;
81.83 + break;
81.84 + case MESSAGE_ERROR:
81.85 + _message_level = GLP_MSG_ERR;
81.86 + break;
81.87 + case MESSAGE_WARNING:
81.88 + _message_level = GLP_MSG_ERR;
81.89 + break;
81.90 + case MESSAGE_NORMAL:
81.91 + _message_level = GLP_MSG_ON;
81.92 + break;
81.93 + case MESSAGE_VERBOSE:
81.94 + _message_level = GLP_MSG_ALL;
81.95 + break;
81.96 + }
81.97 + }
81.98 +
81.99 + GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
81.100 +
81.101 // GlpkLp members
81.102
81.103 GlpkLp::GlpkLp()
81.104 - : LpBase(), GlpkBase(), LpSolver() {
81.105 - messageLevel(MESSAGE_NO_OUTPUT);
81.106 + : LpBase(), LpSolver(), GlpkBase() {
81.107 + presolver(false);
81.108 }
81.109
81.110 GlpkLp::GlpkLp(const GlpkLp& other)
81.111 - : LpBase(other), GlpkBase(other), LpSolver(other) {
81.112 - messageLevel(MESSAGE_NO_OUTPUT);
81.113 + : LpBase(other), LpSolver(other), GlpkBase(other) {
81.114 + presolver(false);
81.115 }
81.116
81.117 - GlpkLp* GlpkLp::_newSolver() const { return new GlpkLp; }
81.118 - GlpkLp* GlpkLp::_cloneSolver() const { return new GlpkLp(*this); }
81.119 + GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
81.120 + GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); }
81.121
81.122 const char* GlpkLp::_solverName() const { return "GlpkLp"; }
81.123
81.124 @@ -554,22 +618,26 @@
81.125 glp_smcp smcp;
81.126 glp_init_smcp(&smcp);
81.127
81.128 - switch (_message_level) {
81.129 - case MESSAGE_NO_OUTPUT:
81.130 - smcp.msg_lev = GLP_MSG_OFF;
81.131 + smcp.msg_lev = _message_level;
81.132 + smcp.presolve = _presolve;
81.133 +
81.134 + // If the basis is not valid we get an error return value.
81.135 + // In this case we can try to create a new basis.
81.136 + switch (glp_simplex(lp, &smcp)) {
81.137 + case 0:
81.138 break;
81.139 - case MESSAGE_ERROR_MESSAGE:
81.140 - smcp.msg_lev = GLP_MSG_ERR;
81.141 + case GLP_EBADB:
81.142 + case GLP_ESING:
81.143 + case GLP_ECOND:
81.144 + glp_term_out(false);
81.145 + glp_adv_basis(lp, 0);
81.146 + glp_term_out(true);
81.147 + if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
81.148 break;
81.149 - case MESSAGE_NORMAL_OUTPUT:
81.150 - smcp.msg_lev = GLP_MSG_ON;
81.151 - break;
81.152 - case MESSAGE_FULL_OUTPUT:
81.153 - smcp.msg_lev = GLP_MSG_ALL;
81.154 - break;
81.155 + default:
81.156 + return UNSOLVED;
81.157 }
81.158
81.159 - if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
81.160 return SOLVED;
81.161 }
81.162
81.163 @@ -579,23 +647,26 @@
81.164 glp_smcp smcp;
81.165 glp_init_smcp(&smcp);
81.166
81.167 - switch (_message_level) {
81.168 - case MESSAGE_NO_OUTPUT:
81.169 - smcp.msg_lev = GLP_MSG_OFF;
81.170 + smcp.msg_lev = _message_level;
81.171 + smcp.meth = GLP_DUAL;
81.172 + smcp.presolve = _presolve;
81.173 +
81.174 + // If the basis is not valid we get an error return value.
81.175 + // In this case we can try to create a new basis.
81.176 + switch (glp_simplex(lp, &smcp)) {
81.177 + case 0:
81.178 break;
81.179 - case MESSAGE_ERROR_MESSAGE:
81.180 - smcp.msg_lev = GLP_MSG_ERR;
81.181 + case GLP_EBADB:
81.182 + case GLP_ESING:
81.183 + case GLP_ECOND:
81.184 + glp_term_out(false);
81.185 + glp_adv_basis(lp, 0);
81.186 + glp_term_out(true);
81.187 + if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
81.188 break;
81.189 - case MESSAGE_NORMAL_OUTPUT:
81.190 - smcp.msg_lev = GLP_MSG_ON;
81.191 - break;
81.192 - case MESSAGE_FULL_OUTPUT:
81.193 - smcp.msg_lev = GLP_MSG_ALL;
81.194 - break;
81.195 + default:
81.196 + return UNSOLVED;
81.197 }
81.198 - smcp.meth = GLP_DUAL;
81.199 -
81.200 - if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
81.201 return SOLVED;
81.202 }
81.203
81.204 @@ -813,24 +884,18 @@
81.205 }
81.206 }
81.207
81.208 - void GlpkLp::presolver(bool b) {
81.209 - lpx_set_int_parm(lp, LPX_K_PRESOL, b ? 1 : 0);
81.210 - }
81.211 -
81.212 - void GlpkLp::messageLevel(MessageLevel m) {
81.213 - _message_level = m;
81.214 + void GlpkLp::presolver(bool presolve) {
81.215 + _presolve = presolve;
81.216 }
81.217
81.218 // GlpkMip members
81.219
81.220 GlpkMip::GlpkMip()
81.221 - : LpBase(), GlpkBase(), MipSolver() {
81.222 - messageLevel(MESSAGE_NO_OUTPUT);
81.223 + : LpBase(), MipSolver(), GlpkBase() {
81.224 }
81.225
81.226 GlpkMip::GlpkMip(const GlpkMip& other)
81.227 - : LpBase(), GlpkBase(other), MipSolver() {
81.228 - messageLevel(MESSAGE_NO_OUTPUT);
81.229 + : LpBase(), MipSolver(), GlpkBase(other) {
81.230 }
81.231
81.232 void GlpkMip::_setColType(int i, GlpkMip::ColTypes col_type) {
81.233 @@ -859,42 +924,32 @@
81.234 glp_smcp smcp;
81.235 glp_init_smcp(&smcp);
81.236
81.237 - switch (_message_level) {
81.238 - case MESSAGE_NO_OUTPUT:
81.239 - smcp.msg_lev = GLP_MSG_OFF;
81.240 - break;
81.241 - case MESSAGE_ERROR_MESSAGE:
81.242 - smcp.msg_lev = GLP_MSG_ERR;
81.243 - break;
81.244 - case MESSAGE_NORMAL_OUTPUT:
81.245 - smcp.msg_lev = GLP_MSG_ON;
81.246 - break;
81.247 - case MESSAGE_FULL_OUTPUT:
81.248 - smcp.msg_lev = GLP_MSG_ALL;
81.249 - break;
81.250 - }
81.251 + smcp.msg_lev = _message_level;
81.252 smcp.meth = GLP_DUAL;
81.253
81.254 - if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
81.255 + // If the basis is not valid we get an error return value.
81.256 + // In this case we can try to create a new basis.
81.257 + switch (glp_simplex(lp, &smcp)) {
81.258 + case 0:
81.259 + break;
81.260 + case GLP_EBADB:
81.261 + case GLP_ESING:
81.262 + case GLP_ECOND:
81.263 + glp_term_out(false);
81.264 + glp_adv_basis(lp, 0);
81.265 + glp_term_out(true);
81.266 + if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
81.267 + break;
81.268 + default:
81.269 + return UNSOLVED;
81.270 + }
81.271 +
81.272 if (glp_get_status(lp) != GLP_OPT) return SOLVED;
81.273
81.274 glp_iocp iocp;
81.275 glp_init_iocp(&iocp);
81.276
81.277 - switch (_message_level) {
81.278 - case MESSAGE_NO_OUTPUT:
81.279 - iocp.msg_lev = GLP_MSG_OFF;
81.280 - break;
81.281 - case MESSAGE_ERROR_MESSAGE:
81.282 - iocp.msg_lev = GLP_MSG_ERR;
81.283 - break;
81.284 - case MESSAGE_NORMAL_OUTPUT:
81.285 - iocp.msg_lev = GLP_MSG_ON;
81.286 - break;
81.287 - case MESSAGE_FULL_OUTPUT:
81.288 - iocp.msg_lev = GLP_MSG_ALL;
81.289 - break;
81.290 - }
81.291 + iocp.msg_lev = _message_level;
81.292
81.293 if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
81.294 return SOLVED;
81.295 @@ -940,13 +995,9 @@
81.296 return glp_mip_obj_val(lp);
81.297 }
81.298
81.299 - GlpkMip* GlpkMip::_newSolver() const { return new GlpkMip; }
81.300 - GlpkMip* GlpkMip::_cloneSolver() const {return new GlpkMip(*this); }
81.301 + GlpkMip* GlpkMip::newSolver() const { return new GlpkMip; }
81.302 + GlpkMip* GlpkMip::cloneSolver() const {return new GlpkMip(*this); }
81.303
81.304 const char* GlpkMip::_solverName() const { return "GlpkMip"; }
81.305
81.306 - void GlpkMip::messageLevel(MessageLevel m) {
81.307 - _message_level = m;
81.308 - }
81.309 -
81.310 } //END OF NAMESPACE LEMON
82.1 --- a/lemon/glpk.h Mon Jan 12 23:11:39 2009 +0100
82.2 +++ b/lemon/glpk.h Thu Nov 05 15:48:01 2009 +0100
82.3 @@ -26,9 +26,10 @@
82.4 #include <lemon/lp_base.h>
82.5
82.6 // forward declaration
82.7 -#ifndef _GLP_PROB
82.8 +#if !defined _GLP_PROB && !defined GLP_PROB
82.9 #define _GLP_PROB
82.10 -typedef struct { double _prob; } glp_prob;
82.11 +#define GLP_PROB
82.12 +typedef struct { double _opaque_prob; } glp_prob;
82.13 /* LP/MIP problem object */
82.14 #endif
82.15
82.16 @@ -53,6 +54,7 @@
82.17
82.18 virtual int _addCol();
82.19 virtual int _addRow();
82.20 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
82.21
82.22 virtual void _eraseCol(int i);
82.23 virtual void _eraseRow(int i);
82.24 @@ -100,6 +102,24 @@
82.25
82.26 virtual void _clear();
82.27
82.28 + virtual void _messageLevel(MessageLevel level);
82.29 +
82.30 + private:
82.31 +
82.32 + static void freeEnv();
82.33 +
82.34 + struct FreeEnvHelper {
82.35 + ~FreeEnvHelper() {
82.36 + freeEnv();
82.37 + }
82.38 + };
82.39 +
82.40 + static FreeEnvHelper freeEnvHelper;
82.41 +
82.42 + protected:
82.43 +
82.44 + int _message_level;
82.45 +
82.46 public:
82.47
82.48 ///Pointer to the underlying GLPK data structure.
82.49 @@ -119,7 +139,7 @@
82.50 ///
82.51 /// This class implements an interface for the GLPK LP solver.
82.52 ///\ingroup lp_group
82.53 - class GlpkLp : public GlpkBase, public LpSolver {
82.54 + class GlpkLp : public LpSolver, public GlpkBase {
82.55 public:
82.56
82.57 ///\e
82.58 @@ -127,6 +147,11 @@
82.59 ///\e
82.60 GlpkLp(const GlpkLp&);
82.61
82.62 + ///\e
82.63 + virtual GlpkLp* cloneSolver() const;
82.64 + ///\e
82.65 + virtual GlpkLp* newSolver() const;
82.66 +
82.67 private:
82.68
82.69 mutable std::vector<double> _primal_ray;
82.70 @@ -136,9 +161,6 @@
82.71
82.72 protected:
82.73
82.74 - virtual GlpkLp* _cloneSolver() const;
82.75 - virtual GlpkLp* _newSolver() const;
82.76 -
82.77 virtual const char* _solverName() const;
82.78
82.79 virtual SolveExitStatus _solve();
82.80 @@ -153,8 +175,6 @@
82.81 virtual Value _getPrimalRay(int i) const;
82.82 virtual Value _getDualRay(int i) const;
82.83
82.84 - ///\todo It should be clarified
82.85 - ///
82.86 virtual ProblemType _getPrimalType() const;
82.87 virtual ProblemType _getDualType() const;
82.88
82.89 @@ -166,44 +186,26 @@
82.90 ///Solve with dual simplex
82.91 SolveExitStatus solveDual();
82.92
82.93 + private:
82.94 +
82.95 + bool _presolve;
82.96 +
82.97 + public:
82.98 +
82.99 ///Turns on or off the presolver
82.100
82.101 ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
82.102 ///
82.103 ///The presolver is off by default.
82.104 - void presolver(bool b);
82.105 + void presolver(bool presolve);
82.106
82.107 - ///Enum for \c messageLevel() parameter
82.108 - enum MessageLevel {
82.109 - /// no output (default value)
82.110 - MESSAGE_NO_OUTPUT = 0,
82.111 - /// error messages only
82.112 - MESSAGE_ERROR_MESSAGE = 1,
82.113 - /// normal output
82.114 - MESSAGE_NORMAL_OUTPUT = 2,
82.115 - /// full output (includes informational messages)
82.116 - MESSAGE_FULL_OUTPUT = 3
82.117 - };
82.118 -
82.119 - private:
82.120 -
82.121 - MessageLevel _message_level;
82.122 -
82.123 - public:
82.124 -
82.125 - ///Set the verbosity of the messages
82.126 -
82.127 - ///Set the verbosity of the messages
82.128 - ///
82.129 - ///\param m is the level of the messages output by the solver routines.
82.130 - void messageLevel(MessageLevel m);
82.131 };
82.132
82.133 /// \brief Interface for the GLPK MIP solver
82.134 ///
82.135 /// This class implements an interface for the GLPK MIP solver.
82.136 ///\ingroup lp_group
82.137 - class GlpkMip : public GlpkBase, public MipSolver {
82.138 + class GlpkMip : public MipSolver, public GlpkBase {
82.139 public:
82.140
82.141 ///\e
82.142 @@ -211,11 +213,11 @@
82.143 ///\e
82.144 GlpkMip(const GlpkMip&);
82.145
82.146 + virtual GlpkMip* cloneSolver() const;
82.147 + virtual GlpkMip* newSolver() const;
82.148 +
82.149 protected:
82.150
82.151 - virtual GlpkMip* _cloneSolver() const;
82.152 - virtual GlpkMip* _newSolver() const;
82.153 -
82.154 virtual const char* _solverName() const;
82.155
82.156 virtual ColTypes _getColType(int col) const;
82.157 @@ -226,30 +228,6 @@
82.158 virtual Value _getSol(int i) const;
82.159 virtual Value _getSolValue() const;
82.160
82.161 - ///Enum for \c messageLevel() parameter
82.162 - enum MessageLevel {
82.163 - /// no output (default value)
82.164 - MESSAGE_NO_OUTPUT = 0,
82.165 - /// error messages only
82.166 - MESSAGE_ERROR_MESSAGE = 1,
82.167 - /// normal output
82.168 - MESSAGE_NORMAL_OUTPUT = 2,
82.169 - /// full output (includes informational messages)
82.170 - MESSAGE_FULL_OUTPUT = 3
82.171 - };
82.172 -
82.173 - private:
82.174 -
82.175 - MessageLevel _message_level;
82.176 -
82.177 - public:
82.178 -
82.179 - ///Set the verbosity of the messages
82.180 -
82.181 - ///Set the verbosity of the messages
82.182 - ///
82.183 - ///\param m is the level of the messages output by the solver routines.
82.184 - void messageLevel(MessageLevel m);
82.185 };
82.186
82.187
83.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
83.2 +++ b/lemon/gomory_hu.h Thu Nov 05 15:48:01 2009 +0100
83.3 @@ -0,0 +1,570 @@
83.4 +/* -*- C++ -*-
83.5 + *
83.6 + * This file is a part of LEMON, a generic C++ optimization library
83.7 + *
83.8 + * Copyright (C) 2003-2008
83.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
83.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
83.11 + *
83.12 + * Permission to use, modify and distribute this software is granted
83.13 + * provided that this copyright notice appears in all copies. For
83.14 + * precise terms see the accompanying LICENSE file.
83.15 + *
83.16 + * This software is provided "AS IS" with no warranty of any kind,
83.17 + * express or implied, and with no claim as to its suitability for any
83.18 + * purpose.
83.19 + *
83.20 + */
83.21 +
83.22 +#ifndef LEMON_GOMORY_HU_TREE_H
83.23 +#define LEMON_GOMORY_HU_TREE_H
83.24 +
83.25 +#include <limits>
83.26 +
83.27 +#include <lemon/core.h>
83.28 +#include <lemon/preflow.h>
83.29 +#include <lemon/concept_check.h>
83.30 +#include <lemon/concepts/maps.h>
83.31 +
83.32 +/// \ingroup min_cut
83.33 +/// \file
83.34 +/// \brief Gomory-Hu cut tree in graphs.
83.35 +
83.36 +namespace lemon {
83.37 +
83.38 + /// \ingroup min_cut
83.39 + ///
83.40 + /// \brief Gomory-Hu cut tree algorithm
83.41 + ///
83.42 + /// The Gomory-Hu tree is a tree on the node set of a given graph, but it
83.43 + /// may contain edges which are not in the original graph. It has the
83.44 + /// property that the minimum capacity edge of the path between two nodes
83.45 + /// in this tree has the same weight as the minimum cut in the graph
83.46 + /// between these nodes. Moreover the components obtained by removing
83.47 + /// this edge from the tree determine the corresponding minimum cut.
83.48 + /// Therefore once this tree is computed, the minimum cut between any pair
83.49 + /// of nodes can easily be obtained.
83.50 + ///
83.51 + /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
83.52 + /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{e})\f$ overall
83.53 + /// time complexity. It calculates a rooted Gomory-Hu tree.
83.54 + /// The structure of the tree and the edge weights can be
83.55 + /// obtained using \c predNode(), \c predValue() and \c rootDist().
83.56 + /// The functions \c minCutMap() and \c minCutValue() calculate
83.57 + /// the minimum cut and the minimum cut value between any two nodes
83.58 + /// in the graph. You can also list (iterate on) the nodes and the
83.59 + /// edges of the cuts using \c MinCutNodeIt and \c MinCutEdgeIt.
83.60 + ///
83.61 + /// \tparam GR The type of the undirected graph the algorithm runs on.
83.62 + /// \tparam CAP The type of the edge map containing the capacities.
83.63 + /// The default map type is \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
83.64 +#ifdef DOXYGEN
83.65 + template <typename GR,
83.66 + typename CAP>
83.67 +#else
83.68 + template <typename GR,
83.69 + typename CAP = typename GR::template EdgeMap<int> >
83.70 +#endif
83.71 + class GomoryHu {
83.72 + public:
83.73 +
83.74 + /// The graph type of the algorithm
83.75 + typedef GR Graph;
83.76 + /// The capacity map type of the algorithm
83.77 + typedef CAP Capacity;
83.78 + /// The value type of capacities
83.79 + typedef typename Capacity::Value Value;
83.80 +
83.81 + private:
83.82 +
83.83 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
83.84 +
83.85 + const Graph& _graph;
83.86 + const Capacity& _capacity;
83.87 +
83.88 + Node _root;
83.89 + typename Graph::template NodeMap<Node>* _pred;
83.90 + typename Graph::template NodeMap<Value>* _weight;
83.91 + typename Graph::template NodeMap<int>* _order;
83.92 +
83.93 + void createStructures() {
83.94 + if (!_pred) {
83.95 + _pred = new typename Graph::template NodeMap<Node>(_graph);
83.96 + }
83.97 + if (!_weight) {
83.98 + _weight = new typename Graph::template NodeMap<Value>(_graph);
83.99 + }
83.100 + if (!_order) {
83.101 + _order = new typename Graph::template NodeMap<int>(_graph);
83.102 + }
83.103 + }
83.104 +
83.105 + void destroyStructures() {
83.106 + if (_pred) {
83.107 + delete _pred;
83.108 + }
83.109 + if (_weight) {
83.110 + delete _weight;
83.111 + }
83.112 + if (_order) {
83.113 + delete _order;
83.114 + }
83.115 + }
83.116 +
83.117 + public:
83.118 +
83.119 + /// \brief Constructor
83.120 + ///
83.121 + /// Constructor.
83.122 + /// \param graph The undirected graph the algorithm runs on.
83.123 + /// \param capacity The edge capacity map.
83.124 + GomoryHu(const Graph& graph, const Capacity& capacity)
83.125 + : _graph(graph), _capacity(capacity),
83.126 + _pred(0), _weight(0), _order(0)
83.127 + {
83.128 + checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
83.129 + }
83.130 +
83.131 +
83.132 + /// \brief Destructor
83.133 + ///
83.134 + /// Destructor.
83.135 + ~GomoryHu() {
83.136 + destroyStructures();
83.137 + }
83.138 +
83.139 + private:
83.140 +
83.141 + // Initialize the internal data structures
83.142 + void init() {
83.143 + createStructures();
83.144 +
83.145 + _root = NodeIt(_graph);
83.146 + for (NodeIt n(_graph); n != INVALID; ++n) {
83.147 + (*_pred)[n] = _root;
83.148 + (*_order)[n] = -1;
83.149 + }
83.150 + (*_pred)[_root] = INVALID;
83.151 + (*_weight)[_root] = std::numeric_limits<Value>::max();
83.152 + }
83.153 +
83.154 +
83.155 + // Start the algorithm
83.156 + void start() {
83.157 + Preflow<Graph, Capacity> fa(_graph, _capacity, _root, INVALID);
83.158 +
83.159 + for (NodeIt n(_graph); n != INVALID; ++n) {
83.160 + if (n == _root) continue;
83.161 +
83.162 + Node pn = (*_pred)[n];
83.163 + fa.source(n);
83.164 + fa.target(pn);
83.165 +
83.166 + fa.runMinCut();
83.167 +
83.168 + (*_weight)[n] = fa.flowValue();
83.169 +
83.170 + for (NodeIt nn(_graph); nn != INVALID; ++nn) {
83.171 + if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
83.172 + (*_pred)[nn] = n;
83.173 + }
83.174 + }
83.175 + if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
83.176 + (*_pred)[n] = (*_pred)[pn];
83.177 + (*_pred)[pn] = n;
83.178 + (*_weight)[n] = (*_weight)[pn];
83.179 + (*_weight)[pn] = fa.flowValue();
83.180 + }
83.181 + }
83.182 +
83.183 + (*_order)[_root] = 0;
83.184 + int index = 1;
83.185 +
83.186 + for (NodeIt n(_graph); n != INVALID; ++n) {
83.187 + std::vector<Node> st;
83.188 + Node nn = n;
83.189 + while ((*_order)[nn] == -1) {
83.190 + st.push_back(nn);
83.191 + nn = (*_pred)[nn];
83.192 + }
83.193 + while (!st.empty()) {
83.194 + (*_order)[st.back()] = index++;
83.195 + st.pop_back();
83.196 + }
83.197 + }
83.198 + }
83.199 +
83.200 + public:
83.201 +
83.202 + ///\name Execution Control
83.203 +
83.204 + ///@{
83.205 +
83.206 + /// \brief Run the Gomory-Hu algorithm.
83.207 + ///
83.208 + /// This function runs the Gomory-Hu algorithm.
83.209 + void run() {
83.210 + init();
83.211 + start();
83.212 + }
83.213 +
83.214 + /// @}
83.215 +
83.216 + ///\name Query Functions
83.217 + ///The results of the algorithm can be obtained using these
83.218 + ///functions.\n
83.219 + ///\ref run() should be called before using them.\n
83.220 + ///See also \ref MinCutNodeIt and \ref MinCutEdgeIt.
83.221 +
83.222 + ///@{
83.223 +
83.224 + /// \brief Return the predecessor node in the Gomory-Hu tree.
83.225 + ///
83.226 + /// This function returns the predecessor node of the given node
83.227 + /// in the Gomory-Hu tree.
83.228 + /// If \c node is the root of the tree, then it returns \c INVALID.
83.229 + ///
83.230 + /// \pre \ref run() must be called before using this function.
83.231 + Node predNode(const Node& node) const {
83.232 + return (*_pred)[node];
83.233 + }
83.234 +
83.235 + /// \brief Return the weight of the predecessor edge in the
83.236 + /// Gomory-Hu tree.
83.237 + ///
83.238 + /// This function returns the weight of the predecessor edge of the
83.239 + /// given node in the Gomory-Hu tree.
83.240 + /// If \c node is the root of the tree, the result is undefined.
83.241 + ///
83.242 + /// \pre \ref run() must be called before using this function.
83.243 + Value predValue(const Node& node) const {
83.244 + return (*_weight)[node];
83.245 + }
83.246 +
83.247 + /// \brief Return the distance from the root node in the Gomory-Hu tree.
83.248 + ///
83.249 + /// This function returns the distance of the given node from the root
83.250 + /// node in the Gomory-Hu tree.
83.251 + ///
83.252 + /// \pre \ref run() must be called before using this function.
83.253 + int rootDist(const Node& node) const {
83.254 + return (*_order)[node];
83.255 + }
83.256 +
83.257 + /// \brief Return the minimum cut value between two nodes
83.258 + ///
83.259 + /// This function returns the minimum cut value between the nodes
83.260 + /// \c s and \c t.
83.261 + /// It finds the nearest common ancestor of the given nodes in the
83.262 + /// Gomory-Hu tree and calculates the minimum weight edge on the
83.263 + /// paths to the ancestor.
83.264 + ///
83.265 + /// \pre \ref run() must be called before using this function.
83.266 + Value minCutValue(const Node& s, const Node& t) const {
83.267 + Node sn = s, tn = t;
83.268 + Value value = std::numeric_limits<Value>::max();
83.269 +
83.270 + while (sn != tn) {
83.271 + if ((*_order)[sn] < (*_order)[tn]) {
83.272 + if ((*_weight)[tn] <= value) value = (*_weight)[tn];
83.273 + tn = (*_pred)[tn];
83.274 + } else {
83.275 + if ((*_weight)[sn] <= value) value = (*_weight)[sn];
83.276 + sn = (*_pred)[sn];
83.277 + }
83.278 + }
83.279 + return value;
83.280 + }
83.281 +
83.282 + /// \brief Return the minimum cut between two nodes
83.283 + ///
83.284 + /// This function returns the minimum cut between the nodes \c s and \c t
83.285 + /// in the \c cutMap parameter by setting the nodes in the component of
83.286 + /// \c s to \c true and the other nodes to \c false.
83.287 + ///
83.288 + /// For higher level interfaces see MinCutNodeIt and MinCutEdgeIt.
83.289 + ///
83.290 + /// \param s The base node.
83.291 + /// \param t The node you want to separate from node \c s.
83.292 + /// \param cutMap The cut will be returned in this map.
83.293 + /// It must be a \c bool (or convertible) \ref concepts::ReadWriteMap
83.294 + /// "ReadWriteMap" on the graph nodes.
83.295 + ///
83.296 + /// \return The value of the minimum cut between \c s and \c t.
83.297 + ///
83.298 + /// \pre \ref run() must be called before using this function.
83.299 + template <typename CutMap>
83.300 + Value minCutMap(const Node& s, ///<
83.301 + const Node& t,
83.302 + ///<
83.303 + CutMap& cutMap
83.304 + ///<
83.305 + ) const {
83.306 + Node sn = s, tn = t;
83.307 + bool s_root=false;
83.308 + Node rn = INVALID;
83.309 + Value value = std::numeric_limits<Value>::max();
83.310 +
83.311 + while (sn != tn) {
83.312 + if ((*_order)[sn] < (*_order)[tn]) {
83.313 + if ((*_weight)[tn] <= value) {
83.314 + rn = tn;
83.315 + s_root = false;
83.316 + value = (*_weight)[tn];
83.317 + }
83.318 + tn = (*_pred)[tn];
83.319 + } else {
83.320 + if ((*_weight)[sn] <= value) {
83.321 + rn = sn;
83.322 + s_root = true;
83.323 + value = (*_weight)[sn];
83.324 + }
83.325 + sn = (*_pred)[sn];
83.326 + }
83.327 + }
83.328 +
83.329 + typename Graph::template NodeMap<bool> reached(_graph, false);
83.330 + reached[_root] = true;
83.331 + cutMap.set(_root, !s_root);
83.332 + reached[rn] = true;
83.333 + cutMap.set(rn, s_root);
83.334 +
83.335 + std::vector<Node> st;
83.336 + for (NodeIt n(_graph); n != INVALID; ++n) {
83.337 + st.clear();
83.338 + Node nn = n;
83.339 + while (!reached[nn]) {
83.340 + st.push_back(nn);
83.341 + nn = (*_pred)[nn];
83.342 + }
83.343 + while (!st.empty()) {
83.344 + cutMap.set(st.back(), cutMap[nn]);
83.345 + st.pop_back();
83.346 + }
83.347 + }
83.348 +
83.349 + return value;
83.350 + }
83.351 +
83.352 + ///@}
83.353 +
83.354 + friend class MinCutNodeIt;
83.355 +
83.356 + /// Iterate on the nodes of a minimum cut
83.357 +
83.358 + /// This iterator class lists the nodes of a minimum cut found by
83.359 + /// GomoryHu. Before using it, you must allocate a GomoryHu class
83.360 + /// and call its \ref GomoryHu::run() "run()" method.
83.361 + ///
83.362 + /// This example counts the nodes in the minimum cut separating \c s from
83.363 + /// \c t.
83.364 + /// \code
83.365 + /// GomoryHu<Graph> gom(g, capacities);
83.366 + /// gom.run();
83.367 + /// int cnt=0;
83.368 + /// for(GomoryHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
83.369 + /// \endcode
83.370 + class MinCutNodeIt
83.371 + {
83.372 + bool _side;
83.373 + typename Graph::NodeIt _node_it;
83.374 + typename Graph::template NodeMap<bool> _cut;
83.375 + public:
83.376 + /// Constructor
83.377 +
83.378 + /// Constructor.
83.379 + ///
83.380 + MinCutNodeIt(GomoryHu const &gomory,
83.381 + ///< The GomoryHu class. You must call its
83.382 + /// run() method
83.383 + /// before initializing this iterator.
83.384 + const Node& s, ///< The base node.
83.385 + const Node& t,
83.386 + ///< The node you want to separate from node \c s.
83.387 + bool side=true
83.388 + ///< If it is \c true (default) then the iterator lists
83.389 + /// the nodes of the component containing \c s,
83.390 + /// otherwise it lists the other component.
83.391 + /// \note As the minimum cut is not always unique,
83.392 + /// \code
83.393 + /// MinCutNodeIt(gomory, s, t, true);
83.394 + /// \endcode
83.395 + /// and
83.396 + /// \code
83.397 + /// MinCutNodeIt(gomory, t, s, false);
83.398 + /// \endcode
83.399 + /// does not necessarily give the same set of nodes.
83.400 + /// However it is ensured that
83.401 + /// \code
83.402 + /// MinCutNodeIt(gomory, s, t, true);
83.403 + /// \endcode
83.404 + /// and
83.405 + /// \code
83.406 + /// MinCutNodeIt(gomory, s, t, false);
83.407 + /// \endcode
83.408 + /// together list each node exactly once.
83.409 + )
83.410 + : _side(side), _cut(gomory._graph)
83.411 + {
83.412 + gomory.minCutMap(s,t,_cut);
83.413 + for(_node_it=typename Graph::NodeIt(gomory._graph);
83.414 + _node_it!=INVALID && _cut[_node_it]!=_side;
83.415 + ++_node_it) {}
83.416 + }
83.417 + /// Conversion to \c Node
83.418 +
83.419 + /// Conversion to \c Node.
83.420 + ///
83.421 + operator typename Graph::Node() const
83.422 + {
83.423 + return _node_it;
83.424 + }
83.425 + bool operator==(Invalid) { return _node_it==INVALID; }
83.426 + bool operator!=(Invalid) { return _node_it!=INVALID; }
83.427 + /// Next node
83.428 +
83.429 + /// Next node.
83.430 + ///
83.431 + MinCutNodeIt &operator++()
83.432 + {
83.433 + for(++_node_it;_node_it!=INVALID&&_cut[_node_it]!=_side;++_node_it) {}
83.434 + return *this;
83.435 + }
83.436 + /// Postfix incrementation
83.437 +
83.438 + /// Postfix incrementation.
83.439 + ///
83.440 + /// \warning This incrementation
83.441 + /// returns a \c Node, not a \c MinCutNodeIt, as one may
83.442 + /// expect.
83.443 + typename Graph::Node operator++(int)
83.444 + {
83.445 + typename Graph::Node n=*this;
83.446 + ++(*this);
83.447 + return n;
83.448 + }
83.449 + };
83.450 +
83.451 + friend class MinCutEdgeIt;
83.452 +
83.453 + /// Iterate on the edges of a minimum cut
83.454 +
83.455 + /// This iterator class lists the edges of a minimum cut found by
83.456 + /// GomoryHu. Before using it, you must allocate a GomoryHu class
83.457 + /// and call its \ref GomoryHu::run() "run()" method.
83.458 + ///
83.459 + /// This example computes the value of the minimum cut separating \c s from
83.460 + /// \c t.
83.461 + /// \code
83.462 + /// GomoryHu<Graph> gom(g, capacities);
83.463 + /// gom.run();
83.464 + /// int value=0;
83.465 + /// for(GomoryHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
83.466 + /// value+=capacities[e];
83.467 + /// \endcode
83.468 + /// The result will be the same as the value returned by
83.469 + /// \ref GomoryHu::minCutValue() "gom.minCutValue(s,t)".
83.470 + class MinCutEdgeIt
83.471 + {
83.472 + bool _side;
83.473 + const Graph &_graph;
83.474 + typename Graph::NodeIt _node_it;
83.475 + typename Graph::OutArcIt _arc_it;
83.476 + typename Graph::template NodeMap<bool> _cut;
83.477 + void step()
83.478 + {
83.479 + ++_arc_it;
83.480 + while(_node_it!=INVALID && _arc_it==INVALID)
83.481 + {
83.482 + for(++_node_it;_node_it!=INVALID&&!_cut[_node_it];++_node_it) {}
83.483 + if(_node_it!=INVALID)
83.484 + _arc_it=typename Graph::OutArcIt(_graph,_node_it);
83.485 + }
83.486 + }
83.487 +
83.488 + public:
83.489 + /// Constructor
83.490 +
83.491 + /// Constructor.
83.492 + ///
83.493 + MinCutEdgeIt(GomoryHu const &gomory,
83.494 + ///< The GomoryHu class. You must call its
83.495 + /// run() method
83.496 + /// before initializing this iterator.
83.497 + const Node& s, ///< The base node.
83.498 + const Node& t,
83.499 + ///< The node you want to separate from node \c s.
83.500 + bool side=true
83.501 + ///< If it is \c true (default) then the listed arcs
83.502 + /// will be oriented from the
83.503 + /// nodes of the component containing \c s,
83.504 + /// otherwise they will be oriented in the opposite
83.505 + /// direction.
83.506 + )
83.507 + : _graph(gomory._graph), _cut(_graph)
83.508 + {
83.509 + gomory.minCutMap(s,t,_cut);
83.510 + if(!side)
83.511 + for(typename Graph::NodeIt n(_graph);n!=INVALID;++n)
83.512 + _cut[n]=!_cut[n];
83.513 +
83.514 + for(_node_it=typename Graph::NodeIt(_graph);
83.515 + _node_it!=INVALID && !_cut[_node_it];
83.516 + ++_node_it) {}
83.517 + _arc_it = _node_it!=INVALID ?
83.518 + typename Graph::OutArcIt(_graph,_node_it) : INVALID;
83.519 + while(_node_it!=INVALID && _arc_it == INVALID)
83.520 + {
83.521 + for(++_node_it; _node_it!=INVALID&&!_cut[_node_it]; ++_node_it) {}
83.522 + if(_node_it!=INVALID)
83.523 + _arc_it= typename Graph::OutArcIt(_graph,_node_it);
83.524 + }
83.525 + while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
83.526 + }
83.527 + /// Conversion to \c Arc
83.528 +
83.529 + /// Conversion to \c Arc.
83.530 + ///
83.531 + operator typename Graph::Arc() const
83.532 + {
83.533 + return _arc_it;
83.534 + }
83.535 + /// Conversion to \c Edge
83.536 +
83.537 + /// Conversion to \c Edge.
83.538 + ///
83.539 + operator typename Graph::Edge() const
83.540 + {
83.541 + return _arc_it;
83.542 + }
83.543 + bool operator==(Invalid) { return _node_it==INVALID; }
83.544 + bool operator!=(Invalid) { return _node_it!=INVALID; }
83.545 + /// Next edge
83.546 +
83.547 + /// Next edge.
83.548 + ///
83.549 + MinCutEdgeIt &operator++()
83.550 + {
83.551 + step();
83.552 + while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
83.553 + return *this;
83.554 + }
83.555 + /// Postfix incrementation
83.556 +
83.557 + /// Postfix incrementation.
83.558 + ///
83.559 + /// \warning This incrementation
83.560 + /// returns an \c Arc, not a \c MinCutEdgeIt, as one may expect.
83.561 + typename Graph::Arc operator++(int)
83.562 + {
83.563 + typename Graph::Arc e=*this;
83.564 + ++(*this);
83.565 + return e;
83.566 + }
83.567 + };
83.568 +
83.569 + };
83.570 +
83.571 +}
83.572 +
83.573 +#endif
84.1 --- a/lemon/graph_to_eps.h Mon Jan 12 23:11:39 2009 +0100
84.2 +++ b/lemon/graph_to_eps.h Thu Nov 05 15:48:01 2009 +0100
84.3 @@ -29,9 +29,7 @@
84.4 #include<sys/time.h>
84.5 #include<ctime>
84.6 #else
84.7 -#define WIN32_LEAN_AND_MEAN
84.8 -#define NOMINMAX
84.9 -#include<windows.h>
84.10 +#include<lemon/bits/windows.h>
84.11 #endif
84.12
84.13 #include<lemon/math.h>
84.14 @@ -66,11 +64,12 @@
84.15
84.16 ///Default traits class of \ref GraphToEps.
84.17 ///
84.18 -///\c G is the type of the underlying graph.
84.19 -template<class G>
84.20 +///\param GR is the type of the underlying graph.
84.21 +template<class GR>
84.22 struct DefaultGraphToEpsTraits
84.23 {
84.24 - typedef G Graph;
84.25 + typedef GR Graph;
84.26 + typedef GR Digraph;
84.27 typedef typename Graph::Node Node;
84.28 typedef typename Graph::NodeIt NodeIt;
84.29 typedef typename Graph::Arc Arc;
84.30 @@ -141,15 +140,14 @@
84.31 ///Constructor
84.32
84.33 ///Constructor
84.34 - ///\param _g Reference to the graph to be printed.
84.35 - ///\param _os Reference to the output stream.
84.36 - ///\param _os Reference to the output stream.
84.37 + ///\param gr Reference to the graph to be printed.
84.38 + ///\param ost Reference to the output stream.
84.39 ///By default it is <tt>std::cout</tt>.
84.40 - ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
84.41 + ///\param pros If it is \c true, then the \c ostream referenced by \c os
84.42 ///will be explicitly deallocated by the destructor.
84.43 - DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
84.44 - bool _pros=false) :
84.45 - g(_g), os(_os),
84.46 + DefaultGraphToEpsTraits(const GR &gr, std::ostream& ost = std::cout,
84.47 + bool pros = false) :
84.48 + g(gr), os(ost),
84.49 _coords(dim2::Point<double>(1,1)), _nodeSizes(1), _nodeShapes(0),
84.50 _nodeColors(WHITE), _arcColors(BLACK),
84.51 _arcWidths(1.0), _arcWidthScale(0.003),
84.52 @@ -160,8 +158,8 @@
84.53 _enableParallel(false), _parArcDist(1),
84.54 _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
84.55 _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
84.56 - _undirected(lemon::UndirectedTagIndicator<G>::value),
84.57 - _pleaseRemoveOsStream(_pros), _scaleToA4(false),
84.58 + _undirected(lemon::UndirectedTagIndicator<GR>::value),
84.59 + _pleaseRemoveOsStream(pros), _scaleToA4(false),
84.60 _nodeTextColorType(SAME_COL), _nodeTextColors(BLACK),
84.61 _autoNodeScale(false),
84.62 _autoArcWidthScale(false),
84.63 @@ -244,6 +242,7 @@
84.64 // dradnats ++C eht yb deriuqer si ti eveileb t'naC
84.65
84.66 typedef typename T::Graph Graph;
84.67 + typedef typename T::Digraph Digraph;
84.68 typedef typename Graph::Node Node;
84.69 typedef typename Graph::NodeIt NodeIt;
84.70 typedef typename Graph::Arc Arc;
84.71 @@ -271,22 +270,18 @@
84.72 /// = 1
84.73 ///\image html nodeshape_1.png
84.74 ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm
84.75 - ///
84.76 SQUARE=1,
84.77 /// = 2
84.78 ///\image html nodeshape_2.png
84.79 ///\image latex nodeshape_2.eps "DIAMOND shape (2)" width=2cm
84.80 - ///
84.81 DIAMOND=2,
84.82 /// = 3
84.83 ///\image html nodeshape_3.png
84.84 - ///\image latex nodeshape_2.eps "MALE shape (4)" width=2cm
84.85 - ///
84.86 + ///\image latex nodeshape_3.eps "MALE shape (3)" width=2cm
84.87 MALE=3,
84.88 /// = 4
84.89 ///\image html nodeshape_4.png
84.90 - ///\image latex nodeshape_2.eps "FEMALE shape (4)" width=2cm
84.91 - ///
84.92 + ///\image latex nodeshape_4.eps "FEMALE shape (4)" width=2cm
84.93 FEMALE=4
84.94 };
84.95
84.96 @@ -679,29 +674,19 @@
84.97 os << "%%Creator: LEMON, graphToEps()\n";
84.98
84.99 {
84.100 + os << "%%CreationDate: ";
84.101 #ifndef WIN32
84.102 timeval tv;
84.103 gettimeofday(&tv, 0);
84.104
84.105 char cbuf[26];
84.106 ctime_r(&tv.tv_sec,cbuf);
84.107 - os << "%%CreationDate: " << cbuf;
84.108 + os << cbuf;
84.109 #else
84.110 - SYSTEMTIME time;
84.111 - char buf1[11], buf2[9], buf3[5];
84.112 -
84.113 - GetSystemTime(&time);
84.114 - if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
84.115 - "ddd MMM dd", buf1, 11) &&
84.116 - GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time,
84.117 - "HH':'mm':'ss", buf2, 9) &&
84.118 - GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
84.119 - "yyyy", buf3, 5)) {
84.120 - os << "%%CreationDate: " << buf1 << ' '
84.121 - << buf2 << ' ' << buf3 << std::endl;
84.122 - }
84.123 + os << bits::getWinFormattedDate();
84.124 #endif
84.125 }
84.126 + os << std::endl;
84.127
84.128 if (_autoArcWidthScale) {
84.129 double max_w=0;
84.130 @@ -1146,55 +1131,55 @@
84.131 ///\warning Don't forget to put the \ref GraphToEps::run() "run()"
84.132 ///to the end of the parameter list.
84.133 ///\sa GraphToEps
84.134 -///\sa graphToEps(G &g, const char *file_name)
84.135 -template<class G>
84.136 -GraphToEps<DefaultGraphToEpsTraits<G> >
84.137 -graphToEps(G &g, std::ostream& os=std::cout)
84.138 +///\sa graphToEps(GR &g, const char *file_name)
84.139 +template<class GR>
84.140 +GraphToEps<DefaultGraphToEpsTraits<GR> >
84.141 +graphToEps(GR &g, std::ostream& os=std::cout)
84.142 {
84.143 return
84.144 - GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
84.145 + GraphToEps<DefaultGraphToEpsTraits<GR> >(DefaultGraphToEpsTraits<GR>(g,os));
84.146 }
84.147
84.148 ///Generates an EPS file from a graph
84.149
84.150 ///\ingroup eps_io
84.151 ///This function does the same as
84.152 -///\ref graphToEps(G &g,std::ostream& os)
84.153 +///\ref graphToEps(GR &g,std::ostream& os)
84.154 ///but it writes its output into the file \c file_name
84.155 ///instead of a stream.
84.156 -///\sa graphToEps(G &g, std::ostream& os)
84.157 -template<class G>
84.158 -GraphToEps<DefaultGraphToEpsTraits<G> >
84.159 -graphToEps(G &g,const char *file_name)
84.160 +///\sa graphToEps(GR &g, std::ostream& os)
84.161 +template<class GR>
84.162 +GraphToEps<DefaultGraphToEpsTraits<GR> >
84.163 +graphToEps(GR &g,const char *file_name)
84.164 {
84.165 std::ostream* os = new std::ofstream(file_name);
84.166 if (!(*os)) {
84.167 delete os;
84.168 throw IoError("Cannot write file", file_name);
84.169 }
84.170 - return GraphToEps<DefaultGraphToEpsTraits<G> >
84.171 - (DefaultGraphToEpsTraits<G>(g,*os,true));
84.172 + return GraphToEps<DefaultGraphToEpsTraits<GR> >
84.173 + (DefaultGraphToEpsTraits<GR>(g,*os,true));
84.174 }
84.175
84.176 ///Generates an EPS file from a graph
84.177
84.178 ///\ingroup eps_io
84.179 ///This function does the same as
84.180 -///\ref graphToEps(G &g,std::ostream& os)
84.181 +///\ref graphToEps(GR &g,std::ostream& os)
84.182 ///but it writes its output into the file \c file_name
84.183 ///instead of a stream.
84.184 -///\sa graphToEps(G &g, std::ostream& os)
84.185 -template<class G>
84.186 -GraphToEps<DefaultGraphToEpsTraits<G> >
84.187 -graphToEps(G &g,const std::string& file_name)
84.188 +///\sa graphToEps(GR &g, std::ostream& os)
84.189 +template<class GR>
84.190 +GraphToEps<DefaultGraphToEpsTraits<GR> >
84.191 +graphToEps(GR &g,const std::string& file_name)
84.192 {
84.193 std::ostream* os = new std::ofstream(file_name.c_str());
84.194 if (!(*os)) {
84.195 delete os;
84.196 throw IoError("Cannot write file", file_name);
84.197 }
84.198 - return GraphToEps<DefaultGraphToEpsTraits<G> >
84.199 - (DefaultGraphToEpsTraits<G>(g,*os,true));
84.200 + return GraphToEps<DefaultGraphToEpsTraits<GR> >
84.201 + (DefaultGraphToEpsTraits<GR>(g,*os,true));
84.202 }
84.203
84.204 } //END OF NAMESPACE LEMON
85.1 --- a/lemon/grid_graph.h Mon Jan 12 23:11:39 2009 +0100
85.2 +++ b/lemon/grid_graph.h Thu Nov 05 15:48:01 2009 +0100
85.3 @@ -470,18 +470,22 @@
85.4 ///
85.5 /// \brief Grid graph class
85.6 ///
85.7 - /// This class implements a special graph type. The nodes of the
85.8 - /// graph can be indexed by two integer \c (i,j) value where \c i is
85.9 - /// in the \c [0..width()-1] range and j is in the \c
85.10 - /// [0..height()-1] range. Two nodes are connected in the graph if
85.11 - /// the indexes differ exactly on one position and exactly one is
85.12 - /// the difference. The nodes of the graph can be indexed by position
85.13 - /// with the \c operator()() function. The positions of the nodes can be
85.14 - /// get with \c pos(), \c col() and \c row() members. The outgoing
85.15 + /// GridGraph implements a special graph type. The nodes of the
85.16 + /// graph can be indexed by two integer values \c (i,j) where \c i is
85.17 + /// in the range <tt>[0..width()-1]</tt> and j is in the range
85.18 + /// <tt>[0..height()-1]</tt>. Two nodes are connected in the graph if
85.19 + /// the indices differ exactly on one position and the difference is
85.20 + /// also exactly one. The nodes of the graph can be obtained by position
85.21 + /// using the \c operator()() function and the indices of the nodes can
85.22 + /// be obtained using \c pos(), \c col() and \c row() members. The outgoing
85.23 /// arcs can be retrieved with the \c right(), \c up(), \c left()
85.24 /// and \c down() functions, where the bottom-left corner is the
85.25 /// origin.
85.26 ///
85.27 + /// This class is completely static and it needs constant memory space.
85.28 + /// Thus you can neither add nor delete nodes or edges, however
85.29 + /// the structure can be resized using resize().
85.30 + ///
85.31 /// \image html grid_graph.png
85.32 /// \image latex grid_graph.eps "Grid graph" width=\textwidth
85.33 ///
85.34 @@ -496,18 +500,19 @@
85.35 /// }
85.36 ///\endcode
85.37 ///
85.38 - /// This graph type is fully conform to the \ref concepts::Graph
85.39 - /// "Graph" concept, and it also has an important extra feature
85.40 - /// that its maps are real \ref concepts::ReferenceMap
85.41 - /// "reference map"s.
85.42 + /// This type fully conforms to the \ref concepts::Graph "Graph concept".
85.43 + /// Most of its member functions and nested classes are documented
85.44 + /// only in the concept class.
85.45 class GridGraph : public ExtendedGridGraphBase {
85.46 + typedef ExtendedGridGraphBase Parent;
85.47 +
85.48 public:
85.49
85.50 - typedef ExtendedGridGraphBase Parent;
85.51 -
85.52 - /// \brief Map to get the indices of the nodes as dim2::Point<int>.
85.53 + /// \brief Map to get the indices of the nodes as \ref dim2::Point
85.54 + /// "dim2::Point<int>".
85.55 ///
85.56 - /// Map to get the indices of the nodes as dim2::Point<int>.
85.57 + /// Map to get the indices of the nodes as \ref dim2::Point
85.58 + /// "dim2::Point<int>".
85.59 class IndexMap {
85.60 public:
85.61 /// \brief The key type of the map
85.62 @@ -516,13 +521,9 @@
85.63 typedef dim2::Point<int> Value;
85.64
85.65 /// \brief Constructor
85.66 - ///
85.67 - /// Constructor
85.68 IndexMap(const GridGraph& graph) : _graph(graph) {}
85.69
85.70 /// \brief The subscript operator
85.71 - ///
85.72 - /// The subscript operator.
85.73 Value operator[](Key key) const {
85.74 return _graph.pos(key);
85.75 }
85.76 @@ -542,13 +543,9 @@
85.77 typedef int Value;
85.78
85.79 /// \brief Constructor
85.80 - ///
85.81 - /// Constructor
85.82 ColMap(const GridGraph& graph) : _graph(graph) {}
85.83
85.84 /// \brief The subscript operator
85.85 - ///
85.86 - /// The subscript operator.
85.87 Value operator[](Key key) const {
85.88 return _graph.col(key);
85.89 }
85.90 @@ -568,13 +565,9 @@
85.91 typedef int Value;
85.92
85.93 /// \brief Constructor
85.94 - ///
85.95 - /// Constructor
85.96 RowMap(const GridGraph& graph) : _graph(graph) {}
85.97
85.98 /// \brief The subscript operator
85.99 - ///
85.100 - /// The subscript operator.
85.101 Value operator[](Key key) const {
85.102 return _graph.row(key);
85.103 }
85.104 @@ -585,15 +578,14 @@
85.105
85.106 /// \brief Constructor
85.107 ///
85.108 - /// Construct a grid graph with given size.
85.109 + /// Construct a grid graph with the given size.
85.110 GridGraph(int width, int height) { construct(width, height); }
85.111
85.112 - /// \brief Resize the graph
85.113 + /// \brief Resizes the graph
85.114 ///
85.115 - /// Resize the graph. The function will fully destroy and rebuild
85.116 - /// the graph. This cause that the maps of the graph will
85.117 - /// reallocated automatically and the previous values will be
85.118 - /// lost.
85.119 + /// This function resizes the graph. It fully destroys and
85.120 + /// rebuilds the structure, therefore the maps of the graph will be
85.121 + /// reallocated automatically and the previous values will be lost.
85.122 void resize(int width, int height) {
85.123 Parent::notifier(Arc()).clear();
85.124 Parent::notifier(Edge()).clear();
85.125 @@ -611,42 +603,42 @@
85.126 return Parent::operator()(i, j);
85.127 }
85.128
85.129 - /// \brief Gives back the column index of the node.
85.130 + /// \brief The column index of the node.
85.131 ///
85.132 /// Gives back the column index of the node.
85.133 int col(Node n) const {
85.134 return Parent::col(n);
85.135 }
85.136
85.137 - /// \brief Gives back the row index of the node.
85.138 + /// \brief The row index of the node.
85.139 ///
85.140 /// Gives back the row index of the node.
85.141 int row(Node n) const {
85.142 return Parent::row(n);
85.143 }
85.144
85.145 - /// \brief Gives back the position of the node.
85.146 + /// \brief The position of the node.
85.147 ///
85.148 /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
85.149 dim2::Point<int> pos(Node n) const {
85.150 return Parent::pos(n);
85.151 }
85.152
85.153 - /// \brief Gives back the number of the columns.
85.154 + /// \brief The number of the columns.
85.155 ///
85.156 /// Gives back the number of the columns.
85.157 int width() const {
85.158 return Parent::width();
85.159 }
85.160
85.161 - /// \brief Gives back the number of the rows.
85.162 + /// \brief The number of the rows.
85.163 ///
85.164 /// Gives back the number of the rows.
85.165 int height() const {
85.166 return Parent::height();
85.167 }
85.168
85.169 - /// \brief Gives back the arc goes right from the node.
85.170 + /// \brief The arc goes right from the node.
85.171 ///
85.172 /// Gives back the arc goes right from the node. If there is not
85.173 /// outgoing arc then it gives back INVALID.
85.174 @@ -654,7 +646,7 @@
85.175 return Parent::right(n);
85.176 }
85.177
85.178 - /// \brief Gives back the arc goes left from the node.
85.179 + /// \brief The arc goes left from the node.
85.180 ///
85.181 /// Gives back the arc goes left from the node. If there is not
85.182 /// outgoing arc then it gives back INVALID.
85.183 @@ -662,7 +654,7 @@
85.184 return Parent::left(n);
85.185 }
85.186
85.187 - /// \brief Gives back the arc goes up from the node.
85.188 + /// \brief The arc goes up from the node.
85.189 ///
85.190 /// Gives back the arc goes up from the node. If there is not
85.191 /// outgoing arc then it gives back INVALID.
85.192 @@ -670,7 +662,7 @@
85.193 return Parent::up(n);
85.194 }
85.195
85.196 - /// \brief Gives back the arc goes down from the node.
85.197 + /// \brief The arc goes down from the node.
85.198 ///
85.199 /// Gives back the arc goes down from the node. If there is not
85.200 /// outgoing arc then it gives back INVALID.
86.1 --- a/lemon/hao_orlin.h Mon Jan 12 23:11:39 2009 +0100
86.2 +++ b/lemon/hao_orlin.h Thu Nov 05 15:48:01 2009 +0100
86.3 @@ -31,57 +31,64 @@
86.4 /// \ingroup min_cut
86.5 /// \brief Implementation of the Hao-Orlin algorithm.
86.6 ///
86.7 -/// Implementation of the Hao-Orlin algorithm class for testing network
86.8 -/// reliability.
86.9 +/// Implementation of the Hao-Orlin algorithm for finding a minimum cut
86.10 +/// in a digraph.
86.11
86.12 namespace lemon {
86.13
86.14 /// \ingroup min_cut
86.15 ///
86.16 - /// \brief %Hao-Orlin algorithm to find a minimum cut in directed graphs.
86.17 + /// \brief Hao-Orlin algorithm for finding a minimum cut in a digraph.
86.18 ///
86.19 - /// Hao-Orlin calculates a minimum cut in a directed graph
86.20 - /// \f$D=(V,A)\f$. It takes a fixed node \f$ source \in V \f$ and
86.21 + /// This class implements the Hao-Orlin algorithm for finding a minimum
86.22 + /// value cut in a directed graph \f$D=(V,A)\f$.
86.23 + /// It takes a fixed node \f$ source \in V \f$ and
86.24 /// consists of two phases: in the first phase it determines a
86.25 /// minimum cut with \f$ source \f$ on the source-side (i.e. a set
86.26 - /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal
86.27 - /// out-degree) and in the second phase it determines a minimum cut
86.28 + /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal outgoing
86.29 + /// capacity) and in the second phase it determines a minimum cut
86.30 /// with \f$ source \f$ on the sink-side (i.e. a set
86.31 - /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal
86.32 - /// out-degree). Obviously, the smaller of these two cuts will be a
86.33 + /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal outgoing
86.34 + /// capacity). Obviously, the smaller of these two cuts will be a
86.35 /// minimum cut of \f$ D \f$. The algorithm is a modified
86.36 - /// push-relabel preflow algorithm and our implementation calculates
86.37 + /// preflow push-relabel algorithm. Our implementation calculates
86.38 /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the
86.39 /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The
86.40 - /// purpose of such algorithm is testing network reliability. For an
86.41 - /// undirected graph you can run just the first phase of the
86.42 - /// algorithm or you can use the algorithm of Nagamochi and Ibaraki
86.43 - /// which solves the undirected problem in
86.44 - /// \f$ O(nm + n^2 \log(n)) \f$ time: it is implemented in the
86.45 - /// NagamochiIbaraki algorithm class.
86.46 + /// purpose of such algorithm is e.g. testing network reliability.
86.47 ///
86.48 - /// \param _Digraph is the graph type of the algorithm.
86.49 - /// \param _CapacityMap is an edge map of capacities which should
86.50 - /// be any numreric type. The default type is _Digraph::ArcMap<int>.
86.51 - /// \param _Tolerance is the handler of the inexact computation. The
86.52 - /// default type for this is Tolerance<CapacityMap::Value>.
86.53 + /// For an undirected graph you can run just the first phase of the
86.54 + /// algorithm or you can use the algorithm of Nagamochi and Ibaraki,
86.55 + /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$
86.56 + /// time. It is implemented in the NagamochiIbaraki algorithm class.
86.57 + ///
86.58 + /// \tparam GR The type of the digraph the algorithm runs on.
86.59 + /// \tparam CAP The type of the arc map containing the capacities,
86.60 + /// which can be any numreric type. The default map type is
86.61 + /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
86.62 + /// \tparam TOL Tolerance class for handling inexact computations. The
86.63 + /// default tolerance type is \ref Tolerance "Tolerance<CAP::Value>".
86.64 #ifdef DOXYGEN
86.65 - template <typename _Digraph, typename _CapacityMap, typename _Tolerance>
86.66 + template <typename GR, typename CAP, typename TOL>
86.67 #else
86.68 - template <typename _Digraph,
86.69 - typename _CapacityMap = typename _Digraph::template ArcMap<int>,
86.70 - typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
86.71 + template <typename GR,
86.72 + typename CAP = typename GR::template ArcMap<int>,
86.73 + typename TOL = Tolerance<typename CAP::Value> >
86.74 #endif
86.75 class HaoOrlin {
86.76 + public:
86.77 +
86.78 + /// The digraph type of the algorithm
86.79 + typedef GR Digraph;
86.80 + /// The capacity map type of the algorithm
86.81 + typedef CAP CapacityMap;
86.82 + /// The tolerance type of the algorithm
86.83 + typedef TOL Tolerance;
86.84 +
86.85 private:
86.86
86.87 - typedef _Digraph Digraph;
86.88 - typedef _CapacityMap CapacityMap;
86.89 - typedef _Tolerance Tolerance;
86.90 -
86.91 typedef typename CapacityMap::Value Value;
86.92
86.93 - TEMPLATE_GRAPH_TYPEDEFS(Digraph);
86.94 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
86.95
86.96 const Digraph& _graph;
86.97 const CapacityMap* _capacity;
86.98 @@ -161,56 +168,56 @@
86.99 private:
86.100
86.101 void activate(const Node& i) {
86.102 - _active->set(i, true);
86.103 + (*_active)[i] = true;
86.104
86.105 int bucket = (*_bucket)[i];
86.106
86.107 if ((*_prev)[i] == INVALID || (*_active)[(*_prev)[i]]) return;
86.108 //unlace
86.109 - _next->set((*_prev)[i], (*_next)[i]);
86.110 + (*_next)[(*_prev)[i]] = (*_next)[i];
86.111 if ((*_next)[i] != INVALID) {
86.112 - _prev->set((*_next)[i], (*_prev)[i]);
86.113 + (*_prev)[(*_next)[i]] = (*_prev)[i];
86.114 } else {
86.115 _last[bucket] = (*_prev)[i];
86.116 }
86.117 //lace
86.118 - _next->set(i, _first[bucket]);
86.119 - _prev->set(_first[bucket], i);
86.120 - _prev->set(i, INVALID);
86.121 + (*_next)[i] = _first[bucket];
86.122 + (*_prev)[_first[bucket]] = i;
86.123 + (*_prev)[i] = INVALID;
86.124 _first[bucket] = i;
86.125 }
86.126
86.127 void deactivate(const Node& i) {
86.128 - _active->set(i, false);
86.129 + (*_active)[i] = false;
86.130 int bucket = (*_bucket)[i];
86.131
86.132 if ((*_next)[i] == INVALID || !(*_active)[(*_next)[i]]) return;
86.133
86.134 //unlace
86.135 - _prev->set((*_next)[i], (*_prev)[i]);
86.136 + (*_prev)[(*_next)[i]] = (*_prev)[i];
86.137 if ((*_prev)[i] != INVALID) {
86.138 - _next->set((*_prev)[i], (*_next)[i]);
86.139 + (*_next)[(*_prev)[i]] = (*_next)[i];
86.140 } else {
86.141 _first[bucket] = (*_next)[i];
86.142 }
86.143 //lace
86.144 - _prev->set(i, _last[bucket]);
86.145 - _next->set(_last[bucket], i);
86.146 - _next->set(i, INVALID);
86.147 + (*_prev)[i] = _last[bucket];
86.148 + (*_next)[_last[bucket]] = i;
86.149 + (*_next)[i] = INVALID;
86.150 _last[bucket] = i;
86.151 }
86.152
86.153 void addItem(const Node& i, int bucket) {
86.154 (*_bucket)[i] = bucket;
86.155 if (_last[bucket] != INVALID) {
86.156 - _prev->set(i, _last[bucket]);
86.157 - _next->set(_last[bucket], i);
86.158 - _next->set(i, INVALID);
86.159 + (*_prev)[i] = _last[bucket];
86.160 + (*_next)[_last[bucket]] = i;
86.161 + (*_next)[i] = INVALID;
86.162 _last[bucket] = i;
86.163 } else {
86.164 - _prev->set(i, INVALID);
86.165 + (*_prev)[i] = INVALID;
86.166 _first[bucket] = i;
86.167 - _next->set(i, INVALID);
86.168 + (*_next)[i] = INVALID;
86.169 _last[bucket] = i;
86.170 }
86.171 }
86.172 @@ -218,11 +225,12 @@
86.173 void findMinCutOut() {
86.174
86.175 for (NodeIt n(_graph); n != INVALID; ++n) {
86.176 - _excess->set(n, 0);
86.177 + (*_excess)[n] = 0;
86.178 + (*_source_set)[n] = false;
86.179 }
86.180
86.181 for (ArcIt a(_graph); a != INVALID; ++a) {
86.182 - _flow->set(a, 0);
86.183 + (*_flow)[a] = 0;
86.184 }
86.185
86.186 int bucket_num = 0;
86.187 @@ -232,7 +240,7 @@
86.188 {
86.189 typename Digraph::template NodeMap<bool> reached(_graph, false);
86.190
86.191 - reached.set(_source, true);
86.192 + reached[_source] = true;
86.193 bool first_set = true;
86.194
86.195 for (NodeIt t(_graph); t != INVALID; ++t) {
86.196 @@ -240,7 +248,7 @@
86.197 _sets.push_front(std::list<int>());
86.198
86.199 queue[qlast++] = t;
86.200 - reached.set(t, true);
86.201 + reached[t] = true;
86.202
86.203 while (qfirst != qlast) {
86.204 if (qsep == qfirst) {
86.205 @@ -257,7 +265,7 @@
86.206 for (InArcIt a(_graph, n); a != INVALID; ++a) {
86.207 Node u = _graph.source(a);
86.208 if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
86.209 - reached.set(u, true);
86.210 + reached[u] = true;
86.211 queue[qlast++] = u;
86.212 }
86.213 }
86.214 @@ -266,18 +274,18 @@
86.215 }
86.216
86.217 ++bucket_num;
86.218 - _bucket->set(_source, 0);
86.219 + (*_bucket)[_source] = 0;
86.220 _dormant[0] = true;
86.221 }
86.222 - _source_set->set(_source, true);
86.223 + (*_source_set)[_source] = true;
86.224
86.225 Node target = _last[_sets.back().back()];
86.226 {
86.227 for (OutArcIt a(_graph, _source); a != INVALID; ++a) {
86.228 if (_tolerance.positive((*_capacity)[a])) {
86.229 Node u = _graph.target(a);
86.230 - _flow->set(a, (*_capacity)[a]);
86.231 - _excess->set(u, (*_excess)[u] + (*_capacity)[a]);
86.232 + (*_flow)[a] = (*_capacity)[a];
86.233 + (*_excess)[u] += (*_capacity)[a];
86.234 if (!(*_active)[u] && u != _source) {
86.235 activate(u);
86.236 }
86.237 @@ -318,14 +326,14 @@
86.238 activate(v);
86.239 }
86.240 if (!_tolerance.less(rem, excess)) {
86.241 - _flow->set(a, (*_flow)[a] + excess);
86.242 - _excess->set(v, (*_excess)[v] + excess);
86.243 + (*_flow)[a] += excess;
86.244 + (*_excess)[v] += excess;
86.245 excess = 0;
86.246 goto no_more_push;
86.247 } else {
86.248 excess -= rem;
86.249 - _excess->set(v, (*_excess)[v] + rem);
86.250 - _flow->set(a, (*_capacity)[a]);
86.251 + (*_excess)[v] += rem;
86.252 + (*_flow)[a] = (*_capacity)[a];
86.253 }
86.254 } else if (next_bucket > (*_bucket)[v]) {
86.255 next_bucket = (*_bucket)[v];
86.256 @@ -342,14 +350,14 @@
86.257 activate(v);
86.258 }
86.259 if (!_tolerance.less(rem, excess)) {
86.260 - _flow->set(a, (*_flow)[a] - excess);
86.261 - _excess->set(v, (*_excess)[v] + excess);
86.262 + (*_flow)[a] -= excess;
86.263 + (*_excess)[v] += excess;
86.264 excess = 0;
86.265 goto no_more_push;
86.266 } else {
86.267 excess -= rem;
86.268 - _excess->set(v, (*_excess)[v] + rem);
86.269 - _flow->set(a, 0);
86.270 + (*_excess)[v] += rem;
86.271 + (*_flow)[a] = 0;
86.272 }
86.273 } else if (next_bucket > (*_bucket)[v]) {
86.274 next_bucket = (*_bucket)[v];
86.275 @@ -358,7 +366,7 @@
86.276
86.277 no_more_push:
86.278
86.279 - _excess->set(n, excess);
86.280 + (*_excess)[n] = excess;
86.281
86.282 if (excess != 0) {
86.283 if ((*_next)[n] == INVALID) {
86.284 @@ -376,16 +384,16 @@
86.285 }
86.286 } else if (next_bucket == _node_num) {
86.287 _first[(*_bucket)[n]] = (*_next)[n];
86.288 - _prev->set((*_next)[n], INVALID);
86.289 + (*_prev)[(*_next)[n]] = INVALID;
86.290
86.291 std::list<std::list<int> >::iterator new_set =
86.292 _sets.insert(--_sets.end(), std::list<int>());
86.293
86.294 new_set->push_front(bucket_num);
86.295 - _bucket->set(n, bucket_num);
86.296 + (*_bucket)[n] = bucket_num;
86.297 _first[bucket_num] = _last[bucket_num] = n;
86.298 - _next->set(n, INVALID);
86.299 - _prev->set(n, INVALID);
86.300 + (*_next)[n] = INVALID;
86.301 + (*_prev)[n] = INVALID;
86.302 _dormant[bucket_num] = true;
86.303 ++bucket_num;
86.304
86.305 @@ -395,7 +403,7 @@
86.306 }
86.307 } else {
86.308 _first[*_highest] = (*_next)[n];
86.309 - _prev->set((*_next)[n], INVALID);
86.310 + (*_prev)[(*_next)[n]] = INVALID;
86.311
86.312 while (next_bucket != *_highest) {
86.313 --_highest;
86.314 @@ -409,10 +417,10 @@
86.315 }
86.316 --_highest;
86.317
86.318 - _bucket->set(n, *_highest);
86.319 - _next->set(n, _first[*_highest]);
86.320 + (*_bucket)[n] = *_highest;
86.321 + (*_next)[n] = _first[*_highest];
86.322 if (_first[*_highest] != INVALID) {
86.323 - _prev->set(_first[*_highest], n);
86.324 + (*_prev)[_first[*_highest]] = n;
86.325 } else {
86.326 _last[*_highest] = n;
86.327 }
86.328 @@ -434,13 +442,13 @@
86.329 if ((*_excess)[target] < _min_cut) {
86.330 _min_cut = (*_excess)[target];
86.331 for (NodeIt i(_graph); i != INVALID; ++i) {
86.332 - _min_cut_map->set(i, true);
86.333 + (*_min_cut_map)[i] = true;
86.334 }
86.335 for (std::list<int>::iterator it = _sets.back().begin();
86.336 it != _sets.back().end(); ++it) {
86.337 Node n = _first[*it];
86.338 while (n != INVALID) {
86.339 - _min_cut_map->set(n, false);
86.340 + (*_min_cut_map)[n] = false;
86.341 n = (*_next)[n];
86.342 }
86.343 }
86.344 @@ -453,13 +461,13 @@
86.345 _last[(*_bucket)[target]] = (*_prev)[target];
86.346 new_target = (*_prev)[target];
86.347 } else {
86.348 - _prev->set((*_next)[target], (*_prev)[target]);
86.349 + (*_prev)[(*_next)[target]] = (*_prev)[target];
86.350 new_target = (*_next)[target];
86.351 }
86.352 if ((*_prev)[target] == INVALID) {
86.353 _first[(*_bucket)[target]] = (*_next)[target];
86.354 } else {
86.355 - _next->set((*_prev)[target], (*_next)[target]);
86.356 + (*_next)[(*_prev)[target]] = (*_next)[target];
86.357 }
86.358 } else {
86.359 _sets.back().pop_back();
86.360 @@ -475,9 +483,9 @@
86.361 new_target = _last[_sets.back().back()];
86.362 }
86.363
86.364 - _bucket->set(target, 0);
86.365 + (*_bucket)[target] = 0;
86.366
86.367 - _source_set->set(target, true);
86.368 + (*_source_set)[target] = true;
86.369 for (OutArcIt a(_graph, target); a != INVALID; ++a) {
86.370 Value rem = (*_capacity)[a] - (*_flow)[a];
86.371 if (!_tolerance.positive(rem)) continue;
86.372 @@ -485,8 +493,8 @@
86.373 if (!(*_active)[v] && !(*_source_set)[v]) {
86.374 activate(v);
86.375 }
86.376 - _excess->set(v, (*_excess)[v] + rem);
86.377 - _flow->set(a, (*_capacity)[a]);
86.378 + (*_excess)[v] += rem;
86.379 + (*_flow)[a] = (*_capacity)[a];
86.380 }
86.381
86.382 for (InArcIt a(_graph, target); a != INVALID; ++a) {
86.383 @@ -496,8 +504,8 @@
86.384 if (!(*_active)[v] && !(*_source_set)[v]) {
86.385 activate(v);
86.386 }
86.387 - _excess->set(v, (*_excess)[v] + rem);
86.388 - _flow->set(a, 0);
86.389 + (*_excess)[v] += rem;
86.390 + (*_flow)[a] = 0;
86.391 }
86.392
86.393 target = new_target;
86.394 @@ -517,11 +525,12 @@
86.395 void findMinCutIn() {
86.396
86.397 for (NodeIt n(_graph); n != INVALID; ++n) {
86.398 - _excess->set(n, 0);
86.399 + (*_excess)[n] = 0;
86.400 + (*_source_set)[n] = false;
86.401 }
86.402
86.403 for (ArcIt a(_graph); a != INVALID; ++a) {
86.404 - _flow->set(a, 0);
86.405 + (*_flow)[a] = 0;
86.406 }
86.407
86.408 int bucket_num = 0;
86.409 @@ -531,7 +540,7 @@
86.410 {
86.411 typename Digraph::template NodeMap<bool> reached(_graph, false);
86.412
86.413 - reached.set(_source, true);
86.414 + reached[_source] = true;
86.415
86.416 bool first_set = true;
86.417
86.418 @@ -540,7 +549,7 @@
86.419 _sets.push_front(std::list<int>());
86.420
86.421 queue[qlast++] = t;
86.422 - reached.set(t, true);
86.423 + reached[t] = true;
86.424
86.425 while (qfirst != qlast) {
86.426 if (qsep == qfirst) {
86.427 @@ -557,7 +566,7 @@
86.428 for (OutArcIt a(_graph, n); a != INVALID; ++a) {
86.429 Node u = _graph.target(a);
86.430 if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
86.431 - reached.set(u, true);
86.432 + reached[u] = true;
86.433 queue[qlast++] = u;
86.434 }
86.435 }
86.436 @@ -566,18 +575,18 @@
86.437 }
86.438
86.439 ++bucket_num;
86.440 - _bucket->set(_source, 0);
86.441 + (*_bucket)[_source] = 0;
86.442 _dormant[0] = true;
86.443 }
86.444 - _source_set->set(_source, true);
86.445 + (*_source_set)[_source] = true;
86.446
86.447 Node target = _last[_sets.back().back()];
86.448 {
86.449 for (InArcIt a(_graph, _source); a != INVALID; ++a) {
86.450 if (_tolerance.positive((*_capacity)[a])) {
86.451 Node u = _graph.source(a);
86.452 - _flow->set(a, (*_capacity)[a]);
86.453 - _excess->set(u, (*_excess)[u] + (*_capacity)[a]);
86.454 + (*_flow)[a] = (*_capacity)[a];
86.455 + (*_excess)[u] += (*_capacity)[a];
86.456 if (!(*_active)[u] && u != _source) {
86.457 activate(u);
86.458 }
86.459 @@ -618,14 +627,14 @@
86.460 activate(v);
86.461 }
86.462 if (!_tolerance.less(rem, excess)) {
86.463 - _flow->set(a, (*_flow)[a] + excess);
86.464 - _excess->set(v, (*_excess)[v] + excess);
86.465 + (*_flow)[a] += excess;
86.466 + (*_excess)[v] += excess;
86.467 excess = 0;
86.468 goto no_more_push;
86.469 } else {
86.470 excess -= rem;
86.471 - _excess->set(v, (*_excess)[v] + rem);
86.472 - _flow->set(a, (*_capacity)[a]);
86.473 + (*_excess)[v] += rem;
86.474 + (*_flow)[a] = (*_capacity)[a];
86.475 }
86.476 } else if (next_bucket > (*_bucket)[v]) {
86.477 next_bucket = (*_bucket)[v];
86.478 @@ -642,14 +651,14 @@
86.479 activate(v);
86.480 }
86.481 if (!_tolerance.less(rem, excess)) {
86.482 - _flow->set(a, (*_flow)[a] - excess);
86.483 - _excess->set(v, (*_excess)[v] + excess);
86.484 + (*_flow)[a] -= excess;
86.485 + (*_excess)[v] += excess;
86.486 excess = 0;
86.487 goto no_more_push;
86.488 } else {
86.489 excess -= rem;
86.490 - _excess->set(v, (*_excess)[v] + rem);
86.491 - _flow->set(a, 0);
86.492 + (*_excess)[v] += rem;
86.493 + (*_flow)[a] = 0;
86.494 }
86.495 } else if (next_bucket > (*_bucket)[v]) {
86.496 next_bucket = (*_bucket)[v];
86.497 @@ -658,7 +667,7 @@
86.498
86.499 no_more_push:
86.500
86.501 - _excess->set(n, excess);
86.502 + (*_excess)[n] = excess;
86.503
86.504 if (excess != 0) {
86.505 if ((*_next)[n] == INVALID) {
86.506 @@ -676,16 +685,16 @@
86.507 }
86.508 } else if (next_bucket == _node_num) {
86.509 _first[(*_bucket)[n]] = (*_next)[n];
86.510 - _prev->set((*_next)[n], INVALID);
86.511 + (*_prev)[(*_next)[n]] = INVALID;
86.512
86.513 std::list<std::list<int> >::iterator new_set =
86.514 _sets.insert(--_sets.end(), std::list<int>());
86.515
86.516 new_set->push_front(bucket_num);
86.517 - _bucket->set(n, bucket_num);
86.518 + (*_bucket)[n] = bucket_num;
86.519 _first[bucket_num] = _last[bucket_num] = n;
86.520 - _next->set(n, INVALID);
86.521 - _prev->set(n, INVALID);
86.522 + (*_next)[n] = INVALID;
86.523 + (*_prev)[n] = INVALID;
86.524 _dormant[bucket_num] = true;
86.525 ++bucket_num;
86.526
86.527 @@ -695,7 +704,7 @@
86.528 }
86.529 } else {
86.530 _first[*_highest] = (*_next)[n];
86.531 - _prev->set((*_next)[n], INVALID);
86.532 + (*_prev)[(*_next)[n]] = INVALID;
86.533
86.534 while (next_bucket != *_highest) {
86.535 --_highest;
86.536 @@ -708,10 +717,10 @@
86.537 }
86.538 --_highest;
86.539
86.540 - _bucket->set(n, *_highest);
86.541 - _next->set(n, _first[*_highest]);
86.542 + (*_bucket)[n] = *_highest;
86.543 + (*_next)[n] = _first[*_highest];
86.544 if (_first[*_highest] != INVALID) {
86.545 - _prev->set(_first[*_highest], n);
86.546 + (*_prev)[_first[*_highest]] = n;
86.547 } else {
86.548 _last[*_highest] = n;
86.549 }
86.550 @@ -733,13 +742,13 @@
86.551 if ((*_excess)[target] < _min_cut) {
86.552 _min_cut = (*_excess)[target];
86.553 for (NodeIt i(_graph); i != INVALID; ++i) {
86.554 - _min_cut_map->set(i, false);
86.555 + (*_min_cut_map)[i] = false;
86.556 }
86.557 for (std::list<int>::iterator it = _sets.back().begin();
86.558 it != _sets.back().end(); ++it) {
86.559 Node n = _first[*it];
86.560 while (n != INVALID) {
86.561 - _min_cut_map->set(n, true);
86.562 + (*_min_cut_map)[n] = true;
86.563 n = (*_next)[n];
86.564 }
86.565 }
86.566 @@ -752,13 +761,13 @@
86.567 _last[(*_bucket)[target]] = (*_prev)[target];
86.568 new_target = (*_prev)[target];
86.569 } else {
86.570 - _prev->set((*_next)[target], (*_prev)[target]);
86.571 + (*_prev)[(*_next)[target]] = (*_prev)[target];
86.572 new_target = (*_next)[target];
86.573 }
86.574 if ((*_prev)[target] == INVALID) {
86.575 _first[(*_bucket)[target]] = (*_next)[target];
86.576 } else {
86.577 - _next->set((*_prev)[target], (*_next)[target]);
86.578 + (*_next)[(*_prev)[target]] = (*_next)[target];
86.579 }
86.580 } else {
86.581 _sets.back().pop_back();
86.582 @@ -774,9 +783,9 @@
86.583 new_target = _last[_sets.back().back()];
86.584 }
86.585
86.586 - _bucket->set(target, 0);
86.587 + (*_bucket)[target] = 0;
86.588
86.589 - _source_set->set(target, true);
86.590 + (*_source_set)[target] = true;
86.591 for (InArcIt a(_graph, target); a != INVALID; ++a) {
86.592 Value rem = (*_capacity)[a] - (*_flow)[a];
86.593 if (!_tolerance.positive(rem)) continue;
86.594 @@ -784,8 +793,8 @@
86.595 if (!(*_active)[v] && !(*_source_set)[v]) {
86.596 activate(v);
86.597 }
86.598 - _excess->set(v, (*_excess)[v] + rem);
86.599 - _flow->set(a, (*_capacity)[a]);
86.600 + (*_excess)[v] += rem;
86.601 + (*_flow)[a] = (*_capacity)[a];
86.602 }
86.603
86.604 for (OutArcIt a(_graph, target); a != INVALID; ++a) {
86.605 @@ -795,8 +804,8 @@
86.606 if (!(*_active)[v] && !(*_source_set)[v]) {
86.607 activate(v);
86.608 }
86.609 - _excess->set(v, (*_excess)[v] + rem);
86.610 - _flow->set(a, 0);
86.611 + (*_excess)[v] += rem;
86.612 + (*_flow)[a] = 0;
86.613 }
86.614
86.615 target = new_target;
86.616 @@ -815,31 +824,32 @@
86.617
86.618 public:
86.619
86.620 - /// \name Execution control
86.621 + /// \name Execution Control
86.622 /// The simplest way to execute the algorithm is to use
86.623 - /// one of the member functions called \c run(...).
86.624 + /// one of the member functions called \ref run().
86.625 /// \n
86.626 - /// If you need more control on the execution,
86.627 - /// first you must call \ref init(), then the \ref calculateIn() or
86.628 - /// \ref calculateOut() functions.
86.629 + /// If you need better control on the execution,
86.630 + /// you have to call one of the \ref init() functions first, then
86.631 + /// \ref calculateOut() and/or \ref calculateIn().
86.632
86.633 /// @{
86.634
86.635 - /// \brief Initializes the internal data structures.
86.636 + /// \brief Initialize the internal data structures.
86.637 ///
86.638 - /// Initializes the internal data structures. It creates
86.639 - /// the maps, residual graph adaptors and some bucket structures
86.640 - /// for the algorithm.
86.641 + /// This function initializes the internal data structures. It creates
86.642 + /// the maps and some bucket structures for the algorithm.
86.643 + /// The first node is used as the source node for the push-relabel
86.644 + /// algorithm.
86.645 void init() {
86.646 init(NodeIt(_graph));
86.647 }
86.648
86.649 - /// \brief Initializes the internal data structures.
86.650 + /// \brief Initialize the internal data structures.
86.651 ///
86.652 - /// Initializes the internal data structures. It creates
86.653 - /// the maps, residual graph adaptor and some bucket structures
86.654 - /// for the algorithm. Node \c source is used as the push-relabel
86.655 - /// algorithm's source.
86.656 + /// This function initializes the internal data structures. It creates
86.657 + /// the maps and some bucket structures for the algorithm.
86.658 + /// The given node is used as the source node for the push-relabel
86.659 + /// algorithm.
86.660 void init(const Node& source) {
86.661 _source = source;
86.662
86.663 @@ -879,31 +889,35 @@
86.664 }
86.665
86.666
86.667 - /// \brief Calculates a minimum cut with \f$ source \f$ on the
86.668 + /// \brief Calculate a minimum cut with \f$ source \f$ on the
86.669 /// source-side.
86.670 ///
86.671 - /// Calculates a minimum cut with \f$ source \f$ on the
86.672 + /// This function calculates a minimum cut with \f$ source \f$ on the
86.673 /// source-side (i.e. a set \f$ X\subsetneq V \f$ with
86.674 - /// \f$ source \in X \f$ and minimal out-degree).
86.675 + /// \f$ source \in X \f$ and minimal outgoing capacity).
86.676 + ///
86.677 + /// \pre \ref init() must be called before using this function.
86.678 void calculateOut() {
86.679 findMinCutOut();
86.680 }
86.681
86.682 - /// \brief Calculates a minimum cut with \f$ source \f$ on the
86.683 - /// target-side.
86.684 + /// \brief Calculate a minimum cut with \f$ source \f$ on the
86.685 + /// sink-side.
86.686 ///
86.687 - /// Calculates a minimum cut with \f$ source \f$ on the
86.688 - /// target-side (i.e. a set \f$ X\subsetneq V \f$ with
86.689 - /// \f$ source \in X \f$ and minimal out-degree).
86.690 + /// This function calculates a minimum cut with \f$ source \f$ on the
86.691 + /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with
86.692 + /// \f$ source \notin X \f$ and minimal outgoing capacity).
86.693 + ///
86.694 + /// \pre \ref init() must be called before using this function.
86.695 void calculateIn() {
86.696 findMinCutIn();
86.697 }
86.698
86.699
86.700 - /// \brief Runs the algorithm.
86.701 + /// \brief Run the algorithm.
86.702 ///
86.703 - /// Runs the algorithm. It finds nodes \c source and \c target
86.704 - /// arbitrarily and then calls \ref init(), \ref calculateOut()
86.705 + /// This function runs the algorithm. It finds nodes \c source and
86.706 + /// \c target arbitrarily and then calls \ref init(), \ref calculateOut()
86.707 /// and \ref calculateIn().
86.708 void run() {
86.709 init();
86.710 @@ -911,11 +925,11 @@
86.711 calculateIn();
86.712 }
86.713
86.714 - /// \brief Runs the algorithm.
86.715 + /// \brief Run the algorithm.
86.716 ///
86.717 - /// Runs the algorithm. It uses the given \c source node, finds a
86.718 - /// proper \c target and then calls the \ref init(), \ref
86.719 - /// calculateOut() and \ref calculateIn().
86.720 + /// This function runs the algorithm. It uses the given \c source node,
86.721 + /// finds a proper \c target node and then calls the \ref init(),
86.722 + /// \ref calculateOut() and \ref calculateIn().
86.723 void run(const Node& s) {
86.724 init(s);
86.725 calculateOut();
86.726 @@ -926,32 +940,41 @@
86.727
86.728 /// \name Query Functions
86.729 /// The result of the %HaoOrlin algorithm
86.730 - /// can be obtained using these functions.
86.731 - /// \n
86.732 - /// Before using these functions, either \ref run(), \ref
86.733 - /// calculateOut() or \ref calculateIn() must be called.
86.734 + /// can be obtained using these functions.\n
86.735 + /// \ref run(), \ref calculateOut() or \ref calculateIn()
86.736 + /// should be called before using them.
86.737
86.738 /// @{
86.739
86.740 - /// \brief Returns the value of the minimum value cut.
86.741 + /// \brief Return the value of the minimum cut.
86.742 ///
86.743 - /// Returns the value of the minimum value cut.
86.744 + /// This function returns the value of the minimum cut.
86.745 + ///
86.746 + /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
86.747 + /// must be called before using this function.
86.748 Value minCutValue() const {
86.749 return _min_cut;
86.750 }
86.751
86.752
86.753 - /// \brief Returns a minimum cut.
86.754 + /// \brief Return a minimum cut.
86.755 ///
86.756 - /// Sets \c nodeMap to the characteristic vector of a minimum
86.757 - /// value cut: it will give a nonempty set \f$ X\subsetneq V \f$
86.758 - /// with minimal out-degree (i.e. \c nodeMap will be true exactly
86.759 - /// for the nodes of \f$ X \f$). \pre nodeMap should be a
86.760 - /// bool-valued node-map.
86.761 - template <typename NodeMap>
86.762 - Value minCutMap(NodeMap& nodeMap) const {
86.763 + /// This function sets \c cutMap to the characteristic vector of a
86.764 + /// minimum value cut: it will give a non-empty set \f$ X\subsetneq V \f$
86.765 + /// with minimal outgoing capacity (i.e. \c cutMap will be \c true exactly
86.766 + /// for the nodes of \f$ X \f$).
86.767 + ///
86.768 + /// \param cutMap A \ref concepts::WriteMap "writable" node map with
86.769 + /// \c bool (or convertible) value type.
86.770 + ///
86.771 + /// \return The value of the minimum cut.
86.772 + ///
86.773 + /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
86.774 + /// must be called before using this function.
86.775 + template <typename CutMap>
86.776 + Value minCutMap(CutMap& cutMap) const {
86.777 for (NodeIt it(_graph); it != INVALID; ++it) {
86.778 - nodeMap.set(it, (*_min_cut_map)[it]);
86.779 + cutMap.set(it, (*_min_cut_map)[it]);
86.780 }
86.781 return _min_cut;
86.782 }
86.783 @@ -960,7 +983,6 @@
86.784
86.785 }; //class HaoOrlin
86.786
86.787 -
86.788 } //namespace lemon
86.789
86.790 #endif //LEMON_HAO_ORLIN_H
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
87.2 +++ b/lemon/hartmann_orlin.h Thu Nov 05 15:48:01 2009 +0100
87.3 @@ -0,0 +1,640 @@
87.4 +/* -*- C++ -*-
87.5 + *
87.6 + * This file is a part of LEMON, a generic C++ optimization library
87.7 + *
87.8 + * Copyright (C) 2003-2008
87.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
87.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
87.11 + *
87.12 + * Permission to use, modify and distribute this software is granted
87.13 + * provided that this copyright notice appears in all copies. For
87.14 + * precise terms see the accompanying LICENSE file.
87.15 + *
87.16 + * This software is provided "AS IS" with no warranty of any kind,
87.17 + * express or implied, and with no claim as to its suitability for any
87.18 + * purpose.
87.19 + *
87.20 + */
87.21 +
87.22 +#ifndef LEMON_HARTMANN_ORLIN_H
87.23 +#define LEMON_HARTMANN_ORLIN_H
87.24 +
87.25 +/// \ingroup min_mean_cycle
87.26 +///
87.27 +/// \file
87.28 +/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
87.29 +
87.30 +#include <vector>
87.31 +#include <limits>
87.32 +#include <lemon/core.h>
87.33 +#include <lemon/path.h>
87.34 +#include <lemon/tolerance.h>
87.35 +#include <lemon/connectivity.h>
87.36 +
87.37 +namespace lemon {
87.38 +
87.39 + /// \brief Default traits class of HartmannOrlin algorithm.
87.40 + ///
87.41 + /// Default traits class of HartmannOrlin algorithm.
87.42 + /// \tparam GR The type of the digraph.
87.43 + /// \tparam LEN The type of the length map.
87.44 + /// It must conform to the \ref concepts::Rea_data "Rea_data" concept.
87.45 +#ifdef DOXYGEN
87.46 + template <typename GR, typename LEN>
87.47 +#else
87.48 + template <typename GR, typename LEN,
87.49 + bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
87.50 +#endif
87.51 + struct HartmannOrlinDefaultTraits
87.52 + {
87.53 + /// The type of the digraph
87.54 + typedef GR Digraph;
87.55 + /// The type of the length map
87.56 + typedef LEN LengthMap;
87.57 + /// The type of the arc lengths
87.58 + typedef typename LengthMap::Value Value;
87.59 +
87.60 + /// \brief The large value type used for internal computations
87.61 + ///
87.62 + /// The large value type used for internal computations.
87.63 + /// It is \c long \c long if the \c Value type is integer,
87.64 + /// otherwise it is \c double.
87.65 + /// \c Value must be convertible to \c LargeValue.
87.66 + typedef double LargeValue;
87.67 +
87.68 + /// The tolerance type used for internal computations
87.69 + typedef lemon::Tolerance<LargeValue> Tolerance;
87.70 +
87.71 + /// \brief The path type of the found cycles
87.72 + ///
87.73 + /// The path type of the found cycles.
87.74 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
87.75 + /// and it must have an \c addFront() function.
87.76 + typedef lemon::Path<Digraph> Path;
87.77 + };
87.78 +
87.79 + // Default traits class for integer value types
87.80 + template <typename GR, typename LEN>
87.81 + struct HartmannOrlinDefaultTraits<GR, LEN, true>
87.82 + {
87.83 + typedef GR Digraph;
87.84 + typedef LEN LengthMap;
87.85 + typedef typename LengthMap::Value Value;
87.86 +#ifdef LEMON_HAVE_LONG_LONG
87.87 + typedef long long LargeValue;
87.88 +#else
87.89 + typedef long LargeValue;
87.90 +#endif
87.91 + typedef lemon::Tolerance<LargeValue> Tolerance;
87.92 + typedef lemon::Path<Digraph> Path;
87.93 + };
87.94 +
87.95 +
87.96 + /// \addtogroup min_mean_cycle
87.97 + /// @{
87.98 +
87.99 + /// \brief Implementation of the Hartmann-Orlin algorithm for finding
87.100 + /// a minimum mean cycle.
87.101 + ///
87.102 + /// This class implements the Hartmann-Orlin algorithm for finding
87.103 + /// a directed cycle of minimum mean length (cost) in a digraph
87.104 + /// \ref amo93networkflows, \ref dasdan98minmeancycle.
87.105 + /// It is an improved version of \ref Karp "Karp"'s original algorithm,
87.106 + /// it applies an efficient early termination scheme.
87.107 + /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
87.108 + ///
87.109 + /// \tparam GR The type of the digraph the algorithm runs on.
87.110 + /// \tparam LEN The type of the length map. The default
87.111 + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
87.112 +#ifdef DOXYGEN
87.113 + template <typename GR, typename LEN, typename TR>
87.114 +#else
87.115 + template < typename GR,
87.116 + typename LEN = typename GR::template ArcMap<int>,
87.117 + typename TR = HartmannOrlinDefaultTraits<GR, LEN> >
87.118 +#endif
87.119 + class HartmannOrlin
87.120 + {
87.121 + public:
87.122 +
87.123 + /// The type of the digraph
87.124 + typedef typename TR::Digraph Digraph;
87.125 + /// The type of the length map
87.126 + typedef typename TR::LengthMap LengthMap;
87.127 + /// The type of the arc lengths
87.128 + typedef typename TR::Value Value;
87.129 +
87.130 + /// \brief The large value type
87.131 + ///
87.132 + /// The large value type used for internal computations.
87.133 + /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
87.134 + /// it is \c long \c long if the \c Value type is integer,
87.135 + /// otherwise it is \c double.
87.136 + typedef typename TR::LargeValue LargeValue;
87.137 +
87.138 + /// The tolerance type
87.139 + typedef typename TR::Tolerance Tolerance;
87.140 +
87.141 + /// \brief The path type of the found cycles
87.142 + ///
87.143 + /// The path type of the found cycles.
87.144 + /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
87.145 + /// it is \ref lemon::Path "Path<Digraph>".
87.146 + typedef typename TR::Path Path;
87.147 +
87.148 + /// The \ref HartmannOrlinDefaultTraits "traits class" of the algorithm
87.149 + typedef TR Traits;
87.150 +
87.151 + private:
87.152 +
87.153 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
87.154 +
87.155 + // Data sturcture for path data
87.156 + struct PathData
87.157 + {
87.158 + LargeValue dist;
87.159 + Arc pred;
87.160 + PathData(LargeValue d, Arc p = INVALID) :
87.161 + dist(d), pred(p) {}
87.162 + };
87.163 +
87.164 + typedef typename Digraph::template NodeMap<std::vector<PathData> >
87.165 + PathDataNodeMap;
87.166 +
87.167 + private:
87.168 +
87.169 + // The digraph the algorithm runs on
87.170 + const Digraph &_gr;
87.171 + // The length of the arcs
87.172 + const LengthMap &_length;
87.173 +
87.174 + // Data for storing the strongly connected components
87.175 + int _comp_num;
87.176 + typename Digraph::template NodeMap<int> _comp;
87.177 + std::vector<std::vector<Node> > _comp_nodes;
87.178 + std::vector<Node>* _nodes;
87.179 + typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
87.180 +
87.181 + // Data for the found cycles
87.182 + bool _curr_found, _best_found;
87.183 + LargeValue _curr_length, _best_length;
87.184 + int _curr_size, _best_size;
87.185 + Node _curr_node, _best_node;
87.186 + int _curr_level, _best_level;
87.187 +
87.188 + Path *_cycle_path;
87.189 + bool _local_path;
87.190 +
87.191 + // Node map for storing path data
87.192 + PathDataNodeMap _data;
87.193 + // The processed nodes in the last round
87.194 + std::vector<Node> _process;
87.195 +
87.196 + Tolerance _tolerance;
87.197 +
87.198 + // Infinite constant
87.199 + const LargeValue INF;
87.200 +
87.201 + public:
87.202 +
87.203 + /// \name Named Template Parameters
87.204 + /// @{
87.205 +
87.206 + template <typename T>
87.207 + struct SetLargeValueTraits : public Traits {
87.208 + typedef T LargeValue;
87.209 + typedef lemon::Tolerance<T> Tolerance;
87.210 + };
87.211 +
87.212 + /// \brief \ref named-templ-param "Named parameter" for setting
87.213 + /// \c LargeValue type.
87.214 + ///
87.215 + /// \ref named-templ-param "Named parameter" for setting \c LargeValue
87.216 + /// type. It is used for internal computations in the algorithm.
87.217 + template <typename T>
87.218 + struct SetLargeValue
87.219 + : public HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > {
87.220 + typedef HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > Create;
87.221 + };
87.222 +
87.223 + template <typename T>
87.224 + struct SetPathTraits : public Traits {
87.225 + typedef T Path;
87.226 + };
87.227 +
87.228 + /// \brief \ref named-templ-param "Named parameter" for setting
87.229 + /// \c %Path type.
87.230 + ///
87.231 + /// \ref named-templ-param "Named parameter" for setting the \c %Path
87.232 + /// type of the found cycles.
87.233 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
87.234 + /// and it must have an \c addFront() function.
87.235 + template <typename T>
87.236 + struct SetPath
87.237 + : public HartmannOrlin<GR, LEN, SetPathTraits<T> > {
87.238 + typedef HartmannOrlin<GR, LEN, SetPathTraits<T> > Create;
87.239 + };
87.240 +
87.241 + /// @}
87.242 +
87.243 + public:
87.244 +
87.245 + /// \brief Constructor.
87.246 + ///
87.247 + /// The constructor of the class.
87.248 + ///
87.249 + /// \param digraph The digraph the algorithm runs on.
87.250 + /// \param length The lengths (costs) of the arcs.
87.251 + HartmannOrlin( const Digraph &digraph,
87.252 + const LengthMap &length ) :
87.253 + _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
87.254 + _best_found(false), _best_length(0), _best_size(1),
87.255 + _cycle_path(NULL), _local_path(false), _data(digraph),
87.256 + INF(std::numeric_limits<LargeValue>::has_infinity ?
87.257 + std::numeric_limits<LargeValue>::infinity() :
87.258 + std::numeric_limits<LargeValue>::max())
87.259 + {}
87.260 +
87.261 + /// Destructor.
87.262 + ~HartmannOrlin() {
87.263 + if (_local_path) delete _cycle_path;
87.264 + }
87.265 +
87.266 + /// \brief Set the path structure for storing the found cycle.
87.267 + ///
87.268 + /// This function sets an external path structure for storing the
87.269 + /// found cycle.
87.270 + ///
87.271 + /// If you don't call this function before calling \ref run() or
87.272 + /// \ref findMinMean(), it will allocate a local \ref Path "path"
87.273 + /// structure. The destuctor deallocates this automatically
87.274 + /// allocated object, of course.
87.275 + ///
87.276 + /// \note The algorithm calls only the \ref lemon::Path::addFront()
87.277 + /// "addFront()" function of the given path structure.
87.278 + ///
87.279 + /// \return <tt>(*this)</tt>
87.280 + HartmannOrlin& cycle(Path &path) {
87.281 + if (_local_path) {
87.282 + delete _cycle_path;
87.283 + _local_path = false;
87.284 + }
87.285 + _cycle_path = &path;
87.286 + return *this;
87.287 + }
87.288 +
87.289 + /// \brief Set the tolerance used by the algorithm.
87.290 + ///
87.291 + /// This function sets the tolerance object used by the algorithm.
87.292 + ///
87.293 + /// \return <tt>(*this)</tt>
87.294 + HartmannOrlin& tolerance(const Tolerance& tolerance) {
87.295 + _tolerance = tolerance;
87.296 + return *this;
87.297 + }
87.298 +
87.299 + /// \brief Return a const reference to the tolerance.
87.300 + ///
87.301 + /// This function returns a const reference to the tolerance object
87.302 + /// used by the algorithm.
87.303 + const Tolerance& tolerance() const {
87.304 + return _tolerance;
87.305 + }
87.306 +
87.307 + /// \name Execution control
87.308 + /// The simplest way to execute the algorithm is to call the \ref run()
87.309 + /// function.\n
87.310 + /// If you only need the minimum mean length, you may call
87.311 + /// \ref findMinMean().
87.312 +
87.313 + /// @{
87.314 +
87.315 + /// \brief Run the algorithm.
87.316 + ///
87.317 + /// This function runs the algorithm.
87.318 + /// It can be called more than once (e.g. if the underlying digraph
87.319 + /// and/or the arc lengths have been modified).
87.320 + ///
87.321 + /// \return \c true if a directed cycle exists in the digraph.
87.322 + ///
87.323 + /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
87.324 + /// \code
87.325 + /// return mmc.findMinMean() && mmc.findCycle();
87.326 + /// \endcode
87.327 + bool run() {
87.328 + return findMinMean() && findCycle();
87.329 + }
87.330 +
87.331 + /// \brief Find the minimum cycle mean.
87.332 + ///
87.333 + /// This function finds the minimum mean length of the directed
87.334 + /// cycles in the digraph.
87.335 + ///
87.336 + /// \return \c true if a directed cycle exists in the digraph.
87.337 + bool findMinMean() {
87.338 + // Initialization and find strongly connected components
87.339 + init();
87.340 + findComponents();
87.341 +
87.342 + // Find the minimum cycle mean in the components
87.343 + for (int comp = 0; comp < _comp_num; ++comp) {
87.344 + if (!initComponent(comp)) continue;
87.345 + processRounds();
87.346 +
87.347 + // Update the best cycle (global minimum mean cycle)
87.348 + if ( _curr_found && (!_best_found ||
87.349 + _curr_length * _best_size < _best_length * _curr_size) ) {
87.350 + _best_found = true;
87.351 + _best_length = _curr_length;
87.352 + _best_size = _curr_size;
87.353 + _best_node = _curr_node;
87.354 + _best_level = _curr_level;
87.355 + }
87.356 + }
87.357 + return _best_found;
87.358 + }
87.359 +
87.360 + /// \brief Find a minimum mean directed cycle.
87.361 + ///
87.362 + /// This function finds a directed cycle of minimum mean length
87.363 + /// in the digraph using the data computed by findMinMean().
87.364 + ///
87.365 + /// \return \c true if a directed cycle exists in the digraph.
87.366 + ///
87.367 + /// \pre \ref findMinMean() must be called before using this function.
87.368 + bool findCycle() {
87.369 + if (!_best_found) return false;
87.370 + IntNodeMap reached(_gr, -1);
87.371 + int r = _best_level + 1;
87.372 + Node u = _best_node;
87.373 + while (reached[u] < 0) {
87.374 + reached[u] = --r;
87.375 + u = _gr.source(_data[u][r].pred);
87.376 + }
87.377 + r = reached[u];
87.378 + Arc e = _data[u][r].pred;
87.379 + _cycle_path->addFront(e);
87.380 + _best_length = _length[e];
87.381 + _best_size = 1;
87.382 + Node v;
87.383 + while ((v = _gr.source(e)) != u) {
87.384 + e = _data[v][--r].pred;
87.385 + _cycle_path->addFront(e);
87.386 + _best_length += _length[e];
87.387 + ++_best_size;
87.388 + }
87.389 + return true;
87.390 + }
87.391 +
87.392 + /// @}
87.393 +
87.394 + /// \name Query Functions
87.395 + /// The results of the algorithm can be obtained using these
87.396 + /// functions.\n
87.397 + /// The algorithm should be executed before using them.
87.398 +
87.399 + /// @{
87.400 +
87.401 + /// \brief Return the total length of the found cycle.
87.402 + ///
87.403 + /// This function returns the total length of the found cycle.
87.404 + ///
87.405 + /// \pre \ref run() or \ref findMinMean() must be called before
87.406 + /// using this function.
87.407 + LargeValue cycleLength() const {
87.408 + return _best_length;
87.409 + }
87.410 +
87.411 + /// \brief Return the number of arcs on the found cycle.
87.412 + ///
87.413 + /// This function returns the number of arcs on the found cycle.
87.414 + ///
87.415 + /// \pre \ref run() or \ref findMinMean() must be called before
87.416 + /// using this function.
87.417 + int cycleArcNum() const {
87.418 + return _best_size;
87.419 + }
87.420 +
87.421 + /// \brief Return the mean length of the found cycle.
87.422 + ///
87.423 + /// This function returns the mean length of the found cycle.
87.424 + ///
87.425 + /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
87.426 + /// following code.
87.427 + /// \code
87.428 + /// return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
87.429 + /// \endcode
87.430 + ///
87.431 + /// \pre \ref run() or \ref findMinMean() must be called before
87.432 + /// using this function.
87.433 + double cycleMean() const {
87.434 + return static_cast<double>(_best_length) / _best_size;
87.435 + }
87.436 +
87.437 + /// \brief Return the found cycle.
87.438 + ///
87.439 + /// This function returns a const reference to the path structure
87.440 + /// storing the found cycle.
87.441 + ///
87.442 + /// \pre \ref run() or \ref findCycle() must be called before using
87.443 + /// this function.
87.444 + const Path& cycle() const {
87.445 + return *_cycle_path;
87.446 + }
87.447 +
87.448 + ///@}
87.449 +
87.450 + private:
87.451 +
87.452 + // Initialization
87.453 + void init() {
87.454 + if (!_cycle_path) {
87.455 + _local_path = true;
87.456 + _cycle_path = new Path;
87.457 + }
87.458 + _cycle_path->clear();
87.459 + _best_found = false;
87.460 + _best_length = 0;
87.461 + _best_size = 1;
87.462 + _cycle_path->clear();
87.463 + for (NodeIt u(_gr); u != INVALID; ++u)
87.464 + _data[u].clear();
87.465 + }
87.466 +
87.467 + // Find strongly connected components and initialize _comp_nodes
87.468 + // and _out_arcs
87.469 + void findComponents() {
87.470 + _comp_num = stronglyConnectedComponents(_gr, _comp);
87.471 + _comp_nodes.resize(_comp_num);
87.472 + if (_comp_num == 1) {
87.473 + _comp_nodes[0].clear();
87.474 + for (NodeIt n(_gr); n != INVALID; ++n) {
87.475 + _comp_nodes[0].push_back(n);
87.476 + _out_arcs[n].clear();
87.477 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
87.478 + _out_arcs[n].push_back(a);
87.479 + }
87.480 + }
87.481 + } else {
87.482 + for (int i = 0; i < _comp_num; ++i)
87.483 + _comp_nodes[i].clear();
87.484 + for (NodeIt n(_gr); n != INVALID; ++n) {
87.485 + int k = _comp[n];
87.486 + _comp_nodes[k].push_back(n);
87.487 + _out_arcs[n].clear();
87.488 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
87.489 + if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
87.490 + }
87.491 + }
87.492 + }
87.493 + }
87.494 +
87.495 + // Initialize path data for the current component
87.496 + bool initComponent(int comp) {
87.497 + _nodes = &(_comp_nodes[comp]);
87.498 + int n = _nodes->size();
87.499 + if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
87.500 + return false;
87.501 + }
87.502 + for (int i = 0; i < n; ++i) {
87.503 + _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
87.504 + }
87.505 + return true;
87.506 + }
87.507 +
87.508 + // Process all rounds of computing path data for the current component.
87.509 + // _data[v][k] is the length of a shortest directed walk from the root
87.510 + // node to node v containing exactly k arcs.
87.511 + void processRounds() {
87.512 + Node start = (*_nodes)[0];
87.513 + _data[start][0] = PathData(0);
87.514 + _process.clear();
87.515 + _process.push_back(start);
87.516 +
87.517 + int k, n = _nodes->size();
87.518 + int next_check = 4;
87.519 + bool terminate = false;
87.520 + for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
87.521 + processNextBuildRound(k);
87.522 + if (k == next_check || k == n) {
87.523 + terminate = checkTermination(k);
87.524 + next_check = next_check * 3 / 2;
87.525 + }
87.526 + }
87.527 + for ( ; k <= n && !terminate; ++k) {
87.528 + processNextFullRound(k);
87.529 + if (k == next_check || k == n) {
87.530 + terminate = checkTermination(k);
87.531 + next_check = next_check * 3 / 2;
87.532 + }
87.533 + }
87.534 + }
87.535 +
87.536 + // Process one round and rebuild _process
87.537 + void processNextBuildRound(int k) {
87.538 + std::vector<Node> next;
87.539 + Node u, v;
87.540 + Arc e;
87.541 + LargeValue d;
87.542 + for (int i = 0; i < int(_process.size()); ++i) {
87.543 + u = _process[i];
87.544 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
87.545 + e = _out_arcs[u][j];
87.546 + v = _gr.target(e);
87.547 + d = _data[u][k-1].dist + _length[e];
87.548 + if (_tolerance.less(d, _data[v][k].dist)) {
87.549 + if (_data[v][k].dist == INF) next.push_back(v);
87.550 + _data[v][k] = PathData(d, e);
87.551 + }
87.552 + }
87.553 + }
87.554 + _process.swap(next);
87.555 + }
87.556 +
87.557 + // Process one round using _nodes instead of _process
87.558 + void processNextFullRound(int k) {
87.559 + Node u, v;
87.560 + Arc e;
87.561 + LargeValue d;
87.562 + for (int i = 0; i < int(_nodes->size()); ++i) {
87.563 + u = (*_nodes)[i];
87.564 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
87.565 + e = _out_arcs[u][j];
87.566 + v = _gr.target(e);
87.567 + d = _data[u][k-1].dist + _length[e];
87.568 + if (_tolerance.less(d, _data[v][k].dist)) {
87.569 + _data[v][k] = PathData(d, e);
87.570 + }
87.571 + }
87.572 + }
87.573 + }
87.574 +
87.575 + // Check early termination
87.576 + bool checkTermination(int k) {
87.577 + typedef std::pair<int, int> Pair;
87.578 + typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
87.579 + typename GR::template NodeMap<LargeValue> pi(_gr);
87.580 + int n = _nodes->size();
87.581 + LargeValue length;
87.582 + int size;
87.583 + Node u;
87.584 +
87.585 + // Search for cycles that are already found
87.586 + _curr_found = false;
87.587 + for (int i = 0; i < n; ++i) {
87.588 + u = (*_nodes)[i];
87.589 + if (_data[u][k].dist == INF) continue;
87.590 + for (int j = k; j >= 0; --j) {
87.591 + if (level[u].first == i && level[u].second > 0) {
87.592 + // A cycle is found
87.593 + length = _data[u][level[u].second].dist - _data[u][j].dist;
87.594 + size = level[u].second - j;
87.595 + if (!_curr_found || length * _curr_size < _curr_length * size) {
87.596 + _curr_length = length;
87.597 + _curr_size = size;
87.598 + _curr_node = u;
87.599 + _curr_level = level[u].second;
87.600 + _curr_found = true;
87.601 + }
87.602 + }
87.603 + level[u] = Pair(i, j);
87.604 + u = _gr.source(_data[u][j].pred);
87.605 + }
87.606 + }
87.607 +
87.608 + // If at least one cycle is found, check the optimality condition
87.609 + LargeValue d;
87.610 + if (_curr_found && k < n) {
87.611 + // Find node potentials
87.612 + for (int i = 0; i < n; ++i) {
87.613 + u = (*_nodes)[i];
87.614 + pi[u] = INF;
87.615 + for (int j = 0; j <= k; ++j) {
87.616 + if (_data[u][j].dist < INF) {
87.617 + d = _data[u][j].dist * _curr_size - j * _curr_length;
87.618 + if (_tolerance.less(d, pi[u])) pi[u] = d;
87.619 + }
87.620 + }
87.621 + }
87.622 +
87.623 + // Check the optimality condition for all arcs
87.624 + bool done = true;
87.625 + for (ArcIt a(_gr); a != INVALID; ++a) {
87.626 + if (_tolerance.less(_length[a] * _curr_size - _curr_length,
87.627 + pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
87.628 + done = false;
87.629 + break;
87.630 + }
87.631 + }
87.632 + return done;
87.633 + }
87.634 + return (k == n);
87.635 + }
87.636 +
87.637 + }; //class HartmannOrlin
87.638 +
87.639 + ///@}
87.640 +
87.641 +} //namespace lemon
87.642 +
87.643 +#endif //LEMON_HARTMANN_ORLIN_H
88.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
88.2 +++ b/lemon/howard.h Thu Nov 05 15:48:01 2009 +0100
88.3 @@ -0,0 +1,597 @@
88.4 +/* -*- C++ -*-
88.5 + *
88.6 + * This file is a part of LEMON, a generic C++ optimization library
88.7 + *
88.8 + * Copyright (C) 2003-2008
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 +#ifndef LEMON_HOWARD_H
88.23 +#define LEMON_HOWARD_H
88.24 +
88.25 +/// \ingroup min_mean_cycle
88.26 +///
88.27 +/// \file
88.28 +/// \brief Howard's algorithm for finding a minimum mean cycle.
88.29 +
88.30 +#include <vector>
88.31 +#include <limits>
88.32 +#include <lemon/core.h>
88.33 +#include <lemon/path.h>
88.34 +#include <lemon/tolerance.h>
88.35 +#include <lemon/connectivity.h>
88.36 +
88.37 +namespace lemon {
88.38 +
88.39 + /// \brief Default traits class of Howard class.
88.40 + ///
88.41 + /// Default traits class of Howard class.
88.42 + /// \tparam GR The type of the digraph.
88.43 + /// \tparam LEN The type of the length map.
88.44 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
88.45 +#ifdef DOXYGEN
88.46 + template <typename GR, typename LEN>
88.47 +#else
88.48 + template <typename GR, typename LEN,
88.49 + bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
88.50 +#endif
88.51 + struct HowardDefaultTraits
88.52 + {
88.53 + /// The type of the digraph
88.54 + typedef GR Digraph;
88.55 + /// The type of the length map
88.56 + typedef LEN LengthMap;
88.57 + /// The type of the arc lengths
88.58 + typedef typename LengthMap::Value Value;
88.59 +
88.60 + /// \brief The large value type used for internal computations
88.61 + ///
88.62 + /// The large value type used for internal computations.
88.63 + /// It is \c long \c long if the \c Value type is integer,
88.64 + /// otherwise it is \c double.
88.65 + /// \c Value must be convertible to \c LargeValue.
88.66 + typedef double LargeValue;
88.67 +
88.68 + /// The tolerance type used for internal computations
88.69 + typedef lemon::Tolerance<LargeValue> Tolerance;
88.70 +
88.71 + /// \brief The path type of the found cycles
88.72 + ///
88.73 + /// The path type of the found cycles.
88.74 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
88.75 + /// and it must have an \c addBack() function.
88.76 + typedef lemon::Path<Digraph> Path;
88.77 + };
88.78 +
88.79 + // Default traits class for integer value types
88.80 + template <typename GR, typename LEN>
88.81 + struct HowardDefaultTraits<GR, LEN, true>
88.82 + {
88.83 + typedef GR Digraph;
88.84 + typedef LEN LengthMap;
88.85 + typedef typename LengthMap::Value Value;
88.86 +#ifdef LEMON_HAVE_LONG_LONG
88.87 + typedef long long LargeValue;
88.88 +#else
88.89 + typedef long LargeValue;
88.90 +#endif
88.91 + typedef lemon::Tolerance<LargeValue> Tolerance;
88.92 + typedef lemon::Path<Digraph> Path;
88.93 + };
88.94 +
88.95 +
88.96 + /// \addtogroup min_mean_cycle
88.97 + /// @{
88.98 +
88.99 + /// \brief Implementation of Howard's algorithm for finding a minimum
88.100 + /// mean cycle.
88.101 + ///
88.102 + /// This class implements Howard's policy iteration algorithm for finding
88.103 + /// a directed cycle of minimum mean length (cost) in a digraph
88.104 + /// \ref amo93networkflows, \ref dasdan98minmeancycle.
88.105 + /// This class provides the most efficient algorithm for the
88.106 + /// minimum mean cycle problem, though the best known theoretical
88.107 + /// bound on its running time is exponential.
88.108 + ///
88.109 + /// \tparam GR The type of the digraph the algorithm runs on.
88.110 + /// \tparam LEN The type of the length map. The default
88.111 + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
88.112 +#ifdef DOXYGEN
88.113 + template <typename GR, typename LEN, typename TR>
88.114 +#else
88.115 + template < typename GR,
88.116 + typename LEN = typename GR::template ArcMap<int>,
88.117 + typename TR = HowardDefaultTraits<GR, LEN> >
88.118 +#endif
88.119 + class Howard
88.120 + {
88.121 + public:
88.122 +
88.123 + /// The type of the digraph
88.124 + typedef typename TR::Digraph Digraph;
88.125 + /// The type of the length map
88.126 + typedef typename TR::LengthMap LengthMap;
88.127 + /// The type of the arc lengths
88.128 + typedef typename TR::Value Value;
88.129 +
88.130 + /// \brief The large value type
88.131 + ///
88.132 + /// The large value type used for internal computations.
88.133 + /// Using the \ref HowardDefaultTraits "default traits class",
88.134 + /// it is \c long \c long if the \c Value type is integer,
88.135 + /// otherwise it is \c double.
88.136 + typedef typename TR::LargeValue LargeValue;
88.137 +
88.138 + /// The tolerance type
88.139 + typedef typename TR::Tolerance Tolerance;
88.140 +
88.141 + /// \brief The path type of the found cycles
88.142 + ///
88.143 + /// The path type of the found cycles.
88.144 + /// Using the \ref HowardDefaultTraits "default traits class",
88.145 + /// it is \ref lemon::Path "Path<Digraph>".
88.146 + typedef typename TR::Path Path;
88.147 +
88.148 + /// The \ref HowardDefaultTraits "traits class" of the algorithm
88.149 + typedef TR Traits;
88.150 +
88.151 + private:
88.152 +
88.153 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
88.154 +
88.155 + // The digraph the algorithm runs on
88.156 + const Digraph &_gr;
88.157 + // The length of the arcs
88.158 + const LengthMap &_length;
88.159 +
88.160 + // Data for the found cycles
88.161 + bool _curr_found, _best_found;
88.162 + LargeValue _curr_length, _best_length;
88.163 + int _curr_size, _best_size;
88.164 + Node _curr_node, _best_node;
88.165 +
88.166 + Path *_cycle_path;
88.167 + bool _local_path;
88.168 +
88.169 + // Internal data used by the algorithm
88.170 + typename Digraph::template NodeMap<Arc> _policy;
88.171 + typename Digraph::template NodeMap<bool> _reached;
88.172 + typename Digraph::template NodeMap<int> _level;
88.173 + typename Digraph::template NodeMap<LargeValue> _dist;
88.174 +
88.175 + // Data for storing the strongly connected components
88.176 + int _comp_num;
88.177 + typename Digraph::template NodeMap<int> _comp;
88.178 + std::vector<std::vector<Node> > _comp_nodes;
88.179 + std::vector<Node>* _nodes;
88.180 + typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
88.181 +
88.182 + // Queue used for BFS search
88.183 + std::vector<Node> _queue;
88.184 + int _qfront, _qback;
88.185 +
88.186 + Tolerance _tolerance;
88.187 +
88.188 + // Infinite constant
88.189 + const LargeValue INF;
88.190 +
88.191 + public:
88.192 +
88.193 + /// \name Named Template Parameters
88.194 + /// @{
88.195 +
88.196 + template <typename T>
88.197 + struct SetLargeValueTraits : public Traits {
88.198 + typedef T LargeValue;
88.199 + typedef lemon::Tolerance<T> Tolerance;
88.200 + };
88.201 +
88.202 + /// \brief \ref named-templ-param "Named parameter" for setting
88.203 + /// \c LargeValue type.
88.204 + ///
88.205 + /// \ref named-templ-param "Named parameter" for setting \c LargeValue
88.206 + /// type. It is used for internal computations in the algorithm.
88.207 + template <typename T>
88.208 + struct SetLargeValue
88.209 + : public Howard<GR, LEN, SetLargeValueTraits<T> > {
88.210 + typedef Howard<GR, LEN, SetLargeValueTraits<T> > Create;
88.211 + };
88.212 +
88.213 + template <typename T>
88.214 + struct SetPathTraits : public Traits {
88.215 + typedef T Path;
88.216 + };
88.217 +
88.218 + /// \brief \ref named-templ-param "Named parameter" for setting
88.219 + /// \c %Path type.
88.220 + ///
88.221 + /// \ref named-templ-param "Named parameter" for setting the \c %Path
88.222 + /// type of the found cycles.
88.223 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
88.224 + /// and it must have an \c addBack() function.
88.225 + template <typename T>
88.226 + struct SetPath
88.227 + : public Howard<GR, LEN, SetPathTraits<T> > {
88.228 + typedef Howard<GR, LEN, SetPathTraits<T> > Create;
88.229 + };
88.230 +
88.231 + /// @}
88.232 +
88.233 + public:
88.234 +
88.235 + /// \brief Constructor.
88.236 + ///
88.237 + /// The constructor of the class.
88.238 + ///
88.239 + /// \param digraph The digraph the algorithm runs on.
88.240 + /// \param length The lengths (costs) of the arcs.
88.241 + Howard( const Digraph &digraph,
88.242 + const LengthMap &length ) :
88.243 + _gr(digraph), _length(length), _best_found(false),
88.244 + _best_length(0), _best_size(1), _cycle_path(NULL), _local_path(false),
88.245 + _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
88.246 + _comp(digraph), _in_arcs(digraph),
88.247 + INF(std::numeric_limits<LargeValue>::has_infinity ?
88.248 + std::numeric_limits<LargeValue>::infinity() :
88.249 + std::numeric_limits<LargeValue>::max())
88.250 + {}
88.251 +
88.252 + /// Destructor.
88.253 + ~Howard() {
88.254 + if (_local_path) delete _cycle_path;
88.255 + }
88.256 +
88.257 + /// \brief Set the path structure for storing the found cycle.
88.258 + ///
88.259 + /// This function sets an external path structure for storing the
88.260 + /// found cycle.
88.261 + ///
88.262 + /// If you don't call this function before calling \ref run() or
88.263 + /// \ref findMinMean(), it will allocate a local \ref Path "path"
88.264 + /// structure. The destuctor deallocates this automatically
88.265 + /// allocated object, of course.
88.266 + ///
88.267 + /// \note The algorithm calls only the \ref lemon::Path::addBack()
88.268 + /// "addBack()" function of the given path structure.
88.269 + ///
88.270 + /// \return <tt>(*this)</tt>
88.271 + Howard& cycle(Path &path) {
88.272 + if (_local_path) {
88.273 + delete _cycle_path;
88.274 + _local_path = false;
88.275 + }
88.276 + _cycle_path = &path;
88.277 + return *this;
88.278 + }
88.279 +
88.280 + /// \brief Set the tolerance used by the algorithm.
88.281 + ///
88.282 + /// This function sets the tolerance object used by the algorithm.
88.283 + ///
88.284 + /// \return <tt>(*this)</tt>
88.285 + Howard& tolerance(const Tolerance& tolerance) {
88.286 + _tolerance = tolerance;
88.287 + return *this;
88.288 + }
88.289 +
88.290 + /// \brief Return a const reference to the tolerance.
88.291 + ///
88.292 + /// This function returns a const reference to the tolerance object
88.293 + /// used by the algorithm.
88.294 + const Tolerance& tolerance() const {
88.295 + return _tolerance;
88.296 + }
88.297 +
88.298 + /// \name Execution control
88.299 + /// The simplest way to execute the algorithm is to call the \ref run()
88.300 + /// function.\n
88.301 + /// If you only need the minimum mean length, you may call
88.302 + /// \ref findMinMean().
88.303 +
88.304 + /// @{
88.305 +
88.306 + /// \brief Run the algorithm.
88.307 + ///
88.308 + /// This function runs the algorithm.
88.309 + /// It can be called more than once (e.g. if the underlying digraph
88.310 + /// and/or the arc lengths have been modified).
88.311 + ///
88.312 + /// \return \c true if a directed cycle exists in the digraph.
88.313 + ///
88.314 + /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
88.315 + /// \code
88.316 + /// return mmc.findMinMean() && mmc.findCycle();
88.317 + /// \endcode
88.318 + bool run() {
88.319 + return findMinMean() && findCycle();
88.320 + }
88.321 +
88.322 + /// \brief Find the minimum cycle mean.
88.323 + ///
88.324 + /// This function finds the minimum mean length of the directed
88.325 + /// cycles in the digraph.
88.326 + ///
88.327 + /// \return \c true if a directed cycle exists in the digraph.
88.328 + bool findMinMean() {
88.329 + // Initialize and find strongly connected components
88.330 + init();
88.331 + findComponents();
88.332 +
88.333 + // Find the minimum cycle mean in the components
88.334 + for (int comp = 0; comp < _comp_num; ++comp) {
88.335 + // Find the minimum mean cycle in the current component
88.336 + if (!buildPolicyGraph(comp)) continue;
88.337 + while (true) {
88.338 + findPolicyCycle();
88.339 + if (!computeNodeDistances()) break;
88.340 + }
88.341 + // Update the best cycle (global minimum mean cycle)
88.342 + if ( _curr_found && (!_best_found ||
88.343 + _curr_length * _best_size < _best_length * _curr_size) ) {
88.344 + _best_found = true;
88.345 + _best_length = _curr_length;
88.346 + _best_size = _curr_size;
88.347 + _best_node = _curr_node;
88.348 + }
88.349 + }
88.350 + return _best_found;
88.351 + }
88.352 +
88.353 + /// \brief Find a minimum mean directed cycle.
88.354 + ///
88.355 + /// This function finds a directed cycle of minimum mean length
88.356 + /// in the digraph using the data computed by findMinMean().
88.357 + ///
88.358 + /// \return \c true if a directed cycle exists in the digraph.
88.359 + ///
88.360 + /// \pre \ref findMinMean() must be called before using this function.
88.361 + bool findCycle() {
88.362 + if (!_best_found) return false;
88.363 + _cycle_path->addBack(_policy[_best_node]);
88.364 + for ( Node v = _best_node;
88.365 + (v = _gr.target(_policy[v])) != _best_node; ) {
88.366 + _cycle_path->addBack(_policy[v]);
88.367 + }
88.368 + return true;
88.369 + }
88.370 +
88.371 + /// @}
88.372 +
88.373 + /// \name Query Functions
88.374 + /// The results of the algorithm can be obtained using these
88.375 + /// functions.\n
88.376 + /// The algorithm should be executed before using them.
88.377 +
88.378 + /// @{
88.379 +
88.380 + /// \brief Return the total length of the found cycle.
88.381 + ///
88.382 + /// This function returns the total length of the found cycle.
88.383 + ///
88.384 + /// \pre \ref run() or \ref findMinMean() must be called before
88.385 + /// using this function.
88.386 + LargeValue cycleLength() const {
88.387 + return _best_length;
88.388 + }
88.389 +
88.390 + /// \brief Return the number of arcs on the found cycle.
88.391 + ///
88.392 + /// This function returns the number of arcs on the found cycle.
88.393 + ///
88.394 + /// \pre \ref run() or \ref findMinMean() must be called before
88.395 + /// using this function.
88.396 + int cycleArcNum() const {
88.397 + return _best_size;
88.398 + }
88.399 +
88.400 + /// \brief Return the mean length of the found cycle.
88.401 + ///
88.402 + /// This function returns the mean length of the found cycle.
88.403 + ///
88.404 + /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
88.405 + /// following code.
88.406 + /// \code
88.407 + /// return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
88.408 + /// \endcode
88.409 + ///
88.410 + /// \pre \ref run() or \ref findMinMean() must be called before
88.411 + /// using this function.
88.412 + double cycleMean() const {
88.413 + return static_cast<double>(_best_length) / _best_size;
88.414 + }
88.415 +
88.416 + /// \brief Return the found cycle.
88.417 + ///
88.418 + /// This function returns a const reference to the path structure
88.419 + /// storing the found cycle.
88.420 + ///
88.421 + /// \pre \ref run() or \ref findCycle() must be called before using
88.422 + /// this function.
88.423 + const Path& cycle() const {
88.424 + return *_cycle_path;
88.425 + }
88.426 +
88.427 + ///@}
88.428 +
88.429 + private:
88.430 +
88.431 + // Initialize
88.432 + void init() {
88.433 + if (!_cycle_path) {
88.434 + _local_path = true;
88.435 + _cycle_path = new Path;
88.436 + }
88.437 + _queue.resize(countNodes(_gr));
88.438 + _best_found = false;
88.439 + _best_length = 0;
88.440 + _best_size = 1;
88.441 + _cycle_path->clear();
88.442 + }
88.443 +
88.444 + // Find strongly connected components and initialize _comp_nodes
88.445 + // and _in_arcs
88.446 + void findComponents() {
88.447 + _comp_num = stronglyConnectedComponents(_gr, _comp);
88.448 + _comp_nodes.resize(_comp_num);
88.449 + if (_comp_num == 1) {
88.450 + _comp_nodes[0].clear();
88.451 + for (NodeIt n(_gr); n != INVALID; ++n) {
88.452 + _comp_nodes[0].push_back(n);
88.453 + _in_arcs[n].clear();
88.454 + for (InArcIt a(_gr, n); a != INVALID; ++a) {
88.455 + _in_arcs[n].push_back(a);
88.456 + }
88.457 + }
88.458 + } else {
88.459 + for (int i = 0; i < _comp_num; ++i)
88.460 + _comp_nodes[i].clear();
88.461 + for (NodeIt n(_gr); n != INVALID; ++n) {
88.462 + int k = _comp[n];
88.463 + _comp_nodes[k].push_back(n);
88.464 + _in_arcs[n].clear();
88.465 + for (InArcIt a(_gr, n); a != INVALID; ++a) {
88.466 + if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
88.467 + }
88.468 + }
88.469 + }
88.470 + }
88.471 +
88.472 + // Build the policy graph in the given strongly connected component
88.473 + // (the out-degree of every node is 1)
88.474 + bool buildPolicyGraph(int comp) {
88.475 + _nodes = &(_comp_nodes[comp]);
88.476 + if (_nodes->size() < 1 ||
88.477 + (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
88.478 + return false;
88.479 + }
88.480 + for (int i = 0; i < int(_nodes->size()); ++i) {
88.481 + _dist[(*_nodes)[i]] = INF;
88.482 + }
88.483 + Node u, v;
88.484 + Arc e;
88.485 + for (int i = 0; i < int(_nodes->size()); ++i) {
88.486 + v = (*_nodes)[i];
88.487 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
88.488 + e = _in_arcs[v][j];
88.489 + u = _gr.source(e);
88.490 + if (_length[e] < _dist[u]) {
88.491 + _dist[u] = _length[e];
88.492 + _policy[u] = e;
88.493 + }
88.494 + }
88.495 + }
88.496 + return true;
88.497 + }
88.498 +
88.499 + // Find the minimum mean cycle in the policy graph
88.500 + void findPolicyCycle() {
88.501 + for (int i = 0; i < int(_nodes->size()); ++i) {
88.502 + _level[(*_nodes)[i]] = -1;
88.503 + }
88.504 + LargeValue clength;
88.505 + int csize;
88.506 + Node u, v;
88.507 + _curr_found = false;
88.508 + for (int i = 0; i < int(_nodes->size()); ++i) {
88.509 + u = (*_nodes)[i];
88.510 + if (_level[u] >= 0) continue;
88.511 + for (; _level[u] < 0; u = _gr.target(_policy[u])) {
88.512 + _level[u] = i;
88.513 + }
88.514 + if (_level[u] == i) {
88.515 + // A cycle is found
88.516 + clength = _length[_policy[u]];
88.517 + csize = 1;
88.518 + for (v = u; (v = _gr.target(_policy[v])) != u; ) {
88.519 + clength += _length[_policy[v]];
88.520 + ++csize;
88.521 + }
88.522 + if ( !_curr_found ||
88.523 + (clength * _curr_size < _curr_length * csize) ) {
88.524 + _curr_found = true;
88.525 + _curr_length = clength;
88.526 + _curr_size = csize;
88.527 + _curr_node = u;
88.528 + }
88.529 + }
88.530 + }
88.531 + }
88.532 +
88.533 + // Contract the policy graph and compute node distances
88.534 + bool computeNodeDistances() {
88.535 + // Find the component of the main cycle and compute node distances
88.536 + // using reverse BFS
88.537 + for (int i = 0; i < int(_nodes->size()); ++i) {
88.538 + _reached[(*_nodes)[i]] = false;
88.539 + }
88.540 + _qfront = _qback = 0;
88.541 + _queue[0] = _curr_node;
88.542 + _reached[_curr_node] = true;
88.543 + _dist[_curr_node] = 0;
88.544 + Node u, v;
88.545 + Arc e;
88.546 + while (_qfront <= _qback) {
88.547 + v = _queue[_qfront++];
88.548 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
88.549 + e = _in_arcs[v][j];
88.550 + u = _gr.source(e);
88.551 + if (_policy[u] == e && !_reached[u]) {
88.552 + _reached[u] = true;
88.553 + _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
88.554 + _queue[++_qback] = u;
88.555 + }
88.556 + }
88.557 + }
88.558 +
88.559 + // Connect all other nodes to this component and compute node
88.560 + // distances using reverse BFS
88.561 + _qfront = 0;
88.562 + while (_qback < int(_nodes->size())-1) {
88.563 + v = _queue[_qfront++];
88.564 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
88.565 + e = _in_arcs[v][j];
88.566 + u = _gr.source(e);
88.567 + if (!_reached[u]) {
88.568 + _reached[u] = true;
88.569 + _policy[u] = e;
88.570 + _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
88.571 + _queue[++_qback] = u;
88.572 + }
88.573 + }
88.574 + }
88.575 +
88.576 + // Improve node distances
88.577 + bool improved = false;
88.578 + for (int i = 0; i < int(_nodes->size()); ++i) {
88.579 + v = (*_nodes)[i];
88.580 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
88.581 + e = _in_arcs[v][j];
88.582 + u = _gr.source(e);
88.583 + LargeValue delta = _dist[v] + _length[e] * _curr_size - _curr_length;
88.584 + if (_tolerance.less(delta, _dist[u])) {
88.585 + _dist[u] = delta;
88.586 + _policy[u] = e;
88.587 + improved = true;
88.588 + }
88.589 + }
88.590 + }
88.591 + return improved;
88.592 + }
88.593 +
88.594 + }; //class Howard
88.595 +
88.596 + ///@}
88.597 +
88.598 +} //namespace lemon
88.599 +
88.600 +#endif //LEMON_HOWARD_H
89.1 --- a/lemon/hypercube_graph.h Mon Jan 12 23:11:39 2009 +0100
89.2 +++ b/lemon/hypercube_graph.h Thu Nov 05 15:48:01 2009 +0100
89.3 @@ -262,7 +262,7 @@
89.4 return arc._id >> _dim;
89.5 }
89.6
89.7 - int index(Node node) const {
89.8 + static int index(Node node) {
89.9 return node._id;
89.10 }
89.11
89.12 @@ -282,29 +282,46 @@
89.13 ///
89.14 /// \brief Hypercube graph class
89.15 ///
89.16 - /// This class implements a special graph type. The nodes of the graph
89.17 - /// are indiced with integers with at most \c dim binary digits.
89.18 + /// HypercubeGraph implements a special graph type. The nodes of the
89.19 + /// graph are indexed with integers having at most \c dim binary digits.
89.20 /// Two nodes are connected in the graph if and only if their indices
89.21 /// differ only on one position in the binary form.
89.22 + /// This class is completely static and it needs constant memory space.
89.23 + /// Thus you can neither add nor delete nodes or edges, however
89.24 + /// the structure can be resized using resize().
89.25 + ///
89.26 + /// This type fully conforms to the \ref concepts::Graph "Graph concept".
89.27 + /// Most of its member functions and nested classes are documented
89.28 + /// only in the concept class.
89.29 ///
89.30 /// \note The type of the indices is chosen to \c int for efficiency
89.31 /// reasons. Thus the maximum dimension of this implementation is 26
89.32 /// (assuming that the size of \c int is 32 bit).
89.33 - ///
89.34 - /// This graph type is fully conform to the \ref concepts::Graph
89.35 - /// "Graph" concept, and it also has an important extra feature
89.36 - /// that its maps are real \ref concepts::ReferenceMap
89.37 - /// "reference map"s.
89.38 class HypercubeGraph : public ExtendedHypercubeGraphBase {
89.39 + typedef ExtendedHypercubeGraphBase Parent;
89.40 +
89.41 public:
89.42
89.43 - typedef ExtendedHypercubeGraphBase Parent;
89.44 -
89.45 /// \brief Constructs a hypercube graph with \c dim dimensions.
89.46 ///
89.47 /// Constructs a hypercube graph with \c dim dimensions.
89.48 HypercubeGraph(int dim) { construct(dim); }
89.49
89.50 + /// \brief Resizes the graph
89.51 + ///
89.52 + /// This function resizes the graph. It fully destroys and
89.53 + /// rebuilds the structure, therefore the maps of the graph will be
89.54 + /// reallocated automatically and the previous values will be lost.
89.55 + void resize(int dim) {
89.56 + Parent::notifier(Arc()).clear();
89.57 + Parent::notifier(Edge()).clear();
89.58 + Parent::notifier(Node()).clear();
89.59 + construct(dim);
89.60 + Parent::notifier(Node()).build();
89.61 + Parent::notifier(Edge()).build();
89.62 + Parent::notifier(Arc()).build();
89.63 + }
89.64 +
89.65 /// \brief The number of dimensions.
89.66 ///
89.67 /// Gives back the number of dimensions.
89.68 @@ -322,7 +339,7 @@
89.69 /// \brief The dimension id of an edge.
89.70 ///
89.71 /// Gives back the dimension id of the given edge.
89.72 - /// It is in the [0..dim-1] range.
89.73 + /// It is in the range <tt>[0..dim-1]</tt>.
89.74 int dimension(Edge edge) const {
89.75 return Parent::dimension(edge);
89.76 }
89.77 @@ -330,7 +347,7 @@
89.78 /// \brief The dimension id of an arc.
89.79 ///
89.80 /// Gives back the dimension id of the given arc.
89.81 - /// It is in the [0..dim-1] range.
89.82 + /// It is in the range <tt>[0..dim-1]</tt>.
89.83 int dimension(Arc arc) const {
89.84 return Parent::dimension(arc);
89.85 }
89.86 @@ -339,7 +356,7 @@
89.87 ///
89.88 /// Gives back the index of the given node.
89.89 /// The lower bits of the integer describes the node.
89.90 - int index(Node node) const {
89.91 + static int index(Node node) {
89.92 return Parent::index(node);
89.93 }
89.94
90.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
90.2 +++ b/lemon/karp.h Thu Nov 05 15:48:01 2009 +0100
90.3 @@ -0,0 +1,582 @@
90.4 +/* -*- C++ -*-
90.5 + *
90.6 + * This file is a part of LEMON, a generic C++ optimization library
90.7 + *
90.8 + * Copyright (C) 2003-2008
90.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
90.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
90.11 + *
90.12 + * Permission to use, modify and distribute this software is granted
90.13 + * provided that this copyright notice appears in all copies. For
90.14 + * precise terms see the accompanying LICENSE file.
90.15 + *
90.16 + * This software is provided "AS IS" with no warranty of any kind,
90.17 + * express or implied, and with no claim as to its suitability for any
90.18 + * purpose.
90.19 + *
90.20 + */
90.21 +
90.22 +#ifndef LEMON_KARP_H
90.23 +#define LEMON_KARP_H
90.24 +
90.25 +/// \ingroup min_mean_cycle
90.26 +///
90.27 +/// \file
90.28 +/// \brief Karp's algorithm for finding a minimum mean cycle.
90.29 +
90.30 +#include <vector>
90.31 +#include <limits>
90.32 +#include <lemon/core.h>
90.33 +#include <lemon/path.h>
90.34 +#include <lemon/tolerance.h>
90.35 +#include <lemon/connectivity.h>
90.36 +
90.37 +namespace lemon {
90.38 +
90.39 + /// \brief Default traits class of Karp algorithm.
90.40 + ///
90.41 + /// Default traits class of Karp algorithm.
90.42 + /// \tparam GR The type of the digraph.
90.43 + /// \tparam LEN The type of the length map.
90.44 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
90.45 +#ifdef DOXYGEN
90.46 + template <typename GR, typename LEN>
90.47 +#else
90.48 + template <typename GR, typename LEN,
90.49 + bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
90.50 +#endif
90.51 + struct KarpDefaultTraits
90.52 + {
90.53 + /// The type of the digraph
90.54 + typedef GR Digraph;
90.55 + /// The type of the length map
90.56 + typedef LEN LengthMap;
90.57 + /// The type of the arc lengths
90.58 + typedef typename LengthMap::Value Value;
90.59 +
90.60 + /// \brief The large value type used for internal computations
90.61 + ///
90.62 + /// The large value type used for internal computations.
90.63 + /// It is \c long \c long if the \c Value type is integer,
90.64 + /// otherwise it is \c double.
90.65 + /// \c Value must be convertible to \c LargeValue.
90.66 + typedef double LargeValue;
90.67 +
90.68 + /// The tolerance type used for internal computations
90.69 + typedef lemon::Tolerance<LargeValue> Tolerance;
90.70 +
90.71 + /// \brief The path type of the found cycles
90.72 + ///
90.73 + /// The path type of the found cycles.
90.74 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
90.75 + /// and it must have an \c addFront() function.
90.76 + typedef lemon::Path<Digraph> Path;
90.77 + };
90.78 +
90.79 + // Default traits class for integer value types
90.80 + template <typename GR, typename LEN>
90.81 + struct KarpDefaultTraits<GR, LEN, true>
90.82 + {
90.83 + typedef GR Digraph;
90.84 + typedef LEN LengthMap;
90.85 + typedef typename LengthMap::Value Value;
90.86 +#ifdef LEMON_HAVE_LONG_LONG
90.87 + typedef long long LargeValue;
90.88 +#else
90.89 + typedef long LargeValue;
90.90 +#endif
90.91 + typedef lemon::Tolerance<LargeValue> Tolerance;
90.92 + typedef lemon::Path<Digraph> Path;
90.93 + };
90.94 +
90.95 +
90.96 + /// \addtogroup min_mean_cycle
90.97 + /// @{
90.98 +
90.99 + /// \brief Implementation of Karp's algorithm for finding a minimum
90.100 + /// mean cycle.
90.101 + ///
90.102 + /// This class implements Karp's algorithm for finding a directed
90.103 + /// cycle of minimum mean length (cost) in a digraph
90.104 + /// \ref amo93networkflows, \ref dasdan98minmeancycle.
90.105 + /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
90.106 + ///
90.107 + /// \tparam GR The type of the digraph the algorithm runs on.
90.108 + /// \tparam LEN The type of the length map. The default
90.109 + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
90.110 +#ifdef DOXYGEN
90.111 + template <typename GR, typename LEN, typename TR>
90.112 +#else
90.113 + template < typename GR,
90.114 + typename LEN = typename GR::template ArcMap<int>,
90.115 + typename TR = KarpDefaultTraits<GR, LEN> >
90.116 +#endif
90.117 + class Karp
90.118 + {
90.119 + public:
90.120 +
90.121 + /// The type of the digraph
90.122 + typedef typename TR::Digraph Digraph;
90.123 + /// The type of the length map
90.124 + typedef typename TR::LengthMap LengthMap;
90.125 + /// The type of the arc lengths
90.126 + typedef typename TR::Value Value;
90.127 +
90.128 + /// \brief The large value type
90.129 + ///
90.130 + /// The large value type used for internal computations.
90.131 + /// Using the \ref KarpDefaultTraits "default traits class",
90.132 + /// it is \c long \c long if the \c Value type is integer,
90.133 + /// otherwise it is \c double.
90.134 + typedef typename TR::LargeValue LargeValue;
90.135 +
90.136 + /// The tolerance type
90.137 + typedef typename TR::Tolerance Tolerance;
90.138 +
90.139 + /// \brief The path type of the found cycles
90.140 + ///
90.141 + /// The path type of the found cycles.
90.142 + /// Using the \ref KarpDefaultTraits "default traits class",
90.143 + /// it is \ref lemon::Path "Path<Digraph>".
90.144 + typedef typename TR::Path Path;
90.145 +
90.146 + /// The \ref KarpDefaultTraits "traits class" of the algorithm
90.147 + typedef TR Traits;
90.148 +
90.149 + private:
90.150 +
90.151 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
90.152 +
90.153 + // Data sturcture for path data
90.154 + struct PathData
90.155 + {
90.156 + LargeValue dist;
90.157 + Arc pred;
90.158 + PathData(LargeValue d, Arc p = INVALID) :
90.159 + dist(d), pred(p) {}
90.160 + };
90.161 +
90.162 + typedef typename Digraph::template NodeMap<std::vector<PathData> >
90.163 + PathDataNodeMap;
90.164 +
90.165 + private:
90.166 +
90.167 + // The digraph the algorithm runs on
90.168 + const Digraph &_gr;
90.169 + // The length of the arcs
90.170 + const LengthMap &_length;
90.171 +
90.172 + // Data for storing the strongly connected components
90.173 + int _comp_num;
90.174 + typename Digraph::template NodeMap<int> _comp;
90.175 + std::vector<std::vector<Node> > _comp_nodes;
90.176 + std::vector<Node>* _nodes;
90.177 + typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
90.178 +
90.179 + // Data for the found cycle
90.180 + LargeValue _cycle_length;
90.181 + int _cycle_size;
90.182 + Node _cycle_node;
90.183 +
90.184 + Path *_cycle_path;
90.185 + bool _local_path;
90.186 +
90.187 + // Node map for storing path data
90.188 + PathDataNodeMap _data;
90.189 + // The processed nodes in the last round
90.190 + std::vector<Node> _process;
90.191 +
90.192 + Tolerance _tolerance;
90.193 +
90.194 + // Infinite constant
90.195 + const LargeValue INF;
90.196 +
90.197 + public:
90.198 +
90.199 + /// \name Named Template Parameters
90.200 + /// @{
90.201 +
90.202 + template <typename T>
90.203 + struct SetLargeValueTraits : public Traits {
90.204 + typedef T LargeValue;
90.205 + typedef lemon::Tolerance<T> Tolerance;
90.206 + };
90.207 +
90.208 + /// \brief \ref named-templ-param "Named parameter" for setting
90.209 + /// \c LargeValue type.
90.210 + ///
90.211 + /// \ref named-templ-param "Named parameter" for setting \c LargeValue
90.212 + /// type. It is used for internal computations in the algorithm.
90.213 + template <typename T>
90.214 + struct SetLargeValue
90.215 + : public Karp<GR, LEN, SetLargeValueTraits<T> > {
90.216 + typedef Karp<GR, LEN, SetLargeValueTraits<T> > Create;
90.217 + };
90.218 +
90.219 + template <typename T>
90.220 + struct SetPathTraits : public Traits {
90.221 + typedef T Path;
90.222 + };
90.223 +
90.224 + /// \brief \ref named-templ-param "Named parameter" for setting
90.225 + /// \c %Path type.
90.226 + ///
90.227 + /// \ref named-templ-param "Named parameter" for setting the \c %Path
90.228 + /// type of the found cycles.
90.229 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
90.230 + /// and it must have an \c addFront() function.
90.231 + template <typename T>
90.232 + struct SetPath
90.233 + : public Karp<GR, LEN, SetPathTraits<T> > {
90.234 + typedef Karp<GR, LEN, SetPathTraits<T> > Create;
90.235 + };
90.236 +
90.237 + /// @}
90.238 +
90.239 + public:
90.240 +
90.241 + /// \brief Constructor.
90.242 + ///
90.243 + /// The constructor of the class.
90.244 + ///
90.245 + /// \param digraph The digraph the algorithm runs on.
90.246 + /// \param length The lengths (costs) of the arcs.
90.247 + Karp( const Digraph &digraph,
90.248 + const LengthMap &length ) :
90.249 + _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
90.250 + _cycle_length(0), _cycle_size(1), _cycle_node(INVALID),
90.251 + _cycle_path(NULL), _local_path(false), _data(digraph),
90.252 + INF(std::numeric_limits<LargeValue>::has_infinity ?
90.253 + std::numeric_limits<LargeValue>::infinity() :
90.254 + std::numeric_limits<LargeValue>::max())
90.255 + {}
90.256 +
90.257 + /// Destructor.
90.258 + ~Karp() {
90.259 + if (_local_path) delete _cycle_path;
90.260 + }
90.261 +
90.262 + /// \brief Set the path structure for storing the found cycle.
90.263 + ///
90.264 + /// This function sets an external path structure for storing the
90.265 + /// found cycle.
90.266 + ///
90.267 + /// If you don't call this function before calling \ref run() or
90.268 + /// \ref findMinMean(), it will allocate a local \ref Path "path"
90.269 + /// structure. The destuctor deallocates this automatically
90.270 + /// allocated object, of course.
90.271 + ///
90.272 + /// \note The algorithm calls only the \ref lemon::Path::addFront()
90.273 + /// "addFront()" function of the given path structure.
90.274 + ///
90.275 + /// \return <tt>(*this)</tt>
90.276 + Karp& cycle(Path &path) {
90.277 + if (_local_path) {
90.278 + delete _cycle_path;
90.279 + _local_path = false;
90.280 + }
90.281 + _cycle_path = &path;
90.282 + return *this;
90.283 + }
90.284 +
90.285 + /// \brief Set the tolerance used by the algorithm.
90.286 + ///
90.287 + /// This function sets the tolerance object used by the algorithm.
90.288 + ///
90.289 + /// \return <tt>(*this)</tt>
90.290 + Karp& tolerance(const Tolerance& tolerance) {
90.291 + _tolerance = tolerance;
90.292 + return *this;
90.293 + }
90.294 +
90.295 + /// \brief Return a const reference to the tolerance.
90.296 + ///
90.297 + /// This function returns a const reference to the tolerance object
90.298 + /// used by the algorithm.
90.299 + const Tolerance& tolerance() const {
90.300 + return _tolerance;
90.301 + }
90.302 +
90.303 + /// \name Execution control
90.304 + /// The simplest way to execute the algorithm is to call the \ref run()
90.305 + /// function.\n
90.306 + /// If you only need the minimum mean length, you may call
90.307 + /// \ref findMinMean().
90.308 +
90.309 + /// @{
90.310 +
90.311 + /// \brief Run the algorithm.
90.312 + ///
90.313 + /// This function runs the algorithm.
90.314 + /// It can be called more than once (e.g. if the underlying digraph
90.315 + /// and/or the arc lengths have been modified).
90.316 + ///
90.317 + /// \return \c true if a directed cycle exists in the digraph.
90.318 + ///
90.319 + /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
90.320 + /// \code
90.321 + /// return mmc.findMinMean() && mmc.findCycle();
90.322 + /// \endcode
90.323 + bool run() {
90.324 + return findMinMean() && findCycle();
90.325 + }
90.326 +
90.327 + /// \brief Find the minimum cycle mean.
90.328 + ///
90.329 + /// This function finds the minimum mean length of the directed
90.330 + /// cycles in the digraph.
90.331 + ///
90.332 + /// \return \c true if a directed cycle exists in the digraph.
90.333 + bool findMinMean() {
90.334 + // Initialization and find strongly connected components
90.335 + init();
90.336 + findComponents();
90.337 +
90.338 + // Find the minimum cycle mean in the components
90.339 + for (int comp = 0; comp < _comp_num; ++comp) {
90.340 + if (!initComponent(comp)) continue;
90.341 + processRounds();
90.342 + updateMinMean();
90.343 + }
90.344 + return (_cycle_node != INVALID);
90.345 + }
90.346 +
90.347 + /// \brief Find a minimum mean directed cycle.
90.348 + ///
90.349 + /// This function finds a directed cycle of minimum mean length
90.350 + /// in the digraph using the data computed by findMinMean().
90.351 + ///
90.352 + /// \return \c true if a directed cycle exists in the digraph.
90.353 + ///
90.354 + /// \pre \ref findMinMean() must be called before using this function.
90.355 + bool findCycle() {
90.356 + if (_cycle_node == INVALID) return false;
90.357 + IntNodeMap reached(_gr, -1);
90.358 + int r = _data[_cycle_node].size();
90.359 + Node u = _cycle_node;
90.360 + while (reached[u] < 0) {
90.361 + reached[u] = --r;
90.362 + u = _gr.source(_data[u][r].pred);
90.363 + }
90.364 + r = reached[u];
90.365 + Arc e = _data[u][r].pred;
90.366 + _cycle_path->addFront(e);
90.367 + _cycle_length = _length[e];
90.368 + _cycle_size = 1;
90.369 + Node v;
90.370 + while ((v = _gr.source(e)) != u) {
90.371 + e = _data[v][--r].pred;
90.372 + _cycle_path->addFront(e);
90.373 + _cycle_length += _length[e];
90.374 + ++_cycle_size;
90.375 + }
90.376 + return true;
90.377 + }
90.378 +
90.379 + /// @}
90.380 +
90.381 + /// \name Query Functions
90.382 + /// The results of the algorithm can be obtained using these
90.383 + /// functions.\n
90.384 + /// The algorithm should be executed before using them.
90.385 +
90.386 + /// @{
90.387 +
90.388 + /// \brief Return the total length of the found cycle.
90.389 + ///
90.390 + /// This function returns the total length of the found cycle.
90.391 + ///
90.392 + /// \pre \ref run() or \ref findMinMean() must be called before
90.393 + /// using this function.
90.394 + LargeValue cycleLength() const {
90.395 + return _cycle_length;
90.396 + }
90.397 +
90.398 + /// \brief Return the number of arcs on the found cycle.
90.399 + ///
90.400 + /// This function returns the number of arcs on the found cycle.
90.401 + ///
90.402 + /// \pre \ref run() or \ref findMinMean() must be called before
90.403 + /// using this function.
90.404 + int cycleArcNum() const {
90.405 + return _cycle_size;
90.406 + }
90.407 +
90.408 + /// \brief Return the mean length of the found cycle.
90.409 + ///
90.410 + /// This function returns the mean length of the found cycle.
90.411 + ///
90.412 + /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
90.413 + /// following code.
90.414 + /// \code
90.415 + /// return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
90.416 + /// \endcode
90.417 + ///
90.418 + /// \pre \ref run() or \ref findMinMean() must be called before
90.419 + /// using this function.
90.420 + double cycleMean() const {
90.421 + return static_cast<double>(_cycle_length) / _cycle_size;
90.422 + }
90.423 +
90.424 + /// \brief Return the found cycle.
90.425 + ///
90.426 + /// This function returns a const reference to the path structure
90.427 + /// storing the found cycle.
90.428 + ///
90.429 + /// \pre \ref run() or \ref findCycle() must be called before using
90.430 + /// this function.
90.431 + const Path& cycle() const {
90.432 + return *_cycle_path;
90.433 + }
90.434 +
90.435 + ///@}
90.436 +
90.437 + private:
90.438 +
90.439 + // Initialization
90.440 + void init() {
90.441 + if (!_cycle_path) {
90.442 + _local_path = true;
90.443 + _cycle_path = new Path;
90.444 + }
90.445 + _cycle_path->clear();
90.446 + _cycle_length = 0;
90.447 + _cycle_size = 1;
90.448 + _cycle_node = INVALID;
90.449 + for (NodeIt u(_gr); u != INVALID; ++u)
90.450 + _data[u].clear();
90.451 + }
90.452 +
90.453 + // Find strongly connected components and initialize _comp_nodes
90.454 + // and _out_arcs
90.455 + void findComponents() {
90.456 + _comp_num = stronglyConnectedComponents(_gr, _comp);
90.457 + _comp_nodes.resize(_comp_num);
90.458 + if (_comp_num == 1) {
90.459 + _comp_nodes[0].clear();
90.460 + for (NodeIt n(_gr); n != INVALID; ++n) {
90.461 + _comp_nodes[0].push_back(n);
90.462 + _out_arcs[n].clear();
90.463 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
90.464 + _out_arcs[n].push_back(a);
90.465 + }
90.466 + }
90.467 + } else {
90.468 + for (int i = 0; i < _comp_num; ++i)
90.469 + _comp_nodes[i].clear();
90.470 + for (NodeIt n(_gr); n != INVALID; ++n) {
90.471 + int k = _comp[n];
90.472 + _comp_nodes[k].push_back(n);
90.473 + _out_arcs[n].clear();
90.474 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
90.475 + if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
90.476 + }
90.477 + }
90.478 + }
90.479 + }
90.480 +
90.481 + // Initialize path data for the current component
90.482 + bool initComponent(int comp) {
90.483 + _nodes = &(_comp_nodes[comp]);
90.484 + int n = _nodes->size();
90.485 + if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
90.486 + return false;
90.487 + }
90.488 + for (int i = 0; i < n; ++i) {
90.489 + _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
90.490 + }
90.491 + return true;
90.492 + }
90.493 +
90.494 + // Process all rounds of computing path data for the current component.
90.495 + // _data[v][k] is the length of a shortest directed walk from the root
90.496 + // node to node v containing exactly k arcs.
90.497 + void processRounds() {
90.498 + Node start = (*_nodes)[0];
90.499 + _data[start][0] = PathData(0);
90.500 + _process.clear();
90.501 + _process.push_back(start);
90.502 +
90.503 + int k, n = _nodes->size();
90.504 + for (k = 1; k <= n && int(_process.size()) < n; ++k) {
90.505 + processNextBuildRound(k);
90.506 + }
90.507 + for ( ; k <= n; ++k) {
90.508 + processNextFullRound(k);
90.509 + }
90.510 + }
90.511 +
90.512 + // Process one round and rebuild _process
90.513 + void processNextBuildRound(int k) {
90.514 + std::vector<Node> next;
90.515 + Node u, v;
90.516 + Arc e;
90.517 + LargeValue d;
90.518 + for (int i = 0; i < int(_process.size()); ++i) {
90.519 + u = _process[i];
90.520 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
90.521 + e = _out_arcs[u][j];
90.522 + v = _gr.target(e);
90.523 + d = _data[u][k-1].dist + _length[e];
90.524 + if (_tolerance.less(d, _data[v][k].dist)) {
90.525 + if (_data[v][k].dist == INF) next.push_back(v);
90.526 + _data[v][k] = PathData(d, e);
90.527 + }
90.528 + }
90.529 + }
90.530 + _process.swap(next);
90.531 + }
90.532 +
90.533 + // Process one round using _nodes instead of _process
90.534 + void processNextFullRound(int k) {
90.535 + Node u, v;
90.536 + Arc e;
90.537 + LargeValue d;
90.538 + for (int i = 0; i < int(_nodes->size()); ++i) {
90.539 + u = (*_nodes)[i];
90.540 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
90.541 + e = _out_arcs[u][j];
90.542 + v = _gr.target(e);
90.543 + d = _data[u][k-1].dist + _length[e];
90.544 + if (_tolerance.less(d, _data[v][k].dist)) {
90.545 + _data[v][k] = PathData(d, e);
90.546 + }
90.547 + }
90.548 + }
90.549 + }
90.550 +
90.551 + // Update the minimum cycle mean
90.552 + void updateMinMean() {
90.553 + int n = _nodes->size();
90.554 + for (int i = 0; i < n; ++i) {
90.555 + Node u = (*_nodes)[i];
90.556 + if (_data[u][n].dist == INF) continue;
90.557 + LargeValue length, max_length = 0;
90.558 + int size, max_size = 1;
90.559 + bool found_curr = false;
90.560 + for (int k = 0; k < n; ++k) {
90.561 + if (_data[u][k].dist == INF) continue;
90.562 + length = _data[u][n].dist - _data[u][k].dist;
90.563 + size = n - k;
90.564 + if (!found_curr || length * max_size > max_length * size) {
90.565 + found_curr = true;
90.566 + max_length = length;
90.567 + max_size = size;
90.568 + }
90.569 + }
90.570 + if ( found_curr && (_cycle_node == INVALID ||
90.571 + max_length * _cycle_size < _cycle_length * max_size) ) {
90.572 + _cycle_length = max_length;
90.573 + _cycle_size = max_size;
90.574 + _cycle_node = u;
90.575 + }
90.576 + }
90.577 + }
90.578 +
90.579 + }; //class Karp
90.580 +
90.581 + ///@}
90.582 +
90.583 +} //namespace lemon
90.584 +
90.585 +#endif //LEMON_KARP_H
91.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
91.2 +++ b/lemon/kary_heap.h Thu Nov 05 15:48:01 2009 +0100
91.3 @@ -0,0 +1,352 @@
91.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
91.5 + *
91.6 + * This file is a part of LEMON, a generic C++ optimization library.
91.7 + *
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 + * Permission to use, modify and distribute this software is granted
91.13 + * provided that this copyright notice appears in all copies. For
91.14 + * precise terms see the accompanying LICENSE file.
91.15 + *
91.16 + * This software is provided "AS IS" with no warranty of any kind,
91.17 + * express or implied, and with no claim as to its suitability for any
91.18 + * purpose.
91.19 + *
91.20 + */
91.21 +
91.22 +#ifndef LEMON_KARY_HEAP_H
91.23 +#define LEMON_KARY_HEAP_H
91.24 +
91.25 +///\ingroup heaps
91.26 +///\file
91.27 +///\brief Fourary heap implementation.
91.28 +
91.29 +#include <vector>
91.30 +#include <utility>
91.31 +#include <functional>
91.32 +
91.33 +namespace lemon {
91.34 +
91.35 + /// \ingroup heaps
91.36 + ///
91.37 + ///\brief K-ary heap data structure.
91.38 + ///
91.39 + /// This class implements the \e K-ary \e heap data structure.
91.40 + /// It fully conforms to the \ref concepts::Heap "heap concept".
91.41 + ///
91.42 + /// The \ref KaryHeap "K-ary heap" is a generalization of the
91.43 + /// \ref BinHeap "binary heap" structure, its nodes have at most
91.44 + /// \c K children, instead of two.
91.45 + /// \ref BinHeap and \ref FouraryHeap are specialized implementations
91.46 + /// of this structure for <tt>K=2</tt> and <tt>K=4</tt>, respectively.
91.47 + ///
91.48 + /// \tparam PR Type of the priorities of the items.
91.49 + /// \tparam IM A read-writable item map with \c int values, used
91.50 + /// internally to handle the cross references.
91.51 + /// \tparam K The degree of the heap, each node have at most \e K
91.52 + /// children. The default is 16. Powers of two are suggested to use
91.53 + /// so that the multiplications and divisions needed to traverse the
91.54 + /// nodes of the heap could be performed faster.
91.55 + /// \tparam CMP A functor class for comparing the priorities.
91.56 + /// The default is \c std::less<PR>.
91.57 + ///
91.58 + ///\sa BinHeap
91.59 + ///\sa FouraryHeap
91.60 +#ifdef DOXYGEN
91.61 + template <typename PR, typename IM, int K, typename CMP>
91.62 +#else
91.63 + template <typename PR, typename IM, int K = 16,
91.64 + typename CMP = std::less<PR> >
91.65 +#endif
91.66 + class KaryHeap {
91.67 + public:
91.68 + /// Type of the item-int map.
91.69 + typedef IM ItemIntMap;
91.70 + /// Type of the priorities.
91.71 + typedef PR Prio;
91.72 + /// Type of the items stored in the heap.
91.73 + typedef typename ItemIntMap::Key Item;
91.74 + /// Type of the item-priority pairs.
91.75 + typedef std::pair<Item,Prio> Pair;
91.76 + /// Functor type for comparing the priorities.
91.77 + typedef CMP Compare;
91.78 +
91.79 + /// \brief Type to represent the states of the items.
91.80 + ///
91.81 + /// Each item has a state associated to it. It can be "in heap",
91.82 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
91.83 + /// heap's point of view, but may be useful to the user.
91.84 + ///
91.85 + /// The item-int map must be initialized in such way that it assigns
91.86 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
91.87 + enum State {
91.88 + IN_HEAP = 0, ///< = 0.
91.89 + PRE_HEAP = -1, ///< = -1.
91.90 + POST_HEAP = -2 ///< = -2.
91.91 + };
91.92 +
91.93 + private:
91.94 + std::vector<Pair> _data;
91.95 + Compare _comp;
91.96 + ItemIntMap &_iim;
91.97 +
91.98 + public:
91.99 + /// \brief Constructor.
91.100 + ///
91.101 + /// Constructor.
91.102 + /// \param map A map that assigns \c int values to the items.
91.103 + /// It is used internally to handle the cross references.
91.104 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
91.105 + explicit KaryHeap(ItemIntMap &map) : _iim(map) {}
91.106 +
91.107 + /// \brief Constructor.
91.108 + ///
91.109 + /// Constructor.
91.110 + /// \param map A map that assigns \c int values to the items.
91.111 + /// It is used internally to handle the cross references.
91.112 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
91.113 + /// \param comp The function object used for comparing the priorities.
91.114 + KaryHeap(ItemIntMap &map, const Compare &comp)
91.115 + : _iim(map), _comp(comp) {}
91.116 +
91.117 + /// \brief The number of items stored in the heap.
91.118 + ///
91.119 + /// This function returns the number of items stored in the heap.
91.120 + int size() const { return _data.size(); }
91.121 +
91.122 + /// \brief Check if the heap is empty.
91.123 + ///
91.124 + /// This function returns \c true if the heap is empty.
91.125 + bool empty() const { return _data.empty(); }
91.126 +
91.127 + /// \brief Make the heap empty.
91.128 + ///
91.129 + /// This functon makes the heap empty.
91.130 + /// It does not change the cross reference map. If you want to reuse
91.131 + /// a heap that is not surely empty, you should first clear it and
91.132 + /// then you should set the cross reference map to \c PRE_HEAP
91.133 + /// for each item.
91.134 + void clear() { _data.clear(); }
91.135 +
91.136 + private:
91.137 + int parent(int i) { return (i-1)/K; }
91.138 + int firstChild(int i) { return K*i+1; }
91.139 +
91.140 + bool less(const Pair &p1, const Pair &p2) const {
91.141 + return _comp(p1.second, p2.second);
91.142 + }
91.143 +
91.144 + void bubbleUp(int hole, Pair p) {
91.145 + int par = parent(hole);
91.146 + while( hole>0 && less(p,_data[par]) ) {
91.147 + move(_data[par],hole);
91.148 + hole = par;
91.149 + par = parent(hole);
91.150 + }
91.151 + move(p, hole);
91.152 + }
91.153 +
91.154 + void bubbleDown(int hole, Pair p, int length) {
91.155 + if( length>1 ) {
91.156 + int child = firstChild(hole);
91.157 + while( child+K<=length ) {
91.158 + int min=child;
91.159 + for (int i=1; i<K; ++i) {
91.160 + if( less(_data[child+i], _data[min]) )
91.161 + min=child+i;
91.162 + }
91.163 + if( !less(_data[min], p) )
91.164 + goto ok;
91.165 + move(_data[min], hole);
91.166 + hole = min;
91.167 + child = firstChild(hole);
91.168 + }
91.169 + if ( child<length ) {
91.170 + int min = child;
91.171 + while (++child < length) {
91.172 + if( less(_data[child], _data[min]) )
91.173 + min=child;
91.174 + }
91.175 + if( less(_data[min], p) ) {
91.176 + move(_data[min], hole);
91.177 + hole = min;
91.178 + }
91.179 + }
91.180 + }
91.181 + ok:
91.182 + move(p, hole);
91.183 + }
91.184 +
91.185 + void move(const Pair &p, int i) {
91.186 + _data[i] = p;
91.187 + _iim.set(p.first, i);
91.188 + }
91.189 +
91.190 + public:
91.191 + /// \brief Insert a pair of item and priority into the heap.
91.192 + ///
91.193 + /// This function inserts \c p.first to the heap with priority
91.194 + /// \c p.second.
91.195 + /// \param p The pair to insert.
91.196 + /// \pre \c p.first must not be stored in the heap.
91.197 + void push(const Pair &p) {
91.198 + int n = _data.size();
91.199 + _data.resize(n+1);
91.200 + bubbleUp(n, p);
91.201 + }
91.202 +
91.203 + /// \brief Insert an item into the heap with the given priority.
91.204 + ///
91.205 + /// This function inserts the given item into the heap with the
91.206 + /// given priority.
91.207 + /// \param i The item to insert.
91.208 + /// \param p The priority of the item.
91.209 + /// \pre \e i must not be stored in the heap.
91.210 + void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
91.211 +
91.212 + /// \brief Return the item having minimum priority.
91.213 + ///
91.214 + /// This function returns the item having minimum priority.
91.215 + /// \pre The heap must be non-empty.
91.216 + Item top() const { return _data[0].first; }
91.217 +
91.218 + /// \brief The minimum priority.
91.219 + ///
91.220 + /// This function returns the minimum priority.
91.221 + /// \pre The heap must be non-empty.
91.222 + Prio prio() const { return _data[0].second; }
91.223 +
91.224 + /// \brief Remove the item having minimum priority.
91.225 + ///
91.226 + /// This function removes the item having minimum priority.
91.227 + /// \pre The heap must be non-empty.
91.228 + void pop() {
91.229 + int n = _data.size()-1;
91.230 + _iim.set(_data[0].first, POST_HEAP);
91.231 + if (n>0) bubbleDown(0, _data[n], n);
91.232 + _data.pop_back();
91.233 + }
91.234 +
91.235 + /// \brief Remove the given item from the heap.
91.236 + ///
91.237 + /// This function removes the given item from the heap if it is
91.238 + /// already stored.
91.239 + /// \param i The item to delete.
91.240 + /// \pre \e i must be in the heap.
91.241 + void erase(const Item &i) {
91.242 + int h = _iim[i];
91.243 + int n = _data.size()-1;
91.244 + _iim.set(_data[h].first, POST_HEAP);
91.245 + if( h<n ) {
91.246 + if( less(_data[parent(h)], _data[n]) )
91.247 + bubbleDown(h, _data[n], n);
91.248 + else
91.249 + bubbleUp(h, _data[n]);
91.250 + }
91.251 + _data.pop_back();
91.252 + }
91.253 +
91.254 + /// \brief The priority of the given item.
91.255 + ///
91.256 + /// This function returns the priority of the given item.
91.257 + /// \param i The item.
91.258 + /// \pre \e i must be in the heap.
91.259 + Prio operator[](const Item &i) const {
91.260 + int idx = _iim[i];
91.261 + return _data[idx].second;
91.262 + }
91.263 +
91.264 + /// \brief Set the priority of an item or insert it, if it is
91.265 + /// not stored in the heap.
91.266 + ///
91.267 + /// This method sets the priority of the given item if it is
91.268 + /// already stored in the heap. Otherwise it inserts the given
91.269 + /// item into the heap with the given priority.
91.270 + /// \param i The item.
91.271 + /// \param p The priority.
91.272 + void set(const Item &i, const Prio &p) {
91.273 + int idx = _iim[i];
91.274 + if( idx<0 )
91.275 + push(i,p);
91.276 + else if( _comp(p, _data[idx].second) )
91.277 + bubbleUp(idx, Pair(i,p));
91.278 + else
91.279 + bubbleDown(idx, Pair(i,p), _data.size());
91.280 + }
91.281 +
91.282 + /// \brief Decrease the priority of an item to the given value.
91.283 + ///
91.284 + /// This function decreases the priority of an item to the given value.
91.285 + /// \param i The item.
91.286 + /// \param p The priority.
91.287 + /// \pre \e i must be stored in the heap with priority at least \e p.
91.288 + void decrease(const Item &i, const Prio &p) {
91.289 + int idx = _iim[i];
91.290 + bubbleUp(idx, Pair(i,p));
91.291 + }
91.292 +
91.293 + /// \brief Increase the priority of an item to the given value.
91.294 + ///
91.295 + /// This function increases the priority of an item to the given value.
91.296 + /// \param i The item.
91.297 + /// \param p The priority.
91.298 + /// \pre \e i must be stored in the heap with priority at most \e p.
91.299 + void increase(const Item &i, const Prio &p) {
91.300 + int idx = _iim[i];
91.301 + bubbleDown(idx, Pair(i,p), _data.size());
91.302 + }
91.303 +
91.304 + /// \brief Return the state of an item.
91.305 + ///
91.306 + /// This method returns \c PRE_HEAP if the given item has never
91.307 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
91.308 + /// and \c POST_HEAP otherwise.
91.309 + /// In the latter case it is possible that the item will get back
91.310 + /// to the heap again.
91.311 + /// \param i The item.
91.312 + State state(const Item &i) const {
91.313 + int s = _iim[i];
91.314 + if (s>=0) s=0;
91.315 + return State(s);
91.316 + }
91.317 +
91.318 + /// \brief Set the state of an item in the heap.
91.319 + ///
91.320 + /// This function sets the state of the given item in the heap.
91.321 + /// It can be used to manually clear the heap when it is important
91.322 + /// to achive better time complexity.
91.323 + /// \param i The item.
91.324 + /// \param st The state. It should not be \c IN_HEAP.
91.325 + void state(const Item& i, State st) {
91.326 + switch (st) {
91.327 + case POST_HEAP:
91.328 + case PRE_HEAP:
91.329 + if (state(i) == IN_HEAP) erase(i);
91.330 + _iim[i] = st;
91.331 + break;
91.332 + case IN_HEAP:
91.333 + break;
91.334 + }
91.335 + }
91.336 +
91.337 + /// \brief Replace an item in the heap.
91.338 + ///
91.339 + /// This function replaces item \c i with item \c j.
91.340 + /// Item \c i must be in the heap, while \c j must be out of the heap.
91.341 + /// After calling this method, item \c i will be out of the
91.342 + /// heap and \c j will be in the heap with the same prioriority
91.343 + /// as item \c i had before.
91.344 + void replace(const Item& i, const Item& j) {
91.345 + int idx=_iim[i];
91.346 + _iim.set(i, _iim[j]);
91.347 + _iim.set(j, idx);
91.348 + _data[idx].first=j;
91.349 + }
91.350 +
91.351 + }; // class KaryHeap
91.352 +
91.353 +} // namespace lemon
91.354 +
91.355 +#endif // LEMON_KARY_HEAP_H
92.1 --- a/lemon/kruskal.h Mon Jan 12 23:11:39 2009 +0100
92.2 +++ b/lemon/kruskal.h Thu Nov 05 15:48:01 2009 +0100
92.3 @@ -248,11 +248,11 @@
92.4
92.5 /// \ingroup spantree
92.6 ///
92.7 - /// \brief Kruskal algorithm to find a minimum cost spanning tree of
92.8 + /// \brief Kruskal's algorithm for finding a minimum cost spanning tree of
92.9 /// a graph.
92.10 ///
92.11 /// This function runs Kruskal's algorithm to find a minimum cost
92.12 - /// spanning tree.
92.13 + /// spanning tree of a graph.
92.14 /// Due to some C++ hacking, it accepts various input and output types.
92.15 ///
92.16 /// \param g The graph the algorithm runs on.
92.17 @@ -264,17 +264,17 @@
92.18 /// \param in This object is used to describe the arc/edge costs.
92.19 /// It can be one of the following choices.
92.20 /// - An STL compatible 'Forward Container' with
92.21 - /// <tt>std::pair<GR::Arc,X></tt> or
92.22 - /// <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, where
92.23 - /// \c X is the type of the costs. The pairs indicates the arcs/edges
92.24 + /// <tt>std::pair<GR::Arc,C></tt> or
92.25 + /// <tt>std::pair<GR::Edge,C></tt> as its <tt>value_type</tt>, where
92.26 + /// \c C is the type of the costs. The pairs indicates the arcs/edges
92.27 /// along with the assigned cost. <em>They must be in a
92.28 /// cost-ascending order.</em>
92.29 /// - Any readable arc/edge map. The values of the map indicate the
92.30 /// arc/edge costs.
92.31 ///
92.32 /// \retval out Here we also have a choice.
92.33 - /// - It can be a writable \c bool arc/edge map. After running the
92.34 - /// algorithm it will contain the found minimum cost spanning
92.35 + /// - It can be a writable arc/edge map with \c bool value type. After
92.36 + /// running the algorithm it will contain the found minimum cost spanning
92.37 /// tree: the value of an arc/edge will be set to \c true if it belongs
92.38 /// to the tree, otherwise it will be set to \c false. The value of
92.39 /// each arc/edge will be set exactly once.
92.40 @@ -301,8 +301,8 @@
92.41 /// forest is calculated instead of a spanning tree.
92.42
92.43 #ifdef DOXYGEN
92.44 - template <class Graph, class In, class Out>
92.45 - Value kruskal(GR const& g, const In& in, Out& out)
92.46 + template <typename Graph, typename In, typename Out>
92.47 + Value kruskal(const Graph& g, const In& in, Out& out)
92.48 #else
92.49 template <class Graph, class In, class Out>
92.50 inline typename _kruskal_bits::KruskalValueSelector<In>::Value
92.51 @@ -314,8 +314,6 @@
92.52 }
92.53
92.54
92.55 -
92.56 -
92.57 template <class Graph, class In, class Out>
92.58 inline typename _kruskal_bits::KruskalValueSelector<In>::Value
92.59 kruskal(const Graph& graph, const In& in, const Out& out)
93.1 --- a/lemon/lemon.pc.in Mon Jan 12 23:11:39 2009 +0100
93.2 +++ b/lemon/lemon.pc.in Thu Nov 05 15:48:01 2009 +0100
93.3 @@ -4,7 +4,7 @@
93.4 includedir=@includedir@
93.5
93.6 Name: @PACKAGE_NAME@
93.7 -Description: Library of Efficient Models and Optimization in Networks
93.8 +Description: Library for Efficient Modeling and Optimization in Networks
93.9 Version: @PACKAGE_VERSION@
93.10 -Libs: -L${libdir} -lemon
93.11 +Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@
93.12 Cflags: -I${includedir}
94.1 --- a/lemon/lgf_reader.h Mon Jan 12 23:11:39 2009 +0100
94.2 +++ b/lemon/lgf_reader.h Thu Nov 05 15:48:01 2009 +0100
94.3 @@ -101,23 +101,23 @@
94.4 }
94.5 };
94.6
94.7 - template <typename _Graph, bool _dir, typename _Map,
94.8 + template <typename _GR, bool _dir, typename _Map,
94.9 typename _Converter = DefaultConverter<typename _Map::Value> >
94.10 - class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
94.11 + class GraphArcMapStorage : public MapStorageBase<typename _GR::Edge> {
94.12 public:
94.13 typedef _Map Map;
94.14 typedef _Converter Converter;
94.15 - typedef _Graph Graph;
94.16 - typedef typename Graph::Edge Item;
94.17 + typedef _GR GR;
94.18 + typedef typename GR::Edge Item;
94.19 static const bool dir = _dir;
94.20
94.21 private:
94.22 - const Graph& _graph;
94.23 + const GR& _graph;
94.24 Map& _map;
94.25 Converter _converter;
94.26
94.27 public:
94.28 - GraphArcMapStorage(const Graph& graph, Map& map,
94.29 + GraphArcMapStorage(const GR& graph, Map& map,
94.30 const Converter& converter = Converter())
94.31 : _graph(graph), _map(map), _converter(converter) {}
94.32 virtual ~GraphArcMapStorage() {}
94.33 @@ -173,21 +173,21 @@
94.34 }
94.35 };
94.36
94.37 - template <typename Graph>
94.38 + template <typename GR>
94.39 struct GraphArcLookUpConverter {
94.40 - const Graph& _graph;
94.41 - const std::map<std::string, typename Graph::Edge>& _map;
94.42 -
94.43 - GraphArcLookUpConverter(const Graph& graph,
94.44 + const GR& _graph;
94.45 + const std::map<std::string, typename GR::Edge>& _map;
94.46 +
94.47 + GraphArcLookUpConverter(const GR& graph,
94.48 const std::map<std::string,
94.49 - typename Graph::Edge>& map)
94.50 + typename GR::Edge>& map)
94.51 : _graph(graph), _map(map) {}
94.52
94.53 - typename Graph::Arc operator()(const std::string& str) {
94.54 + typename GR::Arc operator()(const std::string& str) {
94.55 if (str.empty() || (str[0] != '+' && str[0] != '-')) {
94.56 throw FormatError("Item must start with '+' or '-'");
94.57 }
94.58 - typename std::map<std::string, typename Graph::Edge>
94.59 + typename std::map<std::string, typename GR::Edge>
94.60 ::const_iterator it = _map.find(str.substr(1));
94.61 if (it == _map.end()) {
94.62 throw FormatError("Item not found");
94.63 @@ -387,40 +387,15 @@
94.64
94.65 }
94.66
94.67 - template <typename Digraph>
94.68 + template <typename DGR>
94.69 class DigraphReader;
94.70
94.71 - /// \brief Return a \ref DigraphReader class
94.72 - ///
94.73 - /// This function just returns a \ref DigraphReader class.
94.74 - /// \relates DigraphReader
94.75 - template <typename Digraph>
94.76 - DigraphReader<Digraph> digraphReader(Digraph& digraph,
94.77 - std::istream& is = std::cin) {
94.78 - DigraphReader<Digraph> tmp(digraph, is);
94.79 - return tmp;
94.80 - }
94.81 -
94.82 - /// \brief Return a \ref DigraphReader class
94.83 - ///
94.84 - /// This function just returns a \ref DigraphReader class.
94.85 - /// \relates DigraphReader
94.86 - template <typename Digraph>
94.87 - DigraphReader<Digraph> digraphReader(Digraph& digraph,
94.88 - const std::string& fn) {
94.89 - DigraphReader<Digraph> tmp(digraph, fn);
94.90 - return tmp;
94.91 - }
94.92 -
94.93 - /// \brief Return a \ref DigraphReader class
94.94 - ///
94.95 - /// This function just returns a \ref DigraphReader class.
94.96 - /// \relates DigraphReader
94.97 - template <typename Digraph>
94.98 - DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
94.99 - DigraphReader<Digraph> tmp(digraph, fn);
94.100 - return tmp;
94.101 - }
94.102 + template <typename TDGR>
94.103 + DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is = std::cin);
94.104 + template <typename TDGR>
94.105 + DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn);
94.106 + template <typename TDGR>
94.107 + DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
94.108
94.109 /// \ingroup lemon_io
94.110 ///
94.111 @@ -443,7 +418,7 @@
94.112 /// rules.
94.113 ///
94.114 ///\code
94.115 - /// DigraphReader<Digraph>(digraph, std::cin).
94.116 + /// DigraphReader<DGR>(digraph, std::cin).
94.117 /// nodeMap("coordinates", coord_map).
94.118 /// arcMap("capacity", cap_map).
94.119 /// node("source", src).
94.120 @@ -472,21 +447,21 @@
94.121 /// It is impossible to read this in
94.122 /// a single pass, because the arcs are not constructed when the node
94.123 /// maps are read.
94.124 - template <typename _Digraph>
94.125 + template <typename DGR>
94.126 class DigraphReader {
94.127 public:
94.128
94.129 - typedef _Digraph Digraph;
94.130 - TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
94.131 + typedef DGR Digraph;
94.132
94.133 private:
94.134
94.135 + TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
94.136
94.137 std::istream* _is;
94.138 bool local_is;
94.139 std::string _filename;
94.140
94.141 - Digraph& _digraph;
94.142 + DGR& _digraph;
94.143
94.144 std::string _nodes_caption;
94.145 std::string _arcs_caption;
94.146 @@ -524,7 +499,7 @@
94.147 ///
94.148 /// Construct a directed graph reader, which reads from the given
94.149 /// input stream.
94.150 - DigraphReader(Digraph& digraph, std::istream& is = std::cin)
94.151 + DigraphReader(DGR& digraph, std::istream& is = std::cin)
94.152 : _is(&is), local_is(false), _digraph(digraph),
94.153 _use_nodes(false), _use_arcs(false),
94.154 _skip_nodes(false), _skip_arcs(false) {}
94.155 @@ -533,7 +508,7 @@
94.156 ///
94.157 /// Construct a directed graph reader, which reads from the given
94.158 /// file.
94.159 - DigraphReader(Digraph& digraph, const std::string& fn)
94.160 + DigraphReader(DGR& digraph, const std::string& fn)
94.161 : _is(new std::ifstream(fn.c_str())), local_is(true),
94.162 _filename(fn), _digraph(digraph),
94.163 _use_nodes(false), _use_arcs(false),
94.164 @@ -548,7 +523,7 @@
94.165 ///
94.166 /// Construct a directed graph reader, which reads from the given
94.167 /// file.
94.168 - DigraphReader(Digraph& digraph, const char* fn)
94.169 + DigraphReader(DGR& digraph, const char* fn)
94.170 : _is(new std::ifstream(fn)), local_is(true),
94.171 _filename(fn), _digraph(digraph),
94.172 _use_nodes(false), _use_arcs(false),
94.173 @@ -584,12 +559,13 @@
94.174
94.175 private:
94.176
94.177 - friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
94.178 - std::istream& is);
94.179 - friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
94.180 - const std::string& fn);
94.181 - friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
94.182 - const char *fn);
94.183 + template <typename TDGR>
94.184 + friend DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is);
94.185 + template <typename TDGR>
94.186 + friend DigraphReader<TDGR> digraphReader(TDGR& digraph,
94.187 + const std::string& fn);
94.188 + template <typename TDGR>
94.189 + friend DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
94.190
94.191 DigraphReader(DigraphReader& other)
94.192 : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
94.193 @@ -616,7 +592,7 @@
94.194
94.195 public:
94.196
94.197 - /// \name Reading rules
94.198 + /// \name Reading Rules
94.199 /// @{
94.200
94.201 /// \brief Node map reading rule
94.202 @@ -721,7 +697,7 @@
94.203
94.204 /// @}
94.205
94.206 - /// \name Select section by name
94.207 + /// \name Select Section by Name
94.208 /// @{
94.209
94.210 /// \brief Set \c \@nodes section to be read
94.211 @@ -750,7 +726,7 @@
94.212
94.213 /// @}
94.214
94.215 - /// \name Using previously constructed node or arc set
94.216 + /// \name Using Previously Constructed Node or Arc Set
94.217 /// @{
94.218
94.219 /// \brief Use previously constructed node set
94.220 @@ -1139,7 +1115,7 @@
94.221
94.222 public:
94.223
94.224 - /// \name Execution of the reader
94.225 + /// \name Execution of the Reader
94.226 /// @{
94.227
94.228 /// \brief Start the batch processing
94.229 @@ -1211,40 +1187,76 @@
94.230 /// @}
94.231
94.232 };
94.233 -
94.234 - template <typename Graph>
94.235 - class GraphReader;
94.236 -
94.237 - /// \brief Return a \ref GraphReader class
94.238 +
94.239 + /// \ingroup lemon_io
94.240 ///
94.241 - /// This function just returns a \ref GraphReader class.
94.242 - /// \relates GraphReader
94.243 - template <typename Graph>
94.244 - GraphReader<Graph> graphReader(Graph& graph, std::istream& is = std::cin) {
94.245 - GraphReader<Graph> tmp(graph, is);
94.246 + /// \brief Return a \ref DigraphReader class
94.247 + ///
94.248 + /// This function just returns a \ref DigraphReader class.
94.249 + ///
94.250 + /// With this function a digraph can be read from an
94.251 + /// \ref lgf-format "LGF" file or input stream with several maps and
94.252 + /// attributes. For example, there is network flow problem on a
94.253 + /// digraph, i.e. a digraph with a \e capacity map on the arcs and
94.254 + /// \e source and \e target nodes. This digraph can be read with the
94.255 + /// following code:
94.256 + ///
94.257 + ///\code
94.258 + ///ListDigraph digraph;
94.259 + ///ListDigraph::ArcMap<int> cm(digraph);
94.260 + ///ListDigraph::Node src, trg;
94.261 + ///digraphReader(digraph, std::cin).
94.262 + /// arcMap("capacity", cap).
94.263 + /// node("source", src).
94.264 + /// node("target", trg).
94.265 + /// run();
94.266 + ///\endcode
94.267 + ///
94.268 + /// For a complete documentation, please see the \ref DigraphReader
94.269 + /// class documentation.
94.270 + /// \warning Don't forget to put the \ref DigraphReader::run() "run()"
94.271 + /// to the end of the parameter list.
94.272 + /// \relates DigraphReader
94.273 + /// \sa digraphReader(TDGR& digraph, const std::string& fn)
94.274 + /// \sa digraphReader(TDGR& digraph, const char* fn)
94.275 + template <typename TDGR>
94.276 + DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is) {
94.277 + DigraphReader<TDGR> tmp(digraph, is);
94.278 return tmp;
94.279 }
94.280
94.281 - /// \brief Return a \ref GraphReader class
94.282 + /// \brief Return a \ref DigraphReader class
94.283 ///
94.284 - /// This function just returns a \ref GraphReader class.
94.285 - /// \relates GraphReader
94.286 - template <typename Graph>
94.287 - GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
94.288 - GraphReader<Graph> tmp(graph, fn);
94.289 + /// This function just returns a \ref DigraphReader class.
94.290 + /// \relates DigraphReader
94.291 + /// \sa digraphReader(TDGR& digraph, std::istream& is)
94.292 + template <typename TDGR>
94.293 + DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn) {
94.294 + DigraphReader<TDGR> tmp(digraph, fn);
94.295 return tmp;
94.296 }
94.297
94.298 - /// \brief Return a \ref GraphReader class
94.299 + /// \brief Return a \ref DigraphReader class
94.300 ///
94.301 - /// This function just returns a \ref GraphReader class.
94.302 - /// \relates GraphReader
94.303 - template <typename Graph>
94.304 - GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
94.305 - GraphReader<Graph> tmp(graph, fn);
94.306 + /// This function just returns a \ref DigraphReader class.
94.307 + /// \relates DigraphReader
94.308 + /// \sa digraphReader(TDGR& digraph, std::istream& is)
94.309 + template <typename TDGR>
94.310 + DigraphReader<TDGR> digraphReader(TDGR& digraph, const char* fn) {
94.311 + DigraphReader<TDGR> tmp(digraph, fn);
94.312 return tmp;
94.313 }
94.314
94.315 + template <typename GR>
94.316 + class GraphReader;
94.317 +
94.318 + template <typename TGR>
94.319 + GraphReader<TGR> graphReader(TGR& graph, std::istream& is = std::cin);
94.320 + template <typename TGR>
94.321 + GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
94.322 + template <typename TGR>
94.323 + GraphReader<TGR> graphReader(TGR& graph, const char *fn);
94.324 +
94.325 /// \ingroup lemon_io
94.326 ///
94.327 /// \brief \ref lgf-format "LGF" reader for undirected graphs
94.328 @@ -1260,20 +1272,21 @@
94.329 /// prefixed with \c '+' and \c '-', then these can be read into an
94.330 /// arc map. Similarly, an attribute can be read into an arc, if
94.331 /// it's value is an edge label prefixed with \c '+' or \c '-'.
94.332 - template <typename _Graph>
94.333 + template <typename GR>
94.334 class GraphReader {
94.335 public:
94.336
94.337 - typedef _Graph Graph;
94.338 - TEMPLATE_GRAPH_TYPEDEFS(Graph);
94.339 + typedef GR Graph;
94.340
94.341 private:
94.342
94.343 + TEMPLATE_GRAPH_TYPEDEFS(GR);
94.344 +
94.345 std::istream* _is;
94.346 bool local_is;
94.347 std::string _filename;
94.348
94.349 - Graph& _graph;
94.350 + GR& _graph;
94.351
94.352 std::string _nodes_caption;
94.353 std::string _edges_caption;
94.354 @@ -1311,7 +1324,7 @@
94.355 ///
94.356 /// Construct an undirected graph reader, which reads from the given
94.357 /// input stream.
94.358 - GraphReader(Graph& graph, std::istream& is = std::cin)
94.359 + GraphReader(GR& graph, std::istream& is = std::cin)
94.360 : _is(&is), local_is(false), _graph(graph),
94.361 _use_nodes(false), _use_edges(false),
94.362 _skip_nodes(false), _skip_edges(false) {}
94.363 @@ -1320,7 +1333,7 @@
94.364 ///
94.365 /// Construct an undirected graph reader, which reads from the given
94.366 /// file.
94.367 - GraphReader(Graph& graph, const std::string& fn)
94.368 + GraphReader(GR& graph, const std::string& fn)
94.369 : _is(new std::ifstream(fn.c_str())), local_is(true),
94.370 _filename(fn), _graph(graph),
94.371 _use_nodes(false), _use_edges(false),
94.372 @@ -1335,7 +1348,7 @@
94.373 ///
94.374 /// Construct an undirected graph reader, which reads from the given
94.375 /// file.
94.376 - GraphReader(Graph& graph, const char* fn)
94.377 + GraphReader(GR& graph, const char* fn)
94.378 : _is(new std::ifstream(fn)), local_is(true),
94.379 _filename(fn), _graph(graph),
94.380 _use_nodes(false), _use_edges(false),
94.381 @@ -1370,10 +1383,12 @@
94.382 }
94.383
94.384 private:
94.385 - friend GraphReader<Graph> graphReader<>(Graph& graph, std::istream& is);
94.386 - friend GraphReader<Graph> graphReader<>(Graph& graph,
94.387 - const std::string& fn);
94.388 - friend GraphReader<Graph> graphReader<>(Graph& graph, const char *fn);
94.389 + template <typename TGR>
94.390 + friend GraphReader<TGR> graphReader(TGR& graph, std::istream& is);
94.391 + template <typename TGR>
94.392 + friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
94.393 + template <typename TGR>
94.394 + friend GraphReader<TGR> graphReader(TGR& graph, const char *fn);
94.395
94.396 GraphReader(GraphReader& other)
94.397 : _is(other._is), local_is(other.local_is), _graph(other._graph),
94.398 @@ -1400,7 +1415,7 @@
94.399
94.400 public:
94.401
94.402 - /// \name Reading rules
94.403 + /// \name Reading Rules
94.404 /// @{
94.405
94.406 /// \brief Node map reading rule
94.407 @@ -1465,7 +1480,7 @@
94.408 new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
94.409 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
94.410 _reader_bits::MapStorageBase<Edge>* backward_storage =
94.411 - new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
94.412 + new _reader_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
94.413 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
94.414 return *this;
94.415 }
94.416 @@ -1479,11 +1494,11 @@
94.417 const Converter& converter = Converter()) {
94.418 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
94.419 _reader_bits::MapStorageBase<Edge>* forward_storage =
94.420 - new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
94.421 + new _reader_bits::GraphArcMapStorage<GR, true, Map, Converter>
94.422 (_graph, map, converter);
94.423 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
94.424 _reader_bits::MapStorageBase<Edge>* backward_storage =
94.425 - new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
94.426 + new _reader_bits::GraphArcMapStorage<GR, false, Map, Converter>
94.427 (_graph, map, converter);
94.428 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
94.429 return *this;
94.430 @@ -1541,7 +1556,7 @@
94.431 ///
94.432 /// Add an arc reading rule to reader.
94.433 GraphReader& arc(const std::string& caption, Arc& arc) {
94.434 - typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
94.435 + typedef _reader_bits::GraphArcLookUpConverter<GR> Converter;
94.436 Converter converter(_graph, _edge_index);
94.437 _reader_bits::ValueStorageBase* storage =
94.438 new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
94.439 @@ -1551,7 +1566,7 @@
94.440
94.441 /// @}
94.442
94.443 - /// \name Select section by name
94.444 + /// \name Select Section by Name
94.445 /// @{
94.446
94.447 /// \brief Set \c \@nodes section to be read
94.448 @@ -1580,7 +1595,7 @@
94.449
94.450 /// @}
94.451
94.452 - /// \name Using previously constructed node or edge set
94.453 + /// \name Using Previously Constructed Node or Edge Set
94.454 /// @{
94.455
94.456 /// \brief Use previously constructed node set
94.457 @@ -1970,7 +1985,7 @@
94.458
94.459 public:
94.460
94.461 - /// \name Execution of the reader
94.462 + /// \name Execution of the Reader
94.463 /// @{
94.464
94.465 /// \brief Start the batch processing
94.466 @@ -2044,6 +2059,61 @@
94.467
94.468 };
94.469
94.470 + /// \ingroup lemon_io
94.471 + ///
94.472 + /// \brief Return a \ref GraphReader class
94.473 + ///
94.474 + /// This function just returns a \ref GraphReader class.
94.475 + ///
94.476 + /// With this function a graph can be read from an
94.477 + /// \ref lgf-format "LGF" file or input stream with several maps and
94.478 + /// attributes. For example, there is weighted matching problem on a
94.479 + /// graph, i.e. a graph with a \e weight map on the edges. This
94.480 + /// graph can be read with the following code:
94.481 + ///
94.482 + ///\code
94.483 + ///ListGraph graph;
94.484 + ///ListGraph::EdgeMap<int> weight(graph);
94.485 + ///graphReader(graph, std::cin).
94.486 + /// edgeMap("weight", weight).
94.487 + /// run();
94.488 + ///\endcode
94.489 + ///
94.490 + /// For a complete documentation, please see the \ref GraphReader
94.491 + /// class documentation.
94.492 + /// \warning Don't forget to put the \ref GraphReader::run() "run()"
94.493 + /// to the end of the parameter list.
94.494 + /// \relates GraphReader
94.495 + /// \sa graphReader(TGR& graph, const std::string& fn)
94.496 + /// \sa graphReader(TGR& graph, const char* fn)
94.497 + template <typename TGR>
94.498 + GraphReader<TGR> graphReader(TGR& graph, std::istream& is) {
94.499 + GraphReader<TGR> tmp(graph, is);
94.500 + return tmp;
94.501 + }
94.502 +
94.503 + /// \brief Return a \ref GraphReader class
94.504 + ///
94.505 + /// This function just returns a \ref GraphReader class.
94.506 + /// \relates GraphReader
94.507 + /// \sa graphReader(TGR& graph, std::istream& is)
94.508 + template <typename TGR>
94.509 + GraphReader<TGR> graphReader(TGR& graph, const std::string& fn) {
94.510 + GraphReader<TGR> tmp(graph, fn);
94.511 + return tmp;
94.512 + }
94.513 +
94.514 + /// \brief Return a \ref GraphReader class
94.515 + ///
94.516 + /// This function just returns a \ref GraphReader class.
94.517 + /// \relates GraphReader
94.518 + /// \sa graphReader(TGR& graph, std::istream& is)
94.519 + template <typename TGR>
94.520 + GraphReader<TGR> graphReader(TGR& graph, const char* fn) {
94.521 + GraphReader<TGR> tmp(graph, fn);
94.522 + return tmp;
94.523 + }
94.524 +
94.525 class SectionReader;
94.526
94.527 SectionReader sectionReader(std::istream& is);
94.528 @@ -2139,7 +2209,7 @@
94.529
94.530 public:
94.531
94.532 - /// \name Section readers
94.533 + /// \name Section Readers
94.534 /// @{
94.535
94.536 /// \brief Add a section processor with line oriented reading
94.537 @@ -2238,7 +2308,7 @@
94.538 public:
94.539
94.540
94.541 - /// \name Execution of the reader
94.542 + /// \name Execution of the Reader
94.543 /// @{
94.544
94.545 /// \brief Start the batch processing
94.546 @@ -2297,12 +2367,30 @@
94.547
94.548 };
94.549
94.550 + /// \ingroup lemon_io
94.551 + ///
94.552 + /// \brief Return a \ref SectionReader class
94.553 + ///
94.554 + /// This function just returns a \ref SectionReader class.
94.555 + ///
94.556 + /// Please see SectionReader documentation about the custom section
94.557 + /// input.
94.558 + ///
94.559 + /// \relates SectionReader
94.560 + /// \sa sectionReader(const std::string& fn)
94.561 + /// \sa sectionReader(const char *fn)
94.562 + inline SectionReader sectionReader(std::istream& is) {
94.563 + SectionReader tmp(is);
94.564 + return tmp;
94.565 + }
94.566 +
94.567 /// \brief Return a \ref SectionReader class
94.568 ///
94.569 /// This function just returns a \ref SectionReader class.
94.570 /// \relates SectionReader
94.571 - inline SectionReader sectionReader(std::istream& is) {
94.572 - SectionReader tmp(is);
94.573 + /// \sa sectionReader(std::istream& is)
94.574 + inline SectionReader sectionReader(const std::string& fn) {
94.575 + SectionReader tmp(fn);
94.576 return tmp;
94.577 }
94.578
94.579 @@ -2310,15 +2398,7 @@
94.580 ///
94.581 /// This function just returns a \ref SectionReader class.
94.582 /// \relates SectionReader
94.583 - inline SectionReader sectionReader(const std::string& fn) {
94.584 - SectionReader tmp(fn);
94.585 - return tmp;
94.586 - }
94.587 -
94.588 - /// \brief Return a \ref SectionReader class
94.589 - ///
94.590 - /// This function just returns a \ref SectionReader class.
94.591 - /// \relates SectionReader
94.592 + /// \sa sectionReader(std::istream& is)
94.593 inline SectionReader sectionReader(const char* fn) {
94.594 SectionReader tmp(fn);
94.595 return tmp;
94.596 @@ -2420,7 +2500,7 @@
94.597 public:
94.598
94.599
94.600 - /// \name Node sections
94.601 + /// \name Node Sections
94.602 /// @{
94.603
94.604 /// \brief Gives back the number of node sections in the file.
94.605 @@ -2446,7 +2526,7 @@
94.606
94.607 /// @}
94.608
94.609 - /// \name Arc/Edge sections
94.610 + /// \name Arc/Edge Sections
94.611 /// @{
94.612
94.613 /// \brief Gives back the number of arc/edge sections in the file.
94.614 @@ -2504,7 +2584,7 @@
94.615
94.616 /// @}
94.617
94.618 - /// \name Attribute sections
94.619 + /// \name Attribute Sections
94.620 /// @{
94.621
94.622 /// \brief Gives back the number of attribute sections in the file.
94.623 @@ -2530,7 +2610,7 @@
94.624
94.625 /// @}
94.626
94.627 - /// \name Extra sections
94.628 + /// \name Extra Sections
94.629 /// @{
94.630
94.631 /// \brief Gives back the number of extra sections in the file.
94.632 @@ -2606,7 +2686,7 @@
94.633
94.634 public:
94.635
94.636 - /// \name Execution of the contents reader
94.637 + /// \name Execution of the Contents Reader
94.638 /// @{
94.639
94.640 /// \brief Starts the reading
95.1 --- a/lemon/lgf_writer.h Mon Jan 12 23:11:39 2009 +0100
95.2 +++ b/lemon/lgf_writer.h Thu Nov 05 15:48:01 2009 +0100
95.3 @@ -347,41 +347,18 @@
95.4
95.5 }
95.6
95.7 - template <typename Digraph>
95.8 + template <typename DGR>
95.9 class DigraphWriter;
95.10
95.11 - /// \brief Return a \ref DigraphWriter class
95.12 - ///
95.13 - /// This function just returns a \ref DigraphWriter class.
95.14 - /// \relates DigraphWriter
95.15 - template <typename Digraph>
95.16 - DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
95.17 - std::ostream& os = std::cout) {
95.18 - DigraphWriter<Digraph> tmp(digraph, os);
95.19 - return tmp;
95.20 - }
95.21 + template <typename TDGR>
95.22 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
95.23 + std::ostream& os = std::cout);
95.24 + template <typename TDGR>
95.25 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const std::string& fn);
95.26
95.27 - /// \brief Return a \ref DigraphWriter class
95.28 - ///
95.29 - /// This function just returns a \ref DigraphWriter class.
95.30 - /// \relates DigraphWriter
95.31 - template <typename Digraph>
95.32 - DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
95.33 - const std::string& fn) {
95.34 - DigraphWriter<Digraph> tmp(digraph, fn);
95.35 - return tmp;
95.36 - }
95.37 + template <typename TDGR>
95.38 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn);
95.39
95.40 - /// \brief Return a \ref DigraphWriter class
95.41 - ///
95.42 - /// This function just returns a \ref DigraphWriter class.
95.43 - /// \relates DigraphWriter
95.44 - template <typename Digraph>
95.45 - DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
95.46 - const char* fn) {
95.47 - DigraphWriter<Digraph> tmp(digraph, fn);
95.48 - return tmp;
95.49 - }
95.50
95.51 /// \ingroup lemon_io
95.52 ///
95.53 @@ -402,7 +379,7 @@
95.54 /// arc() functions are used to add attribute writing rules.
95.55 ///
95.56 ///\code
95.57 - /// DigraphWriter<Digraph>(digraph, std::cout).
95.58 + /// DigraphWriter<DGR>(digraph, std::cout).
95.59 /// nodeMap("coordinates", coord_map).
95.60 /// nodeMap("size", size).
95.61 /// nodeMap("title", title).
95.62 @@ -427,12 +404,12 @@
95.63 /// section to the stream. The output stream can be retrieved with
95.64 /// the \c ostream() function, hence the second pass can append its
95.65 /// output to the output of the first pass.
95.66 - template <typename _Digraph>
95.67 + template <typename DGR>
95.68 class DigraphWriter {
95.69 public:
95.70
95.71 - typedef _Digraph Digraph;
95.72 - TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
95.73 + typedef DGR Digraph;
95.74 + TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
95.75
95.76 private:
95.77
95.78 @@ -440,7 +417,7 @@
95.79 std::ostream* _os;
95.80 bool local_os;
95.81
95.82 - const Digraph& _digraph;
95.83 + const DGR& _digraph;
95.84
95.85 std::string _nodes_caption;
95.86 std::string _arcs_caption;
95.87 @@ -472,7 +449,7 @@
95.88 ///
95.89 /// Construct a directed graph writer, which writes to the given
95.90 /// output stream.
95.91 - DigraphWriter(const Digraph& digraph, std::ostream& os = std::cout)
95.92 + DigraphWriter(const DGR& digraph, std::ostream& os = std::cout)
95.93 : _os(&os), local_os(false), _digraph(digraph),
95.94 _skip_nodes(false), _skip_arcs(false) {}
95.95
95.96 @@ -480,7 +457,7 @@
95.97 ///
95.98 /// Construct a directed graph writer, which writes to the given
95.99 /// output file.
95.100 - DigraphWriter(const Digraph& digraph, const std::string& fn)
95.101 + DigraphWriter(const DGR& digraph, const std::string& fn)
95.102 : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
95.103 _skip_nodes(false), _skip_arcs(false) {
95.104 if (!(*_os)) {
95.105 @@ -493,7 +470,7 @@
95.106 ///
95.107 /// Construct a directed graph writer, which writes to the given
95.108 /// output file.
95.109 - DigraphWriter(const Digraph& digraph, const char* fn)
95.110 + DigraphWriter(const DGR& digraph, const char* fn)
95.111 : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
95.112 _skip_nodes(false), _skip_arcs(false) {
95.113 if (!(*_os)) {
95.114 @@ -526,12 +503,15 @@
95.115
95.116 private:
95.117
95.118 - friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
95.119 - std::ostream& os);
95.120 - friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
95.121 - const std::string& fn);
95.122 - friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
95.123 - const char *fn);
95.124 + template <typename TDGR>
95.125 + friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
95.126 + std::ostream& os);
95.127 + template <typename TDGR>
95.128 + friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
95.129 + const std::string& fn);
95.130 + template <typename TDGR>
95.131 + friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
95.132 + const char *fn);
95.133
95.134 DigraphWriter(DigraphWriter& other)
95.135 : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
95.136 @@ -556,7 +536,7 @@
95.137
95.138 public:
95.139
95.140 - /// \name Writing rules
95.141 + /// \name Writing Rules
95.142 /// @{
95.143
95.144 /// \brief Node map writing rule
95.145 @@ -659,7 +639,7 @@
95.146 return *this;
95.147 }
95.148
95.149 - /// \name Section captions
95.150 + /// \name Section Captions
95.151 /// @{
95.152
95.153 /// \brief Add an additional caption to the \c \@nodes section
95.154 @@ -686,7 +666,7 @@
95.155 return *this;
95.156 }
95.157
95.158 - /// \name Skipping section
95.159 + /// \name Skipping Section
95.160 /// @{
95.161
95.162 /// \brief Skip writing the node set
95.163 @@ -742,8 +722,8 @@
95.164 }
95.165
95.166 if (label == 0) {
95.167 - IdMap<Digraph, Node> id_map(_digraph);
95.168 - _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
95.169 + IdMap<DGR, Node> id_map(_digraph);
95.170 + _writer_bits::MapLess<IdMap<DGR, Node> > id_less(id_map);
95.171 std::sort(nodes.begin(), nodes.end(), id_less);
95.172 } else {
95.173 label->sort(nodes);
95.174 @@ -827,8 +807,8 @@
95.175 }
95.176
95.177 if (label == 0) {
95.178 - IdMap<Digraph, Arc> id_map(_digraph);
95.179 - _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
95.180 + IdMap<DGR, Arc> id_map(_digraph);
95.181 + _writer_bits::MapLess<IdMap<DGR, Arc> > id_less(id_map);
95.182 std::sort(arcs.begin(), arcs.end(), id_less);
95.183 } else {
95.184 label->sort(arcs);
95.185 @@ -903,7 +883,7 @@
95.186
95.187 public:
95.188
95.189 - /// \name Execution of the writer
95.190 + /// \name Execution of the Writer
95.191 /// @{
95.192
95.193 /// \brief Start the batch processing
95.194 @@ -933,40 +913,77 @@
95.195 /// @}
95.196 };
95.197
95.198 - template <typename Graph>
95.199 - class GraphWriter;
95.200 -
95.201 - /// \brief Return a \ref GraphWriter class
95.202 + /// \ingroup lemon_io
95.203 ///
95.204 - /// This function just returns a \ref GraphWriter class.
95.205 - /// \relates GraphWriter
95.206 - template <typename Graph>
95.207 - GraphWriter<Graph> graphWriter(const Graph& graph,
95.208 - std::ostream& os = std::cout) {
95.209 - GraphWriter<Graph> tmp(graph, os);
95.210 + /// \brief Return a \ref DigraphWriter class
95.211 + ///
95.212 + /// This function just returns a \ref DigraphWriter class.
95.213 + ///
95.214 + /// With this function a digraph can be write to a file or output
95.215 + /// stream in \ref lgf-format "LGF" format with several maps and
95.216 + /// attributes. For example, with the following code a network flow
95.217 + /// problem can be written to the standard output, i.e. a digraph
95.218 + /// with a \e capacity map on the arcs and \e source and \e target
95.219 + /// nodes:
95.220 + ///
95.221 + ///\code
95.222 + ///ListDigraph digraph;
95.223 + ///ListDigraph::ArcMap<int> cap(digraph);
95.224 + ///ListDigraph::Node src, trg;
95.225 + /// // Setting the capacity map and source and target nodes
95.226 + ///digraphWriter(digraph, std::cout).
95.227 + /// arcMap("capacity", cap).
95.228 + /// node("source", src).
95.229 + /// node("target", trg).
95.230 + /// run();
95.231 + ///\endcode
95.232 + ///
95.233 + /// For a complete documentation, please see the \ref DigraphWriter
95.234 + /// class documentation.
95.235 + /// \warning Don't forget to put the \ref DigraphWriter::run() "run()"
95.236 + /// to the end of the parameter list.
95.237 + /// \relates DigraphWriter
95.238 + /// \sa digraphWriter(const TDGR& digraph, const std::string& fn)
95.239 + /// \sa digraphWriter(const TDGR& digraph, const char* fn)
95.240 + template <typename TDGR>
95.241 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, std::ostream& os) {
95.242 + DigraphWriter<TDGR> tmp(digraph, os);
95.243 return tmp;
95.244 }
95.245
95.246 - /// \brief Return a \ref GraphWriter class
95.247 + /// \brief Return a \ref DigraphWriter class
95.248 ///
95.249 - /// This function just returns a \ref GraphWriter class.
95.250 - /// \relates GraphWriter
95.251 - template <typename Graph>
95.252 - GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
95.253 - GraphWriter<Graph> tmp(graph, fn);
95.254 + /// This function just returns a \ref DigraphWriter class.
95.255 + /// \relates DigraphWriter
95.256 + /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
95.257 + template <typename TDGR>
95.258 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
95.259 + const std::string& fn) {
95.260 + DigraphWriter<TDGR> tmp(digraph, fn);
95.261 return tmp;
95.262 }
95.263
95.264 - /// \brief Return a \ref GraphWriter class
95.265 + /// \brief Return a \ref DigraphWriter class
95.266 ///
95.267 - /// This function just returns a \ref GraphWriter class.
95.268 - /// \relates GraphWriter
95.269 - template <typename Graph>
95.270 - GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
95.271 - GraphWriter<Graph> tmp(graph, fn);
95.272 + /// This function just returns a \ref DigraphWriter class.
95.273 + /// \relates DigraphWriter
95.274 + /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
95.275 + template <typename TDGR>
95.276 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn) {
95.277 + DigraphWriter<TDGR> tmp(digraph, fn);
95.278 return tmp;
95.279 }
95.280
95.281 + template <typename GR>
95.282 + class GraphWriter;
95.283 +
95.284 + template <typename TGR>
95.285 + GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os = std::cout);
95.286 + template <typename TGR>
95.287 + GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn);
95.288 + template <typename TGR>
95.289 + GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn);
95.290 +
95.291 /// \ingroup lemon_io
95.292 ///
95.293 /// \brief \ref lgf-format "LGF" writer for directed graphs
95.294 @@ -982,12 +999,12 @@
95.295 /// '+' and \c '-'. The arcs are written into the \c \@attributes
95.296 /// section as a \c '+' or a \c '-' prefix (depends on the direction
95.297 /// of the arc) and the label of corresponding edge.
95.298 - template <typename _Graph>
95.299 + template <typename GR>
95.300 class GraphWriter {
95.301 public:
95.302
95.303 - typedef _Graph Graph;
95.304 - TEMPLATE_GRAPH_TYPEDEFS(Graph);
95.305 + typedef GR Graph;
95.306 + TEMPLATE_GRAPH_TYPEDEFS(GR);
95.307
95.308 private:
95.309
95.310 @@ -995,7 +1012,7 @@
95.311 std::ostream* _os;
95.312 bool local_os;
95.313
95.314 - const Graph& _graph;
95.315 + const GR& _graph;
95.316
95.317 std::string _nodes_caption;
95.318 std::string _edges_caption;
95.319 @@ -1027,7 +1044,7 @@
95.320 ///
95.321 /// Construct a directed graph writer, which writes to the given
95.322 /// output stream.
95.323 - GraphWriter(const Graph& graph, std::ostream& os = std::cout)
95.324 + GraphWriter(const GR& graph, std::ostream& os = std::cout)
95.325 : _os(&os), local_os(false), _graph(graph),
95.326 _skip_nodes(false), _skip_edges(false) {}
95.327
95.328 @@ -1035,7 +1052,7 @@
95.329 ///
95.330 /// Construct a directed graph writer, which writes to the given
95.331 /// output file.
95.332 - GraphWriter(const Graph& graph, const std::string& fn)
95.333 + GraphWriter(const GR& graph, const std::string& fn)
95.334 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
95.335 _skip_nodes(false), _skip_edges(false) {
95.336 if (!(*_os)) {
95.337 @@ -1048,7 +1065,7 @@
95.338 ///
95.339 /// Construct a directed graph writer, which writes to the given
95.340 /// output file.
95.341 - GraphWriter(const Graph& graph, const char* fn)
95.342 + GraphWriter(const GR& graph, const char* fn)
95.343 : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
95.344 _skip_nodes(false), _skip_edges(false) {
95.345 if (!(*_os)) {
95.346 @@ -1081,13 +1098,14 @@
95.347
95.348 private:
95.349
95.350 - friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
95.351 - std::ostream& os);
95.352 - friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
95.353 - const std::string& fn);
95.354 - friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
95.355 - const char *fn);
95.356 -
95.357 + template <typename TGR>
95.358 + friend GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os);
95.359 + template <typename TGR>
95.360 + friend GraphWriter<TGR> graphWriter(const TGR& graph,
95.361 + const std::string& fn);
95.362 + template <typename TGR>
95.363 + friend GraphWriter<TGR> graphWriter(const TGR& graph, const char *fn);
95.364 +
95.365 GraphWriter(GraphWriter& other)
95.366 : _os(other._os), local_os(other.local_os), _graph(other._graph),
95.367 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
95.368 @@ -1111,7 +1129,7 @@
95.369
95.370 public:
95.371
95.372 - /// \name Writing rules
95.373 + /// \name Writing Rules
95.374 /// @{
95.375
95.376 /// \brief Node map writing rule
95.377 @@ -1173,10 +1191,10 @@
95.378 GraphWriter& arcMap(const std::string& caption, const Map& map) {
95.379 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
95.380 _writer_bits::MapStorageBase<Edge>* forward_storage =
95.381 - new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
95.382 + new _writer_bits::GraphArcMapStorage<GR, true, Map>(_graph, map);
95.383 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
95.384 _writer_bits::MapStorageBase<Edge>* backward_storage =
95.385 - new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
95.386 + new _writer_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
95.387 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
95.388 return *this;
95.389 }
95.390 @@ -1190,11 +1208,11 @@
95.391 const Converter& converter = Converter()) {
95.392 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
95.393 _writer_bits::MapStorageBase<Edge>* forward_storage =
95.394 - new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
95.395 + new _writer_bits::GraphArcMapStorage<GR, true, Map, Converter>
95.396 (_graph, map, converter);
95.397 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
95.398 _writer_bits::MapStorageBase<Edge>* backward_storage =
95.399 - new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
95.400 + new _writer_bits::GraphArcMapStorage<GR, false, Map, Converter>
95.401 (_graph, map, converter);
95.402 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
95.403 return *this;
95.404 @@ -1252,7 +1270,7 @@
95.405 ///
95.406 /// Add an arc writing rule to writer.
95.407 GraphWriter& arc(const std::string& caption, const Arc& arc) {
95.408 - typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
95.409 + typedef _writer_bits::GraphArcLookUpConverter<GR> Converter;
95.410 Converter converter(_graph, _edge_index);
95.411 _writer_bits::ValueStorageBase* storage =
95.412 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
95.413 @@ -1260,7 +1278,7 @@
95.414 return *this;
95.415 }
95.416
95.417 - /// \name Section captions
95.418 + /// \name Section Captions
95.419 /// @{
95.420
95.421 /// \brief Add an additional caption to the \c \@nodes section
95.422 @@ -1287,7 +1305,7 @@
95.423 return *this;
95.424 }
95.425
95.426 - /// \name Skipping section
95.427 + /// \name Skipping Section
95.428 /// @{
95.429
95.430 /// \brief Skip writing the node set
95.431 @@ -1343,8 +1361,8 @@
95.432 }
95.433
95.434 if (label == 0) {
95.435 - IdMap<Graph, Node> id_map(_graph);
95.436 - _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
95.437 + IdMap<GR, Node> id_map(_graph);
95.438 + _writer_bits::MapLess<IdMap<GR, Node> > id_less(id_map);
95.439 std::sort(nodes.begin(), nodes.end(), id_less);
95.440 } else {
95.441 label->sort(nodes);
95.442 @@ -1428,8 +1446,8 @@
95.443 }
95.444
95.445 if (label == 0) {
95.446 - IdMap<Graph, Edge> id_map(_graph);
95.447 - _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
95.448 + IdMap<GR, Edge> id_map(_graph);
95.449 + _writer_bits::MapLess<IdMap<GR, Edge> > id_less(id_map);
95.450 std::sort(edges.begin(), edges.end(), id_less);
95.451 } else {
95.452 label->sort(edges);
95.453 @@ -1504,7 +1522,7 @@
95.454
95.455 public:
95.456
95.457 - /// \name Execution of the writer
95.458 + /// \name Execution of the Writer
95.459 /// @{
95.460
95.461 /// \brief Start the batch processing
95.462 @@ -1534,6 +1552,62 @@
95.463 /// @}
95.464 };
95.465
95.466 + /// \ingroup lemon_io
95.467 + ///
95.468 + /// \brief Return a \ref GraphWriter class
95.469 + ///
95.470 + /// This function just returns a \ref GraphWriter class.
95.471 + ///
95.472 + /// With this function a graph can be write to a file or output
95.473 + /// stream in \ref lgf-format "LGF" format with several maps and
95.474 + /// attributes. For example, with the following code a weighted
95.475 + /// matching problem can be written to the standard output, i.e. a
95.476 + /// graph with a \e weight map on the edges:
95.477 + ///
95.478 + ///\code
95.479 + ///ListGraph graph;
95.480 + ///ListGraph::EdgeMap<int> weight(graph);
95.481 + /// // Setting the weight map
95.482 + ///graphWriter(graph, std::cout).
95.483 + /// edgeMap("weight", weight).
95.484 + /// run();
95.485 + ///\endcode
95.486 + ///
95.487 + /// For a complete documentation, please see the \ref GraphWriter
95.488 + /// class documentation.
95.489 + /// \warning Don't forget to put the \ref GraphWriter::run() "run()"
95.490 + /// to the end of the parameter list.
95.491 + /// \relates GraphWriter
95.492 + /// \sa graphWriter(const TGR& graph, const std::string& fn)
95.493 + /// \sa graphWriter(const TGR& graph, const char* fn)
95.494 + template <typename TGR>
95.495 + GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os) {
95.496 + GraphWriter<TGR> tmp(graph, os);
95.497 + return tmp;
95.498 + }
95.499 +
95.500 + /// \brief Return a \ref GraphWriter class
95.501 + ///
95.502 + /// This function just returns a \ref GraphWriter class.
95.503 + /// \relates GraphWriter
95.504 + /// \sa graphWriter(const TGR& graph, std::ostream& os)
95.505 + template <typename TGR>
95.506 + GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn) {
95.507 + GraphWriter<TGR> tmp(graph, fn);
95.508 + return tmp;
95.509 + }
95.510 +
95.511 + /// \brief Return a \ref GraphWriter class
95.512 + ///
95.513 + /// This function just returns a \ref GraphWriter class.
95.514 + /// \relates GraphWriter
95.515 + /// \sa graphWriter(const TGR& graph, std::ostream& os)
95.516 + template <typename TGR>
95.517 + GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) {
95.518 + GraphWriter<TGR> tmp(graph, fn);
95.519 + return tmp;
95.520 + }
95.521 +
95.522 class SectionWriter;
95.523
95.524 SectionWriter sectionWriter(std::istream& is);
95.525 @@ -1625,7 +1699,7 @@
95.526
95.527 public:
95.528
95.529 - /// \name Section writers
95.530 + /// \name Section Writers
95.531 /// @{
95.532
95.533 /// \brief Add a section writer with line oriented writing
95.534 @@ -1692,7 +1766,7 @@
95.535 public:
95.536
95.537
95.538 - /// \name Execution of the writer
95.539 + /// \name Execution of the Writer
95.540 /// @{
95.541
95.542 /// \brief Start the batch processing
95.543 @@ -1720,10 +1794,18 @@
95.544
95.545 };
95.546
95.547 + /// \ingroup lemon_io
95.548 + ///
95.549 /// \brief Return a \ref SectionWriter class
95.550 ///
95.551 /// This function just returns a \ref SectionWriter class.
95.552 + ///
95.553 + /// Please see SectionWriter documentation about the custom section
95.554 + /// output.
95.555 + ///
95.556 /// \relates SectionWriter
95.557 + /// \sa sectionWriter(const std::string& fn)
95.558 + /// \sa sectionWriter(const char *fn)
95.559 inline SectionWriter sectionWriter(std::ostream& os) {
95.560 SectionWriter tmp(os);
95.561 return tmp;
95.562 @@ -1733,6 +1815,7 @@
95.563 ///
95.564 /// This function just returns a \ref SectionWriter class.
95.565 /// \relates SectionWriter
95.566 + /// \sa sectionWriter(std::ostream& os)
95.567 inline SectionWriter sectionWriter(const std::string& fn) {
95.568 SectionWriter tmp(fn);
95.569 return tmp;
95.570 @@ -1742,6 +1825,7 @@
95.571 ///
95.572 /// This function just returns a \ref SectionWriter class.
95.573 /// \relates SectionWriter
95.574 + /// \sa sectionWriter(std::ostream& os)
95.575 inline SectionWriter sectionWriter(const char* fn) {
95.576 SectionWriter tmp(fn);
95.577 return tmp;
96.1 --- a/lemon/list_graph.h Mon Jan 12 23:11:39 2009 +0100
96.2 +++ b/lemon/list_graph.h Thu Nov 05 15:48:01 2009 +0100
96.3 @@ -21,7 +21,7 @@
96.4
96.5 ///\ingroup graphs
96.6 ///\file
96.7 -///\brief ListDigraph, ListGraph classes.
96.8 +///\brief ListDigraph and ListGraph classes.
96.9
96.10 #include <lemon/core.h>
96.11 #include <lemon/error.h>
96.12 @@ -32,6 +32,8 @@
96.13
96.14 namespace lemon {
96.15
96.16 + class ListDigraph;
96.17 +
96.18 class ListDigraphBase {
96.19
96.20 protected:
96.21 @@ -62,6 +64,7 @@
96.22
96.23 class Node {
96.24 friend class ListDigraphBase;
96.25 + friend class ListDigraph;
96.26 protected:
96.27
96.28 int id;
96.29 @@ -77,6 +80,7 @@
96.30
96.31 class Arc {
96.32 friend class ListDigraphBase;
96.33 + friend class ListDigraph;
96.34 protected:
96.35
96.36 int id;
96.37 @@ -116,20 +120,20 @@
96.38 void first(Arc& arc) const {
96.39 int n;
96.40 for(n = first_node;
96.41 - n!=-1 && nodes[n].first_in == -1;
96.42 + n != -1 && nodes[n].first_out == -1;
96.43 n = nodes[n].next) {}
96.44 - arc.id = (n == -1) ? -1 : nodes[n].first_in;
96.45 + arc.id = (n == -1) ? -1 : nodes[n].first_out;
96.46 }
96.47
96.48 void next(Arc& arc) const {
96.49 - if (arcs[arc.id].next_in != -1) {
96.50 - arc.id = arcs[arc.id].next_in;
96.51 + if (arcs[arc.id].next_out != -1) {
96.52 + arc.id = arcs[arc.id].next_out;
96.53 } else {
96.54 int n;
96.55 - for(n = nodes[arcs[arc.id].target].next;
96.56 - n!=-1 && nodes[n].first_in == -1;
96.57 + for(n = nodes[arcs[arc.id].source].next;
96.58 + n != -1 && nodes[n].first_out == -1;
96.59 n = nodes[n].next) {}
96.60 - arc.id = (n == -1) ? -1 : nodes[n].first_in;
96.61 + arc.id = (n == -1) ? -1 : nodes[n].first_out;
96.62 }
96.63 }
96.64
96.65 @@ -311,37 +315,28 @@
96.66
96.67 ///A general directed graph structure.
96.68
96.69 - ///\ref ListDigraph is a simple and fast <em>directed graph</em>
96.70 - ///implementation based on static linked lists that are stored in
96.71 + ///\ref ListDigraph is a versatile and fast directed graph
96.72 + ///implementation based on linked lists that are stored in
96.73 ///\c std::vector structures.
96.74 ///
96.75 - ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
96.76 - ///also provides several useful additional functionalities.
96.77 - ///Most of the member functions and nested classes are documented
96.78 + ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
96.79 + ///and it also provides several useful additional functionalities.
96.80 + ///Most of its member functions and nested classes are documented
96.81 ///only in the concept class.
96.82 ///
96.83 - ///An important extra feature of this digraph implementation is that
96.84 - ///its maps are real \ref concepts::ReferenceMap "reference map"s.
96.85 - ///
96.86 ///\sa concepts::Digraph
96.87 + ///\sa ListGraph
96.88 + class ListDigraph : public ExtendedListDigraphBase {
96.89 + typedef ExtendedListDigraphBase Parent;
96.90
96.91 - class ListDigraph : public ExtendedListDigraphBase {
96.92 private:
96.93 - ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
96.94 -
96.95 - ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
96.96 - ///
96.97 + /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
96.98 ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
96.99 - ///\brief Assignment of ListDigraph to another one is \e not allowed.
96.100 - ///Use copyDigraph() instead.
96.101 -
96.102 - ///Assignment of ListDigraph to another one is \e not allowed.
96.103 - ///Use copyDigraph() instead.
96.104 + /// \brief Assignment of a digraph to another one is \e not allowed.
96.105 + /// Use DigraphCopy instead.
96.106 void operator=(const ListDigraph &) {}
96.107 public:
96.108
96.109 - typedef ExtendedListDigraphBase Parent;
96.110 -
96.111 /// Constructor
96.112
96.113 /// Constructor.
96.114 @@ -350,71 +345,65 @@
96.115
96.116 ///Add a new node to the digraph.
96.117
96.118 - ///Add a new node to the digraph.
96.119 - ///\return the new node.
96.120 + ///This function adds a new node to the digraph.
96.121 + ///\return The new node.
96.122 Node addNode() { return Parent::addNode(); }
96.123
96.124 ///Add a new arc to the digraph.
96.125
96.126 - ///Add a new arc to the digraph with source node \c s
96.127 + ///This function adds a new arc to the digraph with source node \c s
96.128 ///and target node \c t.
96.129 - ///\return the new arc.
96.130 - Arc addArc(const Node& s, const Node& t) {
96.131 + ///\return The new arc.
96.132 + Arc addArc(Node s, Node t) {
96.133 return Parent::addArc(s, t);
96.134 }
96.135
96.136 ///\brief Erase a node from the digraph.
96.137 ///
96.138 - ///Erase a node from the digraph.
96.139 - ///
96.140 - void erase(const Node& n) { Parent::erase(n); }
96.141 + ///This function erases the given node from the digraph.
96.142 + void erase(Node n) { Parent::erase(n); }
96.143
96.144 ///\brief Erase an arc from the digraph.
96.145 ///
96.146 - ///Erase an arc from the digraph.
96.147 - ///
96.148 - void erase(const Arc& a) { Parent::erase(a); }
96.149 + ///This function erases the given arc from the digraph.
96.150 + void erase(Arc a) { Parent::erase(a); }
96.151
96.152 /// Node validity check
96.153
96.154 - /// This function gives back true if the given node is valid,
96.155 - /// ie. it is a real node of the graph.
96.156 + /// This function gives back \c true if the given node is valid,
96.157 + /// i.e. it is a real node of the digraph.
96.158 ///
96.159 - /// \warning A Node pointing to a removed item
96.160 - /// could become valid again later if new nodes are
96.161 - /// added to the graph.
96.162 + /// \warning A removed node could become valid again if new nodes are
96.163 + /// added to the digraph.
96.164 bool valid(Node n) const { return Parent::valid(n); }
96.165
96.166 /// Arc validity check
96.167
96.168 - /// This function gives back true if the given arc is valid,
96.169 - /// ie. it is a real arc of the graph.
96.170 + /// This function gives back \c true if the given arc is valid,
96.171 + /// i.e. it is a real arc of the digraph.
96.172 ///
96.173 - /// \warning An Arc pointing to a removed item
96.174 - /// could become valid again later if new nodes are
96.175 - /// added to the graph.
96.176 + /// \warning A removed arc could become valid again if new arcs are
96.177 + /// added to the digraph.
96.178 bool valid(Arc a) const { return Parent::valid(a); }
96.179
96.180 - /// Change the target of \c a to \c n
96.181 + /// Change the target node of an arc
96.182
96.183 - /// Change the target of \c a to \c n
96.184 + /// This function changes the target node of the given arc \c a to \c n.
96.185 ///
96.186 - ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
96.187 - ///the changed arc remain valid. However <tt>InArcIt</tt>s are
96.188 - ///invalidated.
96.189 + ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
96.190 + ///arc remain valid, however \c InArcIt iterators are invalidated.
96.191 ///
96.192 ///\warning This functionality cannot be used together with the Snapshot
96.193 ///feature.
96.194 void changeTarget(Arc a, Node n) {
96.195 Parent::changeTarget(a,n);
96.196 }
96.197 - /// Change the source of \c a to \c n
96.198 + /// Change the source node of an arc
96.199
96.200 - /// Change the source of \c a to \c n
96.201 + /// This function changes the source node of the given arc \c a to \c n.
96.202 ///
96.203 - ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
96.204 - ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
96.205 - ///invalidated.
96.206 + ///\note \c InArcIt iterators referencing the changed arc remain
96.207 + ///valid, however \c ArcIt and \c OutArcIt iterators are invalidated.
96.208 ///
96.209 ///\warning This functionality cannot be used together with the Snapshot
96.210 ///feature.
96.211 @@ -422,94 +411,76 @@
96.212 Parent::changeSource(a,n);
96.213 }
96.214
96.215 - /// Invert the direction of an arc.
96.216 + /// Reverse the direction of an arc.
96.217
96.218 - ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
96.219 - ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
96.220 - ///invalidated.
96.221 + /// This function reverses the direction of the given arc.
96.222 + ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
96.223 + ///the changed arc are invalidated.
96.224 ///
96.225 ///\warning This functionality cannot be used together with the Snapshot
96.226 ///feature.
96.227 - void reverseArc(Arc e) {
96.228 - Node t=target(e);
96.229 - changeTarget(e,source(e));
96.230 - changeSource(e,t);
96.231 + void reverseArc(Arc a) {
96.232 + Node t=target(a);
96.233 + changeTarget(a,source(a));
96.234 + changeSource(a,t);
96.235 }
96.236
96.237 - /// Reserve memory for nodes.
96.238 -
96.239 - /// Using this function it is possible to avoid the superfluous memory
96.240 - /// allocation: if you know that the digraph you want to build will
96.241 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
96.242 - /// then it is worth reserving space for this amount before starting
96.243 - /// to build the digraph.
96.244 - /// \sa reserveArc
96.245 - void reserveNode(int n) { nodes.reserve(n); };
96.246 -
96.247 - /// Reserve memory for arcs.
96.248 -
96.249 - /// Using this function it is possible to avoid the superfluous memory
96.250 - /// allocation: if you know that the digraph you want to build will
96.251 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
96.252 - /// then it is worth reserving space for this amount before starting
96.253 - /// to build the digraph.
96.254 - /// \sa reserveNode
96.255 - void reserveArc(int m) { arcs.reserve(m); };
96.256 -
96.257 ///Contract two nodes.
96.258
96.259 - ///This function contracts two nodes.
96.260 - ///Node \p b will be removed but instead of deleting
96.261 - ///incident arcs, they will be joined to \p a.
96.262 - ///The last parameter \p r controls whether to remove loops. \c true
96.263 - ///means that loops will be removed.
96.264 + ///This function contracts the given two nodes.
96.265 + ///Node \c v is removed, but instead of deleting its
96.266 + ///incident arcs, they are joined to node \c u.
96.267 + ///If the last parameter \c r is \c true (this is the default value),
96.268 + ///then the newly created loops are removed.
96.269 ///
96.270 - ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
96.271 - ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
96.272 - ///may be invalidated.
96.273 + ///\note The moved arcs are joined to node \c u using changeSource()
96.274 + ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
96.275 + ///invalidated for the outgoing arcs of node \c v and \c InArcIt
96.276 + ///iterators are invalidated for the incomming arcs of \c v.
96.277 + ///Moreover all iterators referencing node \c v or the removed
96.278 + ///loops are also invalidated. Other iterators remain valid.
96.279 ///
96.280 ///\warning This functionality cannot be used together with the Snapshot
96.281 ///feature.
96.282 - void contract(Node a, Node b, bool r = true)
96.283 + void contract(Node u, Node v, bool r = true)
96.284 {
96.285 - for(OutArcIt e(*this,b);e!=INVALID;) {
96.286 + for(OutArcIt e(*this,v);e!=INVALID;) {
96.287 OutArcIt f=e;
96.288 ++f;
96.289 - if(r && target(e)==a) erase(e);
96.290 - else changeSource(e,a);
96.291 + if(r && target(e)==u) erase(e);
96.292 + else changeSource(e,u);
96.293 e=f;
96.294 }
96.295 - for(InArcIt e(*this,b);e!=INVALID;) {
96.296 + for(InArcIt e(*this,v);e!=INVALID;) {
96.297 InArcIt f=e;
96.298 ++f;
96.299 - if(r && source(e)==a) erase(e);
96.300 - else changeTarget(e,a);
96.301 + if(r && source(e)==u) erase(e);
96.302 + else changeTarget(e,u);
96.303 e=f;
96.304 }
96.305 - erase(b);
96.306 + erase(v);
96.307 }
96.308
96.309 ///Split a node.
96.310
96.311 - ///This function splits a node. First a new node is added to the digraph,
96.312 - ///then the source of each outgoing arc of \c n is moved to this new node.
96.313 - ///If \c connect is \c true (this is the default value), then a new arc
96.314 - ///from \c n to the newly created node is also added.
96.315 + ///This function splits the given node. First, a new node is added
96.316 + ///to the digraph, then the source of each outgoing arc of node \c n
96.317 + ///is moved to this new node.
96.318 + ///If the second parameter \c connect is \c true (this is the default
96.319 + ///value), then a new arc from node \c n to the newly created node
96.320 + ///is also added.
96.321 ///\return The newly created node.
96.322 ///
96.323 - ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
96.324 - ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
96.325 - ///be invalidated.
96.326 + ///\note All iterators remain valid.
96.327 ///
96.328 - ///\warning This functionality cannot be used in conjunction with the
96.329 + ///\warning This functionality cannot be used together with the
96.330 ///Snapshot feature.
96.331 Node split(Node n, bool connect = true) {
96.332 Node b = addNode();
96.333 - for(OutArcIt e(*this,n);e!=INVALID;) {
96.334 - OutArcIt f=e;
96.335 - ++f;
96.336 - changeSource(e,b);
96.337 - e=f;
96.338 + nodes[b.id].first_out=nodes[n.id].first_out;
96.339 + nodes[n.id].first_out=-1;
96.340 + for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {
96.341 + arcs[i].source=b.id;
96.342 }
96.343 if (connect) addArc(n,b);
96.344 return b;
96.345 @@ -517,21 +488,52 @@
96.346
96.347 ///Split an arc.
96.348
96.349 - ///This function splits an arc. First a new node \c b is added to
96.350 - ///the digraph, then the original arc is re-targeted to \c
96.351 - ///b. Finally an arc from \c b to the original target is added.
96.352 + ///This function splits the given arc. First, a new node \c v is
96.353 + ///added to the digraph, then the target node of the original arc
96.354 + ///is set to \c v. Finally, an arc from \c v to the original target
96.355 + ///is added.
96.356 + ///\return The newly created node.
96.357 ///
96.358 - ///\return The newly created node.
96.359 + ///\note \c InArcIt iterators referencing the original arc are
96.360 + ///invalidated. Other iterators remain valid.
96.361 ///
96.362 ///\warning This functionality cannot be used together with the
96.363 ///Snapshot feature.
96.364 - Node split(Arc e) {
96.365 - Node b = addNode();
96.366 - addArc(b,target(e));
96.367 - changeTarget(e,b);
96.368 - return b;
96.369 + Node split(Arc a) {
96.370 + Node v = addNode();
96.371 + addArc(v,target(a));
96.372 + changeTarget(a,v);
96.373 + return v;
96.374 }
96.375
96.376 + ///Clear the digraph.
96.377 +
96.378 + ///This function erases all nodes and arcs from the digraph.
96.379 + ///
96.380 + void clear() {
96.381 + Parent::clear();
96.382 + }
96.383 +
96.384 + /// Reserve memory for nodes.
96.385 +
96.386 + /// Using this function, it is possible to avoid superfluous memory
96.387 + /// allocation: if you know that the digraph you want to build will
96.388 + /// be large (e.g. it will contain millions of nodes and/or arcs),
96.389 + /// then it is worth reserving space for this amount before starting
96.390 + /// to build the digraph.
96.391 + /// \sa reserveArc()
96.392 + void reserveNode(int n) { nodes.reserve(n); };
96.393 +
96.394 + /// Reserve memory for arcs.
96.395 +
96.396 + /// Using this function, it is possible to avoid superfluous memory
96.397 + /// allocation: if you know that the digraph you want to build will
96.398 + /// be large (e.g. it will contain millions of nodes and/or arcs),
96.399 + /// then it is worth reserving space for this amount before starting
96.400 + /// to build the digraph.
96.401 + /// \sa reserveNode()
96.402 + void reserveArc(int m) { arcs.reserve(m); };
96.403 +
96.404 /// \brief Class to make a snapshot of the digraph and restore
96.405 /// it later.
96.406 ///
96.407 @@ -540,9 +542,15 @@
96.408 /// The newly added nodes and arcs can be removed using the
96.409 /// restore() function.
96.410 ///
96.411 - /// \warning Arc and node deletions and other modifications (e.g.
96.412 - /// contracting, splitting, reversing arcs or nodes) cannot be
96.413 + /// \note After a state is restored, you cannot restore a later state,
96.414 + /// i.e. you cannot add the removed nodes and arcs again using
96.415 + /// another Snapshot instance.
96.416 + ///
96.417 + /// \warning Node and arc deletions and other modifications (e.g.
96.418 + /// reversing, contracting, splitting arcs or nodes) cannot be
96.419 /// restored. These events invalidate the snapshot.
96.420 + /// However the arcs and nodes that were added to the digraph after
96.421 + /// making the current snapshot can be removed without invalidating it.
96.422 class Snapshot {
96.423 protected:
96.424
96.425 @@ -712,39 +720,40 @@
96.426 /// \brief Default constructor.
96.427 ///
96.428 /// Default constructor.
96.429 - /// To actually make a snapshot you must call save().
96.430 + /// You have to call save() to actually make a snapshot.
96.431 Snapshot()
96.432 : digraph(0), node_observer_proxy(*this),
96.433 arc_observer_proxy(*this) {}
96.434
96.435 /// \brief Constructor that immediately makes a snapshot.
96.436 ///
96.437 - /// This constructor immediately makes a snapshot of the digraph.
96.438 - /// \param _digraph The digraph we make a snapshot of.
96.439 - Snapshot(ListDigraph &_digraph)
96.440 + /// This constructor immediately makes a snapshot of the given digraph.
96.441 + Snapshot(ListDigraph &gr)
96.442 : node_observer_proxy(*this),
96.443 arc_observer_proxy(*this) {
96.444 - attach(_digraph);
96.445 + attach(gr);
96.446 }
96.447
96.448 /// \brief Make a snapshot.
96.449 ///
96.450 - /// Make a snapshot of the digraph.
96.451 - ///
96.452 - /// This function can be called more than once. In case of a repeated
96.453 + /// This function makes a snapshot of the given digraph.
96.454 + /// It can be called more than once. In case of a repeated
96.455 /// call, the previous snapshot gets lost.
96.456 - /// \param _digraph The digraph we make the snapshot of.
96.457 - void save(ListDigraph &_digraph) {
96.458 + void save(ListDigraph &gr) {
96.459 if (attached()) {
96.460 detach();
96.461 clear();
96.462 }
96.463 - attach(_digraph);
96.464 + attach(gr);
96.465 }
96.466
96.467 /// \brief Undo the changes until the last snapshot.
96.468 - //
96.469 - /// Undo the changes until the last snapshot created by save().
96.470 + ///
96.471 + /// This function undos the changes until the last snapshot
96.472 + /// created by save() or Snapshot(ListDigraph&).
96.473 + ///
96.474 + /// \warning This method invalidates the snapshot, i.e. repeated
96.475 + /// restoring is not supported unless you call save() again.
96.476 void restore() {
96.477 detach();
96.478 for(std::list<Arc>::iterator it = added_arcs.begin();
96.479 @@ -758,9 +767,9 @@
96.480 clear();
96.481 }
96.482
96.483 - /// \brief Gives back true when the snapshot is valid.
96.484 + /// \brief Returns \c true if the snapshot is valid.
96.485 ///
96.486 - /// Gives back true when the snapshot is valid.
96.487 + /// This function returns \c true if the snapshot is valid.
96.488 bool valid() const {
96.489 return attached();
96.490 }
96.491 @@ -796,11 +805,7 @@
96.492
96.493 public:
96.494
96.495 - typedef ListGraphBase Digraph;
96.496 -
96.497 - class Node;
96.498 - class Arc;
96.499 - class Edge;
96.500 + typedef ListGraphBase Graph;
96.501
96.502 class Node {
96.503 friend class ListGraphBase;
96.504 @@ -851,8 +856,6 @@
96.505 bool operator<(const Arc& arc) const {return id < arc.id;}
96.506 };
96.507
96.508 -
96.509 -
96.510 ListGraphBase()
96.511 : nodes(), first_node(-1),
96.512 first_free_node(-1), arcs(), first_free_arc(-1) {}
96.513 @@ -1167,32 +1170,25 @@
96.514
96.515 ///A general undirected graph structure.
96.516
96.517 - ///\ref ListGraph is a simple and fast <em>undirected graph</em>
96.518 - ///implementation based on static linked lists that are stored in
96.519 + ///\ref ListGraph is a versatile and fast undirected graph
96.520 + ///implementation based on linked lists that are stored in
96.521 ///\c std::vector structures.
96.522 ///
96.523 - ///It conforms to the \ref concepts::Graph "Graph concept" and it
96.524 - ///also provides several useful additional functionalities.
96.525 - ///Most of the member functions and nested classes are documented
96.526 + ///This type fully conforms to the \ref concepts::Graph "Graph concept"
96.527 + ///and it also provides several useful additional functionalities.
96.528 + ///Most of its member functions and nested classes are documented
96.529 ///only in the concept class.
96.530 ///
96.531 - ///An important extra feature of this graph implementation is that
96.532 - ///its maps are real \ref concepts::ReferenceMap "reference map"s.
96.533 - ///
96.534 ///\sa concepts::Graph
96.535 + ///\sa ListDigraph
96.536 + class ListGraph : public ExtendedListGraphBase {
96.537 + typedef ExtendedListGraphBase Parent;
96.538
96.539 - class ListGraph : public ExtendedListGraphBase {
96.540 private:
96.541 - ///ListGraph is \e not copy constructible. Use copyGraph() instead.
96.542 -
96.543 - ///ListGraph is \e not copy constructible. Use copyGraph() instead.
96.544 - ///
96.545 + /// Graphs are \e not copy constructible. Use GraphCopy instead.
96.546 ListGraph(const ListGraph &) :ExtendedListGraphBase() {};
96.547 - ///\brief Assignment of ListGraph to another one is \e not allowed.
96.548 - ///Use copyGraph() instead.
96.549 -
96.550 - ///Assignment of ListGraph to another one is \e not allowed.
96.551 - ///Use copyGraph() instead.
96.552 + /// \brief Assignment of a graph to another one is \e not allowed.
96.553 + /// Use GraphCopy instead.
96.554 void operator=(const ListGraph &) {}
96.555 public:
96.556 /// Constructor
96.557 @@ -1201,100 +1197,99 @@
96.558 ///
96.559 ListGraph() {}
96.560
96.561 - typedef ExtendedListGraphBase Parent;
96.562 -
96.563 typedef Parent::OutArcIt IncEdgeIt;
96.564
96.565 /// \brief Add a new node to the graph.
96.566 ///
96.567 - /// Add a new node to the graph.
96.568 - /// \return the new node.
96.569 + /// This function adds a new node to the graph.
96.570 + /// \return The new node.
96.571 Node addNode() { return Parent::addNode(); }
96.572
96.573 /// \brief Add a new edge to the graph.
96.574 ///
96.575 - /// Add a new edge to the graph with source node \c s
96.576 - /// and target node \c t.
96.577 - /// \return the new edge.
96.578 - Edge addEdge(const Node& s, const Node& t) {
96.579 - return Parent::addEdge(s, t);
96.580 + /// This function adds a new edge to the graph between nodes
96.581 + /// \c u and \c v with inherent orientation from node \c u to
96.582 + /// node \c v.
96.583 + /// \return The new edge.
96.584 + Edge addEdge(Node u, Node v) {
96.585 + return Parent::addEdge(u, v);
96.586 }
96.587
96.588 - /// \brief Erase a node from the graph.
96.589 + ///\brief Erase a node from the graph.
96.590 ///
96.591 - /// Erase a node from the graph.
96.592 + /// This function erases the given node from the graph.
96.593 + void erase(Node n) { Parent::erase(n); }
96.594 +
96.595 + ///\brief Erase an edge from the graph.
96.596 ///
96.597 - void erase(const Node& n) { Parent::erase(n); }
96.598 -
96.599 - /// \brief Erase an edge from the graph.
96.600 - ///
96.601 - /// Erase an edge from the graph.
96.602 - ///
96.603 - void erase(const Edge& e) { Parent::erase(e); }
96.604 + /// This function erases the given edge from the graph.
96.605 + void erase(Edge e) { Parent::erase(e); }
96.606 /// Node validity check
96.607
96.608 - /// This function gives back true if the given node is valid,
96.609 - /// ie. it is a real node of the graph.
96.610 + /// This function gives back \c true if the given node is valid,
96.611 + /// i.e. it is a real node of the graph.
96.612 ///
96.613 - /// \warning A Node pointing to a removed item
96.614 - /// could become valid again later if new nodes are
96.615 + /// \warning A removed node could become valid again if new nodes are
96.616 /// added to the graph.
96.617 bool valid(Node n) const { return Parent::valid(n); }
96.618 + /// Edge validity check
96.619 +
96.620 + /// This function gives back \c true if the given edge is valid,
96.621 + /// i.e. it is a real edge of the graph.
96.622 + ///
96.623 + /// \warning A removed edge could become valid again if new edges are
96.624 + /// added to the graph.
96.625 + bool valid(Edge e) const { return Parent::valid(e); }
96.626 /// Arc validity check
96.627
96.628 - /// This function gives back true if the given arc is valid,
96.629 - /// ie. it is a real arc of the graph.
96.630 + /// This function gives back \c true if the given arc is valid,
96.631 + /// i.e. it is a real arc of the graph.
96.632 ///
96.633 - /// \warning An Arc pointing to a removed item
96.634 - /// could become valid again later if new edges are
96.635 + /// \warning A removed arc could become valid again if new edges are
96.636 /// added to the graph.
96.637 bool valid(Arc a) const { return Parent::valid(a); }
96.638 - /// Edge validity check
96.639
96.640 - /// This function gives back true if the given edge is valid,
96.641 - /// ie. it is a real arc of the graph.
96.642 + /// \brief Change the first node of an edge.
96.643 ///
96.644 - /// \warning A Edge pointing to a removed item
96.645 - /// could become valid again later if new edges are
96.646 - /// added to the graph.
96.647 - bool valid(Edge e) const { return Parent::valid(e); }
96.648 - /// \brief Change the end \c u of \c e to \c n
96.649 + /// This function changes the first node of the given edge \c e to \c n.
96.650 ///
96.651 - /// This function changes the end \c u of \c e to node \c n.
96.652 - ///
96.653 - ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
96.654 - ///changed edge are invalidated and if the changed node is the
96.655 - ///base node of an iterator then this iterator is also
96.656 - ///invalidated.
96.657 + ///\note \c EdgeIt and \c ArcIt iterators referencing the
96.658 + ///changed edge are invalidated and all other iterators whose
96.659 + ///base node is the changed node are also invalidated.
96.660 ///
96.661 ///\warning This functionality cannot be used together with the
96.662 ///Snapshot feature.
96.663 void changeU(Edge e, Node n) {
96.664 Parent::changeU(e,n);
96.665 }
96.666 - /// \brief Change the end \c v of \c e to \c n
96.667 + /// \brief Change the second node of an edge.
96.668 ///
96.669 - /// This function changes the end \c v of \c e to \c n.
96.670 + /// This function changes the second node of the given edge \c e to \c n.
96.671 ///
96.672 - ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
96.673 - ///valid, however <tt>ArcIt</tt>s and if the changed node is the
96.674 - ///base node of an iterator then this iterator is invalidated.
96.675 + ///\note \c EdgeIt iterators referencing the changed edge remain
96.676 + ///valid, however \c ArcIt iterators referencing the changed edge and
96.677 + ///all other iterators whose base node is the changed node are also
96.678 + ///invalidated.
96.679 ///
96.680 ///\warning This functionality cannot be used together with the
96.681 ///Snapshot feature.
96.682 void changeV(Edge e, Node n) {
96.683 Parent::changeV(e,n);
96.684 }
96.685 +
96.686 /// \brief Contract two nodes.
96.687 ///
96.688 - /// This function contracts two nodes.
96.689 - /// Node \p b will be removed but instead of deleting
96.690 - /// its neighboring arcs, they will be joined to \p a.
96.691 - /// The last parameter \p r controls whether to remove loops. \c true
96.692 - /// means that loops will be removed.
96.693 + /// This function contracts the given two nodes.
96.694 + /// Node \c b is removed, but instead of deleting
96.695 + /// its incident edges, they are joined to node \c a.
96.696 + /// If the last parameter \c r is \c true (this is the default value),
96.697 + /// then the newly created loops are removed.
96.698 ///
96.699 - /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
96.700 - /// valid.
96.701 + /// \note The moved edges are joined to node \c a using changeU()
96.702 + /// or changeV(), thus all edge and arc iterators whose base node is
96.703 + /// \c b are invalidated.
96.704 + /// Moreover all iterators referencing node \c b or the removed
96.705 + /// loops are also invalidated. Other iterators remain valid.
96.706 ///
96.707 ///\warning This functionality cannot be used together with the
96.708 ///Snapshot feature.
96.709 @@ -1313,6 +1308,33 @@
96.710 erase(b);
96.711 }
96.712
96.713 + ///Clear the graph.
96.714 +
96.715 + ///This function erases all nodes and arcs from the graph.
96.716 + ///
96.717 + void clear() {
96.718 + Parent::clear();
96.719 + }
96.720 +
96.721 + /// Reserve memory for nodes.
96.722 +
96.723 + /// Using this function, it is possible to avoid superfluous memory
96.724 + /// allocation: if you know that the graph you want to build will
96.725 + /// be large (e.g. it will contain millions of nodes and/or edges),
96.726 + /// then it is worth reserving space for this amount before starting
96.727 + /// to build the graph.
96.728 + /// \sa reserveEdge()
96.729 + void reserveNode(int n) { nodes.reserve(n); };
96.730 +
96.731 + /// Reserve memory for edges.
96.732 +
96.733 + /// Using this function, it is possible to avoid superfluous memory
96.734 + /// allocation: if you know that the graph you want to build will
96.735 + /// be large (e.g. it will contain millions of nodes and/or edges),
96.736 + /// then it is worth reserving space for this amount before starting
96.737 + /// to build the graph.
96.738 + /// \sa reserveNode()
96.739 + void reserveEdge(int m) { arcs.reserve(2 * m); };
96.740
96.741 /// \brief Class to make a snapshot of the graph and restore
96.742 /// it later.
96.743 @@ -1322,9 +1344,15 @@
96.744 /// The newly added nodes and edges can be removed
96.745 /// using the restore() function.
96.746 ///
96.747 - /// \warning Edge and node deletions and other modifications
96.748 - /// (e.g. changing nodes of edges, contracting nodes) cannot be
96.749 - /// restored. These events invalidate the snapshot.
96.750 + /// \note After a state is restored, you cannot restore a later state,
96.751 + /// i.e. you cannot add the removed nodes and edges again using
96.752 + /// another Snapshot instance.
96.753 + ///
96.754 + /// \warning Node and edge deletions and other modifications
96.755 + /// (e.g. changing the end-nodes of edges or contracting nodes)
96.756 + /// cannot be restored. These events invalidate the snapshot.
96.757 + /// However the edges and nodes that were added to the graph after
96.758 + /// making the current snapshot can be removed without invalidating it.
96.759 class Snapshot {
96.760 protected:
96.761
96.762 @@ -1494,39 +1522,40 @@
96.763 /// \brief Default constructor.
96.764 ///
96.765 /// Default constructor.
96.766 - /// To actually make a snapshot you must call save().
96.767 + /// You have to call save() to actually make a snapshot.
96.768 Snapshot()
96.769 : graph(0), node_observer_proxy(*this),
96.770 edge_observer_proxy(*this) {}
96.771
96.772 /// \brief Constructor that immediately makes a snapshot.
96.773 ///
96.774 - /// This constructor immediately makes a snapshot of the graph.
96.775 - /// \param _graph The graph we make a snapshot of.
96.776 - Snapshot(ListGraph &_graph)
96.777 + /// This constructor immediately makes a snapshot of the given graph.
96.778 + Snapshot(ListGraph &gr)
96.779 : node_observer_proxy(*this),
96.780 edge_observer_proxy(*this) {
96.781 - attach(_graph);
96.782 + attach(gr);
96.783 }
96.784
96.785 /// \brief Make a snapshot.
96.786 ///
96.787 - /// Make a snapshot of the graph.
96.788 - ///
96.789 - /// This function can be called more than once. In case of a repeated
96.790 + /// This function makes a snapshot of the given graph.
96.791 + /// It can be called more than once. In case of a repeated
96.792 /// call, the previous snapshot gets lost.
96.793 - /// \param _graph The graph we make the snapshot of.
96.794 - void save(ListGraph &_graph) {
96.795 + void save(ListGraph &gr) {
96.796 if (attached()) {
96.797 detach();
96.798 clear();
96.799 }
96.800 - attach(_graph);
96.801 + attach(gr);
96.802 }
96.803
96.804 /// \brief Undo the changes until the last snapshot.
96.805 - //
96.806 - /// Undo the changes until the last snapshot created by save().
96.807 + ///
96.808 + /// This function undos the changes until the last snapshot
96.809 + /// created by save() or Snapshot(ListGraph&).
96.810 + ///
96.811 + /// \warning This method invalidates the snapshot, i.e. repeated
96.812 + /// restoring is not supported unless you call save() again.
96.813 void restore() {
96.814 detach();
96.815 for(std::list<Edge>::iterator it = added_edges.begin();
96.816 @@ -1540,9 +1569,9 @@
96.817 clear();
96.818 }
96.819
96.820 - /// \brief Gives back true when the snapshot is valid.
96.821 + /// \brief Returns \c true if the snapshot is valid.
96.822 ///
96.823 - /// Gives back true when the snapshot is valid.
96.824 + /// This function returns \c true if the snapshot is valid.
96.825 bool valid() const {
96.826 return attached();
96.827 }
97.1 --- a/lemon/lp.h Mon Jan 12 23:11:39 2009 +0100
97.2 +++ b/lemon/lp.h Thu Nov 05 15:48:01 2009 +0100
97.3 @@ -22,13 +22,13 @@
97.4 #include<lemon/config.h>
97.5
97.6
97.7 -#ifdef HAVE_GLPK
97.8 +#ifdef LEMON_HAVE_GLPK
97.9 #include <lemon/glpk.h>
97.10 -#elif HAVE_CPLEX
97.11 +#elif LEMON_HAVE_CPLEX
97.12 #include <lemon/cplex.h>
97.13 -#elif HAVE_SOPLEX
97.14 +#elif LEMON_HAVE_SOPLEX
97.15 #include <lemon/soplex.h>
97.16 -#elif HAVE_CLP
97.17 +#elif LEMON_HAVE_CLP
97.18 #include <lemon/clp.h>
97.19 #endif
97.20
97.21 @@ -69,20 +69,20 @@
97.22 ///Currently, it is either \c GlpkMip or \c CplexMip
97.23 typedef GlpkMip Mip;
97.24 #else
97.25 -#ifdef HAVE_GLPK
97.26 +#ifdef LEMON_HAVE_GLPK
97.27 # define LEMON_DEFAULT_LP GLPK
97.28 typedef GlpkLp Lp;
97.29 # define LEMON_DEFAULT_MIP GLPK
97.30 typedef GlpkMip Mip;
97.31 -#elif HAVE_CPLEX
97.32 +#elif LEMON_HAVE_CPLEX
97.33 # define LEMON_DEFAULT_LP CPLEX
97.34 typedef CplexLp Lp;
97.35 # define LEMON_DEFAULT_MIP CPLEX
97.36 typedef CplexMip Mip;
97.37 -#elif HAVE_SOPLEX
97.38 +#elif LEMON_HAVE_SOPLEX
97.39 # define DEFAULT_LP SOPLEX
97.40 typedef SoplexLp Lp;
97.41 -#elif HAVE_CLP
97.42 +#elif LEMON_HAVE_CLP
97.43 # define DEFAULT_LP CLP
97.44 typedef ClpLp Lp;
97.45 #endif
98.1 --- a/lemon/lp_base.cc Mon Jan 12 23:11:39 2009 +0100
98.2 +++ b/lemon/lp_base.cc Thu Nov 05 15:48:01 2009 +0100
98.3 @@ -22,7 +22,9 @@
98.4 #include <lemon/lp_base.h>
98.5 namespace lemon {
98.6
98.7 - const LpBase::Value LpBase::INF = std::numeric_limits<Value>::infinity();
98.8 - const LpBase::Value LpBase::NaN = std::numeric_limits<Value>::quiet_NaN();
98.9 + const LpBase::Value LpBase::INF =
98.10 + std::numeric_limits<LpBase::Value>::infinity();
98.11 + const LpBase::Value LpBase::NaN =
98.12 + std::numeric_limits<LpBase::Value>::quiet_NaN();
98.13
98.14 } //namespace lemon
99.1 --- a/lemon/lp_base.h Mon Jan 12 23:11:39 2009 +0100
99.2 +++ b/lemon/lp_base.h Thu Nov 05 15:48:01 2009 +0100
99.3 @@ -52,12 +52,12 @@
99.4
99.5 ///Possible outcomes of an LP solving procedure
99.6 enum SolveExitStatus {
99.7 - ///This means that the problem has been successfully solved: either
99.8 + /// = 0. It means that the problem has been successfully solved: either
99.9 ///an optimal solution has been found or infeasibility/unboundedness
99.10 ///has been proved.
99.11 SOLVED = 0,
99.12 - ///Any other case (including the case when some user specified
99.13 - ///limit has been exceeded)
99.14 + /// = 1. Any other case (including the case when some user specified
99.15 + ///limit has been exceeded).
99.16 UNSOLVED = 1
99.17 };
99.18
99.19 @@ -69,6 +69,21 @@
99.20 MAX
99.21 };
99.22
99.23 + ///Enum for \c messageLevel() parameter
99.24 + enum MessageLevel {
99.25 + /// No output (default value).
99.26 + MESSAGE_NOTHING,
99.27 + /// Error messages only.
99.28 + MESSAGE_ERROR,
99.29 + /// Warnings.
99.30 + MESSAGE_WARNING,
99.31 + /// Normal output.
99.32 + MESSAGE_NORMAL,
99.33 + /// Verbose output.
99.34 + MESSAGE_VERBOSE
99.35 + };
99.36 +
99.37 +
99.38 ///The floating point type used by the solver
99.39 typedef double Value;
99.40 ///The infinity constant
99.41 @@ -597,11 +612,11 @@
99.42 const Value &upperBound() const { return _ub; }
99.43 ///Is the constraint lower bounded?
99.44 bool lowerBounded() const {
99.45 - return _lb != -INF && !std::isnan(_lb);
99.46 + return _lb != -INF && !isNaN(_lb);
99.47 }
99.48 ///Is the constraint upper bounded?
99.49 bool upperBounded() const {
99.50 - return _ub != INF && !std::isnan(_ub);
99.51 + return _ub != INF && !isNaN(_ub);
99.52 }
99.53
99.54 };
99.55 @@ -918,8 +933,6 @@
99.56 protected:
99.57
99.58 //Abstract virtual functions
99.59 - virtual LpBase* _newSolver() const = 0;
99.60 - virtual LpBase* _cloneSolver() const = 0;
99.61
99.62 virtual int _addColId(int col) { return cols.addIndex(col); }
99.63 virtual int _addRowId(int row) { return rows.addIndex(row); }
99.64 @@ -930,6 +943,14 @@
99.65 virtual int _addCol() = 0;
99.66 virtual int _addRow() = 0;
99.67
99.68 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
99.69 + int row = _addRow();
99.70 + _setRowCoeffs(row, b, e);
99.71 + _setRowLowerBound(row, l);
99.72 + _setRowUpperBound(row, u);
99.73 + return row;
99.74 + }
99.75 +
99.76 virtual void _eraseCol(int col) = 0;
99.77 virtual void _eraseRow(int row) = 0;
99.78
99.79 @@ -975,6 +996,8 @@
99.80
99.81 virtual const char* _solverName() const = 0;
99.82
99.83 + virtual void _messageLevel(MessageLevel level) = 0;
99.84 +
99.85 //Own protected stuff
99.86
99.87 //Constant component of the objective function
99.88 @@ -987,15 +1010,10 @@
99.89 /// Virtual destructor
99.90 virtual ~LpBase() {}
99.91
99.92 - ///Creates a new LP problem
99.93 - LpBase* newSolver() {return _newSolver();}
99.94 - ///Makes a copy of the LP problem
99.95 - LpBase* cloneSolver() {return _cloneSolver();}
99.96 -
99.97 ///Gives back the name of the solver.
99.98 const char* solverName() const {return _solverName();}
99.99
99.100 - ///\name Build up and modify the LP
99.101 + ///\name Build Up and Modify the LP
99.102
99.103 ///@{
99.104
99.105 @@ -1067,8 +1085,8 @@
99.106 ///a better one.
99.107 void col(Col c, const DualExpr &e) {
99.108 e.simplify();
99.109 - _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), cols),
99.110 - ExprIterator(e.comps.end(), cols));
99.111 + _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), rows),
99.112 + ExprIterator(e.comps.end(), rows));
99.113 }
99.114
99.115 ///Get a column (i.e a dual constraint) of the LP
99.116 @@ -1197,8 +1215,10 @@
99.117 ///\param u is the upper bound (\ref INF means no bound)
99.118 ///\return The created row.
99.119 Row addRow(Value l,const Expr &e, Value u) {
99.120 - Row r=addRow();
99.121 - row(r,l,e,u);
99.122 + Row r;
99.123 + e.simplify();
99.124 + r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols),
99.125 + ExprIterator(e.comps.end(), cols), u - *e));
99.126 return r;
99.127 }
99.128
99.129 @@ -1207,8 +1227,12 @@
99.130 ///\param c is a linear expression (see \ref Constr)
99.131 ///\return The created row.
99.132 Row addRow(const Constr &c) {
99.133 - Row r=addRow();
99.134 - row(r,c);
99.135 + Row r;
99.136 + c.expr().simplify();
99.137 + r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound():-INF,
99.138 + ExprIterator(c.expr().comps.begin(), cols),
99.139 + ExprIterator(c.expr().comps.end(), cols),
99.140 + c.upperBounded()?c.upperBound():INF));
99.141 return r;
99.142 }
99.143 ///Erase a column (i.e a variable) from the LP
99.144 @@ -1383,26 +1407,26 @@
99.145 template<class T>
99.146 void colUpperBound(T &t, Value value) { return 0;}
99.147 #else
99.148 - template<class T>
99.149 - typename enable_if<typename T::value_type::LpCol,void>::type
99.150 - colUpperBound(T &t, Value value,dummy<0> = 0) {
99.151 - for(typename T::iterator i=t.begin();i!=t.end();++i) {
99.152 + template<class T1>
99.153 + typename enable_if<typename T1::value_type::LpCol,void>::type
99.154 + colUpperBound(T1 &t, Value value,dummy<0> = 0) {
99.155 + for(typename T1::iterator i=t.begin();i!=t.end();++i) {
99.156 colUpperBound(*i, value);
99.157 }
99.158 }
99.159 - template<class T>
99.160 - typename enable_if<typename T::value_type::second_type::LpCol,
99.161 + template<class T1>
99.162 + typename enable_if<typename T1::value_type::second_type::LpCol,
99.163 void>::type
99.164 - colUpperBound(T &t, Value value,dummy<1> = 1) {
99.165 - for(typename T::iterator i=t.begin();i!=t.end();++i) {
99.166 + colUpperBound(T1 &t, Value value,dummy<1> = 1) {
99.167 + for(typename T1::iterator i=t.begin();i!=t.end();++i) {
99.168 colUpperBound(i->second, value);
99.169 }
99.170 }
99.171 - template<class T>
99.172 - typename enable_if<typename T::MapIt::Value::LpCol,
99.173 + template<class T1>
99.174 + typename enable_if<typename T1::MapIt::Value::LpCol,
99.175 void>::type
99.176 - colUpperBound(T &t, Value value,dummy<2> = 2) {
99.177 - for(typename T::MapIt i(t); i!=INVALID; ++i){
99.178 + colUpperBound(T1 &t, Value value,dummy<2> = 2) {
99.179 + for(typename T1::MapIt i(t); i!=INVALID; ++i){
99.180 colUpperBound(*i, value);
99.181 }
99.182 }
99.183 @@ -1432,24 +1456,24 @@
99.184 template<class T>
99.185 void colBounds(T &t, Value lower, Value upper) { return 0;}
99.186 #else
99.187 - template<class T>
99.188 - typename enable_if<typename T::value_type::LpCol,void>::type
99.189 - colBounds(T &t, Value lower, Value upper,dummy<0> = 0) {
99.190 - for(typename T::iterator i=t.begin();i!=t.end();++i) {
99.191 + template<class T2>
99.192 + typename enable_if<typename T2::value_type::LpCol,void>::type
99.193 + colBounds(T2 &t, Value lower, Value upper,dummy<0> = 0) {
99.194 + for(typename T2::iterator i=t.begin();i!=t.end();++i) {
99.195 colBounds(*i, lower, upper);
99.196 }
99.197 }
99.198 - template<class T>
99.199 - typename enable_if<typename T::value_type::second_type::LpCol, void>::type
99.200 - colBounds(T &t, Value lower, Value upper,dummy<1> = 1) {
99.201 - for(typename T::iterator i=t.begin();i!=t.end();++i) {
99.202 + template<class T2>
99.203 + typename enable_if<typename T2::value_type::second_type::LpCol, void>::type
99.204 + colBounds(T2 &t, Value lower, Value upper,dummy<1> = 1) {
99.205 + for(typename T2::iterator i=t.begin();i!=t.end();++i) {
99.206 colBounds(i->second, lower, upper);
99.207 }
99.208 }
99.209 - template<class T>
99.210 - typename enable_if<typename T::MapIt::Value::LpCol, void>::type
99.211 - colBounds(T &t, Value lower, Value upper,dummy<2> = 2) {
99.212 - for(typename T::MapIt i(t); i!=INVALID; ++i){
99.213 + template<class T2>
99.214 + typename enable_if<typename T2::MapIt::Value::LpCol, void>::type
99.215 + colBounds(T2 &t, Value lower, Value upper,dummy<2> = 2) {
99.216 + for(typename T2::MapIt i(t); i!=INVALID; ++i){
99.217 colBounds(*i, lower, upper);
99.218 }
99.219 }
99.220 @@ -1534,6 +1558,9 @@
99.221 ///Clears the problem
99.222 void clear() { _clear(); }
99.223
99.224 + /// Sets the message level of the solver
99.225 + void messageLevel(MessageLevel level) { _messageLevel(level); }
99.226 +
99.227 ///@}
99.228
99.229 };
99.230 @@ -1666,7 +1693,7 @@
99.231 inline LpBase::Constr operator<=(const LpBase::Value &n,
99.232 const LpBase::Constr &c) {
99.233 LpBase::Constr tmp(c);
99.234 - LEMON_ASSERT(std::isnan(tmp.lowerBound()), "Wrong LP constraint");
99.235 + LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
99.236 tmp.lowerBound()=n;
99.237 return tmp;
99.238 }
99.239 @@ -1678,7 +1705,7 @@
99.240 const LpBase::Value &n)
99.241 {
99.242 LpBase::Constr tmp(c);
99.243 - LEMON_ASSERT(std::isnan(tmp.upperBound()), "Wrong LP constraint");
99.244 + LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
99.245 tmp.upperBound()=n;
99.246 return tmp;
99.247 }
99.248 @@ -1690,7 +1717,7 @@
99.249 inline LpBase::Constr operator>=(const LpBase::Value &n,
99.250 const LpBase::Constr &c) {
99.251 LpBase::Constr tmp(c);
99.252 - LEMON_ASSERT(std::isnan(tmp.upperBound()), "Wrong LP constraint");
99.253 + LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
99.254 tmp.upperBound()=n;
99.255 return tmp;
99.256 }
99.257 @@ -1702,7 +1729,7 @@
99.258 const LpBase::Value &n)
99.259 {
99.260 LpBase::Constr tmp(c);
99.261 - LEMON_ASSERT(std::isnan(tmp.lowerBound()), "Wrong LP constraint");
99.262 + LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
99.263 tmp.lowerBound()=n;
99.264 return tmp;
99.265 }
99.266 @@ -1775,15 +1802,15 @@
99.267
99.268 /// The problem types for primal and dual problems
99.269 enum ProblemType {
99.270 - ///Feasible solution hasn't been found (but may exist).
99.271 + /// = 0. Feasible solution hasn't been found (but may exist).
99.272 UNDEFINED = 0,
99.273 - ///The problem has no feasible solution
99.274 + /// = 1. The problem has no feasible solution.
99.275 INFEASIBLE = 1,
99.276 - ///Feasible solution found
99.277 + /// = 2. Feasible solution found.
99.278 FEASIBLE = 2,
99.279 - ///Optimal solution exists and found
99.280 + /// = 3. Optimal solution exists and found.
99.281 OPTIMAL = 3,
99.282 - ///The cost function is unbounded
99.283 + /// = 4. The cost function is unbounded.
99.284 UNBOUNDED = 4
99.285 };
99.286
99.287 @@ -1821,6 +1848,11 @@
99.288
99.289 public:
99.290
99.291 + ///Allocate a new LP problem instance
99.292 + virtual LpSolver* newSolver() const = 0;
99.293 + ///Make a copy of the LP problem
99.294 + virtual LpSolver* cloneSolver() const = 0;
99.295 +
99.296 ///\name Solve the LP
99.297
99.298 ///@{
99.299 @@ -1834,7 +1866,7 @@
99.300
99.301 ///@}
99.302
99.303 - ///\name Obtain the solution
99.304 + ///\name Obtain the Solution
99.305
99.306 ///@{
99.307
99.308 @@ -1935,13 +1967,8 @@
99.309 Value primal() const { return _getPrimalValue()+obj_const_comp;}
99.310 ///@}
99.311
99.312 - LpSolver* newSolver() {return _newSolver();}
99.313 - LpSolver* cloneSolver() {return _cloneSolver();}
99.314 -
99.315 protected:
99.316
99.317 - virtual LpSolver* _newSolver() const = 0;
99.318 - virtual LpSolver* _cloneSolver() const = 0;
99.319 };
99.320
99.321
99.322 @@ -1961,20 +1988,24 @@
99.323
99.324 /// The problem types for MIP problems
99.325 enum ProblemType {
99.326 - ///Feasible solution hasn't been found (but may exist).
99.327 + /// = 0. Feasible solution hasn't been found (but may exist).
99.328 UNDEFINED = 0,
99.329 - ///The problem has no feasible solution
99.330 + /// = 1. The problem has no feasible solution.
99.331 INFEASIBLE = 1,
99.332 - ///Feasible solution found
99.333 + /// = 2. Feasible solution found.
99.334 FEASIBLE = 2,
99.335 - ///Optimal solution exists and found
99.336 + /// = 3. Optimal solution exists and found.
99.337 OPTIMAL = 3,
99.338 - ///The cost function is unbounded
99.339 - ///
99.340 - ///The Mip or at least the relaxed problem is unbounded
99.341 + /// = 4. The cost function is unbounded.
99.342 + ///The Mip or at least the relaxed problem is unbounded.
99.343 UNBOUNDED = 4
99.344 };
99.345
99.346 + ///Allocate a new MIP problem instance
99.347 + virtual MipSolver* newSolver() const = 0;
99.348 + ///Make a copy of the MIP problem
99.349 + virtual MipSolver* cloneSolver() const = 0;
99.350 +
99.351 ///\name Solve the MIP
99.352
99.353 ///@{
99.354 @@ -1988,14 +2019,14 @@
99.355
99.356 ///@}
99.357
99.358 - ///\name Setting column type
99.359 + ///\name Set Column Type
99.360 ///@{
99.361
99.362 ///Possible variable (column) types (e.g. real, integer, binary etc.)
99.363 enum ColTypes {
99.364 - ///Continuous variable (default)
99.365 + /// = 0. Continuous variable (default).
99.366 REAL = 0,
99.367 - ///Integer variable
99.368 + /// = 1. Integer variable.
99.369 INTEGER = 1
99.370 };
99.371
99.372 @@ -2016,7 +2047,7 @@
99.373 }
99.374 ///@}
99.375
99.376 - ///\name Obtain the solution
99.377 + ///\name Obtain the Solution
99.378
99.379 ///@{
99.380
99.381 @@ -2062,15 +2093,6 @@
99.382 virtual Value _getSol(int i) const = 0;
99.383 virtual Value _getSolValue() const = 0;
99.384
99.385 - public:
99.386 -
99.387 - MipSolver* newSolver() {return _newSolver();}
99.388 - MipSolver* cloneSolver() {return _cloneSolver();}
99.389 -
99.390 - protected:
99.391 -
99.392 - virtual MipSolver* _newSolver() const = 0;
99.393 - virtual MipSolver* _cloneSolver() const = 0;
99.394 };
99.395
99.396
100.1 --- a/lemon/lp_skeleton.cc Mon Jan 12 23:11:39 2009 +0100
100.2 +++ b/lemon/lp_skeleton.cc Thu Nov 05 15:48:01 2009 +0100
100.3 @@ -32,6 +32,11 @@
100.4 return ++row_num;
100.5 }
100.6
100.7 + int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
100.8 + {
100.9 + return ++row_num;
100.10 + }
100.11 +
100.12 void SkeletonSolverBase::_eraseCol(int) {}
100.13 void SkeletonSolverBase::_eraseRow(int) {}
100.14
100.15 @@ -84,6 +89,8 @@
100.16 row_num = col_num = 0;
100.17 }
100.18
100.19 + void SkeletonSolverBase::_messageLevel(MessageLevel) {}
100.20 +
100.21 LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
100.22
100.23 LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
100.24 @@ -105,10 +112,10 @@
100.25 LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
100.26 { return BASIC; }
100.27
100.28 - LpSkeleton* LpSkeleton::_newSolver() const
100.29 + LpSkeleton* LpSkeleton::newSolver() const
100.30 { return static_cast<LpSkeleton*>(0); }
100.31
100.32 - LpSkeleton* LpSkeleton::_cloneSolver() const
100.33 + LpSkeleton* LpSkeleton::cloneSolver() const
100.34 { return static_cast<LpSkeleton*>(0); }
100.35
100.36 const char* LpSkeleton::_solverName() const { return "LpSkeleton"; }
100.37 @@ -122,10 +129,10 @@
100.38 MipSkeleton::ProblemType MipSkeleton::_getType() const
100.39 { return UNDEFINED; }
100.40
100.41 - MipSkeleton* MipSkeleton::_newSolver() const
100.42 + MipSkeleton* MipSkeleton::newSolver() const
100.43 { return static_cast<MipSkeleton*>(0); }
100.44
100.45 - MipSkeleton* MipSkeleton::_cloneSolver() const
100.46 + MipSkeleton* MipSkeleton::cloneSolver() const
100.47 { return static_cast<MipSkeleton*>(0); }
100.48
100.49 const char* MipSkeleton::_solverName() const { return "MipSkeleton"; }
101.1 --- a/lemon/lp_skeleton.h Mon Jan 12 23:11:39 2009 +0100
101.2 +++ b/lemon/lp_skeleton.h Thu Nov 05 15:48:01 2009 +0100
101.3 @@ -16,16 +16,22 @@
101.4 *
101.5 */
101.6
101.7 -#ifndef LEMON_LP_SKELETON
101.8 -#define LEMON_LP_SKELETON
101.9 +#ifndef LEMON_LP_SKELETON_H
101.10 +#define LEMON_LP_SKELETON_H
101.11
101.12 #include <lemon/lp_base.h>
101.13
101.14 ///\file
101.15 -///\brief A skeleton file to implement LP solver interfaces
101.16 +///\brief Skeleton file to implement LP/MIP solver interfaces
101.17 +///
101.18 +///The classes in this file do nothing, but they can serve as skeletons when
101.19 +///implementing an interface to new solvers.
101.20 namespace lemon {
101.21
101.22 - ///A skeleton class to implement LP solver interfaces
101.23 + ///A skeleton class to implement LP/MIP solver base interface
101.24 +
101.25 + ///This class does nothing, but it can serve as a skeleton when
101.26 + ///implementing an interface to new solvers.
101.27 class SkeletonSolverBase : public virtual LpBase {
101.28 int col_num,row_num;
101.29
101.30 @@ -39,6 +45,8 @@
101.31 /// \e
101.32 virtual int _addRow();
101.33 /// \e
101.34 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
101.35 + /// \e
101.36 virtual void _eraseCol(int i);
101.37 /// \e
101.38 virtual void _eraseRow(int i);
101.39 @@ -134,16 +142,24 @@
101.40 ///\e
101.41 virtual void _clear();
101.42
101.43 + ///\e
101.44 + virtual void _messageLevel(MessageLevel);
101.45 };
101.46
101.47 - /// \brief Interface for a skeleton LP solver
101.48 + /// \brief Skeleton class for an LP solver interface
101.49 ///
101.50 - /// This class implements an interface for a skeleton LP solver.
101.51 + ///This class does nothing, but it can serve as a skeleton when
101.52 + ///implementing an interface to new solvers.
101.53 +
101.54 ///\ingroup lp_group
101.55 - class LpSkeleton : public SkeletonSolverBase, public LpSolver {
101.56 + class LpSkeleton : public LpSolver, public SkeletonSolverBase {
101.57 public:
101.58 - LpSkeleton() : SkeletonSolverBase(), LpSolver() {}
101.59 -
101.60 + ///\e
101.61 + LpSkeleton() : LpSolver(), SkeletonSolverBase() {}
101.62 + ///\e
101.63 + virtual LpSkeleton* newSolver() const;
101.64 + ///\e
101.65 + virtual LpSkeleton* cloneSolver() const;
101.66 protected:
101.67
101.68 ///\e
101.69 @@ -173,57 +189,41 @@
101.70 virtual VarStatus _getRowStatus(int i) const;
101.71
101.72 ///\e
101.73 - virtual LpSkeleton* _newSolver() const;
101.74 - ///\e
101.75 - virtual LpSkeleton* _cloneSolver() const;
101.76 - ///\e
101.77 virtual const char* _solverName() const;
101.78
101.79 };
101.80
101.81 - /// \brief Interface for a skeleton MIP solver
101.82 + /// \brief Skeleton class for a MIP solver interface
101.83 ///
101.84 - /// This class implements an interface for a skeleton MIP solver.
101.85 + ///This class does nothing, but it can serve as a skeleton when
101.86 + ///implementing an interface to new solvers.
101.87 ///\ingroup lp_group
101.88 - class MipSkeleton : public SkeletonSolverBase, public MipSolver {
101.89 + class MipSkeleton : public MipSolver, public SkeletonSolverBase {
101.90 public:
101.91 - MipSkeleton() : SkeletonSolverBase(), MipSolver() {}
101.92 + ///\e
101.93 + MipSkeleton() : MipSolver(), SkeletonSolverBase() {}
101.94 + ///\e
101.95 + virtual MipSkeleton* newSolver() const;
101.96 + ///\e
101.97 + virtual MipSkeleton* cloneSolver() const;
101.98
101.99 protected:
101.100 ///\e
101.101 -
101.102 - ///\bug Wrong interface
101.103 - ///
101.104 virtual SolveExitStatus _solve();
101.105
101.106 ///\e
101.107 -
101.108 - ///\bug Wrong interface
101.109 - ///
101.110 virtual Value _getSol(int i) const;
101.111
101.112 ///\e
101.113 -
101.114 - ///\bug Wrong interface
101.115 - ///
101.116 virtual Value _getSolValue() const;
101.117
101.118 ///\e
101.119 -
101.120 - ///\bug Wrong interface
101.121 - ///
101.122 virtual ProblemType _getType() const;
101.123
101.124 ///\e
101.125 - virtual MipSkeleton* _newSolver() const;
101.126 -
101.127 - ///\e
101.128 - virtual MipSkeleton* _cloneSolver() const;
101.129 - ///\e
101.130 virtual const char* _solverName() const;
101.131 -
101.132 };
101.133
101.134 } //namespace lemon
101.135
101.136 -#endif // LEMON_LP_SKELETON
101.137 +#endif
102.1 --- a/lemon/maps.h Mon Jan 12 23:11:39 2009 +0100
102.2 +++ b/lemon/maps.h Thu Nov 05 15:48:01 2009 +0100
102.3 @@ -22,6 +22,7 @@
102.4 #include <iterator>
102.5 #include <functional>
102.6 #include <vector>
102.7 +#include <map>
102.8
102.9 #include <lemon/core.h>
102.10
102.11 @@ -29,8 +30,6 @@
102.12 ///\ingroup maps
102.13 ///\brief Miscellaneous property maps
102.14
102.15 -#include <map>
102.16 -
102.17 namespace lemon {
102.18
102.19 /// \addtogroup maps
102.20 @@ -57,15 +56,16 @@
102.21 /// its type definitions, or if you have to provide a writable map,
102.22 /// but data written to it is not required (i.e. it will be sent to
102.23 /// <tt>/dev/null</tt>).
102.24 - /// It conforms the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
102.25 + /// It conforms to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
102.26 ///
102.27 /// \sa ConstMap
102.28 template<typename K, typename V>
102.29 class NullMap : public MapBase<K, V> {
102.30 public:
102.31 - typedef MapBase<K, V> Parent;
102.32 - typedef typename Parent::Key Key;
102.33 - typedef typename Parent::Value Value;
102.34 + ///\e
102.35 + typedef K Key;
102.36 + ///\e
102.37 + typedef V Value;
102.38
102.39 /// Gives back a default constructed element.
102.40 Value operator[](const Key&) const { return Value(); }
102.41 @@ -89,7 +89,7 @@
102.42 /// value to each key.
102.43 ///
102.44 /// In other aspects it is equivalent to \c NullMap.
102.45 - /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
102.46 + /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
102.47 /// concept, but it absorbs the data written to it.
102.48 ///
102.49 /// The simplest way of using this map is through the constMap()
102.50 @@ -102,9 +102,10 @@
102.51 private:
102.52 V _value;
102.53 public:
102.54 - typedef MapBase<K, V> Parent;
102.55 - typedef typename Parent::Key Key;
102.56 - typedef typename Parent::Value Value;
102.57 + ///\e
102.58 + typedef K Key;
102.59 + ///\e
102.60 + typedef V Value;
102.61
102.62 /// Default constructor
102.63
102.64 @@ -157,7 +158,7 @@
102.65 /// value to each key.
102.66 ///
102.67 /// In other aspects it is equivalent to \c NullMap.
102.68 - /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
102.69 + /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
102.70 /// concept, but it absorbs the data written to it.
102.71 ///
102.72 /// The simplest way of using this map is through the constMap()
102.73 @@ -168,9 +169,10 @@
102.74 template<typename K, typename V, V v>
102.75 class ConstMap<K, Const<V, v> > : public MapBase<K, V> {
102.76 public:
102.77 - typedef MapBase<K, V> Parent;
102.78 - typedef typename Parent::Key Key;
102.79 - typedef typename Parent::Value Value;
102.80 + ///\e
102.81 + typedef K Key;
102.82 + ///\e
102.83 + typedef V Value;
102.84
102.85 /// Constructor.
102.86 ConstMap() {}
102.87 @@ -202,9 +204,10 @@
102.88 template <typename T>
102.89 class IdentityMap : public MapBase<T, T> {
102.90 public:
102.91 - typedef MapBase<T, T> Parent;
102.92 - typedef typename Parent::Key Key;
102.93 - typedef typename Parent::Value Value;
102.94 + ///\e
102.95 + typedef T Key;
102.96 + ///\e
102.97 + typedef T Value;
102.98
102.99 /// Gives back the given value without any modification.
102.100 Value operator[](const Key &k) const {
102.101 @@ -229,7 +232,7 @@
102.102 /// values to integer keys from the range <tt>[0..size-1]</tt>.
102.103 /// It can be used with some data structures, for example
102.104 /// \c UnionFind, \c BinHeap, when the used items are small
102.105 - /// integers. This map conforms the \ref concepts::ReferenceMap
102.106 + /// integers. This map conforms to the \ref concepts::ReferenceMap
102.107 /// "ReferenceMap" concept.
102.108 ///
102.109 /// The simplest way of using this map is through the rangeMap()
102.110 @@ -245,11 +248,10 @@
102.111
102.112 public:
102.113
102.114 - typedef MapBase<int, V> Parent;
102.115 /// Key type
102.116 - typedef typename Parent::Key Key;
102.117 + typedef int Key;
102.118 /// Value type
102.119 - typedef typename Parent::Value Value;
102.120 + typedef V Value;
102.121 /// Reference type
102.122 typedef typename Vector::reference Reference;
102.123 /// Const reference type
102.124 @@ -338,7 +340,7 @@
102.125 /// that you can specify a default value for the keys that are not
102.126 /// stored actually. This value can be different from the default
102.127 /// contructed value (i.e. \c %Value()).
102.128 - /// This type conforms the \ref concepts::ReferenceMap "ReferenceMap"
102.129 + /// This type conforms to the \ref concepts::ReferenceMap "ReferenceMap"
102.130 /// concept.
102.131 ///
102.132 /// This map is useful if a default value should be assigned to most of
102.133 @@ -353,17 +355,16 @@
102.134 ///
102.135 /// The simplest way of using this map is through the sparseMap()
102.136 /// function.
102.137 - template <typename K, typename V, typename Compare = std::less<K> >
102.138 + template <typename K, typename V, typename Comp = std::less<K> >
102.139 class SparseMap : public MapBase<K, V> {
102.140 template <typename K1, typename V1, typename C1>
102.141 friend class SparseMap;
102.142 public:
102.143
102.144 - typedef MapBase<K, V> Parent;
102.145 /// Key type
102.146 - typedef typename Parent::Key Key;
102.147 + typedef K Key;
102.148 /// Value type
102.149 - typedef typename Parent::Value Value;
102.150 + typedef V Value;
102.151 /// Reference type
102.152 typedef Value& Reference;
102.153 /// Const reference type
102.154 @@ -373,7 +374,7 @@
102.155
102.156 private:
102.157
102.158 - typedef std::map<K, V, Compare> Map;
102.159 + typedef std::map<K, V, Comp> Map;
102.160 Map _map;
102.161 Value _value;
102.162
102.163 @@ -489,14 +490,15 @@
102.164 const M1 &_m1;
102.165 const M2 &_m2;
102.166 public:
102.167 - typedef MapBase<typename M2::Key, typename M1::Value> Parent;
102.168 - typedef typename Parent::Key Key;
102.169 - typedef typename Parent::Value Value;
102.170 + ///\e
102.171 + typedef typename M2::Key Key;
102.172 + ///\e
102.173 + typedef typename M1::Value Value;
102.174
102.175 /// Constructor
102.176 ComposeMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
102.177
102.178 - /// \e
102.179 + ///\e
102.180 typename MapTraits<M1>::ConstReturnValue
102.181 operator[](const Key &k) const { return _m1[_m2[k]]; }
102.182 };
102.183 @@ -545,14 +547,15 @@
102.184 const M2 &_m2;
102.185 F _f;
102.186 public:
102.187 - typedef MapBase<typename M1::Key, V> Parent;
102.188 - typedef typename Parent::Key Key;
102.189 - typedef typename Parent::Value Value;
102.190 + ///\e
102.191 + typedef typename M1::Key Key;
102.192 + ///\e
102.193 + typedef V Value;
102.194
102.195 /// Constructor
102.196 CombineMap(const M1 &m1, const M2 &m2, const F &f = F())
102.197 : _m1(m1), _m2(m2), _f(f) {}
102.198 - /// \e
102.199 + ///\e
102.200 Value operator[](const Key &k) const { return _f(_m1[k],_m2[k]); }
102.201 };
102.202
102.203 @@ -615,13 +618,14 @@
102.204 class FunctorToMap : public MapBase<K, V> {
102.205 F _f;
102.206 public:
102.207 - typedef MapBase<K, V> Parent;
102.208 - typedef typename Parent::Key Key;
102.209 - typedef typename Parent::Value Value;
102.210 + ///\e
102.211 + typedef K Key;
102.212 + ///\e
102.213 + typedef V Value;
102.214
102.215 /// Constructor
102.216 FunctorToMap(const F &f = F()) : _f(f) {}
102.217 - /// \e
102.218 + ///\e
102.219 Value operator[](const Key &k) const { return _f(k); }
102.220 };
102.221
102.222 @@ -669,18 +673,19 @@
102.223 class MapToFunctor : public MapBase<typename M::Key, typename M::Value> {
102.224 const M &_m;
102.225 public:
102.226 - typedef MapBase<typename M::Key, typename M::Value> Parent;
102.227 - typedef typename Parent::Key Key;
102.228 - typedef typename Parent::Value Value;
102.229 -
102.230 - typedef typename Parent::Key argument_type;
102.231 - typedef typename Parent::Value result_type;
102.232 + ///\e
102.233 + typedef typename M::Key Key;
102.234 + ///\e
102.235 + typedef typename M::Value Value;
102.236 +
102.237 + typedef typename M::Key argument_type;
102.238 + typedef typename M::Value result_type;
102.239
102.240 /// Constructor
102.241 MapToFunctor(const M &m) : _m(m) {}
102.242 - /// \e
102.243 + ///\e
102.244 Value operator()(const Key &k) const { return _m[k]; }
102.245 - /// \e
102.246 + ///\e
102.247 Value operator[](const Key &k) const { return _m[k]; }
102.248 };
102.249
102.250 @@ -701,7 +706,7 @@
102.251 /// "readable map" to another type using the default conversion.
102.252 /// The \c Key type of it is inherited from \c M and the \c Value
102.253 /// type is \c V.
102.254 - /// This type conforms the \ref concepts::ReadMap "ReadMap" concept.
102.255 + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
102.256 ///
102.257 /// The simplest way of using this map is through the convertMap()
102.258 /// function.
102.259 @@ -709,9 +714,10 @@
102.260 class ConvertMap : public MapBase<typename M::Key, V> {
102.261 const M &_m;
102.262 public:
102.263 - typedef MapBase<typename M::Key, V> Parent;
102.264 - typedef typename Parent::Key Key;
102.265 - typedef typename Parent::Value Value;
102.266 + ///\e
102.267 + typedef typename M::Key Key;
102.268 + ///\e
102.269 + typedef V Value;
102.270
102.271 /// Constructor
102.272
102.273 @@ -719,7 +725,7 @@
102.274 /// \param m The underlying map.
102.275 ConvertMap(const M &m) : _m(m) {}
102.276
102.277 - /// \e
102.278 + ///\e
102.279 Value operator[](const Key &k) const { return _m[k]; }
102.280 };
102.281
102.282 @@ -751,9 +757,10 @@
102.283 M1 &_m1;
102.284 M2 &_m2;
102.285 public:
102.286 - typedef MapBase<typename M1::Key, typename M1::Value> Parent;
102.287 - typedef typename Parent::Key Key;
102.288 - typedef typename Parent::Value Value;
102.289 + ///\e
102.290 + typedef typename M1::Key Key;
102.291 + ///\e
102.292 + typedef typename M1::Value Value;
102.293
102.294 /// Constructor
102.295 ForkMap(M1 &m1, M2 &m2) : _m1(m1), _m2(m2) {}
102.296 @@ -797,13 +804,14 @@
102.297 const M1 &_m1;
102.298 const M2 &_m2;
102.299 public:
102.300 - typedef MapBase<typename M1::Key, typename M1::Value> Parent;
102.301 - typedef typename Parent::Key Key;
102.302 - typedef typename Parent::Value Value;
102.303 + ///\e
102.304 + typedef typename M1::Key Key;
102.305 + ///\e
102.306 + typedef typename M1::Value Value;
102.307
102.308 /// Constructor
102.309 AddMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
102.310 - /// \e
102.311 + ///\e
102.312 Value operator[](const Key &k) const { return _m1[k]+_m2[k]; }
102.313 };
102.314
102.315 @@ -845,13 +853,14 @@
102.316 const M1 &_m1;
102.317 const M2 &_m2;
102.318 public:
102.319 - typedef MapBase<typename M1::Key, typename M1::Value> Parent;
102.320 - typedef typename Parent::Key Key;
102.321 - typedef typename Parent::Value Value;
102.322 + ///\e
102.323 + typedef typename M1::Key Key;
102.324 + ///\e
102.325 + typedef typename M1::Value Value;
102.326
102.327 /// Constructor
102.328 SubMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
102.329 - /// \e
102.330 + ///\e
102.331 Value operator[](const Key &k) const { return _m1[k]-_m2[k]; }
102.332 };
102.333
102.334 @@ -894,13 +903,14 @@
102.335 const M1 &_m1;
102.336 const M2 &_m2;
102.337 public:
102.338 - typedef MapBase<typename M1::Key, typename M1::Value> Parent;
102.339 - typedef typename Parent::Key Key;
102.340 - typedef typename Parent::Value Value;
102.341 + ///\e
102.342 + typedef typename M1::Key Key;
102.343 + ///\e
102.344 + typedef typename M1::Value Value;
102.345
102.346 /// Constructor
102.347 MulMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
102.348 - /// \e
102.349 + ///\e
102.350 Value operator[](const Key &k) const { return _m1[k]*_m2[k]; }
102.351 };
102.352
102.353 @@ -942,13 +952,14 @@
102.354 const M1 &_m1;
102.355 const M2 &_m2;
102.356 public:
102.357 - typedef MapBase<typename M1::Key, typename M1::Value> Parent;
102.358 - typedef typename Parent::Key Key;
102.359 - typedef typename Parent::Value Value;
102.360 + ///\e
102.361 + typedef typename M1::Key Key;
102.362 + ///\e
102.363 + typedef typename M1::Value Value;
102.364
102.365 /// Constructor
102.366 DivMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
102.367 - /// \e
102.368 + ///\e
102.369 Value operator[](const Key &k) const { return _m1[k]/_m2[k]; }
102.370 };
102.371
102.372 @@ -992,9 +1003,10 @@
102.373 const M &_m;
102.374 C _v;
102.375 public:
102.376 - typedef MapBase<typename M::Key, typename M::Value> Parent;
102.377 - typedef typename Parent::Key Key;
102.378 - typedef typename Parent::Value Value;
102.379 + ///\e
102.380 + typedef typename M::Key Key;
102.381 + ///\e
102.382 + typedef typename M::Value Value;
102.383
102.384 /// Constructor
102.385
102.386 @@ -1002,7 +1014,7 @@
102.387 /// \param m The undelying map.
102.388 /// \param v The constant value.
102.389 ShiftMap(const M &m, const C &v) : _m(m), _v(v) {}
102.390 - /// \e
102.391 + ///\e
102.392 Value operator[](const Key &k) const { return _m[k]+_v; }
102.393 };
102.394
102.395 @@ -1022,9 +1034,10 @@
102.396 M &_m;
102.397 C _v;
102.398 public:
102.399 - typedef MapBase<typename M::Key, typename M::Value> Parent;
102.400 - typedef typename Parent::Key Key;
102.401 - typedef typename Parent::Value Value;
102.402 + ///\e
102.403 + typedef typename M::Key Key;
102.404 + ///\e
102.405 + typedef typename M::Value Value;
102.406
102.407 /// Constructor
102.408
102.409 @@ -1032,9 +1045,9 @@
102.410 /// \param m The undelying map.
102.411 /// \param v The constant value.
102.412 ShiftWriteMap(M &m, const C &v) : _m(m), _v(v) {}
102.413 - /// \e
102.414 + ///\e
102.415 Value operator[](const Key &k) const { return _m[k]+_v; }
102.416 - /// \e
102.417 + ///\e
102.418 void set(const Key &k, const Value &v) { _m.set(k, v-_v); }
102.419 };
102.420
102.421 @@ -1093,9 +1106,10 @@
102.422 const M &_m;
102.423 C _v;
102.424 public:
102.425 - typedef MapBase<typename M::Key, typename M::Value> Parent;
102.426 - typedef typename Parent::Key Key;
102.427 - typedef typename Parent::Value Value;
102.428 + ///\e
102.429 + typedef typename M::Key Key;
102.430 + ///\e
102.431 + typedef typename M::Value Value;
102.432
102.433 /// Constructor
102.434
102.435 @@ -1103,7 +1117,7 @@
102.436 /// \param m The undelying map.
102.437 /// \param v The constant value.
102.438 ScaleMap(const M &m, const C &v) : _m(m), _v(v) {}
102.439 - /// \e
102.440 + ///\e
102.441 Value operator[](const Key &k) const { return _v*_m[k]; }
102.442 };
102.443
102.444 @@ -1124,9 +1138,10 @@
102.445 M &_m;
102.446 C _v;
102.447 public:
102.448 - typedef MapBase<typename M::Key, typename M::Value> Parent;
102.449 - typedef typename Parent::Key Key;
102.450 - typedef typename Parent::Value Value;
102.451 + ///\e
102.452 + typedef typename M::Key Key;
102.453 + ///\e
102.454 + typedef typename M::Value Value;
102.455
102.456 /// Constructor
102.457
102.458 @@ -1134,9 +1149,9 @@
102.459 /// \param m The undelying map.
102.460 /// \param v The constant value.
102.461 ScaleWriteMap(M &m, const C &v) : _m(m), _v(v) {}
102.462 - /// \e
102.463 + ///\e
102.464 Value operator[](const Key &k) const { return _v*_m[k]; }
102.465 - /// \e
102.466 + ///\e
102.467 void set(const Key &k, const Value &v) { _m.set(k, v/_v); }
102.468 };
102.469
102.470 @@ -1193,13 +1208,14 @@
102.471 class NegMap : public MapBase<typename M::Key, typename M::Value> {
102.472 const M& _m;
102.473 public:
102.474 - typedef MapBase<typename M::Key, typename M::Value> Parent;
102.475 - typedef typename Parent::Key Key;
102.476 - typedef typename Parent::Value Value;
102.477 + ///\e
102.478 + typedef typename M::Key Key;
102.479 + ///\e
102.480 + typedef typename M::Value Value;
102.481
102.482 /// Constructor
102.483 NegMap(const M &m) : _m(m) {}
102.484 - /// \e
102.485 + ///\e
102.486 Value operator[](const Key &k) const { return -_m[k]; }
102.487 };
102.488
102.489 @@ -1228,15 +1244,16 @@
102.490 class NegWriteMap : public MapBase<typename M::Key, typename M::Value> {
102.491 M &_m;
102.492 public:
102.493 - typedef MapBase<typename M::Key, typename M::Value> Parent;
102.494 - typedef typename Parent::Key Key;
102.495 - typedef typename Parent::Value Value;
102.496 + ///\e
102.497 + typedef typename M::Key Key;
102.498 + ///\e
102.499 + typedef typename M::Value Value;
102.500
102.501 /// Constructor
102.502 NegWriteMap(M &m) : _m(m) {}
102.503 - /// \e
102.504 + ///\e
102.505 Value operator[](const Key &k) const { return -_m[k]; }
102.506 - /// \e
102.507 + ///\e
102.508 void set(const Key &k, const Value &v) { _m.set(k, -v); }
102.509 };
102.510
102.511 @@ -1282,13 +1299,14 @@
102.512 class AbsMap : public MapBase<typename M::Key, typename M::Value> {
102.513 const M &_m;
102.514 public:
102.515 - typedef MapBase<typename M::Key, typename M::Value> Parent;
102.516 - typedef typename Parent::Key Key;
102.517 - typedef typename Parent::Value Value;
102.518 + ///\e
102.519 + typedef typename M::Key Key;
102.520 + ///\e
102.521 + typedef typename M::Value Value;
102.522
102.523 /// Constructor
102.524 AbsMap(const M &m) : _m(m) {}
102.525 - /// \e
102.526 + ///\e
102.527 Value operator[](const Key &k) const {
102.528 Value tmp = _m[k];
102.529 return tmp >= 0 ? tmp : -tmp;
102.530 @@ -1337,9 +1355,10 @@
102.531 template <typename K>
102.532 class TrueMap : public MapBase<K, bool> {
102.533 public:
102.534 - typedef MapBase<K, bool> Parent;
102.535 - typedef typename Parent::Key Key;
102.536 - typedef typename Parent::Value Value;
102.537 + ///\e
102.538 + typedef K Key;
102.539 + ///\e
102.540 + typedef bool Value;
102.541
102.542 /// Gives back \c true.
102.543 Value operator[](const Key&) const { return true; }
102.544 @@ -1374,9 +1393,10 @@
102.545 template <typename K>
102.546 class FalseMap : public MapBase<K, bool> {
102.547 public:
102.548 - typedef MapBase<K, bool> Parent;
102.549 - typedef typename Parent::Key Key;
102.550 - typedef typename Parent::Value Value;
102.551 + ///\e
102.552 + typedef K Key;
102.553 + ///\e
102.554 + typedef bool Value;
102.555
102.556 /// Gives back \c false.
102.557 Value operator[](const Key&) const { return false; }
102.558 @@ -1419,13 +1439,14 @@
102.559 const M1 &_m1;
102.560 const M2 &_m2;
102.561 public:
102.562 - typedef MapBase<typename M1::Key, bool> Parent;
102.563 - typedef typename Parent::Key Key;
102.564 - typedef typename Parent::Value Value;
102.565 + ///\e
102.566 + typedef typename M1::Key Key;
102.567 + ///\e
102.568 + typedef bool Value;
102.569
102.570 /// Constructor
102.571 AndMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
102.572 - /// \e
102.573 + ///\e
102.574 Value operator[](const Key &k) const { return _m1[k]&&_m2[k]; }
102.575 };
102.576
102.577 @@ -1467,13 +1488,14 @@
102.578 const M1 &_m1;
102.579 const M2 &_m2;
102.580 public:
102.581 - typedef MapBase<typename M1::Key, bool> Parent;
102.582 - typedef typename Parent::Key Key;
102.583 - typedef typename Parent::Value Value;
102.584 + ///\e
102.585 + typedef typename M1::Key Key;
102.586 + ///\e
102.587 + typedef bool Value;
102.588
102.589 /// Constructor
102.590 OrMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
102.591 - /// \e
102.592 + ///\e
102.593 Value operator[](const Key &k) const { return _m1[k]||_m2[k]; }
102.594 };
102.595
102.596 @@ -1506,13 +1528,14 @@
102.597 class NotMap : public MapBase<typename M::Key, bool> {
102.598 const M &_m;
102.599 public:
102.600 - typedef MapBase<typename M::Key, bool> Parent;
102.601 - typedef typename Parent::Key Key;
102.602 - typedef typename Parent::Value Value;
102.603 + ///\e
102.604 + typedef typename M::Key Key;
102.605 + ///\e
102.606 + typedef bool Value;
102.607
102.608 /// Constructor
102.609 NotMap(const M &m) : _m(m) {}
102.610 - /// \e
102.611 + ///\e
102.612 Value operator[](const Key &k) const { return !_m[k]; }
102.613 };
102.614
102.615 @@ -1532,15 +1555,16 @@
102.616 class NotWriteMap : public MapBase<typename M::Key, bool> {
102.617 M &_m;
102.618 public:
102.619 - typedef MapBase<typename M::Key, bool> Parent;
102.620 - typedef typename Parent::Key Key;
102.621 - typedef typename Parent::Value Value;
102.622 + ///\e
102.623 + typedef typename M::Key Key;
102.624 + ///\e
102.625 + typedef bool Value;
102.626
102.627 /// Constructor
102.628 NotWriteMap(M &m) : _m(m) {}
102.629 - /// \e
102.630 + ///\e
102.631 Value operator[](const Key &k) const { return !_m[k]; }
102.632 - /// \e
102.633 + ///\e
102.634 void set(const Key &k, bool v) { _m.set(k, !v); }
102.635 };
102.636
102.637 @@ -1595,13 +1619,14 @@
102.638 const M1 &_m1;
102.639 const M2 &_m2;
102.640 public:
102.641 - typedef MapBase<typename M1::Key, bool> Parent;
102.642 - typedef typename Parent::Key Key;
102.643 - typedef typename Parent::Value Value;
102.644 + ///\e
102.645 + typedef typename M1::Key Key;
102.646 + ///\e
102.647 + typedef bool Value;
102.648
102.649 /// Constructor
102.650 EqualMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
102.651 - /// \e
102.652 + ///\e
102.653 Value operator[](const Key &k) const { return _m1[k]==_m2[k]; }
102.654 };
102.655
102.656 @@ -1643,13 +1668,14 @@
102.657 const M1 &_m1;
102.658 const M2 &_m2;
102.659 public:
102.660 - typedef MapBase<typename M1::Key, bool> Parent;
102.661 - typedef typename Parent::Key Key;
102.662 - typedef typename Parent::Value Value;
102.663 + ///\e
102.664 + typedef typename M1::Key Key;
102.665 + ///\e
102.666 + typedef bool Value;
102.667
102.668 /// Constructor
102.669 LessMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
102.670 - /// \e
102.671 + ///\e
102.672 Value operator[](const Key &k) const { return _m1[k]<_m2[k]; }
102.673 };
102.674
102.675 @@ -1705,24 +1731,27 @@
102.676 /// The simplest way of using this map is through the loggerBoolMap()
102.677 /// function.
102.678 ///
102.679 - /// \tparam It The type of the iterator.
102.680 - /// \tparam Ke The key type of the map. The default value set
102.681 + /// \tparam IT The type of the iterator.
102.682 + /// \tparam KEY The key type of the map. The default value set
102.683 /// according to the iterator type should work in most cases.
102.684 ///
102.685 /// \note The container of the iterator must contain enough space
102.686 /// for the elements or the iterator should be an inserter iterator.
102.687 #ifdef DOXYGEN
102.688 - template <typename It, typename Ke>
102.689 + template <typename IT, typename KEY>
102.690 #else
102.691 - template <typename It,
102.692 - typename Ke=typename _maps_bits::IteratorTraits<It>::Value>
102.693 + template <typename IT,
102.694 + typename KEY = typename _maps_bits::IteratorTraits<IT>::Value>
102.695 #endif
102.696 - class LoggerBoolMap {
102.697 + class LoggerBoolMap : public MapBase<KEY, bool> {
102.698 public:
102.699 - typedef It Iterator;
102.700 -
102.701 - typedef Ke Key;
102.702 +
102.703 + ///\e
102.704 + typedef KEY Key;
102.705 + ///\e
102.706 typedef bool Value;
102.707 + ///\e
102.708 + typedef IT Iterator;
102.709
102.710 /// Constructor
102.711 LoggerBoolMap(Iterator it)
102.712 @@ -1760,11 +1789,11 @@
102.713 /// order of Dfs algorithm, as the following examples show.
102.714 /// \code
102.715 /// std::vector<Node> v;
102.716 - /// dfs(g,s).processedMap(loggerBoolMap(std::back_inserter(v))).run();
102.717 + /// dfs(g).processedMap(loggerBoolMap(std::back_inserter(v))).run(s);
102.718 /// \endcode
102.719 /// \code
102.720 /// std::vector<Node> v(countNodes(g));
102.721 - /// dfs(g,s).processedMap(loggerBoolMap(v.begin())).run();
102.722 + /// dfs(g).processedMap(loggerBoolMap(v.begin())).run(s);
102.723 /// \endcode
102.724 ///
102.725 /// \note The container of the iterator must contain enough space
102.726 @@ -1785,23 +1814,36 @@
102.727 /// \addtogroup graph_maps
102.728 /// @{
102.729
102.730 - /// Provides an immutable and unique id for each item in the graph.
102.731 -
102.732 - /// The IdMap class provides a unique and immutable id for each item of the
102.733 - /// same type (e.g. node) in the graph. This id is <ul><li>\b unique:
102.734 - /// different items (nodes) get different ids <li>\b immutable: the id of an
102.735 - /// item (node) does not change (even if you delete other nodes). </ul>
102.736 - /// Through this map you get access (i.e. can read) the inner id values of
102.737 - /// the items stored in the graph. This map can be inverted with its member
102.738 - /// class \c InverseMap or with the \c operator() member.
102.739 + /// \brief Provides an immutable and unique id for each item in a graph.
102.740 ///
102.741 - template <typename _Graph, typename _Item>
102.742 - class IdMap {
102.743 + /// IdMap provides a unique and immutable id for each item of the
102.744 + /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
102.745 + /// - \b unique: different items get different ids,
102.746 + /// - \b immutable: the id of an item does not change (even if you
102.747 + /// delete other nodes).
102.748 + ///
102.749 + /// Using this map you get access (i.e. can read) the inner id values of
102.750 + /// the items stored in the graph, which is returned by the \c id()
102.751 + /// function of the graph. This map can be inverted with its member
102.752 + /// class \c InverseMap or with the \c operator()() member.
102.753 + ///
102.754 + /// \tparam GR The graph type.
102.755 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
102.756 + /// \c GR::Edge).
102.757 + ///
102.758 + /// \see RangeIdMap
102.759 + template <typename GR, typename K>
102.760 + class IdMap : public MapBase<K, int> {
102.761 public:
102.762 - typedef _Graph Graph;
102.763 + /// The graph type of IdMap.
102.764 + typedef GR Graph;
102.765 + typedef GR Digraph;
102.766 + /// The key type of IdMap (\c Node, \c Arc or \c Edge).
102.767 + typedef K Item;
102.768 + /// The key type of IdMap (\c Node, \c Arc or \c Edge).
102.769 + typedef K Key;
102.770 + /// The value type of IdMap.
102.771 typedef int Value;
102.772 - typedef _Item Item;
102.773 - typedef _Item Key;
102.774
102.775 /// \brief Constructor.
102.776 ///
102.777 @@ -1813,9 +1855,9 @@
102.778 /// Gives back the immutable and unique \e id of the item.
102.779 int operator[](const Item& item) const { return _graph->id(item);}
102.780
102.781 - /// \brief Gives back the item by its id.
102.782 + /// \brief Gives back the \e item by its id.
102.783 ///
102.784 - /// Gives back the item by its id.
102.785 + /// Gives back the \e item by its id.
102.786 Item operator()(int id) { return _graph->fromId(id, Item()); }
102.787
102.788 private:
102.789 @@ -1823,9 +1865,11 @@
102.790
102.791 public:
102.792
102.793 - /// \brief The class represents the inverse of its owner (IdMap).
102.794 + /// \brief The inverse map type of IdMap.
102.795 ///
102.796 - /// The class represents the inverse of its owner (IdMap).
102.797 + /// The inverse map type of IdMap. The subscript operator gives back
102.798 + /// an item by its id.
102.799 + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
102.800 /// \see inverse()
102.801 class InverseMap {
102.802 public:
102.803 @@ -1840,10 +1884,9 @@
102.804 /// Constructor for creating an id-to-item map.
102.805 explicit InverseMap(const IdMap& map) : _graph(map._graph) {}
102.806
102.807 - /// \brief Gives back the given item from its id.
102.808 + /// \brief Gives back an item by its id.
102.809 ///
102.810 - /// Gives back the given item from its id.
102.811 - ///
102.812 + /// Gives back an item by its id.
102.813 Item operator[](int id) const { return _graph->fromId(id, Item());}
102.814
102.815 private:
102.816 @@ -1854,165 +1897,220 @@
102.817 ///
102.818 /// Gives back the inverse of the IdMap.
102.819 InverseMap inverse() const { return InverseMap(*_graph);}
102.820 -
102.821 };
102.822
102.823 -
102.824 - /// \brief General invertable graph-map type.
102.825 -
102.826 - /// This type provides simple invertable graph-maps.
102.827 - /// The InvertableMap wraps an arbitrary ReadWriteMap
102.828 - /// and if a key is set to a new value then store it
102.829 - /// in the inverse map.
102.830 + /// \brief Returns an \c IdMap class.
102.831 ///
102.832 - /// The values of the map can be accessed
102.833 - /// with stl compatible forward iterator.
102.834 + /// This function just returns an \c IdMap class.
102.835 + /// \relates IdMap
102.836 + template <typename K, typename GR>
102.837 + inline IdMap<GR, K> idMap(const GR& graph) {
102.838 + return IdMap<GR, K>(graph);
102.839 + }
102.840 +
102.841 + /// \brief General cross reference graph map type.
102.842 +
102.843 + /// This class provides simple invertable graph maps.
102.844 + /// It wraps a standard graph map (\c NodeMap, \c ArcMap or \c EdgeMap)
102.845 + /// and if a key is set to a new value, then stores it in the inverse map.
102.846 + /// The graph items can be accessed by their values either using
102.847 + /// \c InverseMap or \c operator()(), and the values of the map can be
102.848 + /// accessed with an STL compatible forward iterator (\c ValueIt).
102.849 + ///
102.850 + /// This map is intended to be used when all associated values are
102.851 + /// different (the map is actually invertable) or there are only a few
102.852 + /// items with the same value.
102.853 + /// Otherwise consider to use \c IterableValueMap, which is more
102.854 + /// suitable and more efficient for such cases. It provides iterators
102.855 + /// to traverse the items with the same associated value, however
102.856 + /// it does not have \c InverseMap.
102.857 ///
102.858 - /// \tparam _Graph The graph type.
102.859 - /// \tparam _Item The item type of the graph.
102.860 - /// \tparam _Value The value type of the map.
102.861 + /// This type is not reference map, so it cannot be modified with
102.862 + /// the subscript operator.
102.863 + ///
102.864 + /// \tparam GR The graph type.
102.865 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
102.866 + /// \c GR::Edge).
102.867 + /// \tparam V The value type of the map.
102.868 ///
102.869 /// \see IterableValueMap
102.870 - template <typename _Graph, typename _Item, typename _Value>
102.871 - class InvertableMap
102.872 - : protected ItemSetTraits<_Graph, _Item>::template Map<_Value>::Type {
102.873 + template <typename GR, typename K, typename V>
102.874 + class CrossRefMap
102.875 + : protected ItemSetTraits<GR, K>::template Map<V>::Type {
102.876 private:
102.877
102.878 - typedef typename ItemSetTraits<_Graph, _Item>::
102.879 - template Map<_Value>::Type Map;
102.880 - typedef _Graph Graph;
102.881 -
102.882 - typedef std::map<_Value, _Item> Container;
102.883 + typedef typename ItemSetTraits<GR, K>::
102.884 + template Map<V>::Type Map;
102.885 +
102.886 + typedef std::multimap<V, K> Container;
102.887 Container _inv_map;
102.888
102.889 public:
102.890
102.891 - /// The key type of InvertableMap (Node, Arc, Edge).
102.892 - typedef typename Map::Key Key;
102.893 - /// The value type of the InvertableMap.
102.894 - typedef typename Map::Value Value;
102.895 + /// The graph type of CrossRefMap.
102.896 + typedef GR Graph;
102.897 + typedef GR Digraph;
102.898 + /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
102.899 + typedef K Item;
102.900 + /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
102.901 + typedef K Key;
102.902 + /// The value type of CrossRefMap.
102.903 + typedef V Value;
102.904
102.905 /// \brief Constructor.
102.906 ///
102.907 - /// Construct a new InvertableMap for the graph.
102.908 - ///
102.909 - explicit InvertableMap(const Graph& graph) : Map(graph) {}
102.910 + /// Construct a new CrossRefMap for the given graph.
102.911 + explicit CrossRefMap(const Graph& graph) : Map(graph) {}
102.912
102.913 /// \brief Forward iterator for values.
102.914 ///
102.915 - /// This iterator is an stl compatible forward
102.916 + /// This iterator is an STL compatible forward
102.917 /// iterator on the values of the map. The values can
102.918 - /// be accessed in the [beginValue, endValue) range.
102.919 - ///
102.920 - class ValueIterator
102.921 + /// be accessed in the <tt>[beginValue, endValue)</tt> range.
102.922 + /// They are considered with multiplicity, so each value is
102.923 + /// traversed for each item it is assigned to.
102.924 + class ValueIt
102.925 : public std::iterator<std::forward_iterator_tag, Value> {
102.926 - friend class InvertableMap;
102.927 + friend class CrossRefMap;
102.928 private:
102.929 - ValueIterator(typename Container::const_iterator _it)
102.930 + ValueIt(typename Container::const_iterator _it)
102.931 : it(_it) {}
102.932 public:
102.933
102.934 - ValueIterator() {}
102.935 -
102.936 - ValueIterator& operator++() { ++it; return *this; }
102.937 - ValueIterator operator++(int) {
102.938 - ValueIterator tmp(*this);
102.939 + /// Constructor
102.940 + ValueIt() {}
102.941 +
102.942 + /// \e
102.943 + ValueIt& operator++() { ++it; return *this; }
102.944 + /// \e
102.945 + ValueIt operator++(int) {
102.946 + ValueIt tmp(*this);
102.947 operator++();
102.948 return tmp;
102.949 }
102.950
102.951 + /// \e
102.952 const Value& operator*() const { return it->first; }
102.953 + /// \e
102.954 const Value* operator->() const { return &(it->first); }
102.955
102.956 - bool operator==(ValueIterator jt) const { return it == jt.it; }
102.957 - bool operator!=(ValueIterator jt) const { return it != jt.it; }
102.958 + /// \e
102.959 + bool operator==(ValueIt jt) const { return it == jt.it; }
102.960 + /// \e
102.961 + bool operator!=(ValueIt jt) const { return it != jt.it; }
102.962
102.963 private:
102.964 typename Container::const_iterator it;
102.965 };
102.966 +
102.967 + /// Alias for \c ValueIt
102.968 + typedef ValueIt ValueIterator;
102.969
102.970 /// \brief Returns an iterator to the first value.
102.971 ///
102.972 - /// Returns an stl compatible iterator to the
102.973 + /// Returns an STL compatible iterator to the
102.974 /// first value of the map. The values of the
102.975 - /// map can be accessed in the [beginValue, endValue)
102.976 + /// map can be accessed in the <tt>[beginValue, endValue)</tt>
102.977 /// range.
102.978 - ValueIterator beginValue() const {
102.979 - return ValueIterator(_inv_map.begin());
102.980 + ValueIt beginValue() const {
102.981 + return ValueIt(_inv_map.begin());
102.982 }
102.983
102.984 /// \brief Returns an iterator after the last value.
102.985 ///
102.986 - /// Returns an stl compatible iterator after the
102.987 + /// Returns an STL compatible iterator after the
102.988 /// last value of the map. The values of the
102.989 - /// map can be accessed in the [beginValue, endValue)
102.990 + /// map can be accessed in the <tt>[beginValue, endValue)</tt>
102.991 /// range.
102.992 - ValueIterator endValue() const {
102.993 - return ValueIterator(_inv_map.end());
102.994 + ValueIt endValue() const {
102.995 + return ValueIt(_inv_map.end());
102.996 }
102.997
102.998 - /// \brief The setter function of the map.
102.999 + /// \brief Sets the value associated with the given key.
102.1000 ///
102.1001 - /// Sets the mapped value.
102.1002 + /// Sets the value associated with the given key.
102.1003 void set(const Key& key, const Value& val) {
102.1004 Value oldval = Map::operator[](key);
102.1005 - typename Container::iterator it = _inv_map.find(oldval);
102.1006 - if (it != _inv_map.end() && it->second == key) {
102.1007 - _inv_map.erase(it);
102.1008 + typename Container::iterator it;
102.1009 + for (it = _inv_map.equal_range(oldval).first;
102.1010 + it != _inv_map.equal_range(oldval).second; ++it) {
102.1011 + if (it->second == key) {
102.1012 + _inv_map.erase(it);
102.1013 + break;
102.1014 + }
102.1015 }
102.1016 - _inv_map.insert(make_pair(val, key));
102.1017 + _inv_map.insert(std::make_pair(val, key));
102.1018 Map::set(key, val);
102.1019 }
102.1020
102.1021 - /// \brief The getter function of the map.
102.1022 + /// \brief Returns the value associated with the given key.
102.1023 ///
102.1024 - /// It gives back the value associated with the key.
102.1025 + /// Returns the value associated with the given key.
102.1026 typename MapTraits<Map>::ConstReturnValue
102.1027 operator[](const Key& key) const {
102.1028 return Map::operator[](key);
102.1029 }
102.1030
102.1031 - /// \brief Gives back the item by its value.
102.1032 + /// \brief Gives back an item by its value.
102.1033 ///
102.1034 - /// Gives back the item by its value.
102.1035 - Key operator()(const Value& key) const {
102.1036 - typename Container::const_iterator it = _inv_map.find(key);
102.1037 + /// This function gives back an item that is assigned to
102.1038 + /// the given value or \c INVALID if no such item exists.
102.1039 + /// If there are more items with the same associated value,
102.1040 + /// only one of them is returned.
102.1041 + Key operator()(const Value& val) const {
102.1042 + typename Container::const_iterator it = _inv_map.find(val);
102.1043 return it != _inv_map.end() ? it->second : INVALID;
102.1044 }
102.1045 +
102.1046 + /// \brief Returns the number of items with the given value.
102.1047 + ///
102.1048 + /// This function returns the number of items with the given value
102.1049 + /// associated with it.
102.1050 + int count(const Value &val) const {
102.1051 + return _inv_map.count(val);
102.1052 + }
102.1053
102.1054 protected:
102.1055
102.1056 - /// \brief Erase the key from the map.
102.1057 + /// \brief Erase the key from the map and the inverse map.
102.1058 ///
102.1059 - /// Erase the key to the map. It is called by the
102.1060 + /// Erase the key from the map and the inverse map. It is called by the
102.1061 /// \c AlterationNotifier.
102.1062 virtual void erase(const Key& key) {
102.1063 Value val = Map::operator[](key);
102.1064 - typename Container::iterator it = _inv_map.find(val);
102.1065 - if (it != _inv_map.end() && it->second == key) {
102.1066 - _inv_map.erase(it);
102.1067 + typename Container::iterator it;
102.1068 + for (it = _inv_map.equal_range(val).first;
102.1069 + it != _inv_map.equal_range(val).second; ++it) {
102.1070 + if (it->second == key) {
102.1071 + _inv_map.erase(it);
102.1072 + break;
102.1073 + }
102.1074 }
102.1075 Map::erase(key);
102.1076 }
102.1077
102.1078 - /// \brief Erase more keys from the map.
102.1079 + /// \brief Erase more keys from the map and the inverse map.
102.1080 ///
102.1081 - /// Erase more keys from the map. It is called by the
102.1082 + /// Erase more keys from the map and the inverse map. It is called by the
102.1083 /// \c AlterationNotifier.
102.1084 virtual void erase(const std::vector<Key>& keys) {
102.1085 for (int i = 0; i < int(keys.size()); ++i) {
102.1086 Value val = Map::operator[](keys[i]);
102.1087 - typename Container::iterator it = _inv_map.find(val);
102.1088 - if (it != _inv_map.end() && it->second == keys[i]) {
102.1089 - _inv_map.erase(it);
102.1090 + typename Container::iterator it;
102.1091 + for (it = _inv_map.equal_range(val).first;
102.1092 + it != _inv_map.equal_range(val).second; ++it) {
102.1093 + if (it->second == keys[i]) {
102.1094 + _inv_map.erase(it);
102.1095 + break;
102.1096 + }
102.1097 }
102.1098 }
102.1099 Map::erase(keys);
102.1100 }
102.1101
102.1102 - /// \brief Clear the keys from the map and inverse map.
102.1103 + /// \brief Clear the keys from the map and the inverse map.
102.1104 ///
102.1105 - /// Clear the keys from the map and inverse map. It is called by the
102.1106 + /// Clear the keys from the map and the inverse map. It is called by the
102.1107 /// \c AlterationNotifier.
102.1108 virtual void clear() {
102.1109 _inv_map.clear();
102.1110 @@ -2021,79 +2119,90 @@
102.1111
102.1112 public:
102.1113
102.1114 - /// \brief The inverse map type.
102.1115 + /// \brief The inverse map type of CrossRefMap.
102.1116 ///
102.1117 - /// The inverse of this map. The subscript operator of the map
102.1118 - /// gives back always the item what was last assigned to the value.
102.1119 + /// The inverse map type of CrossRefMap. The subscript operator gives
102.1120 + /// back an item by its value.
102.1121 + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
102.1122 + /// \see inverse()
102.1123 class InverseMap {
102.1124 public:
102.1125 - /// \brief Constructor of the InverseMap.
102.1126 + /// \brief Constructor
102.1127 ///
102.1128 /// Constructor of the InverseMap.
102.1129 - explicit InverseMap(const InvertableMap& inverted)
102.1130 + explicit InverseMap(const CrossRefMap& inverted)
102.1131 : _inverted(inverted) {}
102.1132
102.1133 /// The value type of the InverseMap.
102.1134 - typedef typename InvertableMap::Key Value;
102.1135 + typedef typename CrossRefMap::Key Value;
102.1136 /// The key type of the InverseMap.
102.1137 - typedef typename InvertableMap::Value Key;
102.1138 + typedef typename CrossRefMap::Value Key;
102.1139
102.1140 /// \brief Subscript operator.
102.1141 ///
102.1142 - /// Subscript operator. It gives back always the item
102.1143 - /// what was last assigned to the value.
102.1144 + /// Subscript operator. It gives back an item
102.1145 + /// that is assigned to the given value or \c INVALID
102.1146 + /// if no such item exists.
102.1147 Value operator[](const Key& key) const {
102.1148 return _inverted(key);
102.1149 }
102.1150
102.1151 private:
102.1152 - const InvertableMap& _inverted;
102.1153 + const CrossRefMap& _inverted;
102.1154 };
102.1155
102.1156 - /// \brief It gives back the just readable inverse map.
102.1157 + /// \brief Gives back the inverse of the map.
102.1158 ///
102.1159 - /// It gives back the just readable inverse map.
102.1160 + /// Gives back the inverse of the CrossRefMap.
102.1161 InverseMap inverse() const {
102.1162 return InverseMap(*this);
102.1163 }
102.1164
102.1165 };
102.1166
102.1167 - /// \brief Provides a mutable, continuous and unique descriptor for each
102.1168 - /// item in the graph.
102.1169 + /// \brief Provides continuous and unique id for the
102.1170 + /// items of a graph.
102.1171 ///
102.1172 - /// The DescriptorMap class provides a unique and continuous (but mutable)
102.1173 - /// descriptor (id) for each item of the same type (e.g. node) in the
102.1174 - /// graph. This id is <ul><li>\b unique: different items (nodes) get
102.1175 - /// different ids <li>\b continuous: the range of the ids is the set of
102.1176 - /// integers between 0 and \c n-1, where \c n is the number of the items of
102.1177 - /// this type (e.g. nodes) (so the id of a node can change if you delete an
102.1178 - /// other node, i.e. this id is mutable). </ul> This map can be inverted
102.1179 - /// with its member class \c InverseMap, or with the \c operator() member.
102.1180 + /// RangeIdMap provides a unique and continuous
102.1181 + /// id for each item of a given type (\c Node, \c Arc or
102.1182 + /// \c Edge) in a graph. This id is
102.1183 + /// - \b unique: different items get different ids,
102.1184 + /// - \b continuous: the range of the ids is the set of integers
102.1185 + /// between 0 and \c n-1, where \c n is the number of the items of
102.1186 + /// this type (\c Node, \c Arc or \c Edge).
102.1187 + /// - So, the ids can change when deleting an item of the same type.
102.1188 ///
102.1189 - /// \tparam _Graph The graph class the \c DescriptorMap belongs to.
102.1190 - /// \tparam _Item The Item is the Key of the Map. It may be Node, Arc or
102.1191 - /// Edge.
102.1192 - template <typename _Graph, typename _Item>
102.1193 - class DescriptorMap
102.1194 - : protected ItemSetTraits<_Graph, _Item>::template Map<int>::Type {
102.1195 -
102.1196 - typedef _Item Item;
102.1197 - typedef typename ItemSetTraits<_Graph, _Item>::template Map<int>::Type Map;
102.1198 + /// Thus this id is not (necessarily) the same as what can get using
102.1199 + /// the \c id() function of the graph or \ref IdMap.
102.1200 + /// This map can be inverted with its member class \c InverseMap,
102.1201 + /// or with the \c operator()() member.
102.1202 + ///
102.1203 + /// \tparam GR The graph type.
102.1204 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
102.1205 + /// \c GR::Edge).
102.1206 + ///
102.1207 + /// \see IdMap
102.1208 + template <typename GR, typename K>
102.1209 + class RangeIdMap
102.1210 + : protected ItemSetTraits<GR, K>::template Map<int>::Type {
102.1211 +
102.1212 + typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Map;
102.1213
102.1214 public:
102.1215 - /// The graph class of DescriptorMap.
102.1216 - typedef _Graph Graph;
102.1217 -
102.1218 - /// The key type of DescriptorMap (Node, Arc, Edge).
102.1219 - typedef typename Map::Key Key;
102.1220 - /// The value type of DescriptorMap.
102.1221 - typedef typename Map::Value Value;
102.1222 + /// The graph type of RangeIdMap.
102.1223 + typedef GR Graph;
102.1224 + typedef GR Digraph;
102.1225 + /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
102.1226 + typedef K Item;
102.1227 + /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
102.1228 + typedef K Key;
102.1229 + /// The value type of RangeIdMap.
102.1230 + typedef int Value;
102.1231
102.1232 /// \brief Constructor.
102.1233 ///
102.1234 - /// Constructor for descriptor map.
102.1235 - explicit DescriptorMap(const Graph& _graph) : Map(_graph) {
102.1236 + /// Constructor.
102.1237 + explicit RangeIdMap(const Graph& gr) : Map(gr) {
102.1238 Item it;
102.1239 const typename Map::Notifier* nf = Map::notifier();
102.1240 for (nf->first(it); it != INVALID; nf->next(it)) {
102.1241 @@ -2104,7 +2213,7 @@
102.1242
102.1243 protected:
102.1244
102.1245 - /// \brief Add a new key to the map.
102.1246 + /// \brief Adds a new key to the map.
102.1247 ///
102.1248 /// Add a new key to the map. It is called by the
102.1249 /// \c AlterationNotifier.
102.1250 @@ -2194,16 +2303,16 @@
102.1251 _inv_map[pi] = q;
102.1252 }
102.1253
102.1254 - /// \brief Gives back the \e descriptor of the item.
102.1255 + /// \brief Gives back the \e range \e id of the item
102.1256 ///
102.1257 - /// Gives back the mutable and unique \e descriptor of the map.
102.1258 + /// Gives back the \e range \e id of the item.
102.1259 int operator[](const Item& item) const {
102.1260 return Map::operator[](item);
102.1261 }
102.1262
102.1263 - /// \brief Gives back the item by its descriptor.
102.1264 + /// \brief Gives back the item belonging to a \e range \e id
102.1265 ///
102.1266 - /// Gives back th item by its descriptor.
102.1267 + /// Gives back the item belonging to the given \e range \e id.
102.1268 Item operator()(int id) const {
102.1269 return _inv_map[id];
102.1270 }
102.1271 @@ -2214,27 +2323,30 @@
102.1272 Container _inv_map;
102.1273
102.1274 public:
102.1275 - /// \brief The inverse map type of DescriptorMap.
102.1276 +
102.1277 + /// \brief The inverse map type of RangeIdMap.
102.1278 ///
102.1279 - /// The inverse map type of DescriptorMap.
102.1280 + /// The inverse map type of RangeIdMap. The subscript operator gives
102.1281 + /// back an item by its \e range \e id.
102.1282 + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
102.1283 class InverseMap {
102.1284 public:
102.1285 - /// \brief Constructor of the InverseMap.
102.1286 + /// \brief Constructor
102.1287 ///
102.1288 /// Constructor of the InverseMap.
102.1289 - explicit InverseMap(const DescriptorMap& inverted)
102.1290 + explicit InverseMap(const RangeIdMap& inverted)
102.1291 : _inverted(inverted) {}
102.1292
102.1293
102.1294 /// The value type of the InverseMap.
102.1295 - typedef typename DescriptorMap::Key Value;
102.1296 + typedef typename RangeIdMap::Key Value;
102.1297 /// The key type of the InverseMap.
102.1298 - typedef typename DescriptorMap::Value Key;
102.1299 + typedef typename RangeIdMap::Value Key;
102.1300
102.1301 /// \brief Subscript operator.
102.1302 ///
102.1303 /// Subscript operator. It gives back the item
102.1304 - /// that the descriptor belongs to currently.
102.1305 + /// that the given \e range \e id currently belongs to.
102.1306 Value operator[](const Key& key) const {
102.1307 return _inverted(key);
102.1308 }
102.1309 @@ -2247,241 +2359,1134 @@
102.1310 }
102.1311
102.1312 private:
102.1313 - const DescriptorMap& _inverted;
102.1314 + const RangeIdMap& _inverted;
102.1315 };
102.1316
102.1317 /// \brief Gives back the inverse of the map.
102.1318 ///
102.1319 - /// Gives back the inverse of the map.
102.1320 + /// Gives back the inverse of the RangeIdMap.
102.1321 const InverseMap inverse() const {
102.1322 return InverseMap(*this);
102.1323 }
102.1324 };
102.1325
102.1326 - /// \brief Returns the source of the given arc.
102.1327 + /// \brief Returns a \c RangeIdMap class.
102.1328 ///
102.1329 - /// The SourceMap gives back the source Node of the given arc.
102.1330 + /// This function just returns an \c RangeIdMap class.
102.1331 + /// \relates RangeIdMap
102.1332 + template <typename K, typename GR>
102.1333 + inline RangeIdMap<GR, K> rangeIdMap(const GR& graph) {
102.1334 + return RangeIdMap<GR, K>(graph);
102.1335 + }
102.1336 +
102.1337 + /// \brief Dynamic iterable \c bool map.
102.1338 + ///
102.1339 + /// This class provides a special graph map type which can store a
102.1340 + /// \c bool value for graph items (\c Node, \c Arc or \c Edge).
102.1341 + /// For both \c true and \c false values it is possible to iterate on
102.1342 + /// the keys mapped to the value.
102.1343 + ///
102.1344 + /// This type is a reference map, so it can be modified with the
102.1345 + /// subscript operator.
102.1346 + ///
102.1347 + /// \tparam GR The graph type.
102.1348 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
102.1349 + /// \c GR::Edge).
102.1350 + ///
102.1351 + /// \see IterableIntMap, IterableValueMap
102.1352 + /// \see CrossRefMap
102.1353 + template <typename GR, typename K>
102.1354 + class IterableBoolMap
102.1355 + : protected ItemSetTraits<GR, K>::template Map<int>::Type {
102.1356 + private:
102.1357 + typedef GR Graph;
102.1358 +
102.1359 + typedef typename ItemSetTraits<GR, K>::ItemIt KeyIt;
102.1360 + typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Parent;
102.1361 +
102.1362 + std::vector<K> _array;
102.1363 + int _sep;
102.1364 +
102.1365 + public:
102.1366 +
102.1367 + /// Indicates that the map is reference map.
102.1368 + typedef True ReferenceMapTag;
102.1369 +
102.1370 + /// The key type
102.1371 + typedef K Key;
102.1372 + /// The value type
102.1373 + typedef bool Value;
102.1374 + /// The const reference type.
102.1375 + typedef const Value& ConstReference;
102.1376 +
102.1377 + private:
102.1378 +
102.1379 + int position(const Key& key) const {
102.1380 + return Parent::operator[](key);
102.1381 + }
102.1382 +
102.1383 + public:
102.1384 +
102.1385 + /// \brief Reference to the value of the map.
102.1386 + ///
102.1387 + /// This class is similar to the \c bool type. It can be converted to
102.1388 + /// \c bool and it provides the same operators.
102.1389 + class Reference {
102.1390 + friend class IterableBoolMap;
102.1391 + private:
102.1392 + Reference(IterableBoolMap& map, const Key& key)
102.1393 + : _key(key), _map(map) {}
102.1394 + public:
102.1395 +
102.1396 + Reference& operator=(const Reference& value) {
102.1397 + _map.set(_key, static_cast<bool>(value));
102.1398 + return *this;
102.1399 + }
102.1400 +
102.1401 + operator bool() const {
102.1402 + return static_cast<const IterableBoolMap&>(_map)[_key];
102.1403 + }
102.1404 +
102.1405 + Reference& operator=(bool value) {
102.1406 + _map.set(_key, value);
102.1407 + return *this;
102.1408 + }
102.1409 + Reference& operator&=(bool value) {
102.1410 + _map.set(_key, _map[_key] & value);
102.1411 + return *this;
102.1412 + }
102.1413 + Reference& operator|=(bool value) {
102.1414 + _map.set(_key, _map[_key] | value);
102.1415 + return *this;
102.1416 + }
102.1417 + Reference& operator^=(bool value) {
102.1418 + _map.set(_key, _map[_key] ^ value);
102.1419 + return *this;
102.1420 + }
102.1421 + private:
102.1422 + Key _key;
102.1423 + IterableBoolMap& _map;
102.1424 + };
102.1425 +
102.1426 + /// \brief Constructor of the map with a default value.
102.1427 + ///
102.1428 + /// Constructor of the map with a default value.
102.1429 + explicit IterableBoolMap(const Graph& graph, bool def = false)
102.1430 + : Parent(graph) {
102.1431 + typename Parent::Notifier* nf = Parent::notifier();
102.1432 + Key it;
102.1433 + for (nf->first(it); it != INVALID; nf->next(it)) {
102.1434 + Parent::set(it, _array.size());
102.1435 + _array.push_back(it);
102.1436 + }
102.1437 + _sep = (def ? _array.size() : 0);
102.1438 + }
102.1439 +
102.1440 + /// \brief Const subscript operator of the map.
102.1441 + ///
102.1442 + /// Const subscript operator of the map.
102.1443 + bool operator[](const Key& key) const {
102.1444 + return position(key) < _sep;
102.1445 + }
102.1446 +
102.1447 + /// \brief Subscript operator of the map.
102.1448 + ///
102.1449 + /// Subscript operator of the map.
102.1450 + Reference operator[](const Key& key) {
102.1451 + return Reference(*this, key);
102.1452 + }
102.1453 +
102.1454 + /// \brief Set operation of the map.
102.1455 + ///
102.1456 + /// Set operation of the map.
102.1457 + void set(const Key& key, bool value) {
102.1458 + int pos = position(key);
102.1459 + if (value) {
102.1460 + if (pos < _sep) return;
102.1461 + Key tmp = _array[_sep];
102.1462 + _array[_sep] = key;
102.1463 + Parent::set(key, _sep);
102.1464 + _array[pos] = tmp;
102.1465 + Parent::set(tmp, pos);
102.1466 + ++_sep;
102.1467 + } else {
102.1468 + if (pos >= _sep) return;
102.1469 + --_sep;
102.1470 + Key tmp = _array[_sep];
102.1471 + _array[_sep] = key;
102.1472 + Parent::set(key, _sep);
102.1473 + _array[pos] = tmp;
102.1474 + Parent::set(tmp, pos);
102.1475 + }
102.1476 + }
102.1477 +
102.1478 + /// \brief Set all items.
102.1479 + ///
102.1480 + /// Set all items in the map.
102.1481 + /// \note Constant time operation.
102.1482 + void setAll(bool value) {
102.1483 + _sep = (value ? _array.size() : 0);
102.1484 + }
102.1485 +
102.1486 + /// \brief Returns the number of the keys mapped to \c true.
102.1487 + ///
102.1488 + /// Returns the number of the keys mapped to \c true.
102.1489 + int trueNum() const {
102.1490 + return _sep;
102.1491 + }
102.1492 +
102.1493 + /// \brief Returns the number of the keys mapped to \c false.
102.1494 + ///
102.1495 + /// Returns the number of the keys mapped to \c false.
102.1496 + int falseNum() const {
102.1497 + return _array.size() - _sep;
102.1498 + }
102.1499 +
102.1500 + /// \brief Iterator for the keys mapped to \c true.
102.1501 + ///
102.1502 + /// Iterator for the keys mapped to \c true. It works
102.1503 + /// like a graph item iterator, it can be converted to
102.1504 + /// the key type of the map, incremented with \c ++ operator, and
102.1505 + /// if the iterator leaves the last valid key, it will be equal to
102.1506 + /// \c INVALID.
102.1507 + class TrueIt : public Key {
102.1508 + public:
102.1509 + typedef Key Parent;
102.1510 +
102.1511 + /// \brief Creates an iterator.
102.1512 + ///
102.1513 + /// Creates an iterator. It iterates on the
102.1514 + /// keys mapped to \c true.
102.1515 + /// \param map The IterableBoolMap.
102.1516 + explicit TrueIt(const IterableBoolMap& map)
102.1517 + : Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID),
102.1518 + _map(&map) {}
102.1519 +
102.1520 + /// \brief Invalid constructor \& conversion.
102.1521 + ///
102.1522 + /// This constructor initializes the iterator to be invalid.
102.1523 + /// \sa Invalid for more details.
102.1524 + TrueIt(Invalid) : Parent(INVALID), _map(0) {}
102.1525 +
102.1526 + /// \brief Increment operator.
102.1527 + ///
102.1528 + /// Increment operator.
102.1529 + TrueIt& operator++() {
102.1530 + int pos = _map->position(*this);
102.1531 + Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID);
102.1532 + return *this;
102.1533 + }
102.1534 +
102.1535 + private:
102.1536 + const IterableBoolMap* _map;
102.1537 + };
102.1538 +
102.1539 + /// \brief Iterator for the keys mapped to \c false.
102.1540 + ///
102.1541 + /// Iterator for the keys mapped to \c false. It works
102.1542 + /// like a graph item iterator, it can be converted to
102.1543 + /// the key type of the map, incremented with \c ++ operator, and
102.1544 + /// if the iterator leaves the last valid key, it will be equal to
102.1545 + /// \c INVALID.
102.1546 + class FalseIt : public Key {
102.1547 + public:
102.1548 + typedef Key Parent;
102.1549 +
102.1550 + /// \brief Creates an iterator.
102.1551 + ///
102.1552 + /// Creates an iterator. It iterates on the
102.1553 + /// keys mapped to \c false.
102.1554 + /// \param map The IterableBoolMap.
102.1555 + explicit FalseIt(const IterableBoolMap& map)
102.1556 + : Parent(map._sep < int(map._array.size()) ?
102.1557 + map._array.back() : INVALID), _map(&map) {}
102.1558 +
102.1559 + /// \brief Invalid constructor \& conversion.
102.1560 + ///
102.1561 + /// This constructor initializes the iterator to be invalid.
102.1562 + /// \sa Invalid for more details.
102.1563 + FalseIt(Invalid) : Parent(INVALID), _map(0) {}
102.1564 +
102.1565 + /// \brief Increment operator.
102.1566 + ///
102.1567 + /// Increment operator.
102.1568 + FalseIt& operator++() {
102.1569 + int pos = _map->position(*this);
102.1570 + Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID);
102.1571 + return *this;
102.1572 + }
102.1573 +
102.1574 + private:
102.1575 + const IterableBoolMap* _map;
102.1576 + };
102.1577 +
102.1578 + /// \brief Iterator for the keys mapped to a given value.
102.1579 + ///
102.1580 + /// Iterator for the keys mapped to a given value. It works
102.1581 + /// like a graph item iterator, it can be converted to
102.1582 + /// the key type of the map, incremented with \c ++ operator, and
102.1583 + /// if the iterator leaves the last valid key, it will be equal to
102.1584 + /// \c INVALID.
102.1585 + class ItemIt : public Key {
102.1586 + public:
102.1587 + typedef Key Parent;
102.1588 +
102.1589 + /// \brief Creates an iterator with a value.
102.1590 + ///
102.1591 + /// Creates an iterator with a value. It iterates on the
102.1592 + /// keys mapped to the given value.
102.1593 + /// \param map The IterableBoolMap.
102.1594 + /// \param value The value.
102.1595 + ItemIt(const IterableBoolMap& map, bool value)
102.1596 + : Parent(value ?
102.1597 + (map._sep > 0 ?
102.1598 + map._array[map._sep - 1] : INVALID) :
102.1599 + (map._sep < int(map._array.size()) ?
102.1600 + map._array.back() : INVALID)), _map(&map) {}
102.1601 +
102.1602 + /// \brief Invalid constructor \& conversion.
102.1603 + ///
102.1604 + /// This constructor initializes the iterator to be invalid.
102.1605 + /// \sa Invalid for more details.
102.1606 + ItemIt(Invalid) : Parent(INVALID), _map(0) {}
102.1607 +
102.1608 + /// \brief Increment operator.
102.1609 + ///
102.1610 + /// Increment operator.
102.1611 + ItemIt& operator++() {
102.1612 + int pos = _map->position(*this);
102.1613 + int _sep = pos >= _map->_sep ? _map->_sep : 0;
102.1614 + Parent::operator=(pos > _sep ? _map->_array[pos - 1] : INVALID);
102.1615 + return *this;
102.1616 + }
102.1617 +
102.1618 + private:
102.1619 + const IterableBoolMap* _map;
102.1620 + };
102.1621 +
102.1622 + protected:
102.1623 +
102.1624 + virtual void add(const Key& key) {
102.1625 + Parent::add(key);
102.1626 + Parent::set(key, _array.size());
102.1627 + _array.push_back(key);
102.1628 + }
102.1629 +
102.1630 + virtual void add(const std::vector<Key>& keys) {
102.1631 + Parent::add(keys);
102.1632 + for (int i = 0; i < int(keys.size()); ++i) {
102.1633 + Parent::set(keys[i], _array.size());
102.1634 + _array.push_back(keys[i]);
102.1635 + }
102.1636 + }
102.1637 +
102.1638 + virtual void erase(const Key& key) {
102.1639 + int pos = position(key);
102.1640 + if (pos < _sep) {
102.1641 + --_sep;
102.1642 + Parent::set(_array[_sep], pos);
102.1643 + _array[pos] = _array[_sep];
102.1644 + Parent::set(_array.back(), _sep);
102.1645 + _array[_sep] = _array.back();
102.1646 + _array.pop_back();
102.1647 + } else {
102.1648 + Parent::set(_array.back(), pos);
102.1649 + _array[pos] = _array.back();
102.1650 + _array.pop_back();
102.1651 + }
102.1652 + Parent::erase(key);
102.1653 + }
102.1654 +
102.1655 + virtual void erase(const std::vector<Key>& keys) {
102.1656 + for (int i = 0; i < int(keys.size()); ++i) {
102.1657 + int pos = position(keys[i]);
102.1658 + if (pos < _sep) {
102.1659 + --_sep;
102.1660 + Parent::set(_array[_sep], pos);
102.1661 + _array[pos] = _array[_sep];
102.1662 + Parent::set(_array.back(), _sep);
102.1663 + _array[_sep] = _array.back();
102.1664 + _array.pop_back();
102.1665 + } else {
102.1666 + Parent::set(_array.back(), pos);
102.1667 + _array[pos] = _array.back();
102.1668 + _array.pop_back();
102.1669 + }
102.1670 + }
102.1671 + Parent::erase(keys);
102.1672 + }
102.1673 +
102.1674 + virtual void build() {
102.1675 + Parent::build();
102.1676 + typename Parent::Notifier* nf = Parent::notifier();
102.1677 + Key it;
102.1678 + for (nf->first(it); it != INVALID; nf->next(it)) {
102.1679 + Parent::set(it, _array.size());
102.1680 + _array.push_back(it);
102.1681 + }
102.1682 + _sep = 0;
102.1683 + }
102.1684 +
102.1685 + virtual void clear() {
102.1686 + _array.clear();
102.1687 + _sep = 0;
102.1688 + Parent::clear();
102.1689 + }
102.1690 +
102.1691 + };
102.1692 +
102.1693 +
102.1694 + namespace _maps_bits {
102.1695 + template <typename Item>
102.1696 + struct IterableIntMapNode {
102.1697 + IterableIntMapNode() : value(-1) {}
102.1698 + IterableIntMapNode(int _value) : value(_value) {}
102.1699 + Item prev, next;
102.1700 + int value;
102.1701 + };
102.1702 + }
102.1703 +
102.1704 + /// \brief Dynamic iterable integer map.
102.1705 + ///
102.1706 + /// This class provides a special graph map type which can store an
102.1707 + /// integer value for graph items (\c Node, \c Arc or \c Edge).
102.1708 + /// For each non-negative value it is possible to iterate on the keys
102.1709 + /// mapped to the value.
102.1710 + ///
102.1711 + /// This map is intended to be used with small integer values, for which
102.1712 + /// it is efficient, and supports iteration only for non-negative values.
102.1713 + /// If you need large values and/or iteration for negative integers,
102.1714 + /// consider to use \ref IterableValueMap instead.
102.1715 + ///
102.1716 + /// This type is a reference map, so it can be modified with the
102.1717 + /// subscript operator.
102.1718 + ///
102.1719 + /// \note The size of the data structure depends on the largest
102.1720 + /// value in the map.
102.1721 + ///
102.1722 + /// \tparam GR The graph type.
102.1723 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
102.1724 + /// \c GR::Edge).
102.1725 + ///
102.1726 + /// \see IterableBoolMap, IterableValueMap
102.1727 + /// \see CrossRefMap
102.1728 + template <typename GR, typename K>
102.1729 + class IterableIntMap
102.1730 + : protected ItemSetTraits<GR, K>::
102.1731 + template Map<_maps_bits::IterableIntMapNode<K> >::Type {
102.1732 + public:
102.1733 + typedef typename ItemSetTraits<GR, K>::
102.1734 + template Map<_maps_bits::IterableIntMapNode<K> >::Type Parent;
102.1735 +
102.1736 + /// The key type
102.1737 + typedef K Key;
102.1738 + /// The value type
102.1739 + typedef int Value;
102.1740 + /// The graph type
102.1741 + typedef GR Graph;
102.1742 +
102.1743 + /// \brief Constructor of the map.
102.1744 + ///
102.1745 + /// Constructor of the map. It sets all values to -1.
102.1746 + explicit IterableIntMap(const Graph& graph)
102.1747 + : Parent(graph) {}
102.1748 +
102.1749 + /// \brief Constructor of the map with a given value.
102.1750 + ///
102.1751 + /// Constructor of the map with a given value.
102.1752 + explicit IterableIntMap(const Graph& graph, int value)
102.1753 + : Parent(graph, _maps_bits::IterableIntMapNode<K>(value)) {
102.1754 + if (value >= 0) {
102.1755 + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
102.1756 + lace(it);
102.1757 + }
102.1758 + }
102.1759 + }
102.1760 +
102.1761 + private:
102.1762 +
102.1763 + void unlace(const Key& key) {
102.1764 + typename Parent::Value& node = Parent::operator[](key);
102.1765 + if (node.value < 0) return;
102.1766 + if (node.prev != INVALID) {
102.1767 + Parent::operator[](node.prev).next = node.next;
102.1768 + } else {
102.1769 + _first[node.value] = node.next;
102.1770 + }
102.1771 + if (node.next != INVALID) {
102.1772 + Parent::operator[](node.next).prev = node.prev;
102.1773 + }
102.1774 + while (!_first.empty() && _first.back() == INVALID) {
102.1775 + _first.pop_back();
102.1776 + }
102.1777 + }
102.1778 +
102.1779 + void lace(const Key& key) {
102.1780 + typename Parent::Value& node = Parent::operator[](key);
102.1781 + if (node.value < 0) return;
102.1782 + if (node.value >= int(_first.size())) {
102.1783 + _first.resize(node.value + 1, INVALID);
102.1784 + }
102.1785 + node.prev = INVALID;
102.1786 + node.next = _first[node.value];
102.1787 + if (node.next != INVALID) {
102.1788 + Parent::operator[](node.next).prev = key;
102.1789 + }
102.1790 + _first[node.value] = key;
102.1791 + }
102.1792 +
102.1793 + public:
102.1794 +
102.1795 + /// Indicates that the map is reference map.
102.1796 + typedef True ReferenceMapTag;
102.1797 +
102.1798 + /// \brief Reference to the value of the map.
102.1799 + ///
102.1800 + /// This class is similar to the \c int type. It can
102.1801 + /// be converted to \c int and it has the same operators.
102.1802 + class Reference {
102.1803 + friend class IterableIntMap;
102.1804 + private:
102.1805 + Reference(IterableIntMap& map, const Key& key)
102.1806 + : _key(key), _map(map) {}
102.1807 + public:
102.1808 +
102.1809 + Reference& operator=(const Reference& value) {
102.1810 + _map.set(_key, static_cast<const int&>(value));
102.1811 + return *this;
102.1812 + }
102.1813 +
102.1814 + operator const int&() const {
102.1815 + return static_cast<const IterableIntMap&>(_map)[_key];
102.1816 + }
102.1817 +
102.1818 + Reference& operator=(int value) {
102.1819 + _map.set(_key, value);
102.1820 + return *this;
102.1821 + }
102.1822 + Reference& operator++() {
102.1823 + _map.set(_key, _map[_key] + 1);
102.1824 + return *this;
102.1825 + }
102.1826 + int operator++(int) {
102.1827 + int value = _map[_key];
102.1828 + _map.set(_key, value + 1);
102.1829 + return value;
102.1830 + }
102.1831 + Reference& operator--() {
102.1832 + _map.set(_key, _map[_key] - 1);
102.1833 + return *this;
102.1834 + }
102.1835 + int operator--(int) {
102.1836 + int value = _map[_key];
102.1837 + _map.set(_key, value - 1);
102.1838 + return value;
102.1839 + }
102.1840 + Reference& operator+=(int value) {
102.1841 + _map.set(_key, _map[_key] + value);
102.1842 + return *this;
102.1843 + }
102.1844 + Reference& operator-=(int value) {
102.1845 + _map.set(_key, _map[_key] - value);
102.1846 + return *this;
102.1847 + }
102.1848 + Reference& operator*=(int value) {
102.1849 + _map.set(_key, _map[_key] * value);
102.1850 + return *this;
102.1851 + }
102.1852 + Reference& operator/=(int value) {
102.1853 + _map.set(_key, _map[_key] / value);
102.1854 + return *this;
102.1855 + }
102.1856 + Reference& operator%=(int value) {
102.1857 + _map.set(_key, _map[_key] % value);
102.1858 + return *this;
102.1859 + }
102.1860 + Reference& operator&=(int value) {
102.1861 + _map.set(_key, _map[_key] & value);
102.1862 + return *this;
102.1863 + }
102.1864 + Reference& operator|=(int value) {
102.1865 + _map.set(_key, _map[_key] | value);
102.1866 + return *this;
102.1867 + }
102.1868 + Reference& operator^=(int value) {
102.1869 + _map.set(_key, _map[_key] ^ value);
102.1870 + return *this;
102.1871 + }
102.1872 + Reference& operator<<=(int value) {
102.1873 + _map.set(_key, _map[_key] << value);
102.1874 + return *this;
102.1875 + }
102.1876 + Reference& operator>>=(int value) {
102.1877 + _map.set(_key, _map[_key] >> value);
102.1878 + return *this;
102.1879 + }
102.1880 +
102.1881 + private:
102.1882 + Key _key;
102.1883 + IterableIntMap& _map;
102.1884 + };
102.1885 +
102.1886 + /// The const reference type.
102.1887 + typedef const Value& ConstReference;
102.1888 +
102.1889 + /// \brief Gives back the maximal value plus one.
102.1890 + ///
102.1891 + /// Gives back the maximal value plus one.
102.1892 + int size() const {
102.1893 + return _first.size();
102.1894 + }
102.1895 +
102.1896 + /// \brief Set operation of the map.
102.1897 + ///
102.1898 + /// Set operation of the map.
102.1899 + void set(const Key& key, const Value& value) {
102.1900 + unlace(key);
102.1901 + Parent::operator[](key).value = value;
102.1902 + lace(key);
102.1903 + }
102.1904 +
102.1905 + /// \brief Const subscript operator of the map.
102.1906 + ///
102.1907 + /// Const subscript operator of the map.
102.1908 + const Value& operator[](const Key& key) const {
102.1909 + return Parent::operator[](key).value;
102.1910 + }
102.1911 +
102.1912 + /// \brief Subscript operator of the map.
102.1913 + ///
102.1914 + /// Subscript operator of the map.
102.1915 + Reference operator[](const Key& key) {
102.1916 + return Reference(*this, key);
102.1917 + }
102.1918 +
102.1919 + /// \brief Iterator for the keys with the same value.
102.1920 + ///
102.1921 + /// Iterator for the keys with the same value. It works
102.1922 + /// like a graph item iterator, it can be converted to
102.1923 + /// the item type of the map, incremented with \c ++ operator, and
102.1924 + /// if the iterator leaves the last valid item, it will be equal to
102.1925 + /// \c INVALID.
102.1926 + class ItemIt : public Key {
102.1927 + public:
102.1928 + typedef Key Parent;
102.1929 +
102.1930 + /// \brief Invalid constructor \& conversion.
102.1931 + ///
102.1932 + /// This constructor initializes the iterator to be invalid.
102.1933 + /// \sa Invalid for more details.
102.1934 + ItemIt(Invalid) : Parent(INVALID), _map(0) {}
102.1935 +
102.1936 + /// \brief Creates an iterator with a value.
102.1937 + ///
102.1938 + /// Creates an iterator with a value. It iterates on the
102.1939 + /// keys mapped to the given value.
102.1940 + /// \param map The IterableIntMap.
102.1941 + /// \param value The value.
102.1942 + ItemIt(const IterableIntMap& map, int value) : _map(&map) {
102.1943 + if (value < 0 || value >= int(_map->_first.size())) {
102.1944 + Parent::operator=(INVALID);
102.1945 + } else {
102.1946 + Parent::operator=(_map->_first[value]);
102.1947 + }
102.1948 + }
102.1949 +
102.1950 + /// \brief Increment operator.
102.1951 + ///
102.1952 + /// Increment operator.
102.1953 + ItemIt& operator++() {
102.1954 + Parent::operator=(_map->IterableIntMap::Parent::
102.1955 + operator[](static_cast<Parent&>(*this)).next);
102.1956 + return *this;
102.1957 + }
102.1958 +
102.1959 + private:
102.1960 + const IterableIntMap* _map;
102.1961 + };
102.1962 +
102.1963 + protected:
102.1964 +
102.1965 + virtual void erase(const Key& key) {
102.1966 + unlace(key);
102.1967 + Parent::erase(key);
102.1968 + }
102.1969 +
102.1970 + virtual void erase(const std::vector<Key>& keys) {
102.1971 + for (int i = 0; i < int(keys.size()); ++i) {
102.1972 + unlace(keys[i]);
102.1973 + }
102.1974 + Parent::erase(keys);
102.1975 + }
102.1976 +
102.1977 + virtual void clear() {
102.1978 + _first.clear();
102.1979 + Parent::clear();
102.1980 + }
102.1981 +
102.1982 + private:
102.1983 + std::vector<Key> _first;
102.1984 + };
102.1985 +
102.1986 + namespace _maps_bits {
102.1987 + template <typename Item, typename Value>
102.1988 + struct IterableValueMapNode {
102.1989 + IterableValueMapNode(Value _value = Value()) : value(_value) {}
102.1990 + Item prev, next;
102.1991 + Value value;
102.1992 + };
102.1993 + }
102.1994 +
102.1995 + /// \brief Dynamic iterable map for comparable values.
102.1996 + ///
102.1997 + /// This class provides a special graph map type which can store a
102.1998 + /// comparable value for graph items (\c Node, \c Arc or \c Edge).
102.1999 + /// For each value it is possible to iterate on the keys mapped to
102.2000 + /// the value (\c ItemIt), and the values of the map can be accessed
102.2001 + /// with an STL compatible forward iterator (\c ValueIt).
102.2002 + /// The map stores a linked list for each value, which contains
102.2003 + /// the items mapped to the value, and the used values are stored
102.2004 + /// in balanced binary tree (\c std::map).
102.2005 + ///
102.2006 + /// \ref IterableBoolMap and \ref IterableIntMap are similar classes
102.2007 + /// specialized for \c bool and \c int values, respectively.
102.2008 + ///
102.2009 + /// This type is not reference map, so it cannot be modified with
102.2010 + /// the subscript operator.
102.2011 + ///
102.2012 + /// \tparam GR The graph type.
102.2013 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
102.2014 + /// \c GR::Edge).
102.2015 + /// \tparam V The value type of the map. It can be any comparable
102.2016 + /// value type.
102.2017 + ///
102.2018 + /// \see IterableBoolMap, IterableIntMap
102.2019 + /// \see CrossRefMap
102.2020 + template <typename GR, typename K, typename V>
102.2021 + class IterableValueMap
102.2022 + : protected ItemSetTraits<GR, K>::
102.2023 + template Map<_maps_bits::IterableValueMapNode<K, V> >::Type {
102.2024 + public:
102.2025 + typedef typename ItemSetTraits<GR, K>::
102.2026 + template Map<_maps_bits::IterableValueMapNode<K, V> >::Type Parent;
102.2027 +
102.2028 + /// The key type
102.2029 + typedef K Key;
102.2030 + /// The value type
102.2031 + typedef V Value;
102.2032 + /// The graph type
102.2033 + typedef GR Graph;
102.2034 +
102.2035 + public:
102.2036 +
102.2037 + /// \brief Constructor of the map with a given value.
102.2038 + ///
102.2039 + /// Constructor of the map with a given value.
102.2040 + explicit IterableValueMap(const Graph& graph,
102.2041 + const Value& value = Value())
102.2042 + : Parent(graph, _maps_bits::IterableValueMapNode<K, V>(value)) {
102.2043 + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
102.2044 + lace(it);
102.2045 + }
102.2046 + }
102.2047 +
102.2048 + protected:
102.2049 +
102.2050 + void unlace(const Key& key) {
102.2051 + typename Parent::Value& node = Parent::operator[](key);
102.2052 + if (node.prev != INVALID) {
102.2053 + Parent::operator[](node.prev).next = node.next;
102.2054 + } else {
102.2055 + if (node.next != INVALID) {
102.2056 + _first[node.value] = node.next;
102.2057 + } else {
102.2058 + _first.erase(node.value);
102.2059 + }
102.2060 + }
102.2061 + if (node.next != INVALID) {
102.2062 + Parent::operator[](node.next).prev = node.prev;
102.2063 + }
102.2064 + }
102.2065 +
102.2066 + void lace(const Key& key) {
102.2067 + typename Parent::Value& node = Parent::operator[](key);
102.2068 + typename std::map<Value, Key>::iterator it = _first.find(node.value);
102.2069 + if (it == _first.end()) {
102.2070 + node.prev = node.next = INVALID;
102.2071 + _first.insert(std::make_pair(node.value, key));
102.2072 + } else {
102.2073 + node.prev = INVALID;
102.2074 + node.next = it->second;
102.2075 + if (node.next != INVALID) {
102.2076 + Parent::operator[](node.next).prev = key;
102.2077 + }
102.2078 + it->second = key;
102.2079 + }
102.2080 + }
102.2081 +
102.2082 + public:
102.2083 +
102.2084 + /// \brief Forward iterator for values.
102.2085 + ///
102.2086 + /// This iterator is an STL compatible forward
102.2087 + /// iterator on the values of the map. The values can
102.2088 + /// be accessed in the <tt>[beginValue, endValue)</tt> range.
102.2089 + class ValueIt
102.2090 + : public std::iterator<std::forward_iterator_tag, Value> {
102.2091 + friend class IterableValueMap;
102.2092 + private:
102.2093 + ValueIt(typename std::map<Value, Key>::const_iterator _it)
102.2094 + : it(_it) {}
102.2095 + public:
102.2096 +
102.2097 + /// Constructor
102.2098 + ValueIt() {}
102.2099 +
102.2100 + /// \e
102.2101 + ValueIt& operator++() { ++it; return *this; }
102.2102 + /// \e
102.2103 + ValueIt operator++(int) {
102.2104 + ValueIt tmp(*this);
102.2105 + operator++();
102.2106 + return tmp;
102.2107 + }
102.2108 +
102.2109 + /// \e
102.2110 + const Value& operator*() const { return it->first; }
102.2111 + /// \e
102.2112 + const Value* operator->() const { return &(it->first); }
102.2113 +
102.2114 + /// \e
102.2115 + bool operator==(ValueIt jt) const { return it == jt.it; }
102.2116 + /// \e
102.2117 + bool operator!=(ValueIt jt) const { return it != jt.it; }
102.2118 +
102.2119 + private:
102.2120 + typename std::map<Value, Key>::const_iterator it;
102.2121 + };
102.2122 +
102.2123 + /// \brief Returns an iterator to the first value.
102.2124 + ///
102.2125 + /// Returns an STL compatible iterator to the
102.2126 + /// first value of the map. The values of the
102.2127 + /// map can be accessed in the <tt>[beginValue, endValue)</tt>
102.2128 + /// range.
102.2129 + ValueIt beginValue() const {
102.2130 + return ValueIt(_first.begin());
102.2131 + }
102.2132 +
102.2133 + /// \brief Returns an iterator after the last value.
102.2134 + ///
102.2135 + /// Returns an STL compatible iterator after the
102.2136 + /// last value of the map. The values of the
102.2137 + /// map can be accessed in the <tt>[beginValue, endValue)</tt>
102.2138 + /// range.
102.2139 + ValueIt endValue() const {
102.2140 + return ValueIt(_first.end());
102.2141 + }
102.2142 +
102.2143 + /// \brief Set operation of the map.
102.2144 + ///
102.2145 + /// Set operation of the map.
102.2146 + void set(const Key& key, const Value& value) {
102.2147 + unlace(key);
102.2148 + Parent::operator[](key).value = value;
102.2149 + lace(key);
102.2150 + }
102.2151 +
102.2152 + /// \brief Const subscript operator of the map.
102.2153 + ///
102.2154 + /// Const subscript operator of the map.
102.2155 + const Value& operator[](const Key& key) const {
102.2156 + return Parent::operator[](key).value;
102.2157 + }
102.2158 +
102.2159 + /// \brief Iterator for the keys with the same value.
102.2160 + ///
102.2161 + /// Iterator for the keys with the same value. It works
102.2162 + /// like a graph item iterator, it can be converted to
102.2163 + /// the item type of the map, incremented with \c ++ operator, and
102.2164 + /// if the iterator leaves the last valid item, it will be equal to
102.2165 + /// \c INVALID.
102.2166 + class ItemIt : public Key {
102.2167 + public:
102.2168 + typedef Key Parent;
102.2169 +
102.2170 + /// \brief Invalid constructor \& conversion.
102.2171 + ///
102.2172 + /// This constructor initializes the iterator to be invalid.
102.2173 + /// \sa Invalid for more details.
102.2174 + ItemIt(Invalid) : Parent(INVALID), _map(0) {}
102.2175 +
102.2176 + /// \brief Creates an iterator with a value.
102.2177 + ///
102.2178 + /// Creates an iterator with a value. It iterates on the
102.2179 + /// keys which have the given value.
102.2180 + /// \param map The IterableValueMap
102.2181 + /// \param value The value
102.2182 + ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) {
102.2183 + typename std::map<Value, Key>::const_iterator it =
102.2184 + map._first.find(value);
102.2185 + if (it == map._first.end()) {
102.2186 + Parent::operator=(INVALID);
102.2187 + } else {
102.2188 + Parent::operator=(it->second);
102.2189 + }
102.2190 + }
102.2191 +
102.2192 + /// \brief Increment operator.
102.2193 + ///
102.2194 + /// Increment Operator.
102.2195 + ItemIt& operator++() {
102.2196 + Parent::operator=(_map->IterableValueMap::Parent::
102.2197 + operator[](static_cast<Parent&>(*this)).next);
102.2198 + return *this;
102.2199 + }
102.2200 +
102.2201 +
102.2202 + private:
102.2203 + const IterableValueMap* _map;
102.2204 + };
102.2205 +
102.2206 + protected:
102.2207 +
102.2208 + virtual void add(const Key& key) {
102.2209 + Parent::add(key);
102.2210 + unlace(key);
102.2211 + }
102.2212 +
102.2213 + virtual void add(const std::vector<Key>& keys) {
102.2214 + Parent::add(keys);
102.2215 + for (int i = 0; i < int(keys.size()); ++i) {
102.2216 + lace(keys[i]);
102.2217 + }
102.2218 + }
102.2219 +
102.2220 + virtual void erase(const Key& key) {
102.2221 + unlace(key);
102.2222 + Parent::erase(key);
102.2223 + }
102.2224 +
102.2225 + virtual void erase(const std::vector<Key>& keys) {
102.2226 + for (int i = 0; i < int(keys.size()); ++i) {
102.2227 + unlace(keys[i]);
102.2228 + }
102.2229 + Parent::erase(keys);
102.2230 + }
102.2231 +
102.2232 + virtual void build() {
102.2233 + Parent::build();
102.2234 + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
102.2235 + lace(it);
102.2236 + }
102.2237 + }
102.2238 +
102.2239 + virtual void clear() {
102.2240 + _first.clear();
102.2241 + Parent::clear();
102.2242 + }
102.2243 +
102.2244 + private:
102.2245 + std::map<Value, Key> _first;
102.2246 + };
102.2247 +
102.2248 + /// \brief Map of the source nodes of arcs in a digraph.
102.2249 + ///
102.2250 + /// SourceMap provides access for the source node of each arc in a digraph,
102.2251 + /// which is returned by the \c source() function of the digraph.
102.2252 + /// \tparam GR The digraph type.
102.2253 /// \see TargetMap
102.2254 - template <typename Digraph>
102.2255 + template <typename GR>
102.2256 class SourceMap {
102.2257 public:
102.2258
102.2259 - typedef typename Digraph::Node Value;
102.2260 - typedef typename Digraph::Arc Key;
102.2261 + /// The key type (the \c Arc type of the digraph).
102.2262 + typedef typename GR::Arc Key;
102.2263 + /// The value type (the \c Node type of the digraph).
102.2264 + typedef typename GR::Node Value;
102.2265
102.2266 /// \brief Constructor
102.2267 ///
102.2268 - /// Constructor
102.2269 + /// Constructor.
102.2270 /// \param digraph The digraph that the map belongs to.
102.2271 - explicit SourceMap(const Digraph& digraph) : _digraph(digraph) {}
102.2272 -
102.2273 - /// \brief The subscript operator.
102.2274 + explicit SourceMap(const GR& digraph) : _graph(digraph) {}
102.2275 +
102.2276 + /// \brief Returns the source node of the given arc.
102.2277 ///
102.2278 - /// The subscript operator.
102.2279 - /// \param arc The arc
102.2280 - /// \return The source of the arc
102.2281 + /// Returns the source node of the given arc.
102.2282 Value operator[](const Key& arc) const {
102.2283 - return _digraph.source(arc);
102.2284 + return _graph.source(arc);
102.2285 }
102.2286
102.2287 private:
102.2288 - const Digraph& _digraph;
102.2289 + const GR& _graph;
102.2290 };
102.2291
102.2292 /// \brief Returns a \c SourceMap class.
102.2293 ///
102.2294 /// This function just returns an \c SourceMap class.
102.2295 /// \relates SourceMap
102.2296 - template <typename Digraph>
102.2297 - inline SourceMap<Digraph> sourceMap(const Digraph& digraph) {
102.2298 - return SourceMap<Digraph>(digraph);
102.2299 + template <typename GR>
102.2300 + inline SourceMap<GR> sourceMap(const GR& graph) {
102.2301 + return SourceMap<GR>(graph);
102.2302 }
102.2303
102.2304 - /// \brief Returns the target of the given arc.
102.2305 + /// \brief Map of the target nodes of arcs in a digraph.
102.2306 ///
102.2307 - /// The TargetMap gives back the target Node of the given arc.
102.2308 + /// TargetMap provides access for the target node of each arc in a digraph,
102.2309 + /// which is returned by the \c target() function of the digraph.
102.2310 + /// \tparam GR The digraph type.
102.2311 /// \see SourceMap
102.2312 - template <typename Digraph>
102.2313 + template <typename GR>
102.2314 class TargetMap {
102.2315 public:
102.2316
102.2317 - typedef typename Digraph::Node Value;
102.2318 - typedef typename Digraph::Arc Key;
102.2319 + /// The key type (the \c Arc type of the digraph).
102.2320 + typedef typename GR::Arc Key;
102.2321 + /// The value type (the \c Node type of the digraph).
102.2322 + typedef typename GR::Node Value;
102.2323
102.2324 /// \brief Constructor
102.2325 ///
102.2326 - /// Constructor
102.2327 + /// Constructor.
102.2328 /// \param digraph The digraph that the map belongs to.
102.2329 - explicit TargetMap(const Digraph& digraph) : _digraph(digraph) {}
102.2330 -
102.2331 - /// \brief The subscript operator.
102.2332 + explicit TargetMap(const GR& digraph) : _graph(digraph) {}
102.2333 +
102.2334 + /// \brief Returns the target node of the given arc.
102.2335 ///
102.2336 - /// The subscript operator.
102.2337 - /// \param e The arc
102.2338 - /// \return The target of the arc
102.2339 + /// Returns the target node of the given arc.
102.2340 Value operator[](const Key& e) const {
102.2341 - return _digraph.target(e);
102.2342 + return _graph.target(e);
102.2343 }
102.2344
102.2345 private:
102.2346 - const Digraph& _digraph;
102.2347 + const GR& _graph;
102.2348 };
102.2349
102.2350 /// \brief Returns a \c TargetMap class.
102.2351 ///
102.2352 /// This function just returns a \c TargetMap class.
102.2353 /// \relates TargetMap
102.2354 - template <typename Digraph>
102.2355 - inline TargetMap<Digraph> targetMap(const Digraph& digraph) {
102.2356 - return TargetMap<Digraph>(digraph);
102.2357 + template <typename GR>
102.2358 + inline TargetMap<GR> targetMap(const GR& graph) {
102.2359 + return TargetMap<GR>(graph);
102.2360 }
102.2361
102.2362 - /// \brief Returns the "forward" directed arc view of an edge.
102.2363 + /// \brief Map of the "forward" directed arc view of edges in a graph.
102.2364 ///
102.2365 - /// Returns the "forward" directed arc view of an edge.
102.2366 + /// ForwardMap provides access for the "forward" directed arc view of
102.2367 + /// each edge in a graph, which is returned by the \c direct() function
102.2368 + /// of the graph with \c true parameter.
102.2369 + /// \tparam GR The graph type.
102.2370 /// \see BackwardMap
102.2371 - template <typename Graph>
102.2372 + template <typename GR>
102.2373 class ForwardMap {
102.2374 public:
102.2375
102.2376 - typedef typename Graph::Arc Value;
102.2377 - typedef typename Graph::Edge Key;
102.2378 + /// The key type (the \c Edge type of the digraph).
102.2379 + typedef typename GR::Edge Key;
102.2380 + /// The value type (the \c Arc type of the digraph).
102.2381 + typedef typename GR::Arc Value;
102.2382
102.2383 /// \brief Constructor
102.2384 ///
102.2385 - /// Constructor
102.2386 + /// Constructor.
102.2387 /// \param graph The graph that the map belongs to.
102.2388 - explicit ForwardMap(const Graph& graph) : _graph(graph) {}
102.2389 -
102.2390 - /// \brief The subscript operator.
102.2391 + explicit ForwardMap(const GR& graph) : _graph(graph) {}
102.2392 +
102.2393 + /// \brief Returns the "forward" directed arc view of the given edge.
102.2394 ///
102.2395 - /// The subscript operator.
102.2396 - /// \param key An edge
102.2397 - /// \return The "forward" directed arc view of edge
102.2398 + /// Returns the "forward" directed arc view of the given edge.
102.2399 Value operator[](const Key& key) const {
102.2400 return _graph.direct(key, true);
102.2401 }
102.2402
102.2403 private:
102.2404 - const Graph& _graph;
102.2405 + const GR& _graph;
102.2406 };
102.2407
102.2408 /// \brief Returns a \c ForwardMap class.
102.2409 ///
102.2410 /// This function just returns an \c ForwardMap class.
102.2411 /// \relates ForwardMap
102.2412 - template <typename Graph>
102.2413 - inline ForwardMap<Graph> forwardMap(const Graph& graph) {
102.2414 - return ForwardMap<Graph>(graph);
102.2415 + template <typename GR>
102.2416 + inline ForwardMap<GR> forwardMap(const GR& graph) {
102.2417 + return ForwardMap<GR>(graph);
102.2418 }
102.2419
102.2420 - /// \brief Returns the "backward" directed arc view of an edge.
102.2421 + /// \brief Map of the "backward" directed arc view of edges in a graph.
102.2422 ///
102.2423 - /// Returns the "backward" directed arc view of an edge.
102.2424 + /// BackwardMap provides access for the "backward" directed arc view of
102.2425 + /// each edge in a graph, which is returned by the \c direct() function
102.2426 + /// of the graph with \c false parameter.
102.2427 + /// \tparam GR The graph type.
102.2428 /// \see ForwardMap
102.2429 - template <typename Graph>
102.2430 + template <typename GR>
102.2431 class BackwardMap {
102.2432 public:
102.2433
102.2434 - typedef typename Graph::Arc Value;
102.2435 - typedef typename Graph::Edge Key;
102.2436 + /// The key type (the \c Edge type of the digraph).
102.2437 + typedef typename GR::Edge Key;
102.2438 + /// The value type (the \c Arc type of the digraph).
102.2439 + typedef typename GR::Arc Value;
102.2440
102.2441 /// \brief Constructor
102.2442 ///
102.2443 - /// Constructor
102.2444 + /// Constructor.
102.2445 /// \param graph The graph that the map belongs to.
102.2446 - explicit BackwardMap(const Graph& graph) : _graph(graph) {}
102.2447 -
102.2448 - /// \brief The subscript operator.
102.2449 + explicit BackwardMap(const GR& graph) : _graph(graph) {}
102.2450 +
102.2451 + /// \brief Returns the "backward" directed arc view of the given edge.
102.2452 ///
102.2453 - /// The subscript operator.
102.2454 - /// \param key An edge
102.2455 - /// \return The "backward" directed arc view of edge
102.2456 + /// Returns the "backward" directed arc view of the given edge.
102.2457 Value operator[](const Key& key) const {
102.2458 return _graph.direct(key, false);
102.2459 }
102.2460
102.2461 private:
102.2462 - const Graph& _graph;
102.2463 + const GR& _graph;
102.2464 };
102.2465
102.2466 /// \brief Returns a \c BackwardMap class
102.2467
102.2468 /// This function just returns a \c BackwardMap class.
102.2469 /// \relates BackwardMap
102.2470 - template <typename Graph>
102.2471 - inline BackwardMap<Graph> backwardMap(const Graph& graph) {
102.2472 - return BackwardMap<Graph>(graph);
102.2473 + template <typename GR>
102.2474 + inline BackwardMap<GR> backwardMap(const GR& graph) {
102.2475 + return BackwardMap<GR>(graph);
102.2476 }
102.2477
102.2478 - /// \brief Potential difference map
102.2479 - ///
102.2480 - /// If there is an potential map on the nodes then we
102.2481 - /// can get an arc map as we get the substraction of the
102.2482 - /// values of the target and source.
102.2483 - template <typename Digraph, typename NodeMap>
102.2484 - class PotentialDifferenceMap {
102.2485 - public:
102.2486 - typedef typename Digraph::Arc Key;
102.2487 - typedef typename NodeMap::Value Value;
102.2488 -
102.2489 - /// \brief Constructor
102.2490 - ///
102.2491 - /// Contructor of the map
102.2492 - explicit PotentialDifferenceMap(const Digraph& digraph,
102.2493 - const NodeMap& potential)
102.2494 - : _digraph(digraph), _potential(potential) {}
102.2495 -
102.2496 - /// \brief Const subscription operator
102.2497 - ///
102.2498 - /// Const subscription operator
102.2499 - Value operator[](const Key& arc) const {
102.2500 - return _potential[_digraph.target(arc)] -
102.2501 - _potential[_digraph.source(arc)];
102.2502 - }
102.2503 -
102.2504 - private:
102.2505 - const Digraph& _digraph;
102.2506 - const NodeMap& _potential;
102.2507 - };
102.2508 -
102.2509 - /// \brief Returns a PotentialDifferenceMap.
102.2510 - ///
102.2511 - /// This function just returns a PotentialDifferenceMap.
102.2512 - /// \relates PotentialDifferenceMap
102.2513 - template <typename Digraph, typename NodeMap>
102.2514 - PotentialDifferenceMap<Digraph, NodeMap>
102.2515 - potentialDifferenceMap(const Digraph& digraph, const NodeMap& potential) {
102.2516 - return PotentialDifferenceMap<Digraph, NodeMap>(digraph, potential);
102.2517 - }
102.2518 -
102.2519 - /// \brief Map of the node in-degrees.
102.2520 + /// \brief Map of the in-degrees of nodes in a digraph.
102.2521 ///
102.2522 /// This map returns the in-degree of a node. Once it is constructed,
102.2523 - /// the degrees are stored in a standard NodeMap, so each query is done
102.2524 + /// the degrees are stored in a standard \c NodeMap, so each query is done
102.2525 /// in constant time. On the other hand, the values are updated automatically
102.2526 /// whenever the digraph changes.
102.2527 ///
102.2528 - /// \warning Besides addNode() and addArc(), a digraph structure may provide
102.2529 - /// alternative ways to modify the digraph. The correct behavior of InDegMap
102.2530 - /// is not guarantied if these additional features are used. For example
102.2531 - /// the functions \ref ListDigraph::changeSource() "changeSource()",
102.2532 + /// \warning Besides \c addNode() and \c addArc(), a digraph structure
102.2533 + /// may provide alternative ways to modify the digraph.
102.2534 + /// The correct behavior of InDegMap is not guarantied if these additional
102.2535 + /// features are used. For example the functions
102.2536 + /// \ref ListDigraph::changeSource() "changeSource()",
102.2537 /// \ref ListDigraph::changeTarget() "changeTarget()" and
102.2538 /// \ref ListDigraph::reverseArc() "reverseArc()"
102.2539 /// of \ref ListDigraph will \e not update the degree values correctly.
102.2540 ///
102.2541 /// \sa OutDegMap
102.2542 -
102.2543 - template <typename _Digraph>
102.2544 + template <typename GR>
102.2545 class InDegMap
102.2546 - : protected ItemSetTraits<_Digraph, typename _Digraph::Arc>
102.2547 + : protected ItemSetTraits<GR, typename GR::Arc>
102.2548 ::ItemNotifier::ObserverBase {
102.2549
102.2550 public:
102.2551
102.2552 - typedef _Digraph Digraph;
102.2553 + /// The graph type of InDegMap
102.2554 + typedef GR Graph;
102.2555 + typedef GR Digraph;
102.2556 + /// The key type
102.2557 + typedef typename Digraph::Node Key;
102.2558 + /// The value type
102.2559 typedef int Value;
102.2560 - typedef typename Digraph::Node Key;
102.2561
102.2562 typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
102.2563 ::ItemNotifier::ObserverBase Parent;
102.2564 @@ -2523,9 +3528,9 @@
102.2565
102.2566 /// \brief Constructor.
102.2567 ///
102.2568 - /// Constructor for creating in-degree map.
102.2569 - explicit InDegMap(const Digraph& digraph)
102.2570 - : _digraph(digraph), _deg(digraph) {
102.2571 + /// Constructor for creating an in-degree map.
102.2572 + explicit InDegMap(const Digraph& graph)
102.2573 + : _digraph(graph), _deg(graph) {
102.2574 Parent::attach(_digraph.notifier(typename Digraph::Arc()));
102.2575
102.2576 for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
102.2577 @@ -2533,6 +3538,8 @@
102.2578 }
102.2579 }
102.2580
102.2581 + /// \brief Gives back the in-degree of a Node.
102.2582 + ///
102.2583 /// Gives back the in-degree of a Node.
102.2584 int operator[](const Key& key) const {
102.2585 return _deg[key];
102.2586 @@ -2579,33 +3586,37 @@
102.2587 AutoNodeMap _deg;
102.2588 };
102.2589
102.2590 - /// \brief Map of the node out-degrees.
102.2591 + /// \brief Map of the out-degrees of nodes in a digraph.
102.2592 ///
102.2593 /// This map returns the out-degree of a node. Once it is constructed,
102.2594 - /// the degrees are stored in a standard NodeMap, so each query is done
102.2595 + /// the degrees are stored in a standard \c NodeMap, so each query is done
102.2596 /// in constant time. On the other hand, the values are updated automatically
102.2597 /// whenever the digraph changes.
102.2598 ///
102.2599 - /// \warning Besides addNode() and addArc(), a digraph structure may provide
102.2600 - /// alternative ways to modify the digraph. The correct behavior of OutDegMap
102.2601 - /// is not guarantied if these additional features are used. For example
102.2602 - /// the functions \ref ListDigraph::changeSource() "changeSource()",
102.2603 + /// \warning Besides \c addNode() and \c addArc(), a digraph structure
102.2604 + /// may provide alternative ways to modify the digraph.
102.2605 + /// The correct behavior of OutDegMap is not guarantied if these additional
102.2606 + /// features are used. For example the functions
102.2607 + /// \ref ListDigraph::changeSource() "changeSource()",
102.2608 /// \ref ListDigraph::changeTarget() "changeTarget()" and
102.2609 /// \ref ListDigraph::reverseArc() "reverseArc()"
102.2610 /// of \ref ListDigraph will \e not update the degree values correctly.
102.2611 ///
102.2612 /// \sa InDegMap
102.2613 -
102.2614 - template <typename _Digraph>
102.2615 + template <typename GR>
102.2616 class OutDegMap
102.2617 - : protected ItemSetTraits<_Digraph, typename _Digraph::Arc>
102.2618 + : protected ItemSetTraits<GR, typename GR::Arc>
102.2619 ::ItemNotifier::ObserverBase {
102.2620
102.2621 public:
102.2622
102.2623 - typedef _Digraph Digraph;
102.2624 + /// The graph type of OutDegMap
102.2625 + typedef GR Graph;
102.2626 + typedef GR Digraph;
102.2627 + /// The key type
102.2628 + typedef typename Digraph::Node Key;
102.2629 + /// The value type
102.2630 typedef int Value;
102.2631 - typedef typename Digraph::Node Key;
102.2632
102.2633 typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
102.2634 ::ItemNotifier::ObserverBase Parent;
102.2635 @@ -2645,9 +3656,9 @@
102.2636
102.2637 /// \brief Constructor.
102.2638 ///
102.2639 - /// Constructor for creating out-degree map.
102.2640 - explicit OutDegMap(const Digraph& digraph)
102.2641 - : _digraph(digraph), _deg(digraph) {
102.2642 + /// Constructor for creating an out-degree map.
102.2643 + explicit OutDegMap(const Digraph& graph)
102.2644 + : _digraph(graph), _deg(graph) {
102.2645 Parent::attach(_digraph.notifier(typename Digraph::Arc()));
102.2646
102.2647 for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
102.2648 @@ -2655,6 +3666,8 @@
102.2649 }
102.2650 }
102.2651
102.2652 + /// \brief Gives back the out-degree of a Node.
102.2653 + ///
102.2654 /// Gives back the out-degree of a Node.
102.2655 int operator[](const Key& key) const {
102.2656 return _deg[key];
102.2657 @@ -2701,6 +3714,56 @@
102.2658 AutoNodeMap _deg;
102.2659 };
102.2660
102.2661 + /// \brief Potential difference map
102.2662 + ///
102.2663 + /// PotentialDifferenceMap returns the difference between the potentials of
102.2664 + /// the source and target nodes of each arc in a digraph, i.e. it returns
102.2665 + /// \code
102.2666 + /// potential[gr.target(arc)] - potential[gr.source(arc)].
102.2667 + /// \endcode
102.2668 + /// \tparam GR The digraph type.
102.2669 + /// \tparam POT A node map storing the potentials.
102.2670 + template <typename GR, typename POT>
102.2671 + class PotentialDifferenceMap {
102.2672 + public:
102.2673 + /// Key type
102.2674 + typedef typename GR::Arc Key;
102.2675 + /// Value type
102.2676 + typedef typename POT::Value Value;
102.2677 +
102.2678 + /// \brief Constructor
102.2679 + ///
102.2680 + /// Contructor of the map.
102.2681 + explicit PotentialDifferenceMap(const GR& gr,
102.2682 + const POT& potential)
102.2683 + : _digraph(gr), _potential(potential) {}
102.2684 +
102.2685 + /// \brief Returns the potential difference for the given arc.
102.2686 + ///
102.2687 + /// Returns the potential difference for the given arc, i.e.
102.2688 + /// \code
102.2689 + /// potential[gr.target(arc)] - potential[gr.source(arc)].
102.2690 + /// \endcode
102.2691 + Value operator[](const Key& arc) const {
102.2692 + return _potential[_digraph.target(arc)] -
102.2693 + _potential[_digraph.source(arc)];
102.2694 + }
102.2695 +
102.2696 + private:
102.2697 + const GR& _digraph;
102.2698 + const POT& _potential;
102.2699 + };
102.2700 +
102.2701 + /// \brief Returns a PotentialDifferenceMap.
102.2702 + ///
102.2703 + /// This function just returns a PotentialDifferenceMap.
102.2704 + /// \relates PotentialDifferenceMap
102.2705 + template <typename GR, typename POT>
102.2706 + PotentialDifferenceMap<GR, POT>
102.2707 + potentialDifferenceMap(const GR& gr, const POT& potential) {
102.2708 + return PotentialDifferenceMap<GR, POT>(gr, potential);
102.2709 + }
102.2710 +
102.2711 /// @}
102.2712 }
102.2713
103.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
103.2 +++ b/lemon/matching.h Thu Nov 05 15:48:01 2009 +0100
103.3 @@ -0,0 +1,3244 @@
103.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
103.5 + *
103.6 + * This file is a part of LEMON, a generic C++ optimization library.
103.7 + *
103.8 + * Copyright (C) 2003-2009
103.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
103.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
103.11 + *
103.12 + * Permission to use, modify and distribute this software is granted
103.13 + * provided that this copyright notice appears in all copies. For
103.14 + * precise terms see the accompanying LICENSE file.
103.15 + *
103.16 + * This software is provided "AS IS" with no warranty of any kind,
103.17 + * express or implied, and with no claim as to its suitability for any
103.18 + * purpose.
103.19 + *
103.20 + */
103.21 +
103.22 +#ifndef LEMON_MAX_MATCHING_H
103.23 +#define LEMON_MAX_MATCHING_H
103.24 +
103.25 +#include <vector>
103.26 +#include <queue>
103.27 +#include <set>
103.28 +#include <limits>
103.29 +
103.30 +#include <lemon/core.h>
103.31 +#include <lemon/unionfind.h>
103.32 +#include <lemon/bin_heap.h>
103.33 +#include <lemon/maps.h>
103.34 +
103.35 +///\ingroup matching
103.36 +///\file
103.37 +///\brief Maximum matching algorithms in general graphs.
103.38 +
103.39 +namespace lemon {
103.40 +
103.41 + /// \ingroup matching
103.42 + ///
103.43 + /// \brief Maximum cardinality matching in general graphs
103.44 + ///
103.45 + /// This class implements Edmonds' alternating forest matching algorithm
103.46 + /// for finding a maximum cardinality matching in a general undirected graph.
103.47 + /// It can be started from an arbitrary initial matching
103.48 + /// (the default is the empty one).
103.49 + ///
103.50 + /// The dual solution of the problem is a map of the nodes to
103.51 + /// \ref MaxMatching::Status "Status", having values \c EVEN (or \c D),
103.52 + /// \c ODD (or \c A) and \c MATCHED (or \c C) defining the Gallai-Edmonds
103.53 + /// decomposition of the graph. The nodes in \c EVEN/D induce a subgraph
103.54 + /// with factor-critical components, the nodes in \c ODD/A form the
103.55 + /// canonical barrier, and the nodes in \c MATCHED/C induce a graph having
103.56 + /// a perfect matching. The number of the factor-critical components
103.57 + /// minus the number of barrier nodes is a lower bound on the
103.58 + /// unmatched nodes, and the matching is optimal if and only if this bound is
103.59 + /// tight. This decomposition can be obtained using \ref status() or
103.60 + /// \ref statusMap() after running the algorithm.
103.61 + ///
103.62 + /// \tparam GR The undirected graph type the algorithm runs on.
103.63 + template <typename GR>
103.64 + class MaxMatching {
103.65 + public:
103.66 +
103.67 + /// The graph type of the algorithm
103.68 + typedef GR Graph;
103.69 + /// The type of the matching map
103.70 + typedef typename Graph::template NodeMap<typename Graph::Arc>
103.71 + MatchingMap;
103.72 +
103.73 + ///\brief Status constants for Gallai-Edmonds decomposition.
103.74 + ///
103.75 + ///These constants are used for indicating the Gallai-Edmonds
103.76 + ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
103.77 + ///induce a subgraph with factor-critical components, the nodes with
103.78 + ///status \c ODD (or \c A) form the canonical barrier, and the nodes
103.79 + ///with status \c MATCHED (or \c C) induce a subgraph having a
103.80 + ///perfect matching.
103.81 + enum Status {
103.82 + EVEN = 1, ///< = 1. (\c D is an alias for \c EVEN.)
103.83 + D = 1,
103.84 + MATCHED = 0, ///< = 0. (\c C is an alias for \c MATCHED.)
103.85 + C = 0,
103.86 + ODD = -1, ///< = -1. (\c A is an alias for \c ODD.)
103.87 + A = -1,
103.88 + UNMATCHED = -2 ///< = -2.
103.89 + };
103.90 +
103.91 + /// The type of the status map
103.92 + typedef typename Graph::template NodeMap<Status> StatusMap;
103.93 +
103.94 + private:
103.95 +
103.96 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
103.97 +
103.98 + typedef UnionFindEnum<IntNodeMap> BlossomSet;
103.99 + typedef ExtendFindEnum<IntNodeMap> TreeSet;
103.100 + typedef RangeMap<Node> NodeIntMap;
103.101 + typedef MatchingMap EarMap;
103.102 + typedef std::vector<Node> NodeQueue;
103.103 +
103.104 + const Graph& _graph;
103.105 + MatchingMap* _matching;
103.106 + StatusMap* _status;
103.107 +
103.108 + EarMap* _ear;
103.109 +
103.110 + IntNodeMap* _blossom_set_index;
103.111 + BlossomSet* _blossom_set;
103.112 + NodeIntMap* _blossom_rep;
103.113 +
103.114 + IntNodeMap* _tree_set_index;
103.115 + TreeSet* _tree_set;
103.116 +
103.117 + NodeQueue _node_queue;
103.118 + int _process, _postpone, _last;
103.119 +
103.120 + int _node_num;
103.121 +
103.122 + private:
103.123 +
103.124 + void createStructures() {
103.125 + _node_num = countNodes(_graph);
103.126 + if (!_matching) {
103.127 + _matching = new MatchingMap(_graph);
103.128 + }
103.129 + if (!_status) {
103.130 + _status = new StatusMap(_graph);
103.131 + }
103.132 + if (!_ear) {
103.133 + _ear = new EarMap(_graph);
103.134 + }
103.135 + if (!_blossom_set) {
103.136 + _blossom_set_index = new IntNodeMap(_graph);
103.137 + _blossom_set = new BlossomSet(*_blossom_set_index);
103.138 + }
103.139 + if (!_blossom_rep) {
103.140 + _blossom_rep = new NodeIntMap(_node_num);
103.141 + }
103.142 + if (!_tree_set) {
103.143 + _tree_set_index = new IntNodeMap(_graph);
103.144 + _tree_set = new TreeSet(*_tree_set_index);
103.145 + }
103.146 + _node_queue.resize(_node_num);
103.147 + }
103.148 +
103.149 + void destroyStructures() {
103.150 + if (_matching) {
103.151 + delete _matching;
103.152 + }
103.153 + if (_status) {
103.154 + delete _status;
103.155 + }
103.156 + if (_ear) {
103.157 + delete _ear;
103.158 + }
103.159 + if (_blossom_set) {
103.160 + delete _blossom_set;
103.161 + delete _blossom_set_index;
103.162 + }
103.163 + if (_blossom_rep) {
103.164 + delete _blossom_rep;
103.165 + }
103.166 + if (_tree_set) {
103.167 + delete _tree_set_index;
103.168 + delete _tree_set;
103.169 + }
103.170 + }
103.171 +
103.172 + void processDense(const Node& n) {
103.173 + _process = _postpone = _last = 0;
103.174 + _node_queue[_last++] = n;
103.175 +
103.176 + while (_process != _last) {
103.177 + Node u = _node_queue[_process++];
103.178 + for (OutArcIt a(_graph, u); a != INVALID; ++a) {
103.179 + Node v = _graph.target(a);
103.180 + if ((*_status)[v] == MATCHED) {
103.181 + extendOnArc(a);
103.182 + } else if ((*_status)[v] == UNMATCHED) {
103.183 + augmentOnArc(a);
103.184 + return;
103.185 + }
103.186 + }
103.187 + }
103.188 +
103.189 + while (_postpone != _last) {
103.190 + Node u = _node_queue[_postpone++];
103.191 +
103.192 + for (OutArcIt a(_graph, u); a != INVALID ; ++a) {
103.193 + Node v = _graph.target(a);
103.194 +
103.195 + if ((*_status)[v] == EVEN) {
103.196 + if (_blossom_set->find(u) != _blossom_set->find(v)) {
103.197 + shrinkOnEdge(a);
103.198 + }
103.199 + }
103.200 +
103.201 + while (_process != _last) {
103.202 + Node w = _node_queue[_process++];
103.203 + for (OutArcIt b(_graph, w); b != INVALID; ++b) {
103.204 + Node x = _graph.target(b);
103.205 + if ((*_status)[x] == MATCHED) {
103.206 + extendOnArc(b);
103.207 + } else if ((*_status)[x] == UNMATCHED) {
103.208 + augmentOnArc(b);
103.209 + return;
103.210 + }
103.211 + }
103.212 + }
103.213 + }
103.214 + }
103.215 + }
103.216 +
103.217 + void processSparse(const Node& n) {
103.218 + _process = _last = 0;
103.219 + _node_queue[_last++] = n;
103.220 + while (_process != _last) {
103.221 + Node u = _node_queue[_process++];
103.222 + for (OutArcIt a(_graph, u); a != INVALID; ++a) {
103.223 + Node v = _graph.target(a);
103.224 +
103.225 + if ((*_status)[v] == EVEN) {
103.226 + if (_blossom_set->find(u) != _blossom_set->find(v)) {
103.227 + shrinkOnEdge(a);
103.228 + }
103.229 + } else if ((*_status)[v] == MATCHED) {
103.230 + extendOnArc(a);
103.231 + } else if ((*_status)[v] == UNMATCHED) {
103.232 + augmentOnArc(a);
103.233 + return;
103.234 + }
103.235 + }
103.236 + }
103.237 + }
103.238 +
103.239 + void shrinkOnEdge(const Edge& e) {
103.240 + Node nca = INVALID;
103.241 +
103.242 + {
103.243 + std::set<Node> left_set, right_set;
103.244 +
103.245 + Node left = (*_blossom_rep)[_blossom_set->find(_graph.u(e))];
103.246 + left_set.insert(left);
103.247 +
103.248 + Node right = (*_blossom_rep)[_blossom_set->find(_graph.v(e))];
103.249 + right_set.insert(right);
103.250 +
103.251 + while (true) {
103.252 + if ((*_matching)[left] == INVALID) break;
103.253 + left = _graph.target((*_matching)[left]);
103.254 + left = (*_blossom_rep)[_blossom_set->
103.255 + find(_graph.target((*_ear)[left]))];
103.256 + if (right_set.find(left) != right_set.end()) {
103.257 + nca = left;
103.258 + break;
103.259 + }
103.260 + left_set.insert(left);
103.261 +
103.262 + if ((*_matching)[right] == INVALID) break;
103.263 + right = _graph.target((*_matching)[right]);
103.264 + right = (*_blossom_rep)[_blossom_set->
103.265 + find(_graph.target((*_ear)[right]))];
103.266 + if (left_set.find(right) != left_set.end()) {
103.267 + nca = right;
103.268 + break;
103.269 + }
103.270 + right_set.insert(right);
103.271 + }
103.272 +
103.273 + if (nca == INVALID) {
103.274 + if ((*_matching)[left] == INVALID) {
103.275 + nca = right;
103.276 + while (left_set.find(nca) == left_set.end()) {
103.277 + nca = _graph.target((*_matching)[nca]);
103.278 + nca =(*_blossom_rep)[_blossom_set->
103.279 + find(_graph.target((*_ear)[nca]))];
103.280 + }
103.281 + } else {
103.282 + nca = left;
103.283 + while (right_set.find(nca) == right_set.end()) {
103.284 + nca = _graph.target((*_matching)[nca]);
103.285 + nca = (*_blossom_rep)[_blossom_set->
103.286 + find(_graph.target((*_ear)[nca]))];
103.287 + }
103.288 + }
103.289 + }
103.290 + }
103.291 +
103.292 + {
103.293 +
103.294 + Node node = _graph.u(e);
103.295 + Arc arc = _graph.direct(e, true);
103.296 + Node base = (*_blossom_rep)[_blossom_set->find(node)];
103.297 +
103.298 + while (base != nca) {
103.299 + (*_ear)[node] = arc;
103.300 +
103.301 + Node n = node;
103.302 + while (n != base) {
103.303 + n = _graph.target((*_matching)[n]);
103.304 + Arc a = (*_ear)[n];
103.305 + n = _graph.target(a);
103.306 + (*_ear)[n] = _graph.oppositeArc(a);
103.307 + }
103.308 + node = _graph.target((*_matching)[base]);
103.309 + _tree_set->erase(base);
103.310 + _tree_set->erase(node);
103.311 + _blossom_set->insert(node, _blossom_set->find(base));
103.312 + (*_status)[node] = EVEN;
103.313 + _node_queue[_last++] = node;
103.314 + arc = _graph.oppositeArc((*_ear)[node]);
103.315 + node = _graph.target((*_ear)[node]);
103.316 + base = (*_blossom_rep)[_blossom_set->find(node)];
103.317 + _blossom_set->join(_graph.target(arc), base);
103.318 + }
103.319 + }
103.320 +
103.321 + (*_blossom_rep)[_blossom_set->find(nca)] = nca;
103.322 +
103.323 + {
103.324 +
103.325 + Node node = _graph.v(e);
103.326 + Arc arc = _graph.direct(e, false);
103.327 + Node base = (*_blossom_rep)[_blossom_set->find(node)];
103.328 +
103.329 + while (base != nca) {
103.330 + (*_ear)[node] = arc;
103.331 +
103.332 + Node n = node;
103.333 + while (n != base) {
103.334 + n = _graph.target((*_matching)[n]);
103.335 + Arc a = (*_ear)[n];
103.336 + n = _graph.target(a);
103.337 + (*_ear)[n] = _graph.oppositeArc(a);
103.338 + }
103.339 + node = _graph.target((*_matching)[base]);
103.340 + _tree_set->erase(base);
103.341 + _tree_set->erase(node);
103.342 + _blossom_set->insert(node, _blossom_set->find(base));
103.343 + (*_status)[node] = EVEN;
103.344 + _node_queue[_last++] = node;
103.345 + arc = _graph.oppositeArc((*_ear)[node]);
103.346 + node = _graph.target((*_ear)[node]);
103.347 + base = (*_blossom_rep)[_blossom_set->find(node)];
103.348 + _blossom_set->join(_graph.target(arc), base);
103.349 + }
103.350 + }
103.351 +
103.352 + (*_blossom_rep)[_blossom_set->find(nca)] = nca;
103.353 + }
103.354 +
103.355 + void extendOnArc(const Arc& a) {
103.356 + Node base = _graph.source(a);
103.357 + Node odd = _graph.target(a);
103.358 +
103.359 + (*_ear)[odd] = _graph.oppositeArc(a);
103.360 + Node even = _graph.target((*_matching)[odd]);
103.361 + (*_blossom_rep)[_blossom_set->insert(even)] = even;
103.362 + (*_status)[odd] = ODD;
103.363 + (*_status)[even] = EVEN;
103.364 + int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(base)]);
103.365 + _tree_set->insert(odd, tree);
103.366 + _tree_set->insert(even, tree);
103.367 + _node_queue[_last++] = even;
103.368 +
103.369 + }
103.370 +
103.371 + void augmentOnArc(const Arc& a) {
103.372 + Node even = _graph.source(a);
103.373 + Node odd = _graph.target(a);
103.374 +
103.375 + int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(even)]);
103.376 +
103.377 + (*_matching)[odd] = _graph.oppositeArc(a);
103.378 + (*_status)[odd] = MATCHED;
103.379 +
103.380 + Arc arc = (*_matching)[even];
103.381 + (*_matching)[even] = a;
103.382 +
103.383 + while (arc != INVALID) {
103.384 + odd = _graph.target(arc);
103.385 + arc = (*_ear)[odd];
103.386 + even = _graph.target(arc);
103.387 + (*_matching)[odd] = arc;
103.388 + arc = (*_matching)[even];
103.389 + (*_matching)[even] = _graph.oppositeArc((*_matching)[odd]);
103.390 + }
103.391 +
103.392 + for (typename TreeSet::ItemIt it(*_tree_set, tree);
103.393 + it != INVALID; ++it) {
103.394 + if ((*_status)[it] == ODD) {
103.395 + (*_status)[it] = MATCHED;
103.396 + } else {
103.397 + int blossom = _blossom_set->find(it);
103.398 + for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom);
103.399 + jt != INVALID; ++jt) {
103.400 + (*_status)[jt] = MATCHED;
103.401 + }
103.402 + _blossom_set->eraseClass(blossom);
103.403 + }
103.404 + }
103.405 + _tree_set->eraseClass(tree);
103.406 +
103.407 + }
103.408 +
103.409 + public:
103.410 +
103.411 + /// \brief Constructor
103.412 + ///
103.413 + /// Constructor.
103.414 + MaxMatching(const Graph& graph)
103.415 + : _graph(graph), _matching(0), _status(0), _ear(0),
103.416 + _blossom_set_index(0), _blossom_set(0), _blossom_rep(0),
103.417 + _tree_set_index(0), _tree_set(0) {}
103.418 +
103.419 + ~MaxMatching() {
103.420 + destroyStructures();
103.421 + }
103.422 +
103.423 + /// \name Execution Control
103.424 + /// The simplest way to execute the algorithm is to use the
103.425 + /// \c run() member function.\n
103.426 + /// If you need better control on the execution, you have to call
103.427 + /// one of the functions \ref init(), \ref greedyInit() or
103.428 + /// \ref matchingInit() first, then you can start the algorithm with
103.429 + /// \ref startSparse() or \ref startDense().
103.430 +
103.431 + ///@{
103.432 +
103.433 + /// \brief Set the initial matching to the empty matching.
103.434 + ///
103.435 + /// This function sets the initial matching to the empty matching.
103.436 + void init() {
103.437 + createStructures();
103.438 + for(NodeIt n(_graph); n != INVALID; ++n) {
103.439 + (*_matching)[n] = INVALID;
103.440 + (*_status)[n] = UNMATCHED;
103.441 + }
103.442 + }
103.443 +
103.444 + /// \brief Find an initial matching in a greedy way.
103.445 + ///
103.446 + /// This function finds an initial matching in a greedy way.
103.447 + void greedyInit() {
103.448 + createStructures();
103.449 + for (NodeIt n(_graph); n != INVALID; ++n) {
103.450 + (*_matching)[n] = INVALID;
103.451 + (*_status)[n] = UNMATCHED;
103.452 + }
103.453 + for (NodeIt n(_graph); n != INVALID; ++n) {
103.454 + if ((*_matching)[n] == INVALID) {
103.455 + for (OutArcIt a(_graph, n); a != INVALID ; ++a) {
103.456 + Node v = _graph.target(a);
103.457 + if ((*_matching)[v] == INVALID && v != n) {
103.458 + (*_matching)[n] = a;
103.459 + (*_status)[n] = MATCHED;
103.460 + (*_matching)[v] = _graph.oppositeArc(a);
103.461 + (*_status)[v] = MATCHED;
103.462 + break;
103.463 + }
103.464 + }
103.465 + }
103.466 + }
103.467 + }
103.468 +
103.469 +
103.470 + /// \brief Initialize the matching from a map.
103.471 + ///
103.472 + /// This function initializes the matching from a \c bool valued edge
103.473 + /// map. This map should have the property that there are no two incident
103.474 + /// edges with \c true value, i.e. it really contains a matching.
103.475 + /// \return \c true if the map contains a matching.
103.476 + template <typename MatchingMap>
103.477 + bool matchingInit(const MatchingMap& matching) {
103.478 + createStructures();
103.479 +
103.480 + for (NodeIt n(_graph); n != INVALID; ++n) {
103.481 + (*_matching)[n] = INVALID;
103.482 + (*_status)[n] = UNMATCHED;
103.483 + }
103.484 + for(EdgeIt e(_graph); e!=INVALID; ++e) {
103.485 + if (matching[e]) {
103.486 +
103.487 + Node u = _graph.u(e);
103.488 + if ((*_matching)[u] != INVALID) return false;
103.489 + (*_matching)[u] = _graph.direct(e, true);
103.490 + (*_status)[u] = MATCHED;
103.491 +
103.492 + Node v = _graph.v(e);
103.493 + if ((*_matching)[v] != INVALID) return false;
103.494 + (*_matching)[v] = _graph.direct(e, false);
103.495 + (*_status)[v] = MATCHED;
103.496 + }
103.497 + }
103.498 + return true;
103.499 + }
103.500 +
103.501 + /// \brief Start Edmonds' algorithm
103.502 + ///
103.503 + /// This function runs the original Edmonds' algorithm.
103.504 + ///
103.505 + /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
103.506 + /// called before using this function.
103.507 + void startSparse() {
103.508 + for(NodeIt n(_graph); n != INVALID; ++n) {
103.509 + if ((*_status)[n] == UNMATCHED) {
103.510 + (*_blossom_rep)[_blossom_set->insert(n)] = n;
103.511 + _tree_set->insert(n);
103.512 + (*_status)[n] = EVEN;
103.513 + processSparse(n);
103.514 + }
103.515 + }
103.516 + }
103.517 +
103.518 + /// \brief Start Edmonds' algorithm with a heuristic improvement
103.519 + /// for dense graphs
103.520 + ///
103.521 + /// This function runs Edmonds' algorithm with a heuristic of postponing
103.522 + /// shrinks, therefore resulting in a faster algorithm for dense graphs.
103.523 + ///
103.524 + /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
103.525 + /// called before using this function.
103.526 + void startDense() {
103.527 + for(NodeIt n(_graph); n != INVALID; ++n) {
103.528 + if ((*_status)[n] == UNMATCHED) {
103.529 + (*_blossom_rep)[_blossom_set->insert(n)] = n;
103.530 + _tree_set->insert(n);
103.531 + (*_status)[n] = EVEN;
103.532 + processDense(n);
103.533 + }
103.534 + }
103.535 + }
103.536 +
103.537 +
103.538 + /// \brief Run Edmonds' algorithm
103.539 + ///
103.540 + /// This function runs Edmonds' algorithm. An additional heuristic of
103.541 + /// postponing shrinks is used for relatively dense graphs
103.542 + /// (for which <tt>m>=2*n</tt> holds).
103.543 + void run() {
103.544 + if (countEdges(_graph) < 2 * countNodes(_graph)) {
103.545 + greedyInit();
103.546 + startSparse();
103.547 + } else {
103.548 + init();
103.549 + startDense();
103.550 + }
103.551 + }
103.552 +
103.553 + /// @}
103.554 +
103.555 + /// \name Primal Solution
103.556 + /// Functions to get the primal solution, i.e. the maximum matching.
103.557 +
103.558 + /// @{
103.559 +
103.560 + /// \brief Return the size (cardinality) of the matching.
103.561 + ///
103.562 + /// This function returns the size (cardinality) of the current matching.
103.563 + /// After run() it returns the size of the maximum matching in the graph.
103.564 + int matchingSize() const {
103.565 + int size = 0;
103.566 + for (NodeIt n(_graph); n != INVALID; ++n) {
103.567 + if ((*_matching)[n] != INVALID) {
103.568 + ++size;
103.569 + }
103.570 + }
103.571 + return size / 2;
103.572 + }
103.573 +
103.574 + /// \brief Return \c true if the given edge is in the matching.
103.575 + ///
103.576 + /// This function returns \c true if the given edge is in the current
103.577 + /// matching.
103.578 + bool matching(const Edge& edge) const {
103.579 + return edge == (*_matching)[_graph.u(edge)];
103.580 + }
103.581 +
103.582 + /// \brief Return the matching arc (or edge) incident to the given node.
103.583 + ///
103.584 + /// This function returns the matching arc (or edge) incident to the
103.585 + /// given node in the current matching or \c INVALID if the node is
103.586 + /// not covered by the matching.
103.587 + Arc matching(const Node& n) const {
103.588 + return (*_matching)[n];
103.589 + }
103.590 +
103.591 + /// \brief Return a const reference to the matching map.
103.592 + ///
103.593 + /// This function returns a const reference to a node map that stores
103.594 + /// the matching arc (or edge) incident to each node.
103.595 + const MatchingMap& matchingMap() const {
103.596 + return *_matching;
103.597 + }
103.598 +
103.599 + /// \brief Return the mate of the given node.
103.600 + ///
103.601 + /// This function returns the mate of the given node in the current
103.602 + /// matching or \c INVALID if the node is not covered by the matching.
103.603 + Node mate(const Node& n) const {
103.604 + return (*_matching)[n] != INVALID ?
103.605 + _graph.target((*_matching)[n]) : INVALID;
103.606 + }
103.607 +
103.608 + /// @}
103.609 +
103.610 + /// \name Dual Solution
103.611 + /// Functions to get the dual solution, i.e. the Gallai-Edmonds
103.612 + /// decomposition.
103.613 +
103.614 + /// @{
103.615 +
103.616 + /// \brief Return the status of the given node in the Edmonds-Gallai
103.617 + /// decomposition.
103.618 + ///
103.619 + /// This function returns the \ref Status "status" of the given node
103.620 + /// in the Edmonds-Gallai decomposition.
103.621 + Status status(const Node& n) const {
103.622 + return (*_status)[n];
103.623 + }
103.624 +
103.625 + /// \brief Return a const reference to the status map, which stores
103.626 + /// the Edmonds-Gallai decomposition.
103.627 + ///
103.628 + /// This function returns a const reference to a node map that stores the
103.629 + /// \ref Status "status" of each node in the Edmonds-Gallai decomposition.
103.630 + const StatusMap& statusMap() const {
103.631 + return *_status;
103.632 + }
103.633 +
103.634 + /// \brief Return \c true if the given node is in the barrier.
103.635 + ///
103.636 + /// This function returns \c true if the given node is in the barrier.
103.637 + bool barrier(const Node& n) const {
103.638 + return (*_status)[n] == ODD;
103.639 + }
103.640 +
103.641 + /// @}
103.642 +
103.643 + };
103.644 +
103.645 + /// \ingroup matching
103.646 + ///
103.647 + /// \brief Weighted matching in general graphs
103.648 + ///
103.649 + /// This class provides an efficient implementation of Edmond's
103.650 + /// maximum weighted matching algorithm. The implementation is based
103.651 + /// on extensive use of priority queues and provides
103.652 + /// \f$O(nm\log n)\f$ time complexity.
103.653 + ///
103.654 + /// The maximum weighted matching problem is to find a subset of the
103.655 + /// edges in an undirected graph with maximum overall weight for which
103.656 + /// each node has at most one incident edge.
103.657 + /// It can be formulated with the following linear program.
103.658 + /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
103.659 + /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
103.660 + \quad \forall B\in\mathcal{O}\f] */
103.661 + /// \f[x_e \ge 0\quad \forall e\in E\f]
103.662 + /// \f[\max \sum_{e\in E}x_ew_e\f]
103.663 + /// where \f$\delta(X)\f$ is the set of edges incident to a node in
103.664 + /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
103.665 + /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
103.666 + /// subsets of the nodes.
103.667 + ///
103.668 + /// The algorithm calculates an optimal matching and a proof of the
103.669 + /// optimality. The solution of the dual problem can be used to check
103.670 + /// the result of the algorithm. The dual linear problem is the
103.671 + /// following.
103.672 + /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
103.673 + z_B \ge w_{uv} \quad \forall uv\in E\f] */
103.674 + /// \f[y_u \ge 0 \quad \forall u \in V\f]
103.675 + /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
103.676 + /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
103.677 + \frac{\vert B \vert - 1}{2}z_B\f] */
103.678 + ///
103.679 + /// The algorithm can be executed with the run() function.
103.680 + /// After it the matching (the primal solution) and the dual solution
103.681 + /// can be obtained using the query functions and the
103.682 + /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class,
103.683 + /// which is able to iterate on the nodes of a blossom.
103.684 + /// If the value type is integer, then the dual solution is multiplied
103.685 + /// by \ref MaxWeightedMatching::dualScale "4".
103.686 + ///
103.687 + /// \tparam GR The undirected graph type the algorithm runs on.
103.688 + /// \tparam WM The type edge weight map. The default type is
103.689 + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
103.690 +#ifdef DOXYGEN
103.691 + template <typename GR, typename WM>
103.692 +#else
103.693 + template <typename GR,
103.694 + typename WM = typename GR::template EdgeMap<int> >
103.695 +#endif
103.696 + class MaxWeightedMatching {
103.697 + public:
103.698 +
103.699 + /// The graph type of the algorithm
103.700 + typedef GR Graph;
103.701 + /// The type of the edge weight map
103.702 + typedef WM WeightMap;
103.703 + /// The value type of the edge weights
103.704 + typedef typename WeightMap::Value Value;
103.705 +
103.706 + /// The type of the matching map
103.707 + typedef typename Graph::template NodeMap<typename Graph::Arc>
103.708 + MatchingMap;
103.709 +
103.710 + /// \brief Scaling factor for dual solution
103.711 + ///
103.712 + /// Scaling factor for dual solution. It is equal to 4 or 1
103.713 + /// according to the value type.
103.714 + static const int dualScale =
103.715 + std::numeric_limits<Value>::is_integer ? 4 : 1;
103.716 +
103.717 + private:
103.718 +
103.719 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
103.720 +
103.721 + typedef typename Graph::template NodeMap<Value> NodePotential;
103.722 + typedef std::vector<Node> BlossomNodeList;
103.723 +
103.724 + struct BlossomVariable {
103.725 + int begin, end;
103.726 + Value value;
103.727 +
103.728 + BlossomVariable(int _begin, int _end, Value _value)
103.729 + : begin(_begin), end(_end), value(_value) {}
103.730 +
103.731 + };
103.732 +
103.733 + typedef std::vector<BlossomVariable> BlossomPotential;
103.734 +
103.735 + const Graph& _graph;
103.736 + const WeightMap& _weight;
103.737 +
103.738 + MatchingMap* _matching;
103.739 +
103.740 + NodePotential* _node_potential;
103.741 +
103.742 + BlossomPotential _blossom_potential;
103.743 + BlossomNodeList _blossom_node_list;
103.744 +
103.745 + int _node_num;
103.746 + int _blossom_num;
103.747 +
103.748 + typedef RangeMap<int> IntIntMap;
103.749 +
103.750 + enum Status {
103.751 + EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
103.752 + };
103.753 +
103.754 + typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
103.755 + struct BlossomData {
103.756 + int tree;
103.757 + Status status;
103.758 + Arc pred, next;
103.759 + Value pot, offset;
103.760 + Node base;
103.761 + };
103.762 +
103.763 + IntNodeMap *_blossom_index;
103.764 + BlossomSet *_blossom_set;
103.765 + RangeMap<BlossomData>* _blossom_data;
103.766 +
103.767 + IntNodeMap *_node_index;
103.768 + IntArcMap *_node_heap_index;
103.769 +
103.770 + struct NodeData {
103.771 +
103.772 + NodeData(IntArcMap& node_heap_index)
103.773 + : heap(node_heap_index) {}
103.774 +
103.775 + int blossom;
103.776 + Value pot;
103.777 + BinHeap<Value, IntArcMap> heap;
103.778 + std::map<int, Arc> heap_index;
103.779 +
103.780 + int tree;
103.781 + };
103.782 +
103.783 + RangeMap<NodeData>* _node_data;
103.784 +
103.785 + typedef ExtendFindEnum<IntIntMap> TreeSet;
103.786 +
103.787 + IntIntMap *_tree_set_index;
103.788 + TreeSet *_tree_set;
103.789 +
103.790 + IntNodeMap *_delta1_index;
103.791 + BinHeap<Value, IntNodeMap> *_delta1;
103.792 +
103.793 + IntIntMap *_delta2_index;
103.794 + BinHeap<Value, IntIntMap> *_delta2;
103.795 +
103.796 + IntEdgeMap *_delta3_index;
103.797 + BinHeap<Value, IntEdgeMap> *_delta3;
103.798 +
103.799 + IntIntMap *_delta4_index;
103.800 + BinHeap<Value, IntIntMap> *_delta4;
103.801 +
103.802 + Value _delta_sum;
103.803 +
103.804 + void createStructures() {
103.805 + _node_num = countNodes(_graph);
103.806 + _blossom_num = _node_num * 3 / 2;
103.807 +
103.808 + if (!_matching) {
103.809 + _matching = new MatchingMap(_graph);
103.810 + }
103.811 + if (!_node_potential) {
103.812 + _node_potential = new NodePotential(_graph);
103.813 + }
103.814 + if (!_blossom_set) {
103.815 + _blossom_index = new IntNodeMap(_graph);
103.816 + _blossom_set = new BlossomSet(*_blossom_index);
103.817 + _blossom_data = new RangeMap<BlossomData>(_blossom_num);
103.818 + }
103.819 +
103.820 + if (!_node_index) {
103.821 + _node_index = new IntNodeMap(_graph);
103.822 + _node_heap_index = new IntArcMap(_graph);
103.823 + _node_data = new RangeMap<NodeData>(_node_num,
103.824 + NodeData(*_node_heap_index));
103.825 + }
103.826 +
103.827 + if (!_tree_set) {
103.828 + _tree_set_index = new IntIntMap(_blossom_num);
103.829 + _tree_set = new TreeSet(*_tree_set_index);
103.830 + }
103.831 + if (!_delta1) {
103.832 + _delta1_index = new IntNodeMap(_graph);
103.833 + _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
103.834 + }
103.835 + if (!_delta2) {
103.836 + _delta2_index = new IntIntMap(_blossom_num);
103.837 + _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
103.838 + }
103.839 + if (!_delta3) {
103.840 + _delta3_index = new IntEdgeMap(_graph);
103.841 + _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
103.842 + }
103.843 + if (!_delta4) {
103.844 + _delta4_index = new IntIntMap(_blossom_num);
103.845 + _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
103.846 + }
103.847 + }
103.848 +
103.849 + void destroyStructures() {
103.850 + _node_num = countNodes(_graph);
103.851 + _blossom_num = _node_num * 3 / 2;
103.852 +
103.853 + if (_matching) {
103.854 + delete _matching;
103.855 + }
103.856 + if (_node_potential) {
103.857 + delete _node_potential;
103.858 + }
103.859 + if (_blossom_set) {
103.860 + delete _blossom_index;
103.861 + delete _blossom_set;
103.862 + delete _blossom_data;
103.863 + }
103.864 +
103.865 + if (_node_index) {
103.866 + delete _node_index;
103.867 + delete _node_heap_index;
103.868 + delete _node_data;
103.869 + }
103.870 +
103.871 + if (_tree_set) {
103.872 + delete _tree_set_index;
103.873 + delete _tree_set;
103.874 + }
103.875 + if (_delta1) {
103.876 + delete _delta1_index;
103.877 + delete _delta1;
103.878 + }
103.879 + if (_delta2) {
103.880 + delete _delta2_index;
103.881 + delete _delta2;
103.882 + }
103.883 + if (_delta3) {
103.884 + delete _delta3_index;
103.885 + delete _delta3;
103.886 + }
103.887 + if (_delta4) {
103.888 + delete _delta4_index;
103.889 + delete _delta4;
103.890 + }
103.891 + }
103.892 +
103.893 + void matchedToEven(int blossom, int tree) {
103.894 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
103.895 + _delta2->erase(blossom);
103.896 + }
103.897 +
103.898 + if (!_blossom_set->trivial(blossom)) {
103.899 + (*_blossom_data)[blossom].pot -=
103.900 + 2 * (_delta_sum - (*_blossom_data)[blossom].offset);
103.901 + }
103.902 +
103.903 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
103.904 + n != INVALID; ++n) {
103.905 +
103.906 + _blossom_set->increase(n, std::numeric_limits<Value>::max());
103.907 + int ni = (*_node_index)[n];
103.908 +
103.909 + (*_node_data)[ni].heap.clear();
103.910 + (*_node_data)[ni].heap_index.clear();
103.911 +
103.912 + (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
103.913 +
103.914 + _delta1->push(n, (*_node_data)[ni].pot);
103.915 +
103.916 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
103.917 + Node v = _graph.source(e);
103.918 + int vb = _blossom_set->find(v);
103.919 + int vi = (*_node_index)[v];
103.920 +
103.921 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
103.922 + dualScale * _weight[e];
103.923 +
103.924 + if ((*_blossom_data)[vb].status == EVEN) {
103.925 + if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
103.926 + _delta3->push(e, rw / 2);
103.927 + }
103.928 + } else if ((*_blossom_data)[vb].status == UNMATCHED) {
103.929 + if (_delta3->state(e) != _delta3->IN_HEAP) {
103.930 + _delta3->push(e, rw);
103.931 + }
103.932 + } else {
103.933 + typename std::map<int, Arc>::iterator it =
103.934 + (*_node_data)[vi].heap_index.find(tree);
103.935 +
103.936 + if (it != (*_node_data)[vi].heap_index.end()) {
103.937 + if ((*_node_data)[vi].heap[it->second] > rw) {
103.938 + (*_node_data)[vi].heap.replace(it->second, e);
103.939 + (*_node_data)[vi].heap.decrease(e, rw);
103.940 + it->second = e;
103.941 + }
103.942 + } else {
103.943 + (*_node_data)[vi].heap.push(e, rw);
103.944 + (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
103.945 + }
103.946 +
103.947 + if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
103.948 + _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
103.949 +
103.950 + if ((*_blossom_data)[vb].status == MATCHED) {
103.951 + if (_delta2->state(vb) != _delta2->IN_HEAP) {
103.952 + _delta2->push(vb, _blossom_set->classPrio(vb) -
103.953 + (*_blossom_data)[vb].offset);
103.954 + } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
103.955 + (*_blossom_data)[vb].offset){
103.956 + _delta2->decrease(vb, _blossom_set->classPrio(vb) -
103.957 + (*_blossom_data)[vb].offset);
103.958 + }
103.959 + }
103.960 + }
103.961 + }
103.962 + }
103.963 + }
103.964 + (*_blossom_data)[blossom].offset = 0;
103.965 + }
103.966 +
103.967 + void matchedToOdd(int blossom) {
103.968 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
103.969 + _delta2->erase(blossom);
103.970 + }
103.971 + (*_blossom_data)[blossom].offset += _delta_sum;
103.972 + if (!_blossom_set->trivial(blossom)) {
103.973 + _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
103.974 + (*_blossom_data)[blossom].offset);
103.975 + }
103.976 + }
103.977 +
103.978 + void evenToMatched(int blossom, int tree) {
103.979 + if (!_blossom_set->trivial(blossom)) {
103.980 + (*_blossom_data)[blossom].pot += 2 * _delta_sum;
103.981 + }
103.982 +
103.983 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
103.984 + n != INVALID; ++n) {
103.985 + int ni = (*_node_index)[n];
103.986 + (*_node_data)[ni].pot -= _delta_sum;
103.987 +
103.988 + _delta1->erase(n);
103.989 +
103.990 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
103.991 + Node v = _graph.source(e);
103.992 + int vb = _blossom_set->find(v);
103.993 + int vi = (*_node_index)[v];
103.994 +
103.995 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
103.996 + dualScale * _weight[e];
103.997 +
103.998 + if (vb == blossom) {
103.999 + if (_delta3->state(e) == _delta3->IN_HEAP) {
103.1000 + _delta3->erase(e);
103.1001 + }
103.1002 + } else if ((*_blossom_data)[vb].status == EVEN) {
103.1003 +
103.1004 + if (_delta3->state(e) == _delta3->IN_HEAP) {
103.1005 + _delta3->erase(e);
103.1006 + }
103.1007 +
103.1008 + int vt = _tree_set->find(vb);
103.1009 +
103.1010 + if (vt != tree) {
103.1011 +
103.1012 + Arc r = _graph.oppositeArc(e);
103.1013 +
103.1014 + typename std::map<int, Arc>::iterator it =
103.1015 + (*_node_data)[ni].heap_index.find(vt);
103.1016 +
103.1017 + if (it != (*_node_data)[ni].heap_index.end()) {
103.1018 + if ((*_node_data)[ni].heap[it->second] > rw) {
103.1019 + (*_node_data)[ni].heap.replace(it->second, r);
103.1020 + (*_node_data)[ni].heap.decrease(r, rw);
103.1021 + it->second = r;
103.1022 + }
103.1023 + } else {
103.1024 + (*_node_data)[ni].heap.push(r, rw);
103.1025 + (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
103.1026 + }
103.1027 +
103.1028 + if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
103.1029 + _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
103.1030 +
103.1031 + if (_delta2->state(blossom) != _delta2->IN_HEAP) {
103.1032 + _delta2->push(blossom, _blossom_set->classPrio(blossom) -
103.1033 + (*_blossom_data)[blossom].offset);
103.1034 + } else if ((*_delta2)[blossom] >
103.1035 + _blossom_set->classPrio(blossom) -
103.1036 + (*_blossom_data)[blossom].offset){
103.1037 + _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
103.1038 + (*_blossom_data)[blossom].offset);
103.1039 + }
103.1040 + }
103.1041 + }
103.1042 +
103.1043 + } else if ((*_blossom_data)[vb].status == UNMATCHED) {
103.1044 + if (_delta3->state(e) == _delta3->IN_HEAP) {
103.1045 + _delta3->erase(e);
103.1046 + }
103.1047 + } else {
103.1048 +
103.1049 + typename std::map<int, Arc>::iterator it =
103.1050 + (*_node_data)[vi].heap_index.find(tree);
103.1051 +
103.1052 + if (it != (*_node_data)[vi].heap_index.end()) {
103.1053 + (*_node_data)[vi].heap.erase(it->second);
103.1054 + (*_node_data)[vi].heap_index.erase(it);
103.1055 + if ((*_node_data)[vi].heap.empty()) {
103.1056 + _blossom_set->increase(v, std::numeric_limits<Value>::max());
103.1057 + } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
103.1058 + _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
103.1059 + }
103.1060 +
103.1061 + if ((*_blossom_data)[vb].status == MATCHED) {
103.1062 + if (_blossom_set->classPrio(vb) ==
103.1063 + std::numeric_limits<Value>::max()) {
103.1064 + _delta2->erase(vb);
103.1065 + } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
103.1066 + (*_blossom_data)[vb].offset) {
103.1067 + _delta2->increase(vb, _blossom_set->classPrio(vb) -
103.1068 + (*_blossom_data)[vb].offset);
103.1069 + }
103.1070 + }
103.1071 + }
103.1072 + }
103.1073 + }
103.1074 + }
103.1075 + }
103.1076 +
103.1077 + void oddToMatched(int blossom) {
103.1078 + (*_blossom_data)[blossom].offset -= _delta_sum;
103.1079 +
103.1080 + if (_blossom_set->classPrio(blossom) !=
103.1081 + std::numeric_limits<Value>::max()) {
103.1082 + _delta2->push(blossom, _blossom_set->classPrio(blossom) -
103.1083 + (*_blossom_data)[blossom].offset);
103.1084 + }
103.1085 +
103.1086 + if (!_blossom_set->trivial(blossom)) {
103.1087 + _delta4->erase(blossom);
103.1088 + }
103.1089 + }
103.1090 +
103.1091 + void oddToEven(int blossom, int tree) {
103.1092 + if (!_blossom_set->trivial(blossom)) {
103.1093 + _delta4->erase(blossom);
103.1094 + (*_blossom_data)[blossom].pot -=
103.1095 + 2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
103.1096 + }
103.1097 +
103.1098 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
103.1099 + n != INVALID; ++n) {
103.1100 + int ni = (*_node_index)[n];
103.1101 +
103.1102 + _blossom_set->increase(n, std::numeric_limits<Value>::max());
103.1103 +
103.1104 + (*_node_data)[ni].heap.clear();
103.1105 + (*_node_data)[ni].heap_index.clear();
103.1106 + (*_node_data)[ni].pot +=
103.1107 + 2 * _delta_sum - (*_blossom_data)[blossom].offset;
103.1108 +
103.1109 + _delta1->push(n, (*_node_data)[ni].pot);
103.1110 +
103.1111 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
103.1112 + Node v = _graph.source(e);
103.1113 + int vb = _blossom_set->find(v);
103.1114 + int vi = (*_node_index)[v];
103.1115 +
103.1116 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
103.1117 + dualScale * _weight[e];
103.1118 +
103.1119 + if ((*_blossom_data)[vb].status == EVEN) {
103.1120 + if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
103.1121 + _delta3->push(e, rw / 2);
103.1122 + }
103.1123 + } else if ((*_blossom_data)[vb].status == UNMATCHED) {
103.1124 + if (_delta3->state(e) != _delta3->IN_HEAP) {
103.1125 + _delta3->push(e, rw);
103.1126 + }
103.1127 + } else {
103.1128 +
103.1129 + typename std::map<int, Arc>::iterator it =
103.1130 + (*_node_data)[vi].heap_index.find(tree);
103.1131 +
103.1132 + if (it != (*_node_data)[vi].heap_index.end()) {
103.1133 + if ((*_node_data)[vi].heap[it->second] > rw) {
103.1134 + (*_node_data)[vi].heap.replace(it->second, e);
103.1135 + (*_node_data)[vi].heap.decrease(e, rw);
103.1136 + it->second = e;
103.1137 + }
103.1138 + } else {
103.1139 + (*_node_data)[vi].heap.push(e, rw);
103.1140 + (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
103.1141 + }
103.1142 +
103.1143 + if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
103.1144 + _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
103.1145 +
103.1146 + if ((*_blossom_data)[vb].status == MATCHED) {
103.1147 + if (_delta2->state(vb) != _delta2->IN_HEAP) {
103.1148 + _delta2->push(vb, _blossom_set->classPrio(vb) -
103.1149 + (*_blossom_data)[vb].offset);
103.1150 + } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
103.1151 + (*_blossom_data)[vb].offset) {
103.1152 + _delta2->decrease(vb, _blossom_set->classPrio(vb) -
103.1153 + (*_blossom_data)[vb].offset);
103.1154 + }
103.1155 + }
103.1156 + }
103.1157 + }
103.1158 + }
103.1159 + }
103.1160 + (*_blossom_data)[blossom].offset = 0;
103.1161 + }
103.1162 +
103.1163 +
103.1164 + void matchedToUnmatched(int blossom) {
103.1165 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
103.1166 + _delta2->erase(blossom);
103.1167 + }
103.1168 +
103.1169 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
103.1170 + n != INVALID; ++n) {
103.1171 + int ni = (*_node_index)[n];
103.1172 +
103.1173 + _blossom_set->increase(n, std::numeric_limits<Value>::max());
103.1174 +
103.1175 + (*_node_data)[ni].heap.clear();
103.1176 + (*_node_data)[ni].heap_index.clear();
103.1177 +
103.1178 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
103.1179 + Node v = _graph.target(e);
103.1180 + int vb = _blossom_set->find(v);
103.1181 + int vi = (*_node_index)[v];
103.1182 +
103.1183 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
103.1184 + dualScale * _weight[e];
103.1185 +
103.1186 + if ((*_blossom_data)[vb].status == EVEN) {
103.1187 + if (_delta3->state(e) != _delta3->IN_HEAP) {
103.1188 + _delta3->push(e, rw);
103.1189 + }
103.1190 + }
103.1191 + }
103.1192 + }
103.1193 + }
103.1194 +
103.1195 + void unmatchedToMatched(int blossom) {
103.1196 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
103.1197 + n != INVALID; ++n) {
103.1198 + int ni = (*_node_index)[n];
103.1199 +
103.1200 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
103.1201 + Node v = _graph.source(e);
103.1202 + int vb = _blossom_set->find(v);
103.1203 + int vi = (*_node_index)[v];
103.1204 +
103.1205 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
103.1206 + dualScale * _weight[e];
103.1207 +
103.1208 + if (vb == blossom) {
103.1209 + if (_delta3->state(e) == _delta3->IN_HEAP) {
103.1210 + _delta3->erase(e);
103.1211 + }
103.1212 + } else if ((*_blossom_data)[vb].status == EVEN) {
103.1213 +
103.1214 + if (_delta3->state(e) == _delta3->IN_HEAP) {
103.1215 + _delta3->erase(e);
103.1216 + }
103.1217 +
103.1218 + int vt = _tree_set->find(vb);
103.1219 +
103.1220 + Arc r = _graph.oppositeArc(e);
103.1221 +
103.1222 + typename std::map<int, Arc>::iterator it =
103.1223 + (*_node_data)[ni].heap_index.find(vt);
103.1224 +
103.1225 + if (it != (*_node_data)[ni].heap_index.end()) {
103.1226 + if ((*_node_data)[ni].heap[it->second] > rw) {
103.1227 + (*_node_data)[ni].heap.replace(it->second, r);
103.1228 + (*_node_data)[ni].heap.decrease(r, rw);
103.1229 + it->second = r;
103.1230 + }
103.1231 + } else {
103.1232 + (*_node_data)[ni].heap.push(r, rw);
103.1233 + (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
103.1234 + }
103.1235 +
103.1236 + if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
103.1237 + _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
103.1238 +
103.1239 + if (_delta2->state(blossom) != _delta2->IN_HEAP) {
103.1240 + _delta2->push(blossom, _blossom_set->classPrio(blossom) -
103.1241 + (*_blossom_data)[blossom].offset);
103.1242 + } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
103.1243 + (*_blossom_data)[blossom].offset){
103.1244 + _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
103.1245 + (*_blossom_data)[blossom].offset);
103.1246 + }
103.1247 + }
103.1248 +
103.1249 + } else if ((*_blossom_data)[vb].status == UNMATCHED) {
103.1250 + if (_delta3->state(e) == _delta3->IN_HEAP) {
103.1251 + _delta3->erase(e);
103.1252 + }
103.1253 + }
103.1254 + }
103.1255 + }
103.1256 + }
103.1257 +
103.1258 + void alternatePath(int even, int tree) {
103.1259 + int odd;
103.1260 +
103.1261 + evenToMatched(even, tree);
103.1262 + (*_blossom_data)[even].status = MATCHED;
103.1263 +
103.1264 + while ((*_blossom_data)[even].pred != INVALID) {
103.1265 + odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
103.1266 + (*_blossom_data)[odd].status = MATCHED;
103.1267 + oddToMatched(odd);
103.1268 + (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
103.1269 +
103.1270 + even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
103.1271 + (*_blossom_data)[even].status = MATCHED;
103.1272 + evenToMatched(even, tree);
103.1273 + (*_blossom_data)[even].next =
103.1274 + _graph.oppositeArc((*_blossom_data)[odd].pred);
103.1275 + }
103.1276 +
103.1277 + }
103.1278 +
103.1279 + void destroyTree(int tree) {
103.1280 + for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
103.1281 + if ((*_blossom_data)[b].status == EVEN) {
103.1282 + (*_blossom_data)[b].status = MATCHED;
103.1283 + evenToMatched(b, tree);
103.1284 + } else if ((*_blossom_data)[b].status == ODD) {
103.1285 + (*_blossom_data)[b].status = MATCHED;
103.1286 + oddToMatched(b);
103.1287 + }
103.1288 + }
103.1289 + _tree_set->eraseClass(tree);
103.1290 + }
103.1291 +
103.1292 +
103.1293 + void unmatchNode(const Node& node) {
103.1294 + int blossom = _blossom_set->find(node);
103.1295 + int tree = _tree_set->find(blossom);
103.1296 +
103.1297 + alternatePath(blossom, tree);
103.1298 + destroyTree(tree);
103.1299 +
103.1300 + (*_blossom_data)[blossom].status = UNMATCHED;
103.1301 + (*_blossom_data)[blossom].base = node;
103.1302 + matchedToUnmatched(blossom);
103.1303 + }
103.1304 +
103.1305 +
103.1306 + void augmentOnEdge(const Edge& edge) {
103.1307 +
103.1308 + int left = _blossom_set->find(_graph.u(edge));
103.1309 + int right = _blossom_set->find(_graph.v(edge));
103.1310 +
103.1311 + if ((*_blossom_data)[left].status == EVEN) {
103.1312 + int left_tree = _tree_set->find(left);
103.1313 + alternatePath(left, left_tree);
103.1314 + destroyTree(left_tree);
103.1315 + } else {
103.1316 + (*_blossom_data)[left].status = MATCHED;
103.1317 + unmatchedToMatched(left);
103.1318 + }
103.1319 +
103.1320 + if ((*_blossom_data)[right].status == EVEN) {
103.1321 + int right_tree = _tree_set->find(right);
103.1322 + alternatePath(right, right_tree);
103.1323 + destroyTree(right_tree);
103.1324 + } else {
103.1325 + (*_blossom_data)[right].status = MATCHED;
103.1326 + unmatchedToMatched(right);
103.1327 + }
103.1328 +
103.1329 + (*_blossom_data)[left].next = _graph.direct(edge, true);
103.1330 + (*_blossom_data)[right].next = _graph.direct(edge, false);
103.1331 + }
103.1332 +
103.1333 + void extendOnArc(const Arc& arc) {
103.1334 + int base = _blossom_set->find(_graph.target(arc));
103.1335 + int tree = _tree_set->find(base);
103.1336 +
103.1337 + int odd = _blossom_set->find(_graph.source(arc));
103.1338 + _tree_set->insert(odd, tree);
103.1339 + (*_blossom_data)[odd].status = ODD;
103.1340 + matchedToOdd(odd);
103.1341 + (*_blossom_data)[odd].pred = arc;
103.1342 +
103.1343 + int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
103.1344 + (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
103.1345 + _tree_set->insert(even, tree);
103.1346 + (*_blossom_data)[even].status = EVEN;
103.1347 + matchedToEven(even, tree);
103.1348 + }
103.1349 +
103.1350 + void shrinkOnEdge(const Edge& edge, int tree) {
103.1351 + int nca = -1;
103.1352 + std::vector<int> left_path, right_path;
103.1353 +
103.1354 + {
103.1355 + std::set<int> left_set, right_set;
103.1356 + int left = _blossom_set->find(_graph.u(edge));
103.1357 + left_path.push_back(left);
103.1358 + left_set.insert(left);
103.1359 +
103.1360 + int right = _blossom_set->find(_graph.v(edge));
103.1361 + right_path.push_back(right);
103.1362 + right_set.insert(right);
103.1363 +
103.1364 + while (true) {
103.1365 +
103.1366 + if ((*_blossom_data)[left].pred == INVALID) break;
103.1367 +
103.1368 + left =
103.1369 + _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
103.1370 + left_path.push_back(left);
103.1371 + left =
103.1372 + _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
103.1373 + left_path.push_back(left);
103.1374 +
103.1375 + left_set.insert(left);
103.1376 +
103.1377 + if (right_set.find(left) != right_set.end()) {
103.1378 + nca = left;
103.1379 + break;
103.1380 + }
103.1381 +
103.1382 + if ((*_blossom_data)[right].pred == INVALID) break;
103.1383 +
103.1384 + right =
103.1385 + _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
103.1386 + right_path.push_back(right);
103.1387 + right =
103.1388 + _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
103.1389 + right_path.push_back(right);
103.1390 +
103.1391 + right_set.insert(right);
103.1392 +
103.1393 + if (left_set.find(right) != left_set.end()) {
103.1394 + nca = right;
103.1395 + break;
103.1396 + }
103.1397 +
103.1398 + }
103.1399 +
103.1400 + if (nca == -1) {
103.1401 + if ((*_blossom_data)[left].pred == INVALID) {
103.1402 + nca = right;
103.1403 + while (left_set.find(nca) == left_set.end()) {
103.1404 + nca =
103.1405 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
103.1406 + right_path.push_back(nca);
103.1407 + nca =
103.1408 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
103.1409 + right_path.push_back(nca);
103.1410 + }
103.1411 + } else {
103.1412 + nca = left;
103.1413 + while (right_set.find(nca) == right_set.end()) {
103.1414 + nca =
103.1415 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
103.1416 + left_path.push_back(nca);
103.1417 + nca =
103.1418 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
103.1419 + left_path.push_back(nca);
103.1420 + }
103.1421 + }
103.1422 + }
103.1423 + }
103.1424 +
103.1425 + std::vector<int> subblossoms;
103.1426 + Arc prev;
103.1427 +
103.1428 + prev = _graph.direct(edge, true);
103.1429 + for (int i = 0; left_path[i] != nca; i += 2) {
103.1430 + subblossoms.push_back(left_path[i]);
103.1431 + (*_blossom_data)[left_path[i]].next = prev;
103.1432 + _tree_set->erase(left_path[i]);
103.1433 +
103.1434 + subblossoms.push_back(left_path[i + 1]);
103.1435 + (*_blossom_data)[left_path[i + 1]].status = EVEN;
103.1436 + oddToEven(left_path[i + 1], tree);
103.1437 + _tree_set->erase(left_path[i + 1]);
103.1438 + prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
103.1439 + }
103.1440 +
103.1441 + int k = 0;
103.1442 + while (right_path[k] != nca) ++k;
103.1443 +
103.1444 + subblossoms.push_back(nca);
103.1445 + (*_blossom_data)[nca].next = prev;
103.1446 +
103.1447 + for (int i = k - 2; i >= 0; i -= 2) {
103.1448 + subblossoms.push_back(right_path[i + 1]);
103.1449 + (*_blossom_data)[right_path[i + 1]].status = EVEN;
103.1450 + oddToEven(right_path[i + 1], tree);
103.1451 + _tree_set->erase(right_path[i + 1]);
103.1452 +
103.1453 + (*_blossom_data)[right_path[i + 1]].next =
103.1454 + (*_blossom_data)[right_path[i + 1]].pred;
103.1455 +
103.1456 + subblossoms.push_back(right_path[i]);
103.1457 + _tree_set->erase(right_path[i]);
103.1458 + }
103.1459 +
103.1460 + int surface =
103.1461 + _blossom_set->join(subblossoms.begin(), subblossoms.end());
103.1462 +
103.1463 + for (int i = 0; i < int(subblossoms.size()); ++i) {
103.1464 + if (!_blossom_set->trivial(subblossoms[i])) {
103.1465 + (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
103.1466 + }
103.1467 + (*_blossom_data)[subblossoms[i]].status = MATCHED;
103.1468 + }
103.1469 +
103.1470 + (*_blossom_data)[surface].pot = -2 * _delta_sum;
103.1471 + (*_blossom_data)[surface].offset = 0;
103.1472 + (*_blossom_data)[surface].status = EVEN;
103.1473 + (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
103.1474 + (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
103.1475 +
103.1476 + _tree_set->insert(surface, tree);
103.1477 + _tree_set->erase(nca);
103.1478 + }
103.1479 +
103.1480 + void splitBlossom(int blossom) {
103.1481 + Arc next = (*_blossom_data)[blossom].next;
103.1482 + Arc pred = (*_blossom_data)[blossom].pred;
103.1483 +
103.1484 + int tree = _tree_set->find(blossom);
103.1485 +
103.1486 + (*_blossom_data)[blossom].status = MATCHED;
103.1487 + oddToMatched(blossom);
103.1488 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
103.1489 + _delta2->erase(blossom);
103.1490 + }
103.1491 +
103.1492 + std::vector<int> subblossoms;
103.1493 + _blossom_set->split(blossom, std::back_inserter(subblossoms));
103.1494 +
103.1495 + Value offset = (*_blossom_data)[blossom].offset;
103.1496 + int b = _blossom_set->find(_graph.source(pred));
103.1497 + int d = _blossom_set->find(_graph.source(next));
103.1498 +
103.1499 + int ib = -1, id = -1;
103.1500 + for (int i = 0; i < int(subblossoms.size()); ++i) {
103.1501 + if (subblossoms[i] == b) ib = i;
103.1502 + if (subblossoms[i] == d) id = i;
103.1503 +
103.1504 + (*_blossom_data)[subblossoms[i]].offset = offset;
103.1505 + if (!_blossom_set->trivial(subblossoms[i])) {
103.1506 + (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
103.1507 + }
103.1508 + if (_blossom_set->classPrio(subblossoms[i]) !=
103.1509 + std::numeric_limits<Value>::max()) {
103.1510 + _delta2->push(subblossoms[i],
103.1511 + _blossom_set->classPrio(subblossoms[i]) -
103.1512 + (*_blossom_data)[subblossoms[i]].offset);
103.1513 + }
103.1514 + }
103.1515 +
103.1516 + if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
103.1517 + for (int i = (id + 1) % subblossoms.size();
103.1518 + i != ib; i = (i + 2) % subblossoms.size()) {
103.1519 + int sb = subblossoms[i];
103.1520 + int tb = subblossoms[(i + 1) % subblossoms.size()];
103.1521 + (*_blossom_data)[sb].next =
103.1522 + _graph.oppositeArc((*_blossom_data)[tb].next);
103.1523 + }
103.1524 +
103.1525 + for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
103.1526 + int sb = subblossoms[i];
103.1527 + int tb = subblossoms[(i + 1) % subblossoms.size()];
103.1528 + int ub = subblossoms[(i + 2) % subblossoms.size()];
103.1529 +
103.1530 + (*_blossom_data)[sb].status = ODD;
103.1531 + matchedToOdd(sb);
103.1532 + _tree_set->insert(sb, tree);
103.1533 + (*_blossom_data)[sb].pred = pred;
103.1534 + (*_blossom_data)[sb].next =
103.1535 + _graph.oppositeArc((*_blossom_data)[tb].next);
103.1536 +
103.1537 + pred = (*_blossom_data)[ub].next;
103.1538 +
103.1539 + (*_blossom_data)[tb].status = EVEN;
103.1540 + matchedToEven(tb, tree);
103.1541 + _tree_set->insert(tb, tree);
103.1542 + (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
103.1543 + }
103.1544 +
103.1545 + (*_blossom_data)[subblossoms[id]].status = ODD;
103.1546 + matchedToOdd(subblossoms[id]);
103.1547 + _tree_set->insert(subblossoms[id], tree);
103.1548 + (*_blossom_data)[subblossoms[id]].next = next;
103.1549 + (*_blossom_data)[subblossoms[id]].pred = pred;
103.1550 +
103.1551 + } else {
103.1552 +
103.1553 + for (int i = (ib + 1) % subblossoms.size();
103.1554 + i != id; i = (i + 2) % subblossoms.size()) {
103.1555 + int sb = subblossoms[i];
103.1556 + int tb = subblossoms[(i + 1) % subblossoms.size()];
103.1557 + (*_blossom_data)[sb].next =
103.1558 + _graph.oppositeArc((*_blossom_data)[tb].next);
103.1559 + }
103.1560 +
103.1561 + for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
103.1562 + int sb = subblossoms[i];
103.1563 + int tb = subblossoms[(i + 1) % subblossoms.size()];
103.1564 + int ub = subblossoms[(i + 2) % subblossoms.size()];
103.1565 +
103.1566 + (*_blossom_data)[sb].status = ODD;
103.1567 + matchedToOdd(sb);
103.1568 + _tree_set->insert(sb, tree);
103.1569 + (*_blossom_data)[sb].next = next;
103.1570 + (*_blossom_data)[sb].pred =
103.1571 + _graph.oppositeArc((*_blossom_data)[tb].next);
103.1572 +
103.1573 + (*_blossom_data)[tb].status = EVEN;
103.1574 + matchedToEven(tb, tree);
103.1575 + _tree_set->insert(tb, tree);
103.1576 + (*_blossom_data)[tb].pred =
103.1577 + (*_blossom_data)[tb].next =
103.1578 + _graph.oppositeArc((*_blossom_data)[ub].next);
103.1579 + next = (*_blossom_data)[ub].next;
103.1580 + }
103.1581 +
103.1582 + (*_blossom_data)[subblossoms[ib]].status = ODD;
103.1583 + matchedToOdd(subblossoms[ib]);
103.1584 + _tree_set->insert(subblossoms[ib], tree);
103.1585 + (*_blossom_data)[subblossoms[ib]].next = next;
103.1586 + (*_blossom_data)[subblossoms[ib]].pred = pred;
103.1587 + }
103.1588 + _tree_set->erase(blossom);
103.1589 + }
103.1590 +
103.1591 + void extractBlossom(int blossom, const Node& base, const Arc& matching) {
103.1592 + if (_blossom_set->trivial(blossom)) {
103.1593 + int bi = (*_node_index)[base];
103.1594 + Value pot = (*_node_data)[bi].pot;
103.1595 +
103.1596 + (*_matching)[base] = matching;
103.1597 + _blossom_node_list.push_back(base);
103.1598 + (*_node_potential)[base] = pot;
103.1599 + } else {
103.1600 +
103.1601 + Value pot = (*_blossom_data)[blossom].pot;
103.1602 + int bn = _blossom_node_list.size();
103.1603 +
103.1604 + std::vector<int> subblossoms;
103.1605 + _blossom_set->split(blossom, std::back_inserter(subblossoms));
103.1606 + int b = _blossom_set->find(base);
103.1607 + int ib = -1;
103.1608 + for (int i = 0; i < int(subblossoms.size()); ++i) {
103.1609 + if (subblossoms[i] == b) { ib = i; break; }
103.1610 + }
103.1611 +
103.1612 + for (int i = 1; i < int(subblossoms.size()); i += 2) {
103.1613 + int sb = subblossoms[(ib + i) % subblossoms.size()];
103.1614 + int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
103.1615 +
103.1616 + Arc m = (*_blossom_data)[tb].next;
103.1617 + extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
103.1618 + extractBlossom(tb, _graph.source(m), m);
103.1619 + }
103.1620 + extractBlossom(subblossoms[ib], base, matching);
103.1621 +
103.1622 + int en = _blossom_node_list.size();
103.1623 +
103.1624 + _blossom_potential.push_back(BlossomVariable(bn, en, pot));
103.1625 + }
103.1626 + }
103.1627 +
103.1628 + void extractMatching() {
103.1629 + std::vector<int> blossoms;
103.1630 + for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
103.1631 + blossoms.push_back(c);
103.1632 + }
103.1633 +
103.1634 + for (int i = 0; i < int(blossoms.size()); ++i) {
103.1635 + if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
103.1636 +
103.1637 + Value offset = (*_blossom_data)[blossoms[i]].offset;
103.1638 + (*_blossom_data)[blossoms[i]].pot += 2 * offset;
103.1639 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
103.1640 + n != INVALID; ++n) {
103.1641 + (*_node_data)[(*_node_index)[n]].pot -= offset;
103.1642 + }
103.1643 +
103.1644 + Arc matching = (*_blossom_data)[blossoms[i]].next;
103.1645 + Node base = _graph.source(matching);
103.1646 + extractBlossom(blossoms[i], base, matching);
103.1647 + } else {
103.1648 + Node base = (*_blossom_data)[blossoms[i]].base;
103.1649 + extractBlossom(blossoms[i], base, INVALID);
103.1650 + }
103.1651 + }
103.1652 + }
103.1653 +
103.1654 + public:
103.1655 +
103.1656 + /// \brief Constructor
103.1657 + ///
103.1658 + /// Constructor.
103.1659 + MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
103.1660 + : _graph(graph), _weight(weight), _matching(0),
103.1661 + _node_potential(0), _blossom_potential(), _blossom_node_list(),
103.1662 + _node_num(0), _blossom_num(0),
103.1663 +
103.1664 + _blossom_index(0), _blossom_set(0), _blossom_data(0),
103.1665 + _node_index(0), _node_heap_index(0), _node_data(0),
103.1666 + _tree_set_index(0), _tree_set(0),
103.1667 +
103.1668 + _delta1_index(0), _delta1(0),
103.1669 + _delta2_index(0), _delta2(0),
103.1670 + _delta3_index(0), _delta3(0),
103.1671 + _delta4_index(0), _delta4(0),
103.1672 +
103.1673 + _delta_sum() {}
103.1674 +
103.1675 + ~MaxWeightedMatching() {
103.1676 + destroyStructures();
103.1677 + }
103.1678 +
103.1679 + /// \name Execution Control
103.1680 + /// The simplest way to execute the algorithm is to use the
103.1681 + /// \ref run() member function.
103.1682 +
103.1683 + ///@{
103.1684 +
103.1685 + /// \brief Initialize the algorithm
103.1686 + ///
103.1687 + /// This function initializes the algorithm.
103.1688 + void init() {
103.1689 + createStructures();
103.1690 +
103.1691 + for (ArcIt e(_graph); e != INVALID; ++e) {
103.1692 + (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
103.1693 + }
103.1694 + for (NodeIt n(_graph); n != INVALID; ++n) {
103.1695 + (*_delta1_index)[n] = _delta1->PRE_HEAP;
103.1696 + }
103.1697 + for (EdgeIt e(_graph); e != INVALID; ++e) {
103.1698 + (*_delta3_index)[e] = _delta3->PRE_HEAP;
103.1699 + }
103.1700 + for (int i = 0; i < _blossom_num; ++i) {
103.1701 + (*_delta2_index)[i] = _delta2->PRE_HEAP;
103.1702 + (*_delta4_index)[i] = _delta4->PRE_HEAP;
103.1703 + }
103.1704 +
103.1705 + int index = 0;
103.1706 + for (NodeIt n(_graph); n != INVALID; ++n) {
103.1707 + Value max = 0;
103.1708 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
103.1709 + if (_graph.target(e) == n) continue;
103.1710 + if ((dualScale * _weight[e]) / 2 > max) {
103.1711 + max = (dualScale * _weight[e]) / 2;
103.1712 + }
103.1713 + }
103.1714 + (*_node_index)[n] = index;
103.1715 + (*_node_data)[index].pot = max;
103.1716 + _delta1->push(n, max);
103.1717 + int blossom =
103.1718 + _blossom_set->insert(n, std::numeric_limits<Value>::max());
103.1719 +
103.1720 + _tree_set->insert(blossom);
103.1721 +
103.1722 + (*_blossom_data)[blossom].status = EVEN;
103.1723 + (*_blossom_data)[blossom].pred = INVALID;
103.1724 + (*_blossom_data)[blossom].next = INVALID;
103.1725 + (*_blossom_data)[blossom].pot = 0;
103.1726 + (*_blossom_data)[blossom].offset = 0;
103.1727 + ++index;
103.1728 + }
103.1729 + for (EdgeIt e(_graph); e != INVALID; ++e) {
103.1730 + int si = (*_node_index)[_graph.u(e)];
103.1731 + int ti = (*_node_index)[_graph.v(e)];
103.1732 + if (_graph.u(e) != _graph.v(e)) {
103.1733 + _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
103.1734 + dualScale * _weight[e]) / 2);
103.1735 + }
103.1736 + }
103.1737 + }
103.1738 +
103.1739 + /// \brief Start the algorithm
103.1740 + ///
103.1741 + /// This function starts the algorithm.
103.1742 + ///
103.1743 + /// \pre \ref init() must be called before using this function.
103.1744 + void start() {
103.1745 + enum OpType {
103.1746 + D1, D2, D3, D4
103.1747 + };
103.1748 +
103.1749 + int unmatched = _node_num;
103.1750 + while (unmatched > 0) {
103.1751 + Value d1 = !_delta1->empty() ?
103.1752 + _delta1->prio() : std::numeric_limits<Value>::max();
103.1753 +
103.1754 + Value d2 = !_delta2->empty() ?
103.1755 + _delta2->prio() : std::numeric_limits<Value>::max();
103.1756 +
103.1757 + Value d3 = !_delta3->empty() ?
103.1758 + _delta3->prio() : std::numeric_limits<Value>::max();
103.1759 +
103.1760 + Value d4 = !_delta4->empty() ?
103.1761 + _delta4->prio() : std::numeric_limits<Value>::max();
103.1762 +
103.1763 + _delta_sum = d1; OpType ot = D1;
103.1764 + if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
103.1765 + if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
103.1766 + if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
103.1767 +
103.1768 +
103.1769 + switch (ot) {
103.1770 + case D1:
103.1771 + {
103.1772 + Node n = _delta1->top();
103.1773 + unmatchNode(n);
103.1774 + --unmatched;
103.1775 + }
103.1776 + break;
103.1777 + case D2:
103.1778 + {
103.1779 + int blossom = _delta2->top();
103.1780 + Node n = _blossom_set->classTop(blossom);
103.1781 + Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
103.1782 + extendOnArc(e);
103.1783 + }
103.1784 + break;
103.1785 + case D3:
103.1786 + {
103.1787 + Edge e = _delta3->top();
103.1788 +
103.1789 + int left_blossom = _blossom_set->find(_graph.u(e));
103.1790 + int right_blossom = _blossom_set->find(_graph.v(e));
103.1791 +
103.1792 + if (left_blossom == right_blossom) {
103.1793 + _delta3->pop();
103.1794 + } else {
103.1795 + int left_tree;
103.1796 + if ((*_blossom_data)[left_blossom].status == EVEN) {
103.1797 + left_tree = _tree_set->find(left_blossom);
103.1798 + } else {
103.1799 + left_tree = -1;
103.1800 + ++unmatched;
103.1801 + }
103.1802 + int right_tree;
103.1803 + if ((*_blossom_data)[right_blossom].status == EVEN) {
103.1804 + right_tree = _tree_set->find(right_blossom);
103.1805 + } else {
103.1806 + right_tree = -1;
103.1807 + ++unmatched;
103.1808 + }
103.1809 +
103.1810 + if (left_tree == right_tree) {
103.1811 + shrinkOnEdge(e, left_tree);
103.1812 + } else {
103.1813 + augmentOnEdge(e);
103.1814 + unmatched -= 2;
103.1815 + }
103.1816 + }
103.1817 + } break;
103.1818 + case D4:
103.1819 + splitBlossom(_delta4->top());
103.1820 + break;
103.1821 + }
103.1822 + }
103.1823 + extractMatching();
103.1824 + }
103.1825 +
103.1826 + /// \brief Run the algorithm.
103.1827 + ///
103.1828 + /// This method runs the \c %MaxWeightedMatching algorithm.
103.1829 + ///
103.1830 + /// \note mwm.run() is just a shortcut of the following code.
103.1831 + /// \code
103.1832 + /// mwm.init();
103.1833 + /// mwm.start();
103.1834 + /// \endcode
103.1835 + void run() {
103.1836 + init();
103.1837 + start();
103.1838 + }
103.1839 +
103.1840 + /// @}
103.1841 +
103.1842 + /// \name Primal Solution
103.1843 + /// Functions to get the primal solution, i.e. the maximum weighted
103.1844 + /// matching.\n
103.1845 + /// Either \ref run() or \ref start() function should be called before
103.1846 + /// using them.
103.1847 +
103.1848 + /// @{
103.1849 +
103.1850 + /// \brief Return the weight of the matching.
103.1851 + ///
103.1852 + /// This function returns the weight of the found matching.
103.1853 + ///
103.1854 + /// \pre Either run() or start() must be called before using this function.
103.1855 + Value matchingWeight() const {
103.1856 + Value sum = 0;
103.1857 + for (NodeIt n(_graph); n != INVALID; ++n) {
103.1858 + if ((*_matching)[n] != INVALID) {
103.1859 + sum += _weight[(*_matching)[n]];
103.1860 + }
103.1861 + }
103.1862 + return sum /= 2;
103.1863 + }
103.1864 +
103.1865 + /// \brief Return the size (cardinality) of the matching.
103.1866 + ///
103.1867 + /// This function returns the size (cardinality) of the found matching.
103.1868 + ///
103.1869 + /// \pre Either run() or start() must be called before using this function.
103.1870 + int matchingSize() const {
103.1871 + int num = 0;
103.1872 + for (NodeIt n(_graph); n != INVALID; ++n) {
103.1873 + if ((*_matching)[n] != INVALID) {
103.1874 + ++num;
103.1875 + }
103.1876 + }
103.1877 + return num /= 2;
103.1878 + }
103.1879 +
103.1880 + /// \brief Return \c true if the given edge is in the matching.
103.1881 + ///
103.1882 + /// This function returns \c true if the given edge is in the found
103.1883 + /// matching.
103.1884 + ///
103.1885 + /// \pre Either run() or start() must be called before using this function.
103.1886 + bool matching(const Edge& edge) const {
103.1887 + return edge == (*_matching)[_graph.u(edge)];
103.1888 + }
103.1889 +
103.1890 + /// \brief Return the matching arc (or edge) incident to the given node.
103.1891 + ///
103.1892 + /// This function returns the matching arc (or edge) incident to the
103.1893 + /// given node in the found matching or \c INVALID if the node is
103.1894 + /// not covered by the matching.
103.1895 + ///
103.1896 + /// \pre Either run() or start() must be called before using this function.
103.1897 + Arc matching(const Node& node) const {
103.1898 + return (*_matching)[node];
103.1899 + }
103.1900 +
103.1901 + /// \brief Return a const reference to the matching map.
103.1902 + ///
103.1903 + /// This function returns a const reference to a node map that stores
103.1904 + /// the matching arc (or edge) incident to each node.
103.1905 + const MatchingMap& matchingMap() const {
103.1906 + return *_matching;
103.1907 + }
103.1908 +
103.1909 + /// \brief Return the mate of the given node.
103.1910 + ///
103.1911 + /// This function returns the mate of the given node in the found
103.1912 + /// matching or \c INVALID if the node is not covered by the matching.
103.1913 + ///
103.1914 + /// \pre Either run() or start() must be called before using this function.
103.1915 + Node mate(const Node& node) const {
103.1916 + return (*_matching)[node] != INVALID ?
103.1917 + _graph.target((*_matching)[node]) : INVALID;
103.1918 + }
103.1919 +
103.1920 + /// @}
103.1921 +
103.1922 + /// \name Dual Solution
103.1923 + /// Functions to get the dual solution.\n
103.1924 + /// Either \ref run() or \ref start() function should be called before
103.1925 + /// using them.
103.1926 +
103.1927 + /// @{
103.1928 +
103.1929 + /// \brief Return the value of the dual solution.
103.1930 + ///
103.1931 + /// This function returns the value of the dual solution.
103.1932 + /// It should be equal to the primal value scaled by \ref dualScale
103.1933 + /// "dual scale".
103.1934 + ///
103.1935 + /// \pre Either run() or start() must be called before using this function.
103.1936 + Value dualValue() const {
103.1937 + Value sum = 0;
103.1938 + for (NodeIt n(_graph); n != INVALID; ++n) {
103.1939 + sum += nodeValue(n);
103.1940 + }
103.1941 + for (int i = 0; i < blossomNum(); ++i) {
103.1942 + sum += blossomValue(i) * (blossomSize(i) / 2);
103.1943 + }
103.1944 + return sum;
103.1945 + }
103.1946 +
103.1947 + /// \brief Return the dual value (potential) of the given node.
103.1948 + ///
103.1949 + /// This function returns the dual value (potential) of the given node.
103.1950 + ///
103.1951 + /// \pre Either run() or start() must be called before using this function.
103.1952 + Value nodeValue(const Node& n) const {
103.1953 + return (*_node_potential)[n];
103.1954 + }
103.1955 +
103.1956 + /// \brief Return the number of the blossoms in the basis.
103.1957 + ///
103.1958 + /// This function returns the number of the blossoms in the basis.
103.1959 + ///
103.1960 + /// \pre Either run() or start() must be called before using this function.
103.1961 + /// \see BlossomIt
103.1962 + int blossomNum() const {
103.1963 + return _blossom_potential.size();
103.1964 + }
103.1965 +
103.1966 + /// \brief Return the number of the nodes in the given blossom.
103.1967 + ///
103.1968 + /// This function returns the number of the nodes in the given blossom.
103.1969 + ///
103.1970 + /// \pre Either run() or start() must be called before using this function.
103.1971 + /// \see BlossomIt
103.1972 + int blossomSize(int k) const {
103.1973 + return _blossom_potential[k].end - _blossom_potential[k].begin;
103.1974 + }
103.1975 +
103.1976 + /// \brief Return the dual value (ptential) of the given blossom.
103.1977 + ///
103.1978 + /// This function returns the dual value (ptential) of the given blossom.
103.1979 + ///
103.1980 + /// \pre Either run() or start() must be called before using this function.
103.1981 + Value blossomValue(int k) const {
103.1982 + return _blossom_potential[k].value;
103.1983 + }
103.1984 +
103.1985 + /// \brief Iterator for obtaining the nodes of a blossom.
103.1986 + ///
103.1987 + /// This class provides an iterator for obtaining the nodes of the
103.1988 + /// given blossom. It lists a subset of the nodes.
103.1989 + /// Before using this iterator, you must allocate a
103.1990 + /// MaxWeightedMatching class and execute it.
103.1991 + class BlossomIt {
103.1992 + public:
103.1993 +
103.1994 + /// \brief Constructor.
103.1995 + ///
103.1996 + /// Constructor to get the nodes of the given variable.
103.1997 + ///
103.1998 + /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or
103.1999 + /// \ref MaxWeightedMatching::start() "algorithm.start()" must be
103.2000 + /// called before initializing this iterator.
103.2001 + BlossomIt(const MaxWeightedMatching& algorithm, int variable)
103.2002 + : _algorithm(&algorithm)
103.2003 + {
103.2004 + _index = _algorithm->_blossom_potential[variable].begin;
103.2005 + _last = _algorithm->_blossom_potential[variable].end;
103.2006 + }
103.2007 +
103.2008 + /// \brief Conversion to \c Node.
103.2009 + ///
103.2010 + /// Conversion to \c Node.
103.2011 + operator Node() const {
103.2012 + return _algorithm->_blossom_node_list[_index];
103.2013 + }
103.2014 +
103.2015 + /// \brief Increment operator.
103.2016 + ///
103.2017 + /// Increment operator.
103.2018 + BlossomIt& operator++() {
103.2019 + ++_index;
103.2020 + return *this;
103.2021 + }
103.2022 +
103.2023 + /// \brief Validity checking
103.2024 + ///
103.2025 + /// Checks whether the iterator is invalid.
103.2026 + bool operator==(Invalid) const { return _index == _last; }
103.2027 +
103.2028 + /// \brief Validity checking
103.2029 + ///
103.2030 + /// Checks whether the iterator is valid.
103.2031 + bool operator!=(Invalid) const { return _index != _last; }
103.2032 +
103.2033 + private:
103.2034 + const MaxWeightedMatching* _algorithm;
103.2035 + int _last;
103.2036 + int _index;
103.2037 + };
103.2038 +
103.2039 + /// @}
103.2040 +
103.2041 + };
103.2042 +
103.2043 + /// \ingroup matching
103.2044 + ///
103.2045 + /// \brief Weighted perfect matching in general graphs
103.2046 + ///
103.2047 + /// This class provides an efficient implementation of Edmond's
103.2048 + /// maximum weighted perfect matching algorithm. The implementation
103.2049 + /// is based on extensive use of priority queues and provides
103.2050 + /// \f$O(nm\log n)\f$ time complexity.
103.2051 + ///
103.2052 + /// The maximum weighted perfect matching problem is to find a subset of
103.2053 + /// the edges in an undirected graph with maximum overall weight for which
103.2054 + /// each node has exactly one incident edge.
103.2055 + /// It can be formulated with the following linear program.
103.2056 + /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
103.2057 + /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
103.2058 + \quad \forall B\in\mathcal{O}\f] */
103.2059 + /// \f[x_e \ge 0\quad \forall e\in E\f]
103.2060 + /// \f[\max \sum_{e\in E}x_ew_e\f]
103.2061 + /// where \f$\delta(X)\f$ is the set of edges incident to a node in
103.2062 + /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
103.2063 + /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
103.2064 + /// subsets of the nodes.
103.2065 + ///
103.2066 + /// The algorithm calculates an optimal matching and a proof of the
103.2067 + /// optimality. The solution of the dual problem can be used to check
103.2068 + /// the result of the algorithm. The dual linear problem is the
103.2069 + /// following.
103.2070 + /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
103.2071 + w_{uv} \quad \forall uv\in E\f] */
103.2072 + /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
103.2073 + /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
103.2074 + \frac{\vert B \vert - 1}{2}z_B\f] */
103.2075 + ///
103.2076 + /// The algorithm can be executed with the run() function.
103.2077 + /// After it the matching (the primal solution) and the dual solution
103.2078 + /// can be obtained using the query functions and the
103.2079 + /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class,
103.2080 + /// which is able to iterate on the nodes of a blossom.
103.2081 + /// If the value type is integer, then the dual solution is multiplied
103.2082 + /// by \ref MaxWeightedMatching::dualScale "4".
103.2083 + ///
103.2084 + /// \tparam GR The undirected graph type the algorithm runs on.
103.2085 + /// \tparam WM The type edge weight map. The default type is
103.2086 + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
103.2087 +#ifdef DOXYGEN
103.2088 + template <typename GR, typename WM>
103.2089 +#else
103.2090 + template <typename GR,
103.2091 + typename WM = typename GR::template EdgeMap<int> >
103.2092 +#endif
103.2093 + class MaxWeightedPerfectMatching {
103.2094 + public:
103.2095 +
103.2096 + /// The graph type of the algorithm
103.2097 + typedef GR Graph;
103.2098 + /// The type of the edge weight map
103.2099 + typedef WM WeightMap;
103.2100 + /// The value type of the edge weights
103.2101 + typedef typename WeightMap::Value Value;
103.2102 +
103.2103 + /// \brief Scaling factor for dual solution
103.2104 + ///
103.2105 + /// Scaling factor for dual solution, it is equal to 4 or 1
103.2106 + /// according to the value type.
103.2107 + static const int dualScale =
103.2108 + std::numeric_limits<Value>::is_integer ? 4 : 1;
103.2109 +
103.2110 + /// The type of the matching map
103.2111 + typedef typename Graph::template NodeMap<typename Graph::Arc>
103.2112 + MatchingMap;
103.2113 +
103.2114 + private:
103.2115 +
103.2116 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
103.2117 +
103.2118 + typedef typename Graph::template NodeMap<Value> NodePotential;
103.2119 + typedef std::vector<Node> BlossomNodeList;
103.2120 +
103.2121 + struct BlossomVariable {
103.2122 + int begin, end;
103.2123 + Value value;
103.2124 +
103.2125 + BlossomVariable(int _begin, int _end, Value _value)
103.2126 + : begin(_begin), end(_end), value(_value) {}
103.2127 +
103.2128 + };
103.2129 +
103.2130 + typedef std::vector<BlossomVariable> BlossomPotential;
103.2131 +
103.2132 + const Graph& _graph;
103.2133 + const WeightMap& _weight;
103.2134 +
103.2135 + MatchingMap* _matching;
103.2136 +
103.2137 + NodePotential* _node_potential;
103.2138 +
103.2139 + BlossomPotential _blossom_potential;
103.2140 + BlossomNodeList _blossom_node_list;
103.2141 +
103.2142 + int _node_num;
103.2143 + int _blossom_num;
103.2144 +
103.2145 + typedef RangeMap<int> IntIntMap;
103.2146 +
103.2147 + enum Status {
103.2148 + EVEN = -1, MATCHED = 0, ODD = 1
103.2149 + };
103.2150 +
103.2151 + typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
103.2152 + struct BlossomData {
103.2153 + int tree;
103.2154 + Status status;
103.2155 + Arc pred, next;
103.2156 + Value pot, offset;
103.2157 + };
103.2158 +
103.2159 + IntNodeMap *_blossom_index;
103.2160 + BlossomSet *_blossom_set;
103.2161 + RangeMap<BlossomData>* _blossom_data;
103.2162 +
103.2163 + IntNodeMap *_node_index;
103.2164 + IntArcMap *_node_heap_index;
103.2165 +
103.2166 + struct NodeData {
103.2167 +
103.2168 + NodeData(IntArcMap& node_heap_index)
103.2169 + : heap(node_heap_index) {}
103.2170 +
103.2171 + int blossom;
103.2172 + Value pot;
103.2173 + BinHeap<Value, IntArcMap> heap;
103.2174 + std::map<int, Arc> heap_index;
103.2175 +
103.2176 + int tree;
103.2177 + };
103.2178 +
103.2179 + RangeMap<NodeData>* _node_data;
103.2180 +
103.2181 + typedef ExtendFindEnum<IntIntMap> TreeSet;
103.2182 +
103.2183 + IntIntMap *_tree_set_index;
103.2184 + TreeSet *_tree_set;
103.2185 +
103.2186 + IntIntMap *_delta2_index;
103.2187 + BinHeap<Value, IntIntMap> *_delta2;
103.2188 +
103.2189 + IntEdgeMap *_delta3_index;
103.2190 + BinHeap<Value, IntEdgeMap> *_delta3;
103.2191 +
103.2192 + IntIntMap *_delta4_index;
103.2193 + BinHeap<Value, IntIntMap> *_delta4;
103.2194 +
103.2195 + Value _delta_sum;
103.2196 +
103.2197 + void createStructures() {
103.2198 + _node_num = countNodes(_graph);
103.2199 + _blossom_num = _node_num * 3 / 2;
103.2200 +
103.2201 + if (!_matching) {
103.2202 + _matching = new MatchingMap(_graph);
103.2203 + }
103.2204 + if (!_node_potential) {
103.2205 + _node_potential = new NodePotential(_graph);
103.2206 + }
103.2207 + if (!_blossom_set) {
103.2208 + _blossom_index = new IntNodeMap(_graph);
103.2209 + _blossom_set = new BlossomSet(*_blossom_index);
103.2210 + _blossom_data = new RangeMap<BlossomData>(_blossom_num);
103.2211 + }
103.2212 +
103.2213 + if (!_node_index) {
103.2214 + _node_index = new IntNodeMap(_graph);
103.2215 + _node_heap_index = new IntArcMap(_graph);
103.2216 + _node_data = new RangeMap<NodeData>(_node_num,
103.2217 + NodeData(*_node_heap_index));
103.2218 + }
103.2219 +
103.2220 + if (!_tree_set) {
103.2221 + _tree_set_index = new IntIntMap(_blossom_num);
103.2222 + _tree_set = new TreeSet(*_tree_set_index);
103.2223 + }
103.2224 + if (!_delta2) {
103.2225 + _delta2_index = new IntIntMap(_blossom_num);
103.2226 + _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
103.2227 + }
103.2228 + if (!_delta3) {
103.2229 + _delta3_index = new IntEdgeMap(_graph);
103.2230 + _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
103.2231 + }
103.2232 + if (!_delta4) {
103.2233 + _delta4_index = new IntIntMap(_blossom_num);
103.2234 + _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
103.2235 + }
103.2236 + }
103.2237 +
103.2238 + void destroyStructures() {
103.2239 + _node_num = countNodes(_graph);
103.2240 + _blossom_num = _node_num * 3 / 2;
103.2241 +
103.2242 + if (_matching) {
103.2243 + delete _matching;
103.2244 + }
103.2245 + if (_node_potential) {
103.2246 + delete _node_potential;
103.2247 + }
103.2248 + if (_blossom_set) {
103.2249 + delete _blossom_index;
103.2250 + delete _blossom_set;
103.2251 + delete _blossom_data;
103.2252 + }
103.2253 +
103.2254 + if (_node_index) {
103.2255 + delete _node_index;
103.2256 + delete _node_heap_index;
103.2257 + delete _node_data;
103.2258 + }
103.2259 +
103.2260 + if (_tree_set) {
103.2261 + delete _tree_set_index;
103.2262 + delete _tree_set;
103.2263 + }
103.2264 + if (_delta2) {
103.2265 + delete _delta2_index;
103.2266 + delete _delta2;
103.2267 + }
103.2268 + if (_delta3) {
103.2269 + delete _delta3_index;
103.2270 + delete _delta3;
103.2271 + }
103.2272 + if (_delta4) {
103.2273 + delete _delta4_index;
103.2274 + delete _delta4;
103.2275 + }
103.2276 + }
103.2277 +
103.2278 + void matchedToEven(int blossom, int tree) {
103.2279 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
103.2280 + _delta2->erase(blossom);
103.2281 + }
103.2282 +
103.2283 + if (!_blossom_set->trivial(blossom)) {
103.2284 + (*_blossom_data)[blossom].pot -=
103.2285 + 2 * (_delta_sum - (*_blossom_data)[blossom].offset);
103.2286 + }
103.2287 +
103.2288 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
103.2289 + n != INVALID; ++n) {
103.2290 +
103.2291 + _blossom_set->increase(n, std::numeric_limits<Value>::max());
103.2292 + int ni = (*_node_index)[n];
103.2293 +
103.2294 + (*_node_data)[ni].heap.clear();
103.2295 + (*_node_data)[ni].heap_index.clear();
103.2296 +
103.2297 + (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
103.2298 +
103.2299 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
103.2300 + Node v = _graph.source(e);
103.2301 + int vb = _blossom_set->find(v);
103.2302 + int vi = (*_node_index)[v];
103.2303 +
103.2304 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
103.2305 + dualScale * _weight[e];
103.2306 +
103.2307 + if ((*_blossom_data)[vb].status == EVEN) {
103.2308 + if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
103.2309 + _delta3->push(e, rw / 2);
103.2310 + }
103.2311 + } else {
103.2312 + typename std::map<int, Arc>::iterator it =
103.2313 + (*_node_data)[vi].heap_index.find(tree);
103.2314 +
103.2315 + if (it != (*_node_data)[vi].heap_index.end()) {
103.2316 + if ((*_node_data)[vi].heap[it->second] > rw) {
103.2317 + (*_node_data)[vi].heap.replace(it->second, e);
103.2318 + (*_node_data)[vi].heap.decrease(e, rw);
103.2319 + it->second = e;
103.2320 + }
103.2321 + } else {
103.2322 + (*_node_data)[vi].heap.push(e, rw);
103.2323 + (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
103.2324 + }
103.2325 +
103.2326 + if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
103.2327 + _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
103.2328 +
103.2329 + if ((*_blossom_data)[vb].status == MATCHED) {
103.2330 + if (_delta2->state(vb) != _delta2->IN_HEAP) {
103.2331 + _delta2->push(vb, _blossom_set->classPrio(vb) -
103.2332 + (*_blossom_data)[vb].offset);
103.2333 + } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
103.2334 + (*_blossom_data)[vb].offset){
103.2335 + _delta2->decrease(vb, _blossom_set->classPrio(vb) -
103.2336 + (*_blossom_data)[vb].offset);
103.2337 + }
103.2338 + }
103.2339 + }
103.2340 + }
103.2341 + }
103.2342 + }
103.2343 + (*_blossom_data)[blossom].offset = 0;
103.2344 + }
103.2345 +
103.2346 + void matchedToOdd(int blossom) {
103.2347 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
103.2348 + _delta2->erase(blossom);
103.2349 + }
103.2350 + (*_blossom_data)[blossom].offset += _delta_sum;
103.2351 + if (!_blossom_set->trivial(blossom)) {
103.2352 + _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
103.2353 + (*_blossom_data)[blossom].offset);
103.2354 + }
103.2355 + }
103.2356 +
103.2357 + void evenToMatched(int blossom, int tree) {
103.2358 + if (!_blossom_set->trivial(blossom)) {
103.2359 + (*_blossom_data)[blossom].pot += 2 * _delta_sum;
103.2360 + }
103.2361 +
103.2362 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
103.2363 + n != INVALID; ++n) {
103.2364 + int ni = (*_node_index)[n];
103.2365 + (*_node_data)[ni].pot -= _delta_sum;
103.2366 +
103.2367 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
103.2368 + Node v = _graph.source(e);
103.2369 + int vb = _blossom_set->find(v);
103.2370 + int vi = (*_node_index)[v];
103.2371 +
103.2372 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
103.2373 + dualScale * _weight[e];
103.2374 +
103.2375 + if (vb == blossom) {
103.2376 + if (_delta3->state(e) == _delta3->IN_HEAP) {
103.2377 + _delta3->erase(e);
103.2378 + }
103.2379 + } else if ((*_blossom_data)[vb].status == EVEN) {
103.2380 +
103.2381 + if (_delta3->state(e) == _delta3->IN_HEAP) {
103.2382 + _delta3->erase(e);
103.2383 + }
103.2384 +
103.2385 + int vt = _tree_set->find(vb);
103.2386 +
103.2387 + if (vt != tree) {
103.2388 +
103.2389 + Arc r = _graph.oppositeArc(e);
103.2390 +
103.2391 + typename std::map<int, Arc>::iterator it =
103.2392 + (*_node_data)[ni].heap_index.find(vt);
103.2393 +
103.2394 + if (it != (*_node_data)[ni].heap_index.end()) {
103.2395 + if ((*_node_data)[ni].heap[it->second] > rw) {
103.2396 + (*_node_data)[ni].heap.replace(it->second, r);
103.2397 + (*_node_data)[ni].heap.decrease(r, rw);
103.2398 + it->second = r;
103.2399 + }
103.2400 + } else {
103.2401 + (*_node_data)[ni].heap.push(r, rw);
103.2402 + (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
103.2403 + }
103.2404 +
103.2405 + if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
103.2406 + _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
103.2407 +
103.2408 + if (_delta2->state(blossom) != _delta2->IN_HEAP) {
103.2409 + _delta2->push(blossom, _blossom_set->classPrio(blossom) -
103.2410 + (*_blossom_data)[blossom].offset);
103.2411 + } else if ((*_delta2)[blossom] >
103.2412 + _blossom_set->classPrio(blossom) -
103.2413 + (*_blossom_data)[blossom].offset){
103.2414 + _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
103.2415 + (*_blossom_data)[blossom].offset);
103.2416 + }
103.2417 + }
103.2418 + }
103.2419 + } else {
103.2420 +
103.2421 + typename std::map<int, Arc>::iterator it =
103.2422 + (*_node_data)[vi].heap_index.find(tree);
103.2423 +
103.2424 + if (it != (*_node_data)[vi].heap_index.end()) {
103.2425 + (*_node_data)[vi].heap.erase(it->second);
103.2426 + (*_node_data)[vi].heap_index.erase(it);
103.2427 + if ((*_node_data)[vi].heap.empty()) {
103.2428 + _blossom_set->increase(v, std::numeric_limits<Value>::max());
103.2429 + } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
103.2430 + _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
103.2431 + }
103.2432 +
103.2433 + if ((*_blossom_data)[vb].status == MATCHED) {
103.2434 + if (_blossom_set->classPrio(vb) ==
103.2435 + std::numeric_limits<Value>::max()) {
103.2436 + _delta2->erase(vb);
103.2437 + } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
103.2438 + (*_blossom_data)[vb].offset) {
103.2439 + _delta2->increase(vb, _blossom_set->classPrio(vb) -
103.2440 + (*_blossom_data)[vb].offset);
103.2441 + }
103.2442 + }
103.2443 + }
103.2444 + }
103.2445 + }
103.2446 + }
103.2447 + }
103.2448 +
103.2449 + void oddToMatched(int blossom) {
103.2450 + (*_blossom_data)[blossom].offset -= _delta_sum;
103.2451 +
103.2452 + if (_blossom_set->classPrio(blossom) !=
103.2453 + std::numeric_limits<Value>::max()) {
103.2454 + _delta2->push(blossom, _blossom_set->classPrio(blossom) -
103.2455 + (*_blossom_data)[blossom].offset);
103.2456 + }
103.2457 +
103.2458 + if (!_blossom_set->trivial(blossom)) {
103.2459 + _delta4->erase(blossom);
103.2460 + }
103.2461 + }
103.2462 +
103.2463 + void oddToEven(int blossom, int tree) {
103.2464 + if (!_blossom_set->trivial(blossom)) {
103.2465 + _delta4->erase(blossom);
103.2466 + (*_blossom_data)[blossom].pot -=
103.2467 + 2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
103.2468 + }
103.2469 +
103.2470 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
103.2471 + n != INVALID; ++n) {
103.2472 + int ni = (*_node_index)[n];
103.2473 +
103.2474 + _blossom_set->increase(n, std::numeric_limits<Value>::max());
103.2475 +
103.2476 + (*_node_data)[ni].heap.clear();
103.2477 + (*_node_data)[ni].heap_index.clear();
103.2478 + (*_node_data)[ni].pot +=
103.2479 + 2 * _delta_sum - (*_blossom_data)[blossom].offset;
103.2480 +
103.2481 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
103.2482 + Node v = _graph.source(e);
103.2483 + int vb = _blossom_set->find(v);
103.2484 + int vi = (*_node_index)[v];
103.2485 +
103.2486 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
103.2487 + dualScale * _weight[e];
103.2488 +
103.2489 + if ((*_blossom_data)[vb].status == EVEN) {
103.2490 + if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
103.2491 + _delta3->push(e, rw / 2);
103.2492 + }
103.2493 + } else {
103.2494 +
103.2495 + typename std::map<int, Arc>::iterator it =
103.2496 + (*_node_data)[vi].heap_index.find(tree);
103.2497 +
103.2498 + if (it != (*_node_data)[vi].heap_index.end()) {
103.2499 + if ((*_node_data)[vi].heap[it->second] > rw) {
103.2500 + (*_node_data)[vi].heap.replace(it->second, e);
103.2501 + (*_node_data)[vi].heap.decrease(e, rw);
103.2502 + it->second = e;
103.2503 + }
103.2504 + } else {
103.2505 + (*_node_data)[vi].heap.push(e, rw);
103.2506 + (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
103.2507 + }
103.2508 +
103.2509 + if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
103.2510 + _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
103.2511 +
103.2512 + if ((*_blossom_data)[vb].status == MATCHED) {
103.2513 + if (_delta2->state(vb) != _delta2->IN_HEAP) {
103.2514 + _delta2->push(vb, _blossom_set->classPrio(vb) -
103.2515 + (*_blossom_data)[vb].offset);
103.2516 + } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
103.2517 + (*_blossom_data)[vb].offset) {
103.2518 + _delta2->decrease(vb, _blossom_set->classPrio(vb) -
103.2519 + (*_blossom_data)[vb].offset);
103.2520 + }
103.2521 + }
103.2522 + }
103.2523 + }
103.2524 + }
103.2525 + }
103.2526 + (*_blossom_data)[blossom].offset = 0;
103.2527 + }
103.2528 +
103.2529 + void alternatePath(int even, int tree) {
103.2530 + int odd;
103.2531 +
103.2532 + evenToMatched(even, tree);
103.2533 + (*_blossom_data)[even].status = MATCHED;
103.2534 +
103.2535 + while ((*_blossom_data)[even].pred != INVALID) {
103.2536 + odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
103.2537 + (*_blossom_data)[odd].status = MATCHED;
103.2538 + oddToMatched(odd);
103.2539 + (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
103.2540 +
103.2541 + even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
103.2542 + (*_blossom_data)[even].status = MATCHED;
103.2543 + evenToMatched(even, tree);
103.2544 + (*_blossom_data)[even].next =
103.2545 + _graph.oppositeArc((*_blossom_data)[odd].pred);
103.2546 + }
103.2547 +
103.2548 + }
103.2549 +
103.2550 + void destroyTree(int tree) {
103.2551 + for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
103.2552 + if ((*_blossom_data)[b].status == EVEN) {
103.2553 + (*_blossom_data)[b].status = MATCHED;
103.2554 + evenToMatched(b, tree);
103.2555 + } else if ((*_blossom_data)[b].status == ODD) {
103.2556 + (*_blossom_data)[b].status = MATCHED;
103.2557 + oddToMatched(b);
103.2558 + }
103.2559 + }
103.2560 + _tree_set->eraseClass(tree);
103.2561 + }
103.2562 +
103.2563 + void augmentOnEdge(const Edge& edge) {
103.2564 +
103.2565 + int left = _blossom_set->find(_graph.u(edge));
103.2566 + int right = _blossom_set->find(_graph.v(edge));
103.2567 +
103.2568 + int left_tree = _tree_set->find(left);
103.2569 + alternatePath(left, left_tree);
103.2570 + destroyTree(left_tree);
103.2571 +
103.2572 + int right_tree = _tree_set->find(right);
103.2573 + alternatePath(right, right_tree);
103.2574 + destroyTree(right_tree);
103.2575 +
103.2576 + (*_blossom_data)[left].next = _graph.direct(edge, true);
103.2577 + (*_blossom_data)[right].next = _graph.direct(edge, false);
103.2578 + }
103.2579 +
103.2580 + void extendOnArc(const Arc& arc) {
103.2581 + int base = _blossom_set->find(_graph.target(arc));
103.2582 + int tree = _tree_set->find(base);
103.2583 +
103.2584 + int odd = _blossom_set->find(_graph.source(arc));
103.2585 + _tree_set->insert(odd, tree);
103.2586 + (*_blossom_data)[odd].status = ODD;
103.2587 + matchedToOdd(odd);
103.2588 + (*_blossom_data)[odd].pred = arc;
103.2589 +
103.2590 + int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
103.2591 + (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
103.2592 + _tree_set->insert(even, tree);
103.2593 + (*_blossom_data)[even].status = EVEN;
103.2594 + matchedToEven(even, tree);
103.2595 + }
103.2596 +
103.2597 + void shrinkOnEdge(const Edge& edge, int tree) {
103.2598 + int nca = -1;
103.2599 + std::vector<int> left_path, right_path;
103.2600 +
103.2601 + {
103.2602 + std::set<int> left_set, right_set;
103.2603 + int left = _blossom_set->find(_graph.u(edge));
103.2604 + left_path.push_back(left);
103.2605 + left_set.insert(left);
103.2606 +
103.2607 + int right = _blossom_set->find(_graph.v(edge));
103.2608 + right_path.push_back(right);
103.2609 + right_set.insert(right);
103.2610 +
103.2611 + while (true) {
103.2612 +
103.2613 + if ((*_blossom_data)[left].pred == INVALID) break;
103.2614 +
103.2615 + left =
103.2616 + _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
103.2617 + left_path.push_back(left);
103.2618 + left =
103.2619 + _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
103.2620 + left_path.push_back(left);
103.2621 +
103.2622 + left_set.insert(left);
103.2623 +
103.2624 + if (right_set.find(left) != right_set.end()) {
103.2625 + nca = left;
103.2626 + break;
103.2627 + }
103.2628 +
103.2629 + if ((*_blossom_data)[right].pred == INVALID) break;
103.2630 +
103.2631 + right =
103.2632 + _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
103.2633 + right_path.push_back(right);
103.2634 + right =
103.2635 + _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
103.2636 + right_path.push_back(right);
103.2637 +
103.2638 + right_set.insert(right);
103.2639 +
103.2640 + if (left_set.find(right) != left_set.end()) {
103.2641 + nca = right;
103.2642 + break;
103.2643 + }
103.2644 +
103.2645 + }
103.2646 +
103.2647 + if (nca == -1) {
103.2648 + if ((*_blossom_data)[left].pred == INVALID) {
103.2649 + nca = right;
103.2650 + while (left_set.find(nca) == left_set.end()) {
103.2651 + nca =
103.2652 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
103.2653 + right_path.push_back(nca);
103.2654 + nca =
103.2655 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
103.2656 + right_path.push_back(nca);
103.2657 + }
103.2658 + } else {
103.2659 + nca = left;
103.2660 + while (right_set.find(nca) == right_set.end()) {
103.2661 + nca =
103.2662 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
103.2663 + left_path.push_back(nca);
103.2664 + nca =
103.2665 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
103.2666 + left_path.push_back(nca);
103.2667 + }
103.2668 + }
103.2669 + }
103.2670 + }
103.2671 +
103.2672 + std::vector<int> subblossoms;
103.2673 + Arc prev;
103.2674 +
103.2675 + prev = _graph.direct(edge, true);
103.2676 + for (int i = 0; left_path[i] != nca; i += 2) {
103.2677 + subblossoms.push_back(left_path[i]);
103.2678 + (*_blossom_data)[left_path[i]].next = prev;
103.2679 + _tree_set->erase(left_path[i]);
103.2680 +
103.2681 + subblossoms.push_back(left_path[i + 1]);
103.2682 + (*_blossom_data)[left_path[i + 1]].status = EVEN;
103.2683 + oddToEven(left_path[i + 1], tree);
103.2684 + _tree_set->erase(left_path[i + 1]);
103.2685 + prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
103.2686 + }
103.2687 +
103.2688 + int k = 0;
103.2689 + while (right_path[k] != nca) ++k;
103.2690 +
103.2691 + subblossoms.push_back(nca);
103.2692 + (*_blossom_data)[nca].next = prev;
103.2693 +
103.2694 + for (int i = k - 2; i >= 0; i -= 2) {
103.2695 + subblossoms.push_back(right_path[i + 1]);
103.2696 + (*_blossom_data)[right_path[i + 1]].status = EVEN;
103.2697 + oddToEven(right_path[i + 1], tree);
103.2698 + _tree_set->erase(right_path[i + 1]);
103.2699 +
103.2700 + (*_blossom_data)[right_path[i + 1]].next =
103.2701 + (*_blossom_data)[right_path[i + 1]].pred;
103.2702 +
103.2703 + subblossoms.push_back(right_path[i]);
103.2704 + _tree_set->erase(right_path[i]);
103.2705 + }
103.2706 +
103.2707 + int surface =
103.2708 + _blossom_set->join(subblossoms.begin(), subblossoms.end());
103.2709 +
103.2710 + for (int i = 0; i < int(subblossoms.size()); ++i) {
103.2711 + if (!_blossom_set->trivial(subblossoms[i])) {
103.2712 + (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
103.2713 + }
103.2714 + (*_blossom_data)[subblossoms[i]].status = MATCHED;
103.2715 + }
103.2716 +
103.2717 + (*_blossom_data)[surface].pot = -2 * _delta_sum;
103.2718 + (*_blossom_data)[surface].offset = 0;
103.2719 + (*_blossom_data)[surface].status = EVEN;
103.2720 + (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
103.2721 + (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
103.2722 +
103.2723 + _tree_set->insert(surface, tree);
103.2724 + _tree_set->erase(nca);
103.2725 + }
103.2726 +
103.2727 + void splitBlossom(int blossom) {
103.2728 + Arc next = (*_blossom_data)[blossom].next;
103.2729 + Arc pred = (*_blossom_data)[blossom].pred;
103.2730 +
103.2731 + int tree = _tree_set->find(blossom);
103.2732 +
103.2733 + (*_blossom_data)[blossom].status = MATCHED;
103.2734 + oddToMatched(blossom);
103.2735 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
103.2736 + _delta2->erase(blossom);
103.2737 + }
103.2738 +
103.2739 + std::vector<int> subblossoms;
103.2740 + _blossom_set->split(blossom, std::back_inserter(subblossoms));
103.2741 +
103.2742 + Value offset = (*_blossom_data)[blossom].offset;
103.2743 + int b = _blossom_set->find(_graph.source(pred));
103.2744 + int d = _blossom_set->find(_graph.source(next));
103.2745 +
103.2746 + int ib = -1, id = -1;
103.2747 + for (int i = 0; i < int(subblossoms.size()); ++i) {
103.2748 + if (subblossoms[i] == b) ib = i;
103.2749 + if (subblossoms[i] == d) id = i;
103.2750 +
103.2751 + (*_blossom_data)[subblossoms[i]].offset = offset;
103.2752 + if (!_blossom_set->trivial(subblossoms[i])) {
103.2753 + (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
103.2754 + }
103.2755 + if (_blossom_set->classPrio(subblossoms[i]) !=
103.2756 + std::numeric_limits<Value>::max()) {
103.2757 + _delta2->push(subblossoms[i],
103.2758 + _blossom_set->classPrio(subblossoms[i]) -
103.2759 + (*_blossom_data)[subblossoms[i]].offset);
103.2760 + }
103.2761 + }
103.2762 +
103.2763 + if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
103.2764 + for (int i = (id + 1) % subblossoms.size();
103.2765 + i != ib; i = (i + 2) % subblossoms.size()) {
103.2766 + int sb = subblossoms[i];
103.2767 + int tb = subblossoms[(i + 1) % subblossoms.size()];
103.2768 + (*_blossom_data)[sb].next =
103.2769 + _graph.oppositeArc((*_blossom_data)[tb].next);
103.2770 + }
103.2771 +
103.2772 + for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
103.2773 + int sb = subblossoms[i];
103.2774 + int tb = subblossoms[(i + 1) % subblossoms.size()];
103.2775 + int ub = subblossoms[(i + 2) % subblossoms.size()];
103.2776 +
103.2777 + (*_blossom_data)[sb].status = ODD;
103.2778 + matchedToOdd(sb);
103.2779 + _tree_set->insert(sb, tree);
103.2780 + (*_blossom_data)[sb].pred = pred;
103.2781 + (*_blossom_data)[sb].next =
103.2782 + _graph.oppositeArc((*_blossom_data)[tb].next);
103.2783 +
103.2784 + pred = (*_blossom_data)[ub].next;
103.2785 +
103.2786 + (*_blossom_data)[tb].status = EVEN;
103.2787 + matchedToEven(tb, tree);
103.2788 + _tree_set->insert(tb, tree);
103.2789 + (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
103.2790 + }
103.2791 +
103.2792 + (*_blossom_data)[subblossoms[id]].status = ODD;
103.2793 + matchedToOdd(subblossoms[id]);
103.2794 + _tree_set->insert(subblossoms[id], tree);
103.2795 + (*_blossom_data)[subblossoms[id]].next = next;
103.2796 + (*_blossom_data)[subblossoms[id]].pred = pred;
103.2797 +
103.2798 + } else {
103.2799 +
103.2800 + for (int i = (ib + 1) % subblossoms.size();
103.2801 + i != id; i = (i + 2) % subblossoms.size()) {
103.2802 + int sb = subblossoms[i];
103.2803 + int tb = subblossoms[(i + 1) % subblossoms.size()];
103.2804 + (*_blossom_data)[sb].next =
103.2805 + _graph.oppositeArc((*_blossom_data)[tb].next);
103.2806 + }
103.2807 +
103.2808 + for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
103.2809 + int sb = subblossoms[i];
103.2810 + int tb = subblossoms[(i + 1) % subblossoms.size()];
103.2811 + int ub = subblossoms[(i + 2) % subblossoms.size()];
103.2812 +
103.2813 + (*_blossom_data)[sb].status = ODD;
103.2814 + matchedToOdd(sb);
103.2815 + _tree_set->insert(sb, tree);
103.2816 + (*_blossom_data)[sb].next = next;
103.2817 + (*_blossom_data)[sb].pred =
103.2818 + _graph.oppositeArc((*_blossom_data)[tb].next);
103.2819 +
103.2820 + (*_blossom_data)[tb].status = EVEN;
103.2821 + matchedToEven(tb, tree);
103.2822 + _tree_set->insert(tb, tree);
103.2823 + (*_blossom_data)[tb].pred =
103.2824 + (*_blossom_data)[tb].next =
103.2825 + _graph.oppositeArc((*_blossom_data)[ub].next);
103.2826 + next = (*_blossom_data)[ub].next;
103.2827 + }
103.2828 +
103.2829 + (*_blossom_data)[subblossoms[ib]].status = ODD;
103.2830 + matchedToOdd(subblossoms[ib]);
103.2831 + _tree_set->insert(subblossoms[ib], tree);
103.2832 + (*_blossom_data)[subblossoms[ib]].next = next;
103.2833 + (*_blossom_data)[subblossoms[ib]].pred = pred;
103.2834 + }
103.2835 + _tree_set->erase(blossom);
103.2836 + }
103.2837 +
103.2838 + void extractBlossom(int blossom, const Node& base, const Arc& matching) {
103.2839 + if (_blossom_set->trivial(blossom)) {
103.2840 + int bi = (*_node_index)[base];
103.2841 + Value pot = (*_node_data)[bi].pot;
103.2842 +
103.2843 + (*_matching)[base] = matching;
103.2844 + _blossom_node_list.push_back(base);
103.2845 + (*_node_potential)[base] = pot;
103.2846 + } else {
103.2847 +
103.2848 + Value pot = (*_blossom_data)[blossom].pot;
103.2849 + int bn = _blossom_node_list.size();
103.2850 +
103.2851 + std::vector<int> subblossoms;
103.2852 + _blossom_set->split(blossom, std::back_inserter(subblossoms));
103.2853 + int b = _blossom_set->find(base);
103.2854 + int ib = -1;
103.2855 + for (int i = 0; i < int(subblossoms.size()); ++i) {
103.2856 + if (subblossoms[i] == b) { ib = i; break; }
103.2857 + }
103.2858 +
103.2859 + for (int i = 1; i < int(subblossoms.size()); i += 2) {
103.2860 + int sb = subblossoms[(ib + i) % subblossoms.size()];
103.2861 + int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
103.2862 +
103.2863 + Arc m = (*_blossom_data)[tb].next;
103.2864 + extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
103.2865 + extractBlossom(tb, _graph.source(m), m);
103.2866 + }
103.2867 + extractBlossom(subblossoms[ib], base, matching);
103.2868 +
103.2869 + int en = _blossom_node_list.size();
103.2870 +
103.2871 + _blossom_potential.push_back(BlossomVariable(bn, en, pot));
103.2872 + }
103.2873 + }
103.2874 +
103.2875 + void extractMatching() {
103.2876 + std::vector<int> blossoms;
103.2877 + for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
103.2878 + blossoms.push_back(c);
103.2879 + }
103.2880 +
103.2881 + for (int i = 0; i < int(blossoms.size()); ++i) {
103.2882 +
103.2883 + Value offset = (*_blossom_data)[blossoms[i]].offset;
103.2884 + (*_blossom_data)[blossoms[i]].pot += 2 * offset;
103.2885 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
103.2886 + n != INVALID; ++n) {
103.2887 + (*_node_data)[(*_node_index)[n]].pot -= offset;
103.2888 + }
103.2889 +
103.2890 + Arc matching = (*_blossom_data)[blossoms[i]].next;
103.2891 + Node base = _graph.source(matching);
103.2892 + extractBlossom(blossoms[i], base, matching);
103.2893 + }
103.2894 + }
103.2895 +
103.2896 + public:
103.2897 +
103.2898 + /// \brief Constructor
103.2899 + ///
103.2900 + /// Constructor.
103.2901 + MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
103.2902 + : _graph(graph), _weight(weight), _matching(0),
103.2903 + _node_potential(0), _blossom_potential(), _blossom_node_list(),
103.2904 + _node_num(0), _blossom_num(0),
103.2905 +
103.2906 + _blossom_index(0), _blossom_set(0), _blossom_data(0),
103.2907 + _node_index(0), _node_heap_index(0), _node_data(0),
103.2908 + _tree_set_index(0), _tree_set(0),
103.2909 +
103.2910 + _delta2_index(0), _delta2(0),
103.2911 + _delta3_index(0), _delta3(0),
103.2912 + _delta4_index(0), _delta4(0),
103.2913 +
103.2914 + _delta_sum() {}
103.2915 +
103.2916 + ~MaxWeightedPerfectMatching() {
103.2917 + destroyStructures();
103.2918 + }
103.2919 +
103.2920 + /// \name Execution Control
103.2921 + /// The simplest way to execute the algorithm is to use the
103.2922 + /// \ref run() member function.
103.2923 +
103.2924 + ///@{
103.2925 +
103.2926 + /// \brief Initialize the algorithm
103.2927 + ///
103.2928 + /// This function initializes the algorithm.
103.2929 + void init() {
103.2930 + createStructures();
103.2931 +
103.2932 + for (ArcIt e(_graph); e != INVALID; ++e) {
103.2933 + (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
103.2934 + }
103.2935 + for (EdgeIt e(_graph); e != INVALID; ++e) {
103.2936 + (*_delta3_index)[e] = _delta3->PRE_HEAP;
103.2937 + }
103.2938 + for (int i = 0; i < _blossom_num; ++i) {
103.2939 + (*_delta2_index)[i] = _delta2->PRE_HEAP;
103.2940 + (*_delta4_index)[i] = _delta4->PRE_HEAP;
103.2941 + }
103.2942 +
103.2943 + int index = 0;
103.2944 + for (NodeIt n(_graph); n != INVALID; ++n) {
103.2945 + Value max = - std::numeric_limits<Value>::max();
103.2946 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
103.2947 + if (_graph.target(e) == n) continue;
103.2948 + if ((dualScale * _weight[e]) / 2 > max) {
103.2949 + max = (dualScale * _weight[e]) / 2;
103.2950 + }
103.2951 + }
103.2952 + (*_node_index)[n] = index;
103.2953 + (*_node_data)[index].pot = max;
103.2954 + int blossom =
103.2955 + _blossom_set->insert(n, std::numeric_limits<Value>::max());
103.2956 +
103.2957 + _tree_set->insert(blossom);
103.2958 +
103.2959 + (*_blossom_data)[blossom].status = EVEN;
103.2960 + (*_blossom_data)[blossom].pred = INVALID;
103.2961 + (*_blossom_data)[blossom].next = INVALID;
103.2962 + (*_blossom_data)[blossom].pot = 0;
103.2963 + (*_blossom_data)[blossom].offset = 0;
103.2964 + ++index;
103.2965 + }
103.2966 + for (EdgeIt e(_graph); e != INVALID; ++e) {
103.2967 + int si = (*_node_index)[_graph.u(e)];
103.2968 + int ti = (*_node_index)[_graph.v(e)];
103.2969 + if (_graph.u(e) != _graph.v(e)) {
103.2970 + _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
103.2971 + dualScale * _weight[e]) / 2);
103.2972 + }
103.2973 + }
103.2974 + }
103.2975 +
103.2976 + /// \brief Start the algorithm
103.2977 + ///
103.2978 + /// This function starts the algorithm.
103.2979 + ///
103.2980 + /// \pre \ref init() must be called before using this function.
103.2981 + bool start() {
103.2982 + enum OpType {
103.2983 + D2, D3, D4
103.2984 + };
103.2985 +
103.2986 + int unmatched = _node_num;
103.2987 + while (unmatched > 0) {
103.2988 + Value d2 = !_delta2->empty() ?
103.2989 + _delta2->prio() : std::numeric_limits<Value>::max();
103.2990 +
103.2991 + Value d3 = !_delta3->empty() ?
103.2992 + _delta3->prio() : std::numeric_limits<Value>::max();
103.2993 +
103.2994 + Value d4 = !_delta4->empty() ?
103.2995 + _delta4->prio() : std::numeric_limits<Value>::max();
103.2996 +
103.2997 + _delta_sum = d2; OpType ot = D2;
103.2998 + if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
103.2999 + if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
103.3000 +
103.3001 + if (_delta_sum == std::numeric_limits<Value>::max()) {
103.3002 + return false;
103.3003 + }
103.3004 +
103.3005 + switch (ot) {
103.3006 + case D2:
103.3007 + {
103.3008 + int blossom = _delta2->top();
103.3009 + Node n = _blossom_set->classTop(blossom);
103.3010 + Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
103.3011 + extendOnArc(e);
103.3012 + }
103.3013 + break;
103.3014 + case D3:
103.3015 + {
103.3016 + Edge e = _delta3->top();
103.3017 +
103.3018 + int left_blossom = _blossom_set->find(_graph.u(e));
103.3019 + int right_blossom = _blossom_set->find(_graph.v(e));
103.3020 +
103.3021 + if (left_blossom == right_blossom) {
103.3022 + _delta3->pop();
103.3023 + } else {
103.3024 + int left_tree = _tree_set->find(left_blossom);
103.3025 + int right_tree = _tree_set->find(right_blossom);
103.3026 +
103.3027 + if (left_tree == right_tree) {
103.3028 + shrinkOnEdge(e, left_tree);
103.3029 + } else {
103.3030 + augmentOnEdge(e);
103.3031 + unmatched -= 2;
103.3032 + }
103.3033 + }
103.3034 + } break;
103.3035 + case D4:
103.3036 + splitBlossom(_delta4->top());
103.3037 + break;
103.3038 + }
103.3039 + }
103.3040 + extractMatching();
103.3041 + return true;
103.3042 + }
103.3043 +
103.3044 + /// \brief Run the algorithm.
103.3045 + ///
103.3046 + /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
103.3047 + ///
103.3048 + /// \note mwpm.run() is just a shortcut of the following code.
103.3049 + /// \code
103.3050 + /// mwpm.init();
103.3051 + /// mwpm.start();
103.3052 + /// \endcode
103.3053 + bool run() {
103.3054 + init();
103.3055 + return start();
103.3056 + }
103.3057 +
103.3058 + /// @}
103.3059 +
103.3060 + /// \name Primal Solution
103.3061 + /// Functions to get the primal solution, i.e. the maximum weighted
103.3062 + /// perfect matching.\n
103.3063 + /// Either \ref run() or \ref start() function should be called before
103.3064 + /// using them.
103.3065 +
103.3066 + /// @{
103.3067 +
103.3068 + /// \brief Return the weight of the matching.
103.3069 + ///
103.3070 + /// This function returns the weight of the found matching.
103.3071 + ///
103.3072 + /// \pre Either run() or start() must be called before using this function.
103.3073 + Value matchingWeight() const {
103.3074 + Value sum = 0;
103.3075 + for (NodeIt n(_graph); n != INVALID; ++n) {
103.3076 + if ((*_matching)[n] != INVALID) {
103.3077 + sum += _weight[(*_matching)[n]];
103.3078 + }
103.3079 + }
103.3080 + return sum /= 2;
103.3081 + }
103.3082 +
103.3083 + /// \brief Return \c true if the given edge is in the matching.
103.3084 + ///
103.3085 + /// This function returns \c true if the given edge is in the found
103.3086 + /// matching.
103.3087 + ///
103.3088 + /// \pre Either run() or start() must be called before using this function.
103.3089 + bool matching(const Edge& edge) const {
103.3090 + return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
103.3091 + }
103.3092 +
103.3093 + /// \brief Return the matching arc (or edge) incident to the given node.
103.3094 + ///
103.3095 + /// This function returns the matching arc (or edge) incident to the
103.3096 + /// given node in the found matching or \c INVALID if the node is
103.3097 + /// not covered by the matching.
103.3098 + ///
103.3099 + /// \pre Either run() or start() must be called before using this function.
103.3100 + Arc matching(const Node& node) const {
103.3101 + return (*_matching)[node];
103.3102 + }
103.3103 +
103.3104 + /// \brief Return a const reference to the matching map.
103.3105 + ///
103.3106 + /// This function returns a const reference to a node map that stores
103.3107 + /// the matching arc (or edge) incident to each node.
103.3108 + const MatchingMap& matchingMap() const {
103.3109 + return *_matching;
103.3110 + }
103.3111 +
103.3112 + /// \brief Return the mate of the given node.
103.3113 + ///
103.3114 + /// This function returns the mate of the given node in the found
103.3115 + /// matching or \c INVALID if the node is not covered by the matching.
103.3116 + ///
103.3117 + /// \pre Either run() or start() must be called before using this function.
103.3118 + Node mate(const Node& node) const {
103.3119 + return _graph.target((*_matching)[node]);
103.3120 + }
103.3121 +
103.3122 + /// @}
103.3123 +
103.3124 + /// \name Dual Solution
103.3125 + /// Functions to get the dual solution.\n
103.3126 + /// Either \ref run() or \ref start() function should be called before
103.3127 + /// using them.
103.3128 +
103.3129 + /// @{
103.3130 +
103.3131 + /// \brief Return the value of the dual solution.
103.3132 + ///
103.3133 + /// This function returns the value of the dual solution.
103.3134 + /// It should be equal to the primal value scaled by \ref dualScale
103.3135 + /// "dual scale".
103.3136 + ///
103.3137 + /// \pre Either run() or start() must be called before using this function.
103.3138 + Value dualValue() const {
103.3139 + Value sum = 0;
103.3140 + for (NodeIt n(_graph); n != INVALID; ++n) {
103.3141 + sum += nodeValue(n);
103.3142 + }
103.3143 + for (int i = 0; i < blossomNum(); ++i) {
103.3144 + sum += blossomValue(i) * (blossomSize(i) / 2);
103.3145 + }
103.3146 + return sum;
103.3147 + }
103.3148 +
103.3149 + /// \brief Return the dual value (potential) of the given node.
103.3150 + ///
103.3151 + /// This function returns the dual value (potential) of the given node.
103.3152 + ///
103.3153 + /// \pre Either run() or start() must be called before using this function.
103.3154 + Value nodeValue(const Node& n) const {
103.3155 + return (*_node_potential)[n];
103.3156 + }
103.3157 +
103.3158 + /// \brief Return the number of the blossoms in the basis.
103.3159 + ///
103.3160 + /// This function returns the number of the blossoms in the basis.
103.3161 + ///
103.3162 + /// \pre Either run() or start() must be called before using this function.
103.3163 + /// \see BlossomIt
103.3164 + int blossomNum() const {
103.3165 + return _blossom_potential.size();
103.3166 + }
103.3167 +
103.3168 + /// \brief Return the number of the nodes in the given blossom.
103.3169 + ///
103.3170 + /// This function returns the number of the nodes in the given blossom.
103.3171 + ///
103.3172 + /// \pre Either run() or start() must be called before using this function.
103.3173 + /// \see BlossomIt
103.3174 + int blossomSize(int k) const {
103.3175 + return _blossom_potential[k].end - _blossom_potential[k].begin;
103.3176 + }
103.3177 +
103.3178 + /// \brief Return the dual value (ptential) of the given blossom.
103.3179 + ///
103.3180 + /// This function returns the dual value (ptential) of the given blossom.
103.3181 + ///
103.3182 + /// \pre Either run() or start() must be called before using this function.
103.3183 + Value blossomValue(int k) const {
103.3184 + return _blossom_potential[k].value;
103.3185 + }
103.3186 +
103.3187 + /// \brief Iterator for obtaining the nodes of a blossom.
103.3188 + ///
103.3189 + /// This class provides an iterator for obtaining the nodes of the
103.3190 + /// given blossom. It lists a subset of the nodes.
103.3191 + /// Before using this iterator, you must allocate a
103.3192 + /// MaxWeightedPerfectMatching class and execute it.
103.3193 + class BlossomIt {
103.3194 + public:
103.3195 +
103.3196 + /// \brief Constructor.
103.3197 + ///
103.3198 + /// Constructor to get the nodes of the given variable.
103.3199 + ///
103.3200 + /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()"
103.3201 + /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()"
103.3202 + /// must be called before initializing this iterator.
103.3203 + BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
103.3204 + : _algorithm(&algorithm)
103.3205 + {
103.3206 + _index = _algorithm->_blossom_potential[variable].begin;
103.3207 + _last = _algorithm->_blossom_potential[variable].end;
103.3208 + }
103.3209 +
103.3210 + /// \brief Conversion to \c Node.
103.3211 + ///
103.3212 + /// Conversion to \c Node.
103.3213 + operator Node() const {
103.3214 + return _algorithm->_blossom_node_list[_index];
103.3215 + }
103.3216 +
103.3217 + /// \brief Increment operator.
103.3218 + ///
103.3219 + /// Increment operator.
103.3220 + BlossomIt& operator++() {
103.3221 + ++_index;
103.3222 + return *this;
103.3223 + }
103.3224 +
103.3225 + /// \brief Validity checking
103.3226 + ///
103.3227 + /// This function checks whether the iterator is invalid.
103.3228 + bool operator==(Invalid) const { return _index == _last; }
103.3229 +
103.3230 + /// \brief Validity checking
103.3231 + ///
103.3232 + /// This function checks whether the iterator is valid.
103.3233 + bool operator!=(Invalid) const { return _index != _last; }
103.3234 +
103.3235 + private:
103.3236 + const MaxWeightedPerfectMatching* _algorithm;
103.3237 + int _last;
103.3238 + int _index;
103.3239 + };
103.3240 +
103.3241 + /// @}
103.3242 +
103.3243 + };
103.3244 +
103.3245 +} //END OF NAMESPACE LEMON
103.3246 +
103.3247 +#endif //LEMON_MAX_MATCHING_H
104.1 --- a/lemon/math.h Mon Jan 12 23:11:39 2009 +0100
104.2 +++ b/lemon/math.h Thu Nov 05 15:48:01 2009 +0100
104.3 @@ -55,6 +55,15 @@
104.4 /// 1/sqrt(2)
104.5 const long double SQRT1_2 = 0.7071067811865475244008443621048490L;
104.6
104.7 + ///Check whether the parameter is NaN or not
104.8 +
104.9 + ///This function checks whether the parameter is NaN or not.
104.10 + ///Is should be equivalent with std::isnan(), but it is not
104.11 + ///provided by all compilers.
104.12 + inline bool isNaN(double v)
104.13 + {
104.14 + return v!=v;
104.15 + }
104.16
104.17 /// @}
104.18
105.1 --- a/lemon/max_matching.h Mon Jan 12 23:11:39 2009 +0100
105.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
105.3 @@ -1,3104 +0,0 @@
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 LEMON_MAX_MATCHING_H
105.23 -#define LEMON_MAX_MATCHING_H
105.24 -
105.25 -#include <vector>
105.26 -#include <queue>
105.27 -#include <set>
105.28 -#include <limits>
105.29 -
105.30 -#include <lemon/core.h>
105.31 -#include <lemon/unionfind.h>
105.32 -#include <lemon/bin_heap.h>
105.33 -#include <lemon/maps.h>
105.34 -
105.35 -///\ingroup matching
105.36 -///\file
105.37 -///\brief Maximum matching algorithms in general graphs.
105.38 -
105.39 -namespace lemon {
105.40 -
105.41 - /// \ingroup matching
105.42 - ///
105.43 - /// \brief Edmonds' alternating forest maximum matching algorithm.
105.44 - ///
105.45 - /// This class implements Edmonds' alternating forest matching
105.46 - /// algorithm. The algorithm can be started from an arbitrary initial
105.47 - /// matching (the default is the empty one)
105.48 - ///
105.49 - /// The dual solution of the problem is a map of the nodes to
105.50 - /// MaxMatching::Status, having values \c EVEN/D, \c ODD/A and \c
105.51 - /// MATCHED/C showing the Gallai-Edmonds decomposition of the
105.52 - /// graph. The nodes in \c EVEN/D induce a graph with
105.53 - /// factor-critical components, the nodes in \c ODD/A form the
105.54 - /// barrier, and the nodes in \c MATCHED/C induce a graph having a
105.55 - /// perfect matching. The number of the factor-critical components
105.56 - /// minus the number of barrier nodes is a lower bound on the
105.57 - /// unmatched nodes, and the matching is optimal if and only if this bound is
105.58 - /// tight. This decomposition can be attained by calling \c
105.59 - /// decomposition() after running the algorithm.
105.60 - ///
105.61 - /// \param _Graph The graph type the algorithm runs on.
105.62 - template <typename _Graph>
105.63 - class MaxMatching {
105.64 - public:
105.65 -
105.66 - typedef _Graph Graph;
105.67 - typedef typename Graph::template NodeMap<typename Graph::Arc>
105.68 - MatchingMap;
105.69 -
105.70 - ///\brief Indicates the Gallai-Edmonds decomposition of the graph.
105.71 - ///
105.72 - ///Indicates the Gallai-Edmonds decomposition of the graph. The
105.73 - ///nodes with Status \c EVEN/D induce a graph with factor-critical
105.74 - ///components, the nodes in \c ODD/A form the canonical barrier,
105.75 - ///and the nodes in \c MATCHED/C induce a graph having a perfect
105.76 - ///matching.
105.77 - enum Status {
105.78 - EVEN = 1, D = 1, MATCHED = 0, C = 0, ODD = -1, A = -1, UNMATCHED = -2
105.79 - };
105.80 -
105.81 - typedef typename Graph::template NodeMap<Status> StatusMap;
105.82 -
105.83 - private:
105.84 -
105.85 - TEMPLATE_GRAPH_TYPEDEFS(Graph);
105.86 -
105.87 - typedef UnionFindEnum<IntNodeMap> BlossomSet;
105.88 - typedef ExtendFindEnum<IntNodeMap> TreeSet;
105.89 - typedef RangeMap<Node> NodeIntMap;
105.90 - typedef MatchingMap EarMap;
105.91 - typedef std::vector<Node> NodeQueue;
105.92 -
105.93 - const Graph& _graph;
105.94 - MatchingMap* _matching;
105.95 - StatusMap* _status;
105.96 -
105.97 - EarMap* _ear;
105.98 -
105.99 - IntNodeMap* _blossom_set_index;
105.100 - BlossomSet* _blossom_set;
105.101 - NodeIntMap* _blossom_rep;
105.102 -
105.103 - IntNodeMap* _tree_set_index;
105.104 - TreeSet* _tree_set;
105.105 -
105.106 - NodeQueue _node_queue;
105.107 - int _process, _postpone, _last;
105.108 -
105.109 - int _node_num;
105.110 -
105.111 - private:
105.112 -
105.113 - void createStructures() {
105.114 - _node_num = countNodes(_graph);
105.115 - if (!_matching) {
105.116 - _matching = new MatchingMap(_graph);
105.117 - }
105.118 - if (!_status) {
105.119 - _status = new StatusMap(_graph);
105.120 - }
105.121 - if (!_ear) {
105.122 - _ear = new EarMap(_graph);
105.123 - }
105.124 - if (!_blossom_set) {
105.125 - _blossom_set_index = new IntNodeMap(_graph);
105.126 - _blossom_set = new BlossomSet(*_blossom_set_index);
105.127 - }
105.128 - if (!_blossom_rep) {
105.129 - _blossom_rep = new NodeIntMap(_node_num);
105.130 - }
105.131 - if (!_tree_set) {
105.132 - _tree_set_index = new IntNodeMap(_graph);
105.133 - _tree_set = new TreeSet(*_tree_set_index);
105.134 - }
105.135 - _node_queue.resize(_node_num);
105.136 - }
105.137 -
105.138 - void destroyStructures() {
105.139 - if (_matching) {
105.140 - delete _matching;
105.141 - }
105.142 - if (_status) {
105.143 - delete _status;
105.144 - }
105.145 - if (_ear) {
105.146 - delete _ear;
105.147 - }
105.148 - if (_blossom_set) {
105.149 - delete _blossom_set;
105.150 - delete _blossom_set_index;
105.151 - }
105.152 - if (_blossom_rep) {
105.153 - delete _blossom_rep;
105.154 - }
105.155 - if (_tree_set) {
105.156 - delete _tree_set_index;
105.157 - delete _tree_set;
105.158 - }
105.159 - }
105.160 -
105.161 - void processDense(const Node& n) {
105.162 - _process = _postpone = _last = 0;
105.163 - _node_queue[_last++] = n;
105.164 -
105.165 - while (_process != _last) {
105.166 - Node u = _node_queue[_process++];
105.167 - for (OutArcIt a(_graph, u); a != INVALID; ++a) {
105.168 - Node v = _graph.target(a);
105.169 - if ((*_status)[v] == MATCHED) {
105.170 - extendOnArc(a);
105.171 - } else if ((*_status)[v] == UNMATCHED) {
105.172 - augmentOnArc(a);
105.173 - return;
105.174 - }
105.175 - }
105.176 - }
105.177 -
105.178 - while (_postpone != _last) {
105.179 - Node u = _node_queue[_postpone++];
105.180 -
105.181 - for (OutArcIt a(_graph, u); a != INVALID ; ++a) {
105.182 - Node v = _graph.target(a);
105.183 -
105.184 - if ((*_status)[v] == EVEN) {
105.185 - if (_blossom_set->find(u) != _blossom_set->find(v)) {
105.186 - shrinkOnEdge(a);
105.187 - }
105.188 - }
105.189 -
105.190 - while (_process != _last) {
105.191 - Node w = _node_queue[_process++];
105.192 - for (OutArcIt b(_graph, w); b != INVALID; ++b) {
105.193 - Node x = _graph.target(b);
105.194 - if ((*_status)[x] == MATCHED) {
105.195 - extendOnArc(b);
105.196 - } else if ((*_status)[x] == UNMATCHED) {
105.197 - augmentOnArc(b);
105.198 - return;
105.199 - }
105.200 - }
105.201 - }
105.202 - }
105.203 - }
105.204 - }
105.205 -
105.206 - void processSparse(const Node& n) {
105.207 - _process = _last = 0;
105.208 - _node_queue[_last++] = n;
105.209 - while (_process != _last) {
105.210 - Node u = _node_queue[_process++];
105.211 - for (OutArcIt a(_graph, u); a != INVALID; ++a) {
105.212 - Node v = _graph.target(a);
105.213 -
105.214 - if ((*_status)[v] == EVEN) {
105.215 - if (_blossom_set->find(u) != _blossom_set->find(v)) {
105.216 - shrinkOnEdge(a);
105.217 - }
105.218 - } else if ((*_status)[v] == MATCHED) {
105.219 - extendOnArc(a);
105.220 - } else if ((*_status)[v] == UNMATCHED) {
105.221 - augmentOnArc(a);
105.222 - return;
105.223 - }
105.224 - }
105.225 - }
105.226 - }
105.227 -
105.228 - void shrinkOnEdge(const Edge& e) {
105.229 - Node nca = INVALID;
105.230 -
105.231 - {
105.232 - std::set<Node> left_set, right_set;
105.233 -
105.234 - Node left = (*_blossom_rep)[_blossom_set->find(_graph.u(e))];
105.235 - left_set.insert(left);
105.236 -
105.237 - Node right = (*_blossom_rep)[_blossom_set->find(_graph.v(e))];
105.238 - right_set.insert(right);
105.239 -
105.240 - while (true) {
105.241 - if ((*_matching)[left] == INVALID) break;
105.242 - left = _graph.target((*_matching)[left]);
105.243 - left = (*_blossom_rep)[_blossom_set->
105.244 - find(_graph.target((*_ear)[left]))];
105.245 - if (right_set.find(left) != right_set.end()) {
105.246 - nca = left;
105.247 - break;
105.248 - }
105.249 - left_set.insert(left);
105.250 -
105.251 - if ((*_matching)[right] == INVALID) break;
105.252 - right = _graph.target((*_matching)[right]);
105.253 - right = (*_blossom_rep)[_blossom_set->
105.254 - find(_graph.target((*_ear)[right]))];
105.255 - if (left_set.find(right) != left_set.end()) {
105.256 - nca = right;
105.257 - break;
105.258 - }
105.259 - right_set.insert(right);
105.260 - }
105.261 -
105.262 - if (nca == INVALID) {
105.263 - if ((*_matching)[left] == INVALID) {
105.264 - nca = right;
105.265 - while (left_set.find(nca) == left_set.end()) {
105.266 - nca = _graph.target((*_matching)[nca]);
105.267 - nca =(*_blossom_rep)[_blossom_set->
105.268 - find(_graph.target((*_ear)[nca]))];
105.269 - }
105.270 - } else {
105.271 - nca = left;
105.272 - while (right_set.find(nca) == right_set.end()) {
105.273 - nca = _graph.target((*_matching)[nca]);
105.274 - nca = (*_blossom_rep)[_blossom_set->
105.275 - find(_graph.target((*_ear)[nca]))];
105.276 - }
105.277 - }
105.278 - }
105.279 - }
105.280 -
105.281 - {
105.282 -
105.283 - Node node = _graph.u(e);
105.284 - Arc arc = _graph.direct(e, true);
105.285 - Node base = (*_blossom_rep)[_blossom_set->find(node)];
105.286 -
105.287 - while (base != nca) {
105.288 - _ear->set(node, arc);
105.289 -
105.290 - Node n = node;
105.291 - while (n != base) {
105.292 - n = _graph.target((*_matching)[n]);
105.293 - Arc a = (*_ear)[n];
105.294 - n = _graph.target(a);
105.295 - _ear->set(n, _graph.oppositeArc(a));
105.296 - }
105.297 - node = _graph.target((*_matching)[base]);
105.298 - _tree_set->erase(base);
105.299 - _tree_set->erase(node);
105.300 - _blossom_set->insert(node, _blossom_set->find(base));
105.301 - _status->set(node, EVEN);
105.302 - _node_queue[_last++] = node;
105.303 - arc = _graph.oppositeArc((*_ear)[node]);
105.304 - node = _graph.target((*_ear)[node]);
105.305 - base = (*_blossom_rep)[_blossom_set->find(node)];
105.306 - _blossom_set->join(_graph.target(arc), base);
105.307 - }
105.308 - }
105.309 -
105.310 - _blossom_rep->set(_blossom_set->find(nca), nca);
105.311 -
105.312 - {
105.313 -
105.314 - Node node = _graph.v(e);
105.315 - Arc arc = _graph.direct(e, false);
105.316 - Node base = (*_blossom_rep)[_blossom_set->find(node)];
105.317 -
105.318 - while (base != nca) {
105.319 - _ear->set(node, arc);
105.320 -
105.321 - Node n = node;
105.322 - while (n != base) {
105.323 - n = _graph.target((*_matching)[n]);
105.324 - Arc a = (*_ear)[n];
105.325 - n = _graph.target(a);
105.326 - _ear->set(n, _graph.oppositeArc(a));
105.327 - }
105.328 - node = _graph.target((*_matching)[base]);
105.329 - _tree_set->erase(base);
105.330 - _tree_set->erase(node);
105.331 - _blossom_set->insert(node, _blossom_set->find(base));
105.332 - _status->set(node, EVEN);
105.333 - _node_queue[_last++] = node;
105.334 - arc = _graph.oppositeArc((*_ear)[node]);
105.335 - node = _graph.target((*_ear)[node]);
105.336 - base = (*_blossom_rep)[_blossom_set->find(node)];
105.337 - _blossom_set->join(_graph.target(arc), base);
105.338 - }
105.339 - }
105.340 -
105.341 - _blossom_rep->set(_blossom_set->find(nca), nca);
105.342 - }
105.343 -
105.344 -
105.345 -
105.346 - void extendOnArc(const Arc& a) {
105.347 - Node base = _graph.source(a);
105.348 - Node odd = _graph.target(a);
105.349 -
105.350 - _ear->set(odd, _graph.oppositeArc(a));
105.351 - Node even = _graph.target((*_matching)[odd]);
105.352 - _blossom_rep->set(_blossom_set->insert(even), even);
105.353 - _status->set(odd, ODD);
105.354 - _status->set(even, EVEN);
105.355 - int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(base)]);
105.356 - _tree_set->insert(odd, tree);
105.357 - _tree_set->insert(even, tree);
105.358 - _node_queue[_last++] = even;
105.359 -
105.360 - }
105.361 -
105.362 - void augmentOnArc(const Arc& a) {
105.363 - Node even = _graph.source(a);
105.364 - Node odd = _graph.target(a);
105.365 -
105.366 - int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(even)]);
105.367 -
105.368 - _matching->set(odd, _graph.oppositeArc(a));
105.369 - _status->set(odd, MATCHED);
105.370 -
105.371 - Arc arc = (*_matching)[even];
105.372 - _matching->set(even, a);
105.373 -
105.374 - while (arc != INVALID) {
105.375 - odd = _graph.target(arc);
105.376 - arc = (*_ear)[odd];
105.377 - even = _graph.target(arc);
105.378 - _matching->set(odd, arc);
105.379 - arc = (*_matching)[even];
105.380 - _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
105.381 - }
105.382 -
105.383 - for (typename TreeSet::ItemIt it(*_tree_set, tree);
105.384 - it != INVALID; ++it) {
105.385 - if ((*_status)[it] == ODD) {
105.386 - _status->set(it, MATCHED);
105.387 - } else {
105.388 - int blossom = _blossom_set->find(it);
105.389 - for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom);
105.390 - jt != INVALID; ++jt) {
105.391 - _status->set(jt, MATCHED);
105.392 - }
105.393 - _blossom_set->eraseClass(blossom);
105.394 - }
105.395 - }
105.396 - _tree_set->eraseClass(tree);
105.397 -
105.398 - }
105.399 -
105.400 - public:
105.401 -
105.402 - /// \brief Constructor
105.403 - ///
105.404 - /// Constructor.
105.405 - MaxMatching(const Graph& graph)
105.406 - : _graph(graph), _matching(0), _status(0), _ear(0),
105.407 - _blossom_set_index(0), _blossom_set(0), _blossom_rep(0),
105.408 - _tree_set_index(0), _tree_set(0) {}
105.409 -
105.410 - ~MaxMatching() {
105.411 - destroyStructures();
105.412 - }
105.413 -
105.414 - /// \name Execution control
105.415 - /// The simplest way to execute the algorithm is to use the
105.416 - /// \c run() member function.
105.417 - /// \n
105.418 -
105.419 - /// If you need better control on the execution, you must call
105.420 - /// \ref init(), \ref greedyInit() or \ref matchingInit()
105.421 - /// functions first, then you can start the algorithm with the \ref
105.422 - /// startSparse() or startDense() functions.
105.423 -
105.424 - ///@{
105.425 -
105.426 - /// \brief Sets the actual matching to the empty matching.
105.427 - ///
105.428 - /// Sets the actual matching to the empty matching.
105.429 - ///
105.430 - void init() {
105.431 - createStructures();
105.432 - for(NodeIt n(_graph); n != INVALID; ++n) {
105.433 - _matching->set(n, INVALID);
105.434 - _status->set(n, UNMATCHED);
105.435 - }
105.436 - }
105.437 -
105.438 - ///\brief Finds an initial matching in a greedy way
105.439 - ///
105.440 - ///It finds an initial matching in a greedy way.
105.441 - void greedyInit() {
105.442 - createStructures();
105.443 - for (NodeIt n(_graph); n != INVALID; ++n) {
105.444 - _matching->set(n, INVALID);
105.445 - _status->set(n, UNMATCHED);
105.446 - }
105.447 - for (NodeIt n(_graph); n != INVALID; ++n) {
105.448 - if ((*_matching)[n] == INVALID) {
105.449 - for (OutArcIt a(_graph, n); a != INVALID ; ++a) {
105.450 - Node v = _graph.target(a);
105.451 - if ((*_matching)[v] == INVALID && v != n) {
105.452 - _matching->set(n, a);
105.453 - _status->set(n, MATCHED);
105.454 - _matching->set(v, _graph.oppositeArc(a));
105.455 - _status->set(v, MATCHED);
105.456 - break;
105.457 - }
105.458 - }
105.459 - }
105.460 - }
105.461 - }
105.462 -
105.463 -
105.464 - /// \brief Initialize the matching from a map containing.
105.465 - ///
105.466 - /// Initialize the matching from a \c bool valued \c Edge map. This
105.467 - /// map must have the property that there are no two incident edges
105.468 - /// with true value, ie. it contains a matching.
105.469 - /// \return %True if the map contains a matching.
105.470 - template <typename MatchingMap>
105.471 - bool matchingInit(const MatchingMap& matching) {
105.472 - createStructures();
105.473 -
105.474 - for (NodeIt n(_graph); n != INVALID; ++n) {
105.475 - _matching->set(n, INVALID);
105.476 - _status->set(n, UNMATCHED);
105.477 - }
105.478 - for(EdgeIt e(_graph); e!=INVALID; ++e) {
105.479 - if (matching[e]) {
105.480 -
105.481 - Node u = _graph.u(e);
105.482 - if ((*_matching)[u] != INVALID) return false;
105.483 - _matching->set(u, _graph.direct(e, true));
105.484 - _status->set(u, MATCHED);
105.485 -
105.486 - Node v = _graph.v(e);
105.487 - if ((*_matching)[v] != INVALID) return false;
105.488 - _matching->set(v, _graph.direct(e, false));
105.489 - _status->set(v, MATCHED);
105.490 - }
105.491 - }
105.492 - return true;
105.493 - }
105.494 -
105.495 - /// \brief Starts Edmonds' algorithm
105.496 - ///
105.497 - /// If runs the original Edmonds' algorithm.
105.498 - void startSparse() {
105.499 - for(NodeIt n(_graph); n != INVALID; ++n) {
105.500 - if ((*_status)[n] == UNMATCHED) {
105.501 - (*_blossom_rep)[_blossom_set->insert(n)] = n;
105.502 - _tree_set->insert(n);
105.503 - _status->set(n, EVEN);
105.504 - processSparse(n);
105.505 - }
105.506 - }
105.507 - }
105.508 -
105.509 - /// \brief Starts Edmonds' algorithm.
105.510 - ///
105.511 - /// It runs Edmonds' algorithm with a heuristic of postponing
105.512 - /// shrinks, therefore resulting in a faster algorithm for dense graphs.
105.513 - void startDense() {
105.514 - for(NodeIt n(_graph); n != INVALID; ++n) {
105.515 - if ((*_status)[n] == UNMATCHED) {
105.516 - (*_blossom_rep)[_blossom_set->insert(n)] = n;
105.517 - _tree_set->insert(n);
105.518 - _status->set(n, EVEN);
105.519 - processDense(n);
105.520 - }
105.521 - }
105.522 - }
105.523 -
105.524 -
105.525 - /// \brief Runs Edmonds' algorithm
105.526 - ///
105.527 - /// Runs Edmonds' algorithm for sparse graphs (<tt>m<2*n</tt>)
105.528 - /// or Edmonds' algorithm with a heuristic of
105.529 - /// postponing shrinks for dense graphs.
105.530 - void run() {
105.531 - if (countEdges(_graph) < 2 * countNodes(_graph)) {
105.532 - greedyInit();
105.533 - startSparse();
105.534 - } else {
105.535 - init();
105.536 - startDense();
105.537 - }
105.538 - }
105.539 -
105.540 - /// @}
105.541 -
105.542 - /// \name Primal solution
105.543 - /// Functions to get the primal solution, ie. the matching.
105.544 -
105.545 - /// @{
105.546 -
105.547 - ///\brief Returns the size of the current matching.
105.548 - ///
105.549 - ///Returns the size of the current matching. After \ref
105.550 - ///run() it returns the size of the maximum matching in the graph.
105.551 - int matchingSize() const {
105.552 - int size = 0;
105.553 - for (NodeIt n(_graph); n != INVALID; ++n) {
105.554 - if ((*_matching)[n] != INVALID) {
105.555 - ++size;
105.556 - }
105.557 - }
105.558 - return size / 2;
105.559 - }
105.560 -
105.561 - /// \brief Returns true when the edge is in the matching.
105.562 - ///
105.563 - /// Returns true when the edge is in the matching.
105.564 - bool matching(const Edge& edge) const {
105.565 - return edge == (*_matching)[_graph.u(edge)];
105.566 - }
105.567 -
105.568 - /// \brief Returns the matching edge incident to the given node.
105.569 - ///
105.570 - /// Returns the matching edge of a \c node in the actual matching or
105.571 - /// INVALID if the \c node is not covered by the actual matching.
105.572 - Arc matching(const Node& n) const {
105.573 - return (*_matching)[n];
105.574 - }
105.575 -
105.576 - ///\brief Returns the mate of a node in the actual matching.
105.577 - ///
105.578 - ///Returns the mate of a \c node in the actual matching or
105.579 - ///INVALID if the \c node is not covered by the actual matching.
105.580 - Node mate(const Node& n) const {
105.581 - return (*_matching)[n] != INVALID ?
105.582 - _graph.target((*_matching)[n]) : INVALID;
105.583 - }
105.584 -
105.585 - /// @}
105.586 -
105.587 - /// \name Dual solution
105.588 - /// Functions to get the dual solution, ie. the decomposition.
105.589 -
105.590 - /// @{
105.591 -
105.592 - /// \brief Returns the class of the node in the Edmonds-Gallai
105.593 - /// decomposition.
105.594 - ///
105.595 - /// Returns the class of the node in the Edmonds-Gallai
105.596 - /// decomposition.
105.597 - Status decomposition(const Node& n) const {
105.598 - return (*_status)[n];
105.599 - }
105.600 -
105.601 - /// \brief Returns true when the node is in the barrier.
105.602 - ///
105.603 - /// Returns true when the node is in the barrier.
105.604 - bool barrier(const Node& n) const {
105.605 - return (*_status)[n] == ODD;
105.606 - }
105.607 -
105.608 - /// @}
105.609 -
105.610 - };
105.611 -
105.612 - /// \ingroup matching
105.613 - ///
105.614 - /// \brief Weighted matching in general graphs
105.615 - ///
105.616 - /// This class provides an efficient implementation of Edmond's
105.617 - /// maximum weighted matching algorithm. The implementation is based
105.618 - /// on extensive use of priority queues and provides
105.619 - /// \f$O(nm\log(n))\f$ time complexity.
105.620 - ///
105.621 - /// The maximum weighted matching problem is to find undirected
105.622 - /// edges in the graph with maximum overall weight and no two of
105.623 - /// them shares their ends. The problem can be formulated with the
105.624 - /// following linear program.
105.625 - /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
105.626 - /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
105.627 - \quad \forall B\in\mathcal{O}\f] */
105.628 - /// \f[x_e \ge 0\quad \forall e\in E\f]
105.629 - /// \f[\max \sum_{e\in E}x_ew_e\f]
105.630 - /// where \f$\delta(X)\f$ is the set of edges incident to a node in
105.631 - /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
105.632 - /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
105.633 - /// subsets of the nodes.
105.634 - ///
105.635 - /// The algorithm calculates an optimal matching and a proof of the
105.636 - /// optimality. The solution of the dual problem can be used to check
105.637 - /// the result of the algorithm. The dual linear problem is the
105.638 - /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
105.639 - z_B \ge w_{uv} \quad \forall uv\in E\f] */
105.640 - /// \f[y_u \ge 0 \quad \forall u \in V\f]
105.641 - /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
105.642 - /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
105.643 - \frac{\vert B \vert - 1}{2}z_B\f] */
105.644 - ///
105.645 - /// The algorithm can be executed with \c run() or the \c init() and
105.646 - /// then the \c start() member functions. After it the matching can
105.647 - /// be asked with \c matching() or mate() functions. The dual
105.648 - /// solution can be get with \c nodeValue(), \c blossomNum() and \c
105.649 - /// blossomValue() members and \ref MaxWeightedMatching::BlossomIt
105.650 - /// "BlossomIt" nested class, which is able to iterate on the nodes
105.651 - /// of a blossom. If the value type is integral then the dual
105.652 - /// solution is multiplied by \ref MaxWeightedMatching::dualScale "4".
105.653 - template <typename _Graph,
105.654 - typename _WeightMap = typename _Graph::template EdgeMap<int> >
105.655 - class MaxWeightedMatching {
105.656 - public:
105.657 -
105.658 - typedef _Graph Graph;
105.659 - typedef _WeightMap WeightMap;
105.660 - typedef typename WeightMap::Value Value;
105.661 -
105.662 - /// \brief Scaling factor for dual solution
105.663 - ///
105.664 - /// Scaling factor for dual solution, it is equal to 4 or 1
105.665 - /// according to the value type.
105.666 - static const int dualScale =
105.667 - std::numeric_limits<Value>::is_integer ? 4 : 1;
105.668 -
105.669 - typedef typename Graph::template NodeMap<typename Graph::Arc>
105.670 - MatchingMap;
105.671 -
105.672 - private:
105.673 -
105.674 - TEMPLATE_GRAPH_TYPEDEFS(Graph);
105.675 -
105.676 - typedef typename Graph::template NodeMap<Value> NodePotential;
105.677 - typedef std::vector<Node> BlossomNodeList;
105.678 -
105.679 - struct BlossomVariable {
105.680 - int begin, end;
105.681 - Value value;
105.682 -
105.683 - BlossomVariable(int _begin, int _end, Value _value)
105.684 - : begin(_begin), end(_end), value(_value) {}
105.685 -
105.686 - };
105.687 -
105.688 - typedef std::vector<BlossomVariable> BlossomPotential;
105.689 -
105.690 - const Graph& _graph;
105.691 - const WeightMap& _weight;
105.692 -
105.693 - MatchingMap* _matching;
105.694 -
105.695 - NodePotential* _node_potential;
105.696 -
105.697 - BlossomPotential _blossom_potential;
105.698 - BlossomNodeList _blossom_node_list;
105.699 -
105.700 - int _node_num;
105.701 - int _blossom_num;
105.702 -
105.703 - typedef RangeMap<int> IntIntMap;
105.704 -
105.705 - enum Status {
105.706 - EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
105.707 - };
105.708 -
105.709 - typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
105.710 - struct BlossomData {
105.711 - int tree;
105.712 - Status status;
105.713 - Arc pred, next;
105.714 - Value pot, offset;
105.715 - Node base;
105.716 - };
105.717 -
105.718 - IntNodeMap *_blossom_index;
105.719 - BlossomSet *_blossom_set;
105.720 - RangeMap<BlossomData>* _blossom_data;
105.721 -
105.722 - IntNodeMap *_node_index;
105.723 - IntArcMap *_node_heap_index;
105.724 -
105.725 - struct NodeData {
105.726 -
105.727 - NodeData(IntArcMap& node_heap_index)
105.728 - : heap(node_heap_index) {}
105.729 -
105.730 - int blossom;
105.731 - Value pot;
105.732 - BinHeap<Value, IntArcMap> heap;
105.733 - std::map<int, Arc> heap_index;
105.734 -
105.735 - int tree;
105.736 - };
105.737 -
105.738 - RangeMap<NodeData>* _node_data;
105.739 -
105.740 - typedef ExtendFindEnum<IntIntMap> TreeSet;
105.741 -
105.742 - IntIntMap *_tree_set_index;
105.743 - TreeSet *_tree_set;
105.744 -
105.745 - IntNodeMap *_delta1_index;
105.746 - BinHeap<Value, IntNodeMap> *_delta1;
105.747 -
105.748 - IntIntMap *_delta2_index;
105.749 - BinHeap<Value, IntIntMap> *_delta2;
105.750 -
105.751 - IntEdgeMap *_delta3_index;
105.752 - BinHeap<Value, IntEdgeMap> *_delta3;
105.753 -
105.754 - IntIntMap *_delta4_index;
105.755 - BinHeap<Value, IntIntMap> *_delta4;
105.756 -
105.757 - Value _delta_sum;
105.758 -
105.759 - void createStructures() {
105.760 - _node_num = countNodes(_graph);
105.761 - _blossom_num = _node_num * 3 / 2;
105.762 -
105.763 - if (!_matching) {
105.764 - _matching = new MatchingMap(_graph);
105.765 - }
105.766 - if (!_node_potential) {
105.767 - _node_potential = new NodePotential(_graph);
105.768 - }
105.769 - if (!_blossom_set) {
105.770 - _blossom_index = new IntNodeMap(_graph);
105.771 - _blossom_set = new BlossomSet(*_blossom_index);
105.772 - _blossom_data = new RangeMap<BlossomData>(_blossom_num);
105.773 - }
105.774 -
105.775 - if (!_node_index) {
105.776 - _node_index = new IntNodeMap(_graph);
105.777 - _node_heap_index = new IntArcMap(_graph);
105.778 - _node_data = new RangeMap<NodeData>(_node_num,
105.779 - NodeData(*_node_heap_index));
105.780 - }
105.781 -
105.782 - if (!_tree_set) {
105.783 - _tree_set_index = new IntIntMap(_blossom_num);
105.784 - _tree_set = new TreeSet(*_tree_set_index);
105.785 - }
105.786 - if (!_delta1) {
105.787 - _delta1_index = new IntNodeMap(_graph);
105.788 - _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
105.789 - }
105.790 - if (!_delta2) {
105.791 - _delta2_index = new IntIntMap(_blossom_num);
105.792 - _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
105.793 - }
105.794 - if (!_delta3) {
105.795 - _delta3_index = new IntEdgeMap(_graph);
105.796 - _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
105.797 - }
105.798 - if (!_delta4) {
105.799 - _delta4_index = new IntIntMap(_blossom_num);
105.800 - _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
105.801 - }
105.802 - }
105.803 -
105.804 - void destroyStructures() {
105.805 - _node_num = countNodes(_graph);
105.806 - _blossom_num = _node_num * 3 / 2;
105.807 -
105.808 - if (_matching) {
105.809 - delete _matching;
105.810 - }
105.811 - if (_node_potential) {
105.812 - delete _node_potential;
105.813 - }
105.814 - if (_blossom_set) {
105.815 - delete _blossom_index;
105.816 - delete _blossom_set;
105.817 - delete _blossom_data;
105.818 - }
105.819 -
105.820 - if (_node_index) {
105.821 - delete _node_index;
105.822 - delete _node_heap_index;
105.823 - delete _node_data;
105.824 - }
105.825 -
105.826 - if (_tree_set) {
105.827 - delete _tree_set_index;
105.828 - delete _tree_set;
105.829 - }
105.830 - if (_delta1) {
105.831 - delete _delta1_index;
105.832 - delete _delta1;
105.833 - }
105.834 - if (_delta2) {
105.835 - delete _delta2_index;
105.836 - delete _delta2;
105.837 - }
105.838 - if (_delta3) {
105.839 - delete _delta3_index;
105.840 - delete _delta3;
105.841 - }
105.842 - if (_delta4) {
105.843 - delete _delta4_index;
105.844 - delete _delta4;
105.845 - }
105.846 - }
105.847 -
105.848 - void matchedToEven(int blossom, int tree) {
105.849 - if (_delta2->state(blossom) == _delta2->IN_HEAP) {
105.850 - _delta2->erase(blossom);
105.851 - }
105.852 -
105.853 - if (!_blossom_set->trivial(blossom)) {
105.854 - (*_blossom_data)[blossom].pot -=
105.855 - 2 * (_delta_sum - (*_blossom_data)[blossom].offset);
105.856 - }
105.857 -
105.858 - for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
105.859 - n != INVALID; ++n) {
105.860 -
105.861 - _blossom_set->increase(n, std::numeric_limits<Value>::max());
105.862 - int ni = (*_node_index)[n];
105.863 -
105.864 - (*_node_data)[ni].heap.clear();
105.865 - (*_node_data)[ni].heap_index.clear();
105.866 -
105.867 - (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
105.868 -
105.869 - _delta1->push(n, (*_node_data)[ni].pot);
105.870 -
105.871 - for (InArcIt e(_graph, n); e != INVALID; ++e) {
105.872 - Node v = _graph.source(e);
105.873 - int vb = _blossom_set->find(v);
105.874 - int vi = (*_node_index)[v];
105.875 -
105.876 - Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
105.877 - dualScale * _weight[e];
105.878 -
105.879 - if ((*_blossom_data)[vb].status == EVEN) {
105.880 - if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
105.881 - _delta3->push(e, rw / 2);
105.882 - }
105.883 - } else if ((*_blossom_data)[vb].status == UNMATCHED) {
105.884 - if (_delta3->state(e) != _delta3->IN_HEAP) {
105.885 - _delta3->push(e, rw);
105.886 - }
105.887 - } else {
105.888 - typename std::map<int, Arc>::iterator it =
105.889 - (*_node_data)[vi].heap_index.find(tree);
105.890 -
105.891 - if (it != (*_node_data)[vi].heap_index.end()) {
105.892 - if ((*_node_data)[vi].heap[it->second] > rw) {
105.893 - (*_node_data)[vi].heap.replace(it->second, e);
105.894 - (*_node_data)[vi].heap.decrease(e, rw);
105.895 - it->second = e;
105.896 - }
105.897 - } else {
105.898 - (*_node_data)[vi].heap.push(e, rw);
105.899 - (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
105.900 - }
105.901 -
105.902 - if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
105.903 - _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
105.904 -
105.905 - if ((*_blossom_data)[vb].status == MATCHED) {
105.906 - if (_delta2->state(vb) != _delta2->IN_HEAP) {
105.907 - _delta2->push(vb, _blossom_set->classPrio(vb) -
105.908 - (*_blossom_data)[vb].offset);
105.909 - } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
105.910 - (*_blossom_data)[vb].offset){
105.911 - _delta2->decrease(vb, _blossom_set->classPrio(vb) -
105.912 - (*_blossom_data)[vb].offset);
105.913 - }
105.914 - }
105.915 - }
105.916 - }
105.917 - }
105.918 - }
105.919 - (*_blossom_data)[blossom].offset = 0;
105.920 - }
105.921 -
105.922 - void matchedToOdd(int blossom) {
105.923 - if (_delta2->state(blossom) == _delta2->IN_HEAP) {
105.924 - _delta2->erase(blossom);
105.925 - }
105.926 - (*_blossom_data)[blossom].offset += _delta_sum;
105.927 - if (!_blossom_set->trivial(blossom)) {
105.928 - _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
105.929 - (*_blossom_data)[blossom].offset);
105.930 - }
105.931 - }
105.932 -
105.933 - void evenToMatched(int blossom, int tree) {
105.934 - if (!_blossom_set->trivial(blossom)) {
105.935 - (*_blossom_data)[blossom].pot += 2 * _delta_sum;
105.936 - }
105.937 -
105.938 - for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
105.939 - n != INVALID; ++n) {
105.940 - int ni = (*_node_index)[n];
105.941 - (*_node_data)[ni].pot -= _delta_sum;
105.942 -
105.943 - _delta1->erase(n);
105.944 -
105.945 - for (InArcIt e(_graph, n); e != INVALID; ++e) {
105.946 - Node v = _graph.source(e);
105.947 - int vb = _blossom_set->find(v);
105.948 - int vi = (*_node_index)[v];
105.949 -
105.950 - Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
105.951 - dualScale * _weight[e];
105.952 -
105.953 - if (vb == blossom) {
105.954 - if (_delta3->state(e) == _delta3->IN_HEAP) {
105.955 - _delta3->erase(e);
105.956 - }
105.957 - } else if ((*_blossom_data)[vb].status == EVEN) {
105.958 -
105.959 - if (_delta3->state(e) == _delta3->IN_HEAP) {
105.960 - _delta3->erase(e);
105.961 - }
105.962 -
105.963 - int vt = _tree_set->find(vb);
105.964 -
105.965 - if (vt != tree) {
105.966 -
105.967 - Arc r = _graph.oppositeArc(e);
105.968 -
105.969 - typename std::map<int, Arc>::iterator it =
105.970 - (*_node_data)[ni].heap_index.find(vt);
105.971 -
105.972 - if (it != (*_node_data)[ni].heap_index.end()) {
105.973 - if ((*_node_data)[ni].heap[it->second] > rw) {
105.974 - (*_node_data)[ni].heap.replace(it->second, r);
105.975 - (*_node_data)[ni].heap.decrease(r, rw);
105.976 - it->second = r;
105.977 - }
105.978 - } else {
105.979 - (*_node_data)[ni].heap.push(r, rw);
105.980 - (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
105.981 - }
105.982 -
105.983 - if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
105.984 - _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
105.985 -
105.986 - if (_delta2->state(blossom) != _delta2->IN_HEAP) {
105.987 - _delta2->push(blossom, _blossom_set->classPrio(blossom) -
105.988 - (*_blossom_data)[blossom].offset);
105.989 - } else if ((*_delta2)[blossom] >
105.990 - _blossom_set->classPrio(blossom) -
105.991 - (*_blossom_data)[blossom].offset){
105.992 - _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
105.993 - (*_blossom_data)[blossom].offset);
105.994 - }
105.995 - }
105.996 - }
105.997 -
105.998 - } else if ((*_blossom_data)[vb].status == UNMATCHED) {
105.999 - if (_delta3->state(e) == _delta3->IN_HEAP) {
105.1000 - _delta3->erase(e);
105.1001 - }
105.1002 - } else {
105.1003 -
105.1004 - typename std::map<int, Arc>::iterator it =
105.1005 - (*_node_data)[vi].heap_index.find(tree);
105.1006 -
105.1007 - if (it != (*_node_data)[vi].heap_index.end()) {
105.1008 - (*_node_data)[vi].heap.erase(it->second);
105.1009 - (*_node_data)[vi].heap_index.erase(it);
105.1010 - if ((*_node_data)[vi].heap.empty()) {
105.1011 - _blossom_set->increase(v, std::numeric_limits<Value>::max());
105.1012 - } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
105.1013 - _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
105.1014 - }
105.1015 -
105.1016 - if ((*_blossom_data)[vb].status == MATCHED) {
105.1017 - if (_blossom_set->classPrio(vb) ==
105.1018 - std::numeric_limits<Value>::max()) {
105.1019 - _delta2->erase(vb);
105.1020 - } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
105.1021 - (*_blossom_data)[vb].offset) {
105.1022 - _delta2->increase(vb, _blossom_set->classPrio(vb) -
105.1023 - (*_blossom_data)[vb].offset);
105.1024 - }
105.1025 - }
105.1026 - }
105.1027 - }
105.1028 - }
105.1029 - }
105.1030 - }
105.1031 -
105.1032 - void oddToMatched(int blossom) {
105.1033 - (*_blossom_data)[blossom].offset -= _delta_sum;
105.1034 -
105.1035 - if (_blossom_set->classPrio(blossom) !=
105.1036 - std::numeric_limits<Value>::max()) {
105.1037 - _delta2->push(blossom, _blossom_set->classPrio(blossom) -
105.1038 - (*_blossom_data)[blossom].offset);
105.1039 - }
105.1040 -
105.1041 - if (!_blossom_set->trivial(blossom)) {
105.1042 - _delta4->erase(blossom);
105.1043 - }
105.1044 - }
105.1045 -
105.1046 - void oddToEven(int blossom, int tree) {
105.1047 - if (!_blossom_set->trivial(blossom)) {
105.1048 - _delta4->erase(blossom);
105.1049 - (*_blossom_data)[blossom].pot -=
105.1050 - 2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
105.1051 - }
105.1052 -
105.1053 - for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
105.1054 - n != INVALID; ++n) {
105.1055 - int ni = (*_node_index)[n];
105.1056 -
105.1057 - _blossom_set->increase(n, std::numeric_limits<Value>::max());
105.1058 -
105.1059 - (*_node_data)[ni].heap.clear();
105.1060 - (*_node_data)[ni].heap_index.clear();
105.1061 - (*_node_data)[ni].pot +=
105.1062 - 2 * _delta_sum - (*_blossom_data)[blossom].offset;
105.1063 -
105.1064 - _delta1->push(n, (*_node_data)[ni].pot);
105.1065 -
105.1066 - for (InArcIt e(_graph, n); e != INVALID; ++e) {
105.1067 - Node v = _graph.source(e);
105.1068 - int vb = _blossom_set->find(v);
105.1069 - int vi = (*_node_index)[v];
105.1070 -
105.1071 - Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
105.1072 - dualScale * _weight[e];
105.1073 -
105.1074 - if ((*_blossom_data)[vb].status == EVEN) {
105.1075 - if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
105.1076 - _delta3->push(e, rw / 2);
105.1077 - }
105.1078 - } else if ((*_blossom_data)[vb].status == UNMATCHED) {
105.1079 - if (_delta3->state(e) != _delta3->IN_HEAP) {
105.1080 - _delta3->push(e, rw);
105.1081 - }
105.1082 - } else {
105.1083 -
105.1084 - typename std::map<int, Arc>::iterator it =
105.1085 - (*_node_data)[vi].heap_index.find(tree);
105.1086 -
105.1087 - if (it != (*_node_data)[vi].heap_index.end()) {
105.1088 - if ((*_node_data)[vi].heap[it->second] > rw) {
105.1089 - (*_node_data)[vi].heap.replace(it->second, e);
105.1090 - (*_node_data)[vi].heap.decrease(e, rw);
105.1091 - it->second = e;
105.1092 - }
105.1093 - } else {
105.1094 - (*_node_data)[vi].heap.push(e, rw);
105.1095 - (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
105.1096 - }
105.1097 -
105.1098 - if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
105.1099 - _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
105.1100 -
105.1101 - if ((*_blossom_data)[vb].status == MATCHED) {
105.1102 - if (_delta2->state(vb) != _delta2->IN_HEAP) {
105.1103 - _delta2->push(vb, _blossom_set->classPrio(vb) -
105.1104 - (*_blossom_data)[vb].offset);
105.1105 - } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
105.1106 - (*_blossom_data)[vb].offset) {
105.1107 - _delta2->decrease(vb, _blossom_set->classPrio(vb) -
105.1108 - (*_blossom_data)[vb].offset);
105.1109 - }
105.1110 - }
105.1111 - }
105.1112 - }
105.1113 - }
105.1114 - }
105.1115 - (*_blossom_data)[blossom].offset = 0;
105.1116 - }
105.1117 -
105.1118 -
105.1119 - void matchedToUnmatched(int blossom) {
105.1120 - if (_delta2->state(blossom) == _delta2->IN_HEAP) {
105.1121 - _delta2->erase(blossom);
105.1122 - }
105.1123 -
105.1124 - for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
105.1125 - n != INVALID; ++n) {
105.1126 - int ni = (*_node_index)[n];
105.1127 -
105.1128 - _blossom_set->increase(n, std::numeric_limits<Value>::max());
105.1129 -
105.1130 - (*_node_data)[ni].heap.clear();
105.1131 - (*_node_data)[ni].heap_index.clear();
105.1132 -
105.1133 - for (OutArcIt e(_graph, n); e != INVALID; ++e) {
105.1134 - Node v = _graph.target(e);
105.1135 - int vb = _blossom_set->find(v);
105.1136 - int vi = (*_node_index)[v];
105.1137 -
105.1138 - Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
105.1139 - dualScale * _weight[e];
105.1140 -
105.1141 - if ((*_blossom_data)[vb].status == EVEN) {
105.1142 - if (_delta3->state(e) != _delta3->IN_HEAP) {
105.1143 - _delta3->push(e, rw);
105.1144 - }
105.1145 - }
105.1146 - }
105.1147 - }
105.1148 - }
105.1149 -
105.1150 - void unmatchedToMatched(int blossom) {
105.1151 - for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
105.1152 - n != INVALID; ++n) {
105.1153 - int ni = (*_node_index)[n];
105.1154 -
105.1155 - for (InArcIt e(_graph, n); e != INVALID; ++e) {
105.1156 - Node v = _graph.source(e);
105.1157 - int vb = _blossom_set->find(v);
105.1158 - int vi = (*_node_index)[v];
105.1159 -
105.1160 - Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
105.1161 - dualScale * _weight[e];
105.1162 -
105.1163 - if (vb == blossom) {
105.1164 - if (_delta3->state(e) == _delta3->IN_HEAP) {
105.1165 - _delta3->erase(e);
105.1166 - }
105.1167 - } else if ((*_blossom_data)[vb].status == EVEN) {
105.1168 -
105.1169 - if (_delta3->state(e) == _delta3->IN_HEAP) {
105.1170 - _delta3->erase(e);
105.1171 - }
105.1172 -
105.1173 - int vt = _tree_set->find(vb);
105.1174 -
105.1175 - Arc r = _graph.oppositeArc(e);
105.1176 -
105.1177 - typename std::map<int, Arc>::iterator it =
105.1178 - (*_node_data)[ni].heap_index.find(vt);
105.1179 -
105.1180 - if (it != (*_node_data)[ni].heap_index.end()) {
105.1181 - if ((*_node_data)[ni].heap[it->second] > rw) {
105.1182 - (*_node_data)[ni].heap.replace(it->second, r);
105.1183 - (*_node_data)[ni].heap.decrease(r, rw);
105.1184 - it->second = r;
105.1185 - }
105.1186 - } else {
105.1187 - (*_node_data)[ni].heap.push(r, rw);
105.1188 - (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
105.1189 - }
105.1190 -
105.1191 - if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
105.1192 - _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
105.1193 -
105.1194 - if (_delta2->state(blossom) != _delta2->IN_HEAP) {
105.1195 - _delta2->push(blossom, _blossom_set->classPrio(blossom) -
105.1196 - (*_blossom_data)[blossom].offset);
105.1197 - } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
105.1198 - (*_blossom_data)[blossom].offset){
105.1199 - _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
105.1200 - (*_blossom_data)[blossom].offset);
105.1201 - }
105.1202 - }
105.1203 -
105.1204 - } else if ((*_blossom_data)[vb].status == UNMATCHED) {
105.1205 - if (_delta3->state(e) == _delta3->IN_HEAP) {
105.1206 - _delta3->erase(e);
105.1207 - }
105.1208 - }
105.1209 - }
105.1210 - }
105.1211 - }
105.1212 -
105.1213 - void alternatePath(int even, int tree) {
105.1214 - int odd;
105.1215 -
105.1216 - evenToMatched(even, tree);
105.1217 - (*_blossom_data)[even].status = MATCHED;
105.1218 -
105.1219 - while ((*_blossom_data)[even].pred != INVALID) {
105.1220 - odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
105.1221 - (*_blossom_data)[odd].status = MATCHED;
105.1222 - oddToMatched(odd);
105.1223 - (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
105.1224 -
105.1225 - even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
105.1226 - (*_blossom_data)[even].status = MATCHED;
105.1227 - evenToMatched(even, tree);
105.1228 - (*_blossom_data)[even].next =
105.1229 - _graph.oppositeArc((*_blossom_data)[odd].pred);
105.1230 - }
105.1231 -
105.1232 - }
105.1233 -
105.1234 - void destroyTree(int tree) {
105.1235 - for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
105.1236 - if ((*_blossom_data)[b].status == EVEN) {
105.1237 - (*_blossom_data)[b].status = MATCHED;
105.1238 - evenToMatched(b, tree);
105.1239 - } else if ((*_blossom_data)[b].status == ODD) {
105.1240 - (*_blossom_data)[b].status = MATCHED;
105.1241 - oddToMatched(b);
105.1242 - }
105.1243 - }
105.1244 - _tree_set->eraseClass(tree);
105.1245 - }
105.1246 -
105.1247 -
105.1248 - void unmatchNode(const Node& node) {
105.1249 - int blossom = _blossom_set->find(node);
105.1250 - int tree = _tree_set->find(blossom);
105.1251 -
105.1252 - alternatePath(blossom, tree);
105.1253 - destroyTree(tree);
105.1254 -
105.1255 - (*_blossom_data)[blossom].status = UNMATCHED;
105.1256 - (*_blossom_data)[blossom].base = node;
105.1257 - matchedToUnmatched(blossom);
105.1258 - }
105.1259 -
105.1260 -
105.1261 - void augmentOnEdge(const Edge& edge) {
105.1262 -
105.1263 - int left = _blossom_set->find(_graph.u(edge));
105.1264 - int right = _blossom_set->find(_graph.v(edge));
105.1265 -
105.1266 - if ((*_blossom_data)[left].status == EVEN) {
105.1267 - int left_tree = _tree_set->find(left);
105.1268 - alternatePath(left, left_tree);
105.1269 - destroyTree(left_tree);
105.1270 - } else {
105.1271 - (*_blossom_data)[left].status = MATCHED;
105.1272 - unmatchedToMatched(left);
105.1273 - }
105.1274 -
105.1275 - if ((*_blossom_data)[right].status == EVEN) {
105.1276 - int right_tree = _tree_set->find(right);
105.1277 - alternatePath(right, right_tree);
105.1278 - destroyTree(right_tree);
105.1279 - } else {
105.1280 - (*_blossom_data)[right].status = MATCHED;
105.1281 - unmatchedToMatched(right);
105.1282 - }
105.1283 -
105.1284 - (*_blossom_data)[left].next = _graph.direct(edge, true);
105.1285 - (*_blossom_data)[right].next = _graph.direct(edge, false);
105.1286 - }
105.1287 -
105.1288 - void extendOnArc(const Arc& arc) {
105.1289 - int base = _blossom_set->find(_graph.target(arc));
105.1290 - int tree = _tree_set->find(base);
105.1291 -
105.1292 - int odd = _blossom_set->find(_graph.source(arc));
105.1293 - _tree_set->insert(odd, tree);
105.1294 - (*_blossom_data)[odd].status = ODD;
105.1295 - matchedToOdd(odd);
105.1296 - (*_blossom_data)[odd].pred = arc;
105.1297 -
105.1298 - int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
105.1299 - (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
105.1300 - _tree_set->insert(even, tree);
105.1301 - (*_blossom_data)[even].status = EVEN;
105.1302 - matchedToEven(even, tree);
105.1303 - }
105.1304 -
105.1305 - void shrinkOnEdge(const Edge& edge, int tree) {
105.1306 - int nca = -1;
105.1307 - std::vector<int> left_path, right_path;
105.1308 -
105.1309 - {
105.1310 - std::set<int> left_set, right_set;
105.1311 - int left = _blossom_set->find(_graph.u(edge));
105.1312 - left_path.push_back(left);
105.1313 - left_set.insert(left);
105.1314 -
105.1315 - int right = _blossom_set->find(_graph.v(edge));
105.1316 - right_path.push_back(right);
105.1317 - right_set.insert(right);
105.1318 -
105.1319 - while (true) {
105.1320 -
105.1321 - if ((*_blossom_data)[left].pred == INVALID) break;
105.1322 -
105.1323 - left =
105.1324 - _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
105.1325 - left_path.push_back(left);
105.1326 - left =
105.1327 - _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
105.1328 - left_path.push_back(left);
105.1329 -
105.1330 - left_set.insert(left);
105.1331 -
105.1332 - if (right_set.find(left) != right_set.end()) {
105.1333 - nca = left;
105.1334 - break;
105.1335 - }
105.1336 -
105.1337 - if ((*_blossom_data)[right].pred == INVALID) break;
105.1338 -
105.1339 - right =
105.1340 - _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
105.1341 - right_path.push_back(right);
105.1342 - right =
105.1343 - _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
105.1344 - right_path.push_back(right);
105.1345 -
105.1346 - right_set.insert(right);
105.1347 -
105.1348 - if (left_set.find(right) != left_set.end()) {
105.1349 - nca = right;
105.1350 - break;
105.1351 - }
105.1352 -
105.1353 - }
105.1354 -
105.1355 - if (nca == -1) {
105.1356 - if ((*_blossom_data)[left].pred == INVALID) {
105.1357 - nca = right;
105.1358 - while (left_set.find(nca) == left_set.end()) {
105.1359 - nca =
105.1360 - _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
105.1361 - right_path.push_back(nca);
105.1362 - nca =
105.1363 - _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
105.1364 - right_path.push_back(nca);
105.1365 - }
105.1366 - } else {
105.1367 - nca = left;
105.1368 - while (right_set.find(nca) == right_set.end()) {
105.1369 - nca =
105.1370 - _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
105.1371 - left_path.push_back(nca);
105.1372 - nca =
105.1373 - _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
105.1374 - left_path.push_back(nca);
105.1375 - }
105.1376 - }
105.1377 - }
105.1378 - }
105.1379 -
105.1380 - std::vector<int> subblossoms;
105.1381 - Arc prev;
105.1382 -
105.1383 - prev = _graph.direct(edge, true);
105.1384 - for (int i = 0; left_path[i] != nca; i += 2) {
105.1385 - subblossoms.push_back(left_path[i]);
105.1386 - (*_blossom_data)[left_path[i]].next = prev;
105.1387 - _tree_set->erase(left_path[i]);
105.1388 -
105.1389 - subblossoms.push_back(left_path[i + 1]);
105.1390 - (*_blossom_data)[left_path[i + 1]].status = EVEN;
105.1391 - oddToEven(left_path[i + 1], tree);
105.1392 - _tree_set->erase(left_path[i + 1]);
105.1393 - prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
105.1394 - }
105.1395 -
105.1396 - int k = 0;
105.1397 - while (right_path[k] != nca) ++k;
105.1398 -
105.1399 - subblossoms.push_back(nca);
105.1400 - (*_blossom_data)[nca].next = prev;
105.1401 -
105.1402 - for (int i = k - 2; i >= 0; i -= 2) {
105.1403 - subblossoms.push_back(right_path[i + 1]);
105.1404 - (*_blossom_data)[right_path[i + 1]].status = EVEN;
105.1405 - oddToEven(right_path[i + 1], tree);
105.1406 - _tree_set->erase(right_path[i + 1]);
105.1407 -
105.1408 - (*_blossom_data)[right_path[i + 1]].next =
105.1409 - (*_blossom_data)[right_path[i + 1]].pred;
105.1410 -
105.1411 - subblossoms.push_back(right_path[i]);
105.1412 - _tree_set->erase(right_path[i]);
105.1413 - }
105.1414 -
105.1415 - int surface =
105.1416 - _blossom_set->join(subblossoms.begin(), subblossoms.end());
105.1417 -
105.1418 - for (int i = 0; i < int(subblossoms.size()); ++i) {
105.1419 - if (!_blossom_set->trivial(subblossoms[i])) {
105.1420 - (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
105.1421 - }
105.1422 - (*_blossom_data)[subblossoms[i]].status = MATCHED;
105.1423 - }
105.1424 -
105.1425 - (*_blossom_data)[surface].pot = -2 * _delta_sum;
105.1426 - (*_blossom_data)[surface].offset = 0;
105.1427 - (*_blossom_data)[surface].status = EVEN;
105.1428 - (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
105.1429 - (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
105.1430 -
105.1431 - _tree_set->insert(surface, tree);
105.1432 - _tree_set->erase(nca);
105.1433 - }
105.1434 -
105.1435 - void splitBlossom(int blossom) {
105.1436 - Arc next = (*_blossom_data)[blossom].next;
105.1437 - Arc pred = (*_blossom_data)[blossom].pred;
105.1438 -
105.1439 - int tree = _tree_set->find(blossom);
105.1440 -
105.1441 - (*_blossom_data)[blossom].status = MATCHED;
105.1442 - oddToMatched(blossom);
105.1443 - if (_delta2->state(blossom) == _delta2->IN_HEAP) {
105.1444 - _delta2->erase(blossom);
105.1445 - }
105.1446 -
105.1447 - std::vector<int> subblossoms;
105.1448 - _blossom_set->split(blossom, std::back_inserter(subblossoms));
105.1449 -
105.1450 - Value offset = (*_blossom_data)[blossom].offset;
105.1451 - int b = _blossom_set->find(_graph.source(pred));
105.1452 - int d = _blossom_set->find(_graph.source(next));
105.1453 -
105.1454 - int ib = -1, id = -1;
105.1455 - for (int i = 0; i < int(subblossoms.size()); ++i) {
105.1456 - if (subblossoms[i] == b) ib = i;
105.1457 - if (subblossoms[i] == d) id = i;
105.1458 -
105.1459 - (*_blossom_data)[subblossoms[i]].offset = offset;
105.1460 - if (!_blossom_set->trivial(subblossoms[i])) {
105.1461 - (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
105.1462 - }
105.1463 - if (_blossom_set->classPrio(subblossoms[i]) !=
105.1464 - std::numeric_limits<Value>::max()) {
105.1465 - _delta2->push(subblossoms[i],
105.1466 - _blossom_set->classPrio(subblossoms[i]) -
105.1467 - (*_blossom_data)[subblossoms[i]].offset);
105.1468 - }
105.1469 - }
105.1470 -
105.1471 - if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
105.1472 - for (int i = (id + 1) % subblossoms.size();
105.1473 - i != ib; i = (i + 2) % subblossoms.size()) {
105.1474 - int sb = subblossoms[i];
105.1475 - int tb = subblossoms[(i + 1) % subblossoms.size()];
105.1476 - (*_blossom_data)[sb].next =
105.1477 - _graph.oppositeArc((*_blossom_data)[tb].next);
105.1478 - }
105.1479 -
105.1480 - for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
105.1481 - int sb = subblossoms[i];
105.1482 - int tb = subblossoms[(i + 1) % subblossoms.size()];
105.1483 - int ub = subblossoms[(i + 2) % subblossoms.size()];
105.1484 -
105.1485 - (*_blossom_data)[sb].status = ODD;
105.1486 - matchedToOdd(sb);
105.1487 - _tree_set->insert(sb, tree);
105.1488 - (*_blossom_data)[sb].pred = pred;
105.1489 - (*_blossom_data)[sb].next =
105.1490 - _graph.oppositeArc((*_blossom_data)[tb].next);
105.1491 -
105.1492 - pred = (*_blossom_data)[ub].next;
105.1493 -
105.1494 - (*_blossom_data)[tb].status = EVEN;
105.1495 - matchedToEven(tb, tree);
105.1496 - _tree_set->insert(tb, tree);
105.1497 - (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
105.1498 - }
105.1499 -
105.1500 - (*_blossom_data)[subblossoms[id]].status = ODD;
105.1501 - matchedToOdd(subblossoms[id]);
105.1502 - _tree_set->insert(subblossoms[id], tree);
105.1503 - (*_blossom_data)[subblossoms[id]].next = next;
105.1504 - (*_blossom_data)[subblossoms[id]].pred = pred;
105.1505 -
105.1506 - } else {
105.1507 -
105.1508 - for (int i = (ib + 1) % subblossoms.size();
105.1509 - i != id; i = (i + 2) % subblossoms.size()) {
105.1510 - int sb = subblossoms[i];
105.1511 - int tb = subblossoms[(i + 1) % subblossoms.size()];
105.1512 - (*_blossom_data)[sb].next =
105.1513 - _graph.oppositeArc((*_blossom_data)[tb].next);
105.1514 - }
105.1515 -
105.1516 - for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
105.1517 - int sb = subblossoms[i];
105.1518 - int tb = subblossoms[(i + 1) % subblossoms.size()];
105.1519 - int ub = subblossoms[(i + 2) % subblossoms.size()];
105.1520 -
105.1521 - (*_blossom_data)[sb].status = ODD;
105.1522 - matchedToOdd(sb);
105.1523 - _tree_set->insert(sb, tree);
105.1524 - (*_blossom_data)[sb].next = next;
105.1525 - (*_blossom_data)[sb].pred =
105.1526 - _graph.oppositeArc((*_blossom_data)[tb].next);
105.1527 -
105.1528 - (*_blossom_data)[tb].status = EVEN;
105.1529 - matchedToEven(tb, tree);
105.1530 - _tree_set->insert(tb, tree);
105.1531 - (*_blossom_data)[tb].pred =
105.1532 - (*_blossom_data)[tb].next =
105.1533 - _graph.oppositeArc((*_blossom_data)[ub].next);
105.1534 - next = (*_blossom_data)[ub].next;
105.1535 - }
105.1536 -
105.1537 - (*_blossom_data)[subblossoms[ib]].status = ODD;
105.1538 - matchedToOdd(subblossoms[ib]);
105.1539 - _tree_set->insert(subblossoms[ib], tree);
105.1540 - (*_blossom_data)[subblossoms[ib]].next = next;
105.1541 - (*_blossom_data)[subblossoms[ib]].pred = pred;
105.1542 - }
105.1543 - _tree_set->erase(blossom);
105.1544 - }
105.1545 -
105.1546 - void extractBlossom(int blossom, const Node& base, const Arc& matching) {
105.1547 - if (_blossom_set->trivial(blossom)) {
105.1548 - int bi = (*_node_index)[base];
105.1549 - Value pot = (*_node_data)[bi].pot;
105.1550 -
105.1551 - _matching->set(base, matching);
105.1552 - _blossom_node_list.push_back(base);
105.1553 - _node_potential->set(base, pot);
105.1554 - } else {
105.1555 -
105.1556 - Value pot = (*_blossom_data)[blossom].pot;
105.1557 - int bn = _blossom_node_list.size();
105.1558 -
105.1559 - std::vector<int> subblossoms;
105.1560 - _blossom_set->split(blossom, std::back_inserter(subblossoms));
105.1561 - int b = _blossom_set->find(base);
105.1562 - int ib = -1;
105.1563 - for (int i = 0; i < int(subblossoms.size()); ++i) {
105.1564 - if (subblossoms[i] == b) { ib = i; break; }
105.1565 - }
105.1566 -
105.1567 - for (int i = 1; i < int(subblossoms.size()); i += 2) {
105.1568 - int sb = subblossoms[(ib + i) % subblossoms.size()];
105.1569 - int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
105.1570 -
105.1571 - Arc m = (*_blossom_data)[tb].next;
105.1572 - extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
105.1573 - extractBlossom(tb, _graph.source(m), m);
105.1574 - }
105.1575 - extractBlossom(subblossoms[ib], base, matching);
105.1576 -
105.1577 - int en = _blossom_node_list.size();
105.1578 -
105.1579 - _blossom_potential.push_back(BlossomVariable(bn, en, pot));
105.1580 - }
105.1581 - }
105.1582 -
105.1583 - void extractMatching() {
105.1584 - std::vector<int> blossoms;
105.1585 - for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
105.1586 - blossoms.push_back(c);
105.1587 - }
105.1588 -
105.1589 - for (int i = 0; i < int(blossoms.size()); ++i) {
105.1590 - if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
105.1591 -
105.1592 - Value offset = (*_blossom_data)[blossoms[i]].offset;
105.1593 - (*_blossom_data)[blossoms[i]].pot += 2 * offset;
105.1594 - for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
105.1595 - n != INVALID; ++n) {
105.1596 - (*_node_data)[(*_node_index)[n]].pot -= offset;
105.1597 - }
105.1598 -
105.1599 - Arc matching = (*_blossom_data)[blossoms[i]].next;
105.1600 - Node base = _graph.source(matching);
105.1601 - extractBlossom(blossoms[i], base, matching);
105.1602 - } else {
105.1603 - Node base = (*_blossom_data)[blossoms[i]].base;
105.1604 - extractBlossom(blossoms[i], base, INVALID);
105.1605 - }
105.1606 - }
105.1607 - }
105.1608 -
105.1609 - public:
105.1610 -
105.1611 - /// \brief Constructor
105.1612 - ///
105.1613 - /// Constructor.
105.1614 - MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
105.1615 - : _graph(graph), _weight(weight), _matching(0),
105.1616 - _node_potential(0), _blossom_potential(), _blossom_node_list(),
105.1617 - _node_num(0), _blossom_num(0),
105.1618 -
105.1619 - _blossom_index(0), _blossom_set(0), _blossom_data(0),
105.1620 - _node_index(0), _node_heap_index(0), _node_data(0),
105.1621 - _tree_set_index(0), _tree_set(0),
105.1622 -
105.1623 - _delta1_index(0), _delta1(0),
105.1624 - _delta2_index(0), _delta2(0),
105.1625 - _delta3_index(0), _delta3(0),
105.1626 - _delta4_index(0), _delta4(0),
105.1627 -
105.1628 - _delta_sum() {}
105.1629 -
105.1630 - ~MaxWeightedMatching() {
105.1631 - destroyStructures();
105.1632 - }
105.1633 -
105.1634 - /// \name Execution control
105.1635 - /// The simplest way to execute the algorithm is to use the
105.1636 - /// \c run() member function.
105.1637 -
105.1638 - ///@{
105.1639 -
105.1640 - /// \brief Initialize the algorithm
105.1641 - ///
105.1642 - /// Initialize the algorithm
105.1643 - void init() {
105.1644 - createStructures();
105.1645 -
105.1646 - for (ArcIt e(_graph); e != INVALID; ++e) {
105.1647 - _node_heap_index->set(e, BinHeap<Value, IntArcMap>::PRE_HEAP);
105.1648 - }
105.1649 - for (NodeIt n(_graph); n != INVALID; ++n) {
105.1650 - _delta1_index->set(n, _delta1->PRE_HEAP);
105.1651 - }
105.1652 - for (EdgeIt e(_graph); e != INVALID; ++e) {
105.1653 - _delta3_index->set(e, _delta3->PRE_HEAP);
105.1654 - }
105.1655 - for (int i = 0; i < _blossom_num; ++i) {
105.1656 - _delta2_index->set(i, _delta2->PRE_HEAP);
105.1657 - _delta4_index->set(i, _delta4->PRE_HEAP);
105.1658 - }
105.1659 -
105.1660 - int index = 0;
105.1661 - for (NodeIt n(_graph); n != INVALID; ++n) {
105.1662 - Value max = 0;
105.1663 - for (OutArcIt e(_graph, n); e != INVALID; ++e) {
105.1664 - if (_graph.target(e) == n) continue;
105.1665 - if ((dualScale * _weight[e]) / 2 > max) {
105.1666 - max = (dualScale * _weight[e]) / 2;
105.1667 - }
105.1668 - }
105.1669 - _node_index->set(n, index);
105.1670 - (*_node_data)[index].pot = max;
105.1671 - _delta1->push(n, max);
105.1672 - int blossom =
105.1673 - _blossom_set->insert(n, std::numeric_limits<Value>::max());
105.1674 -
105.1675 - _tree_set->insert(blossom);
105.1676 -
105.1677 - (*_blossom_data)[blossom].status = EVEN;
105.1678 - (*_blossom_data)[blossom].pred = INVALID;
105.1679 - (*_blossom_data)[blossom].next = INVALID;
105.1680 - (*_blossom_data)[blossom].pot = 0;
105.1681 - (*_blossom_data)[blossom].offset = 0;
105.1682 - ++index;
105.1683 - }
105.1684 - for (EdgeIt e(_graph); e != INVALID; ++e) {
105.1685 - int si = (*_node_index)[_graph.u(e)];
105.1686 - int ti = (*_node_index)[_graph.v(e)];
105.1687 - if (_graph.u(e) != _graph.v(e)) {
105.1688 - _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
105.1689 - dualScale * _weight[e]) / 2);
105.1690 - }
105.1691 - }
105.1692 - }
105.1693 -
105.1694 - /// \brief Starts the algorithm
105.1695 - ///
105.1696 - /// Starts the algorithm
105.1697 - void start() {
105.1698 - enum OpType {
105.1699 - D1, D2, D3, D4
105.1700 - };
105.1701 -
105.1702 - int unmatched = _node_num;
105.1703 - while (unmatched > 0) {
105.1704 - Value d1 = !_delta1->empty() ?
105.1705 - _delta1->prio() : std::numeric_limits<Value>::max();
105.1706 -
105.1707 - Value d2 = !_delta2->empty() ?
105.1708 - _delta2->prio() : std::numeric_limits<Value>::max();
105.1709 -
105.1710 - Value d3 = !_delta3->empty() ?
105.1711 - _delta3->prio() : std::numeric_limits<Value>::max();
105.1712 -
105.1713 - Value d4 = !_delta4->empty() ?
105.1714 - _delta4->prio() : std::numeric_limits<Value>::max();
105.1715 -
105.1716 - _delta_sum = d1; OpType ot = D1;
105.1717 - if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
105.1718 - if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
105.1719 - if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
105.1720 -
105.1721 -
105.1722 - switch (ot) {
105.1723 - case D1:
105.1724 - {
105.1725 - Node n = _delta1->top();
105.1726 - unmatchNode(n);
105.1727 - --unmatched;
105.1728 - }
105.1729 - break;
105.1730 - case D2:
105.1731 - {
105.1732 - int blossom = _delta2->top();
105.1733 - Node n = _blossom_set->classTop(blossom);
105.1734 - Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
105.1735 - extendOnArc(e);
105.1736 - }
105.1737 - break;
105.1738 - case D3:
105.1739 - {
105.1740 - Edge e = _delta3->top();
105.1741 -
105.1742 - int left_blossom = _blossom_set->find(_graph.u(e));
105.1743 - int right_blossom = _blossom_set->find(_graph.v(e));
105.1744 -
105.1745 - if (left_blossom == right_blossom) {
105.1746 - _delta3->pop();
105.1747 - } else {
105.1748 - int left_tree;
105.1749 - if ((*_blossom_data)[left_blossom].status == EVEN) {
105.1750 - left_tree = _tree_set->find(left_blossom);
105.1751 - } else {
105.1752 - left_tree = -1;
105.1753 - ++unmatched;
105.1754 - }
105.1755 - int right_tree;
105.1756 - if ((*_blossom_data)[right_blossom].status == EVEN) {
105.1757 - right_tree = _tree_set->find(right_blossom);
105.1758 - } else {
105.1759 - right_tree = -1;
105.1760 - ++unmatched;
105.1761 - }
105.1762 -
105.1763 - if (left_tree == right_tree) {
105.1764 - shrinkOnEdge(e, left_tree);
105.1765 - } else {
105.1766 - augmentOnEdge(e);
105.1767 - unmatched -= 2;
105.1768 - }
105.1769 - }
105.1770 - } break;
105.1771 - case D4:
105.1772 - splitBlossom(_delta4->top());
105.1773 - break;
105.1774 - }
105.1775 - }
105.1776 - extractMatching();
105.1777 - }
105.1778 -
105.1779 - /// \brief Runs %MaxWeightedMatching algorithm.
105.1780 - ///
105.1781 - /// This method runs the %MaxWeightedMatching algorithm.
105.1782 - ///
105.1783 - /// \note mwm.run() is just a shortcut of the following code.
105.1784 - /// \code
105.1785 - /// mwm.init();
105.1786 - /// mwm.start();
105.1787 - /// \endcode
105.1788 - void run() {
105.1789 - init();
105.1790 - start();
105.1791 - }
105.1792 -
105.1793 - /// @}
105.1794 -
105.1795 - /// \name Primal solution
105.1796 - /// Functions to get the primal solution, ie. the matching.
105.1797 -
105.1798 - /// @{
105.1799 -
105.1800 - /// \brief Returns the weight of the matching.
105.1801 - ///
105.1802 - /// Returns the weight of the matching.
105.1803 - Value matchingValue() const {
105.1804 - Value sum = 0;
105.1805 - for (NodeIt n(_graph); n != INVALID; ++n) {
105.1806 - if ((*_matching)[n] != INVALID) {
105.1807 - sum += _weight[(*_matching)[n]];
105.1808 - }
105.1809 - }
105.1810 - return sum /= 2;
105.1811 - }
105.1812 -
105.1813 - /// \brief Returns the cardinality of the matching.
105.1814 - ///
105.1815 - /// Returns the cardinality of the matching.
105.1816 - int matchingSize() const {
105.1817 - int num = 0;
105.1818 - for (NodeIt n(_graph); n != INVALID; ++n) {
105.1819 - if ((*_matching)[n] != INVALID) {
105.1820 - ++num;
105.1821 - }
105.1822 - }
105.1823 - return num /= 2;
105.1824 - }
105.1825 -
105.1826 - /// \brief Returns true when the edge is in the matching.
105.1827 - ///
105.1828 - /// Returns true when the edge is in the matching.
105.1829 - bool matching(const Edge& edge) const {
105.1830 - return edge == (*_matching)[_graph.u(edge)];
105.1831 - }
105.1832 -
105.1833 - /// \brief Returns the incident matching arc.
105.1834 - ///
105.1835 - /// Returns the incident matching arc from given node. If the
105.1836 - /// node is not matched then it gives back \c INVALID.
105.1837 - Arc matching(const Node& node) const {
105.1838 - return (*_matching)[node];
105.1839 - }
105.1840 -
105.1841 - /// \brief Returns the mate of the node.
105.1842 - ///
105.1843 - /// Returns the adjancent node in a mathcing arc. If the node is
105.1844 - /// not matched then it gives back \c INVALID.
105.1845 - Node mate(const Node& node) const {
105.1846 - return (*_matching)[node] != INVALID ?
105.1847 - _graph.target((*_matching)[node]) : INVALID;
105.1848 - }
105.1849 -
105.1850 - /// @}
105.1851 -
105.1852 - /// \name Dual solution
105.1853 - /// Functions to get the dual solution.
105.1854 -
105.1855 - /// @{
105.1856 -
105.1857 - /// \brief Returns the value of the dual solution.
105.1858 - ///
105.1859 - /// Returns the value of the dual solution. It should be equal to
105.1860 - /// the primal value scaled by \ref dualScale "dual scale".
105.1861 - Value dualValue() const {
105.1862 - Value sum = 0;
105.1863 - for (NodeIt n(_graph); n != INVALID; ++n) {
105.1864 - sum += nodeValue(n);
105.1865 - }
105.1866 - for (int i = 0; i < blossomNum(); ++i) {
105.1867 - sum += blossomValue(i) * (blossomSize(i) / 2);
105.1868 - }
105.1869 - return sum;
105.1870 - }
105.1871 -
105.1872 - /// \brief Returns the value of the node.
105.1873 - ///
105.1874 - /// Returns the the value of the node.
105.1875 - Value nodeValue(const Node& n) const {
105.1876 - return (*_node_potential)[n];
105.1877 - }
105.1878 -
105.1879 - /// \brief Returns the number of the blossoms in the basis.
105.1880 - ///
105.1881 - /// Returns the number of the blossoms in the basis.
105.1882 - /// \see BlossomIt
105.1883 - int blossomNum() const {
105.1884 - return _blossom_potential.size();
105.1885 - }
105.1886 -
105.1887 -
105.1888 - /// \brief Returns the number of the nodes in the blossom.
105.1889 - ///
105.1890 - /// Returns the number of the nodes in the blossom.
105.1891 - int blossomSize(int k) const {
105.1892 - return _blossom_potential[k].end - _blossom_potential[k].begin;
105.1893 - }
105.1894 -
105.1895 - /// \brief Returns the value of the blossom.
105.1896 - ///
105.1897 - /// Returns the the value of the blossom.
105.1898 - /// \see BlossomIt
105.1899 - Value blossomValue(int k) const {
105.1900 - return _blossom_potential[k].value;
105.1901 - }
105.1902 -
105.1903 - /// \brief Iterator for obtaining the nodes of the blossom.
105.1904 - ///
105.1905 - /// Iterator for obtaining the nodes of the blossom. This class
105.1906 - /// provides a common lemon style iterator for listing a
105.1907 - /// subset of the nodes.
105.1908 - class BlossomIt {
105.1909 - public:
105.1910 -
105.1911 - /// \brief Constructor.
105.1912 - ///
105.1913 - /// Constructor to get the nodes of the variable.
105.1914 - BlossomIt(const MaxWeightedMatching& algorithm, int variable)
105.1915 - : _algorithm(&algorithm)
105.1916 - {
105.1917 - _index = _algorithm->_blossom_potential[variable].begin;
105.1918 - _last = _algorithm->_blossom_potential[variable].end;
105.1919 - }
105.1920 -
105.1921 - /// \brief Conversion to node.
105.1922 - ///
105.1923 - /// Conversion to node.
105.1924 - operator Node() const {
105.1925 - return _algorithm->_blossom_node_list[_index];
105.1926 - }
105.1927 -
105.1928 - /// \brief Increment operator.
105.1929 - ///
105.1930 - /// Increment operator.
105.1931 - BlossomIt& operator++() {
105.1932 - ++_index;
105.1933 - return *this;
105.1934 - }
105.1935 -
105.1936 - /// \brief Validity checking
105.1937 - ///
105.1938 - /// Checks whether the iterator is invalid.
105.1939 - bool operator==(Invalid) const { return _index == _last; }
105.1940 -
105.1941 - /// \brief Validity checking
105.1942 - ///
105.1943 - /// Checks whether the iterator is valid.
105.1944 - bool operator!=(Invalid) const { return _index != _last; }
105.1945 -
105.1946 - private:
105.1947 - const MaxWeightedMatching* _algorithm;
105.1948 - int _last;
105.1949 - int _index;
105.1950 - };
105.1951 -
105.1952 - /// @}
105.1953 -
105.1954 - };
105.1955 -
105.1956 - /// \ingroup matching
105.1957 - ///
105.1958 - /// \brief Weighted perfect matching in general graphs
105.1959 - ///
105.1960 - /// This class provides an efficient implementation of Edmond's
105.1961 - /// maximum weighted perfect matching algorithm. The implementation
105.1962 - /// is based on extensive use of priority queues and provides
105.1963 - /// \f$O(nm\log(n))\f$ time complexity.
105.1964 - ///
105.1965 - /// The maximum weighted matching problem is to find undirected
105.1966 - /// edges in the graph with maximum overall weight and no two of
105.1967 - /// them shares their ends and covers all nodes. The problem can be
105.1968 - /// formulated with the following linear program.
105.1969 - /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
105.1970 - /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
105.1971 - \quad \forall B\in\mathcal{O}\f] */
105.1972 - /// \f[x_e \ge 0\quad \forall e\in E\f]
105.1973 - /// \f[\max \sum_{e\in E}x_ew_e\f]
105.1974 - /// where \f$\delta(X)\f$ is the set of edges incident to a node in
105.1975 - /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
105.1976 - /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
105.1977 - /// subsets of the nodes.
105.1978 - ///
105.1979 - /// The algorithm calculates an optimal matching and a proof of the
105.1980 - /// optimality. The solution of the dual problem can be used to check
105.1981 - /// the result of the algorithm. The dual linear problem is the
105.1982 - /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
105.1983 - w_{uv} \quad \forall uv\in E\f] */
105.1984 - /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
105.1985 - /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
105.1986 - \frac{\vert B \vert - 1}{2}z_B\f] */
105.1987 - ///
105.1988 - /// The algorithm can be executed with \c run() or the \c init() and
105.1989 - /// then the \c start() member functions. After it the matching can
105.1990 - /// be asked with \c matching() or mate() functions. The dual
105.1991 - /// solution can be get with \c nodeValue(), \c blossomNum() and \c
105.1992 - /// blossomValue() members and \ref MaxWeightedMatching::BlossomIt
105.1993 - /// "BlossomIt" nested class which is able to iterate on the nodes
105.1994 - /// of a blossom. If the value type is integral then the dual
105.1995 - /// solution is multiplied by \ref MaxWeightedMatching::dualScale "4".
105.1996 - template <typename _Graph,
105.1997 - typename _WeightMap = typename _Graph::template EdgeMap<int> >
105.1998 - class MaxWeightedPerfectMatching {
105.1999 - public:
105.2000 -
105.2001 - typedef _Graph Graph;
105.2002 - typedef _WeightMap WeightMap;
105.2003 - typedef typename WeightMap::Value Value;
105.2004 -
105.2005 - /// \brief Scaling factor for dual solution
105.2006 - ///
105.2007 - /// Scaling factor for dual solution, it is equal to 4 or 1
105.2008 - /// according to the value type.
105.2009 - static const int dualScale =
105.2010 - std::numeric_limits<Value>::is_integer ? 4 : 1;
105.2011 -
105.2012 - typedef typename Graph::template NodeMap<typename Graph::Arc>
105.2013 - MatchingMap;
105.2014 -
105.2015 - private:
105.2016 -
105.2017 - TEMPLATE_GRAPH_TYPEDEFS(Graph);
105.2018 -
105.2019 - typedef typename Graph::template NodeMap<Value> NodePotential;
105.2020 - typedef std::vector<Node> BlossomNodeList;
105.2021 -
105.2022 - struct BlossomVariable {
105.2023 - int begin, end;
105.2024 - Value value;
105.2025 -
105.2026 - BlossomVariable(int _begin, int _end, Value _value)
105.2027 - : begin(_begin), end(_end), value(_value) {}
105.2028 -
105.2029 - };
105.2030 -
105.2031 - typedef std::vector<BlossomVariable> BlossomPotential;
105.2032 -
105.2033 - const Graph& _graph;
105.2034 - const WeightMap& _weight;
105.2035 -
105.2036 - MatchingMap* _matching;
105.2037 -
105.2038 - NodePotential* _node_potential;
105.2039 -
105.2040 - BlossomPotential _blossom_potential;
105.2041 - BlossomNodeList _blossom_node_list;
105.2042 -
105.2043 - int _node_num;
105.2044 - int _blossom_num;
105.2045 -
105.2046 - typedef RangeMap<int> IntIntMap;
105.2047 -
105.2048 - enum Status {
105.2049 - EVEN = -1, MATCHED = 0, ODD = 1
105.2050 - };
105.2051 -
105.2052 - typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
105.2053 - struct BlossomData {
105.2054 - int tree;
105.2055 - Status status;
105.2056 - Arc pred, next;
105.2057 - Value pot, offset;
105.2058 - };
105.2059 -
105.2060 - IntNodeMap *_blossom_index;
105.2061 - BlossomSet *_blossom_set;
105.2062 - RangeMap<BlossomData>* _blossom_data;
105.2063 -
105.2064 - IntNodeMap *_node_index;
105.2065 - IntArcMap *_node_heap_index;
105.2066 -
105.2067 - struct NodeData {
105.2068 -
105.2069 - NodeData(IntArcMap& node_heap_index)
105.2070 - : heap(node_heap_index) {}
105.2071 -
105.2072 - int blossom;
105.2073 - Value pot;
105.2074 - BinHeap<Value, IntArcMap> heap;
105.2075 - std::map<int, Arc> heap_index;
105.2076 -
105.2077 - int tree;
105.2078 - };
105.2079 -
105.2080 - RangeMap<NodeData>* _node_data;
105.2081 -
105.2082 - typedef ExtendFindEnum<IntIntMap> TreeSet;
105.2083 -
105.2084 - IntIntMap *_tree_set_index;
105.2085 - TreeSet *_tree_set;
105.2086 -
105.2087 - IntIntMap *_delta2_index;
105.2088 - BinHeap<Value, IntIntMap> *_delta2;
105.2089 -
105.2090 - IntEdgeMap *_delta3_index;
105.2091 - BinHeap<Value, IntEdgeMap> *_delta3;
105.2092 -
105.2093 - IntIntMap *_delta4_index;
105.2094 - BinHeap<Value, IntIntMap> *_delta4;
105.2095 -
105.2096 - Value _delta_sum;
105.2097 -
105.2098 - void createStructures() {
105.2099 - _node_num = countNodes(_graph);
105.2100 - _blossom_num = _node_num * 3 / 2;
105.2101 -
105.2102 - if (!_matching) {
105.2103 - _matching = new MatchingMap(_graph);
105.2104 - }
105.2105 - if (!_node_potential) {
105.2106 - _node_potential = new NodePotential(_graph);
105.2107 - }
105.2108 - if (!_blossom_set) {
105.2109 - _blossom_index = new IntNodeMap(_graph);
105.2110 - _blossom_set = new BlossomSet(*_blossom_index);
105.2111 - _blossom_data = new RangeMap<BlossomData>(_blossom_num);
105.2112 - }
105.2113 -
105.2114 - if (!_node_index) {
105.2115 - _node_index = new IntNodeMap(_graph);
105.2116 - _node_heap_index = new IntArcMap(_graph);
105.2117 - _node_data = new RangeMap<NodeData>(_node_num,
105.2118 - NodeData(*_node_heap_index));
105.2119 - }
105.2120 -
105.2121 - if (!_tree_set) {
105.2122 - _tree_set_index = new IntIntMap(_blossom_num);
105.2123 - _tree_set = new TreeSet(*_tree_set_index);
105.2124 - }
105.2125 - if (!_delta2) {
105.2126 - _delta2_index = new IntIntMap(_blossom_num);
105.2127 - _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
105.2128 - }
105.2129 - if (!_delta3) {
105.2130 - _delta3_index = new IntEdgeMap(_graph);
105.2131 - _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
105.2132 - }
105.2133 - if (!_delta4) {
105.2134 - _delta4_index = new IntIntMap(_blossom_num);
105.2135 - _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
105.2136 - }
105.2137 - }
105.2138 -
105.2139 - void destroyStructures() {
105.2140 - _node_num = countNodes(_graph);
105.2141 - _blossom_num = _node_num * 3 / 2;
105.2142 -
105.2143 - if (_matching) {
105.2144 - delete _matching;
105.2145 - }
105.2146 - if (_node_potential) {
105.2147 - delete _node_potential;
105.2148 - }
105.2149 - if (_blossom_set) {
105.2150 - delete _blossom_index;
105.2151 - delete _blossom_set;
105.2152 - delete _blossom_data;
105.2153 - }
105.2154 -
105.2155 - if (_node_index) {
105.2156 - delete _node_index;
105.2157 - delete _node_heap_index;
105.2158 - delete _node_data;
105.2159 - }
105.2160 -
105.2161 - if (_tree_set) {
105.2162 - delete _tree_set_index;
105.2163 - delete _tree_set;
105.2164 - }
105.2165 - if (_delta2) {
105.2166 - delete _delta2_index;
105.2167 - delete _delta2;
105.2168 - }
105.2169 - if (_delta3) {
105.2170 - delete _delta3_index;
105.2171 - delete _delta3;
105.2172 - }
105.2173 - if (_delta4) {
105.2174 - delete _delta4_index;
105.2175 - delete _delta4;
105.2176 - }
105.2177 - }
105.2178 -
105.2179 - void matchedToEven(int blossom, int tree) {
105.2180 - if (_delta2->state(blossom) == _delta2->IN_HEAP) {
105.2181 - _delta2->erase(blossom);
105.2182 - }
105.2183 -
105.2184 - if (!_blossom_set->trivial(blossom)) {
105.2185 - (*_blossom_data)[blossom].pot -=
105.2186 - 2 * (_delta_sum - (*_blossom_data)[blossom].offset);
105.2187 - }
105.2188 -
105.2189 - for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
105.2190 - n != INVALID; ++n) {
105.2191 -
105.2192 - _blossom_set->increase(n, std::numeric_limits<Value>::max());
105.2193 - int ni = (*_node_index)[n];
105.2194 -
105.2195 - (*_node_data)[ni].heap.clear();
105.2196 - (*_node_data)[ni].heap_index.clear();
105.2197 -
105.2198 - (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
105.2199 -
105.2200 - for (InArcIt e(_graph, n); e != INVALID; ++e) {
105.2201 - Node v = _graph.source(e);
105.2202 - int vb = _blossom_set->find(v);
105.2203 - int vi = (*_node_index)[v];
105.2204 -
105.2205 - Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
105.2206 - dualScale * _weight[e];
105.2207 -
105.2208 - if ((*_blossom_data)[vb].status == EVEN) {
105.2209 - if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
105.2210 - _delta3->push(e, rw / 2);
105.2211 - }
105.2212 - } else {
105.2213 - typename std::map<int, Arc>::iterator it =
105.2214 - (*_node_data)[vi].heap_index.find(tree);
105.2215 -
105.2216 - if (it != (*_node_data)[vi].heap_index.end()) {
105.2217 - if ((*_node_data)[vi].heap[it->second] > rw) {
105.2218 - (*_node_data)[vi].heap.replace(it->second, e);
105.2219 - (*_node_data)[vi].heap.decrease(e, rw);
105.2220 - it->second = e;
105.2221 - }
105.2222 - } else {
105.2223 - (*_node_data)[vi].heap.push(e, rw);
105.2224 - (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
105.2225 - }
105.2226 -
105.2227 - if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
105.2228 - _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
105.2229 -
105.2230 - if ((*_blossom_data)[vb].status == MATCHED) {
105.2231 - if (_delta2->state(vb) != _delta2->IN_HEAP) {
105.2232 - _delta2->push(vb, _blossom_set->classPrio(vb) -
105.2233 - (*_blossom_data)[vb].offset);
105.2234 - } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
105.2235 - (*_blossom_data)[vb].offset){
105.2236 - _delta2->decrease(vb, _blossom_set->classPrio(vb) -
105.2237 - (*_blossom_data)[vb].offset);
105.2238 - }
105.2239 - }
105.2240 - }
105.2241 - }
105.2242 - }
105.2243 - }
105.2244 - (*_blossom_data)[blossom].offset = 0;
105.2245 - }
105.2246 -
105.2247 - void matchedToOdd(int blossom) {
105.2248 - if (_delta2->state(blossom) == _delta2->IN_HEAP) {
105.2249 - _delta2->erase(blossom);
105.2250 - }
105.2251 - (*_blossom_data)[blossom].offset += _delta_sum;
105.2252 - if (!_blossom_set->trivial(blossom)) {
105.2253 - _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
105.2254 - (*_blossom_data)[blossom].offset);
105.2255 - }
105.2256 - }
105.2257 -
105.2258 - void evenToMatched(int blossom, int tree) {
105.2259 - if (!_blossom_set->trivial(blossom)) {
105.2260 - (*_blossom_data)[blossom].pot += 2 * _delta_sum;
105.2261 - }
105.2262 -
105.2263 - for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
105.2264 - n != INVALID; ++n) {
105.2265 - int ni = (*_node_index)[n];
105.2266 - (*_node_data)[ni].pot -= _delta_sum;
105.2267 -
105.2268 - for (InArcIt e(_graph, n); e != INVALID; ++e) {
105.2269 - Node v = _graph.source(e);
105.2270 - int vb = _blossom_set->find(v);
105.2271 - int vi = (*_node_index)[v];
105.2272 -
105.2273 - Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
105.2274 - dualScale * _weight[e];
105.2275 -
105.2276 - if (vb == blossom) {
105.2277 - if (_delta3->state(e) == _delta3->IN_HEAP) {
105.2278 - _delta3->erase(e);
105.2279 - }
105.2280 - } else if ((*_blossom_data)[vb].status == EVEN) {
105.2281 -
105.2282 - if (_delta3->state(e) == _delta3->IN_HEAP) {
105.2283 - _delta3->erase(e);
105.2284 - }
105.2285 -
105.2286 - int vt = _tree_set->find(vb);
105.2287 -
105.2288 - if (vt != tree) {
105.2289 -
105.2290 - Arc r = _graph.oppositeArc(e);
105.2291 -
105.2292 - typename std::map<int, Arc>::iterator it =
105.2293 - (*_node_data)[ni].heap_index.find(vt);
105.2294 -
105.2295 - if (it != (*_node_data)[ni].heap_index.end()) {
105.2296 - if ((*_node_data)[ni].heap[it->second] > rw) {
105.2297 - (*_node_data)[ni].heap.replace(it->second, r);
105.2298 - (*_node_data)[ni].heap.decrease(r, rw);
105.2299 - it->second = r;
105.2300 - }
105.2301 - } else {
105.2302 - (*_node_data)[ni].heap.push(r, rw);
105.2303 - (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
105.2304 - }
105.2305 -
105.2306 - if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
105.2307 - _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
105.2308 -
105.2309 - if (_delta2->state(blossom) != _delta2->IN_HEAP) {
105.2310 - _delta2->push(blossom, _blossom_set->classPrio(blossom) -
105.2311 - (*_blossom_data)[blossom].offset);
105.2312 - } else if ((*_delta2)[blossom] >
105.2313 - _blossom_set->classPrio(blossom) -
105.2314 - (*_blossom_data)[blossom].offset){
105.2315 - _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
105.2316 - (*_blossom_data)[blossom].offset);
105.2317 - }
105.2318 - }
105.2319 - }
105.2320 - } else {
105.2321 -
105.2322 - typename std::map<int, Arc>::iterator it =
105.2323 - (*_node_data)[vi].heap_index.find(tree);
105.2324 -
105.2325 - if (it != (*_node_data)[vi].heap_index.end()) {
105.2326 - (*_node_data)[vi].heap.erase(it->second);
105.2327 - (*_node_data)[vi].heap_index.erase(it);
105.2328 - if ((*_node_data)[vi].heap.empty()) {
105.2329 - _blossom_set->increase(v, std::numeric_limits<Value>::max());
105.2330 - } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
105.2331 - _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
105.2332 - }
105.2333 -
105.2334 - if ((*_blossom_data)[vb].status == MATCHED) {
105.2335 - if (_blossom_set->classPrio(vb) ==
105.2336 - std::numeric_limits<Value>::max()) {
105.2337 - _delta2->erase(vb);
105.2338 - } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
105.2339 - (*_blossom_data)[vb].offset) {
105.2340 - _delta2->increase(vb, _blossom_set->classPrio(vb) -
105.2341 - (*_blossom_data)[vb].offset);
105.2342 - }
105.2343 - }
105.2344 - }
105.2345 - }
105.2346 - }
105.2347 - }
105.2348 - }
105.2349 -
105.2350 - void oddToMatched(int blossom) {
105.2351 - (*_blossom_data)[blossom].offset -= _delta_sum;
105.2352 -
105.2353 - if (_blossom_set->classPrio(blossom) !=
105.2354 - std::numeric_limits<Value>::max()) {
105.2355 - _delta2->push(blossom, _blossom_set->classPrio(blossom) -
105.2356 - (*_blossom_data)[blossom].offset);
105.2357 - }
105.2358 -
105.2359 - if (!_blossom_set->trivial(blossom)) {
105.2360 - _delta4->erase(blossom);
105.2361 - }
105.2362 - }
105.2363 -
105.2364 - void oddToEven(int blossom, int tree) {
105.2365 - if (!_blossom_set->trivial(blossom)) {
105.2366 - _delta4->erase(blossom);
105.2367 - (*_blossom_data)[blossom].pot -=
105.2368 - 2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
105.2369 - }
105.2370 -
105.2371 - for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
105.2372 - n != INVALID; ++n) {
105.2373 - int ni = (*_node_index)[n];
105.2374 -
105.2375 - _blossom_set->increase(n, std::numeric_limits<Value>::max());
105.2376 -
105.2377 - (*_node_data)[ni].heap.clear();
105.2378 - (*_node_data)[ni].heap_index.clear();
105.2379 - (*_node_data)[ni].pot +=
105.2380 - 2 * _delta_sum - (*_blossom_data)[blossom].offset;
105.2381 -
105.2382 - for (InArcIt e(_graph, n); e != INVALID; ++e) {
105.2383 - Node v = _graph.source(e);
105.2384 - int vb = _blossom_set->find(v);
105.2385 - int vi = (*_node_index)[v];
105.2386 -
105.2387 - Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
105.2388 - dualScale * _weight[e];
105.2389 -
105.2390 - if ((*_blossom_data)[vb].status == EVEN) {
105.2391 - if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
105.2392 - _delta3->push(e, rw / 2);
105.2393 - }
105.2394 - } else {
105.2395 -
105.2396 - typename std::map<int, Arc>::iterator it =
105.2397 - (*_node_data)[vi].heap_index.find(tree);
105.2398 -
105.2399 - if (it != (*_node_data)[vi].heap_index.end()) {
105.2400 - if ((*_node_data)[vi].heap[it->second] > rw) {
105.2401 - (*_node_data)[vi].heap.replace(it->second, e);
105.2402 - (*_node_data)[vi].heap.decrease(e, rw);
105.2403 - it->second = e;
105.2404 - }
105.2405 - } else {
105.2406 - (*_node_data)[vi].heap.push(e, rw);
105.2407 - (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
105.2408 - }
105.2409 -
105.2410 - if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
105.2411 - _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
105.2412 -
105.2413 - if ((*_blossom_data)[vb].status == MATCHED) {
105.2414 - if (_delta2->state(vb) != _delta2->IN_HEAP) {
105.2415 - _delta2->push(vb, _blossom_set->classPrio(vb) -
105.2416 - (*_blossom_data)[vb].offset);
105.2417 - } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
105.2418 - (*_blossom_data)[vb].offset) {
105.2419 - _delta2->decrease(vb, _blossom_set->classPrio(vb) -
105.2420 - (*_blossom_data)[vb].offset);
105.2421 - }
105.2422 - }
105.2423 - }
105.2424 - }
105.2425 - }
105.2426 - }
105.2427 - (*_blossom_data)[blossom].offset = 0;
105.2428 - }
105.2429 -
105.2430 - void alternatePath(int even, int tree) {
105.2431 - int odd;
105.2432 -
105.2433 - evenToMatched(even, tree);
105.2434 - (*_blossom_data)[even].status = MATCHED;
105.2435 -
105.2436 - while ((*_blossom_data)[even].pred != INVALID) {
105.2437 - odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
105.2438 - (*_blossom_data)[odd].status = MATCHED;
105.2439 - oddToMatched(odd);
105.2440 - (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
105.2441 -
105.2442 - even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
105.2443 - (*_blossom_data)[even].status = MATCHED;
105.2444 - evenToMatched(even, tree);
105.2445 - (*_blossom_data)[even].next =
105.2446 - _graph.oppositeArc((*_blossom_data)[odd].pred);
105.2447 - }
105.2448 -
105.2449 - }
105.2450 -
105.2451 - void destroyTree(int tree) {
105.2452 - for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
105.2453 - if ((*_blossom_data)[b].status == EVEN) {
105.2454 - (*_blossom_data)[b].status = MATCHED;
105.2455 - evenToMatched(b, tree);
105.2456 - } else if ((*_blossom_data)[b].status == ODD) {
105.2457 - (*_blossom_data)[b].status = MATCHED;
105.2458 - oddToMatched(b);
105.2459 - }
105.2460 - }
105.2461 - _tree_set->eraseClass(tree);
105.2462 - }
105.2463 -
105.2464 - void augmentOnEdge(const Edge& edge) {
105.2465 -
105.2466 - int left = _blossom_set->find(_graph.u(edge));
105.2467 - int right = _blossom_set->find(_graph.v(edge));
105.2468 -
105.2469 - int left_tree = _tree_set->find(left);
105.2470 - alternatePath(left, left_tree);
105.2471 - destroyTree(left_tree);
105.2472 -
105.2473 - int right_tree = _tree_set->find(right);
105.2474 - alternatePath(right, right_tree);
105.2475 - destroyTree(right_tree);
105.2476 -
105.2477 - (*_blossom_data)[left].next = _graph.direct(edge, true);
105.2478 - (*_blossom_data)[right].next = _graph.direct(edge, false);
105.2479 - }
105.2480 -
105.2481 - void extendOnArc(const Arc& arc) {
105.2482 - int base = _blossom_set->find(_graph.target(arc));
105.2483 - int tree = _tree_set->find(base);
105.2484 -
105.2485 - int odd = _blossom_set->find(_graph.source(arc));
105.2486 - _tree_set->insert(odd, tree);
105.2487 - (*_blossom_data)[odd].status = ODD;
105.2488 - matchedToOdd(odd);
105.2489 - (*_blossom_data)[odd].pred = arc;
105.2490 -
105.2491 - int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
105.2492 - (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
105.2493 - _tree_set->insert(even, tree);
105.2494 - (*_blossom_data)[even].status = EVEN;
105.2495 - matchedToEven(even, tree);
105.2496 - }
105.2497 -
105.2498 - void shrinkOnEdge(const Edge& edge, int tree) {
105.2499 - int nca = -1;
105.2500 - std::vector<int> left_path, right_path;
105.2501 -
105.2502 - {
105.2503 - std::set<int> left_set, right_set;
105.2504 - int left = _blossom_set->find(_graph.u(edge));
105.2505 - left_path.push_back(left);
105.2506 - left_set.insert(left);
105.2507 -
105.2508 - int right = _blossom_set->find(_graph.v(edge));
105.2509 - right_path.push_back(right);
105.2510 - right_set.insert(right);
105.2511 -
105.2512 - while (true) {
105.2513 -
105.2514 - if ((*_blossom_data)[left].pred == INVALID) break;
105.2515 -
105.2516 - left =
105.2517 - _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
105.2518 - left_path.push_back(left);
105.2519 - left =
105.2520 - _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
105.2521 - left_path.push_back(left);
105.2522 -
105.2523 - left_set.insert(left);
105.2524 -
105.2525 - if (right_set.find(left) != right_set.end()) {
105.2526 - nca = left;
105.2527 - break;
105.2528 - }
105.2529 -
105.2530 - if ((*_blossom_data)[right].pred == INVALID) break;
105.2531 -
105.2532 - right =
105.2533 - _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
105.2534 - right_path.push_back(right);
105.2535 - right =
105.2536 - _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
105.2537 - right_path.push_back(right);
105.2538 -
105.2539 - right_set.insert(right);
105.2540 -
105.2541 - if (left_set.find(right) != left_set.end()) {
105.2542 - nca = right;
105.2543 - break;
105.2544 - }
105.2545 -
105.2546 - }
105.2547 -
105.2548 - if (nca == -1) {
105.2549 - if ((*_blossom_data)[left].pred == INVALID) {
105.2550 - nca = right;
105.2551 - while (left_set.find(nca) == left_set.end()) {
105.2552 - nca =
105.2553 - _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
105.2554 - right_path.push_back(nca);
105.2555 - nca =
105.2556 - _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
105.2557 - right_path.push_back(nca);
105.2558 - }
105.2559 - } else {
105.2560 - nca = left;
105.2561 - while (right_set.find(nca) == right_set.end()) {
105.2562 - nca =
105.2563 - _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
105.2564 - left_path.push_back(nca);
105.2565 - nca =
105.2566 - _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
105.2567 - left_path.push_back(nca);
105.2568 - }
105.2569 - }
105.2570 - }
105.2571 - }
105.2572 -
105.2573 - std::vector<int> subblossoms;
105.2574 - Arc prev;
105.2575 -
105.2576 - prev = _graph.direct(edge, true);
105.2577 - for (int i = 0; left_path[i] != nca; i += 2) {
105.2578 - subblossoms.push_back(left_path[i]);
105.2579 - (*_blossom_data)[left_path[i]].next = prev;
105.2580 - _tree_set->erase(left_path[i]);
105.2581 -
105.2582 - subblossoms.push_back(left_path[i + 1]);
105.2583 - (*_blossom_data)[left_path[i + 1]].status = EVEN;
105.2584 - oddToEven(left_path[i + 1], tree);
105.2585 - _tree_set->erase(left_path[i + 1]);
105.2586 - prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
105.2587 - }
105.2588 -
105.2589 - int k = 0;
105.2590 - while (right_path[k] != nca) ++k;
105.2591 -
105.2592 - subblossoms.push_back(nca);
105.2593 - (*_blossom_data)[nca].next = prev;
105.2594 -
105.2595 - for (int i = k - 2; i >= 0; i -= 2) {
105.2596 - subblossoms.push_back(right_path[i + 1]);
105.2597 - (*_blossom_data)[right_path[i + 1]].status = EVEN;
105.2598 - oddToEven(right_path[i + 1], tree);
105.2599 - _tree_set->erase(right_path[i + 1]);
105.2600 -
105.2601 - (*_blossom_data)[right_path[i + 1]].next =
105.2602 - (*_blossom_data)[right_path[i + 1]].pred;
105.2603 -
105.2604 - subblossoms.push_back(right_path[i]);
105.2605 - _tree_set->erase(right_path[i]);
105.2606 - }
105.2607 -
105.2608 - int surface =
105.2609 - _blossom_set->join(subblossoms.begin(), subblossoms.end());
105.2610 -
105.2611 - for (int i = 0; i < int(subblossoms.size()); ++i) {
105.2612 - if (!_blossom_set->trivial(subblossoms[i])) {
105.2613 - (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
105.2614 - }
105.2615 - (*_blossom_data)[subblossoms[i]].status = MATCHED;
105.2616 - }
105.2617 -
105.2618 - (*_blossom_data)[surface].pot = -2 * _delta_sum;
105.2619 - (*_blossom_data)[surface].offset = 0;
105.2620 - (*_blossom_data)[surface].status = EVEN;
105.2621 - (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
105.2622 - (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
105.2623 -
105.2624 - _tree_set->insert(surface, tree);
105.2625 - _tree_set->erase(nca);
105.2626 - }
105.2627 -
105.2628 - void splitBlossom(int blossom) {
105.2629 - Arc next = (*_blossom_data)[blossom].next;
105.2630 - Arc pred = (*_blossom_data)[blossom].pred;
105.2631 -
105.2632 - int tree = _tree_set->find(blossom);
105.2633 -
105.2634 - (*_blossom_data)[blossom].status = MATCHED;
105.2635 - oddToMatched(blossom);
105.2636 - if (_delta2->state(blossom) == _delta2->IN_HEAP) {
105.2637 - _delta2->erase(blossom);
105.2638 - }
105.2639 -
105.2640 - std::vector<int> subblossoms;
105.2641 - _blossom_set->split(blossom, std::back_inserter(subblossoms));
105.2642 -
105.2643 - Value offset = (*_blossom_data)[blossom].offset;
105.2644 - int b = _blossom_set->find(_graph.source(pred));
105.2645 - int d = _blossom_set->find(_graph.source(next));
105.2646 -
105.2647 - int ib = -1, id = -1;
105.2648 - for (int i = 0; i < int(subblossoms.size()); ++i) {
105.2649 - if (subblossoms[i] == b) ib = i;
105.2650 - if (subblossoms[i] == d) id = i;
105.2651 -
105.2652 - (*_blossom_data)[subblossoms[i]].offset = offset;
105.2653 - if (!_blossom_set->trivial(subblossoms[i])) {
105.2654 - (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
105.2655 - }
105.2656 - if (_blossom_set->classPrio(subblossoms[i]) !=
105.2657 - std::numeric_limits<Value>::max()) {
105.2658 - _delta2->push(subblossoms[i],
105.2659 - _blossom_set->classPrio(subblossoms[i]) -
105.2660 - (*_blossom_data)[subblossoms[i]].offset);
105.2661 - }
105.2662 - }
105.2663 -
105.2664 - if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
105.2665 - for (int i = (id + 1) % subblossoms.size();
105.2666 - i != ib; i = (i + 2) % subblossoms.size()) {
105.2667 - int sb = subblossoms[i];
105.2668 - int tb = subblossoms[(i + 1) % subblossoms.size()];
105.2669 - (*_blossom_data)[sb].next =
105.2670 - _graph.oppositeArc((*_blossom_data)[tb].next);
105.2671 - }
105.2672 -
105.2673 - for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
105.2674 - int sb = subblossoms[i];
105.2675 - int tb = subblossoms[(i + 1) % subblossoms.size()];
105.2676 - int ub = subblossoms[(i + 2) % subblossoms.size()];
105.2677 -
105.2678 - (*_blossom_data)[sb].status = ODD;
105.2679 - matchedToOdd(sb);
105.2680 - _tree_set->insert(sb, tree);
105.2681 - (*_blossom_data)[sb].pred = pred;
105.2682 - (*_blossom_data)[sb].next =
105.2683 - _graph.oppositeArc((*_blossom_data)[tb].next);
105.2684 -
105.2685 - pred = (*_blossom_data)[ub].next;
105.2686 -
105.2687 - (*_blossom_data)[tb].status = EVEN;
105.2688 - matchedToEven(tb, tree);
105.2689 - _tree_set->insert(tb, tree);
105.2690 - (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
105.2691 - }
105.2692 -
105.2693 - (*_blossom_data)[subblossoms[id]].status = ODD;
105.2694 - matchedToOdd(subblossoms[id]);
105.2695 - _tree_set->insert(subblossoms[id], tree);
105.2696 - (*_blossom_data)[subblossoms[id]].next = next;
105.2697 - (*_blossom_data)[subblossoms[id]].pred = pred;
105.2698 -
105.2699 - } else {
105.2700 -
105.2701 - for (int i = (ib + 1) % subblossoms.size();
105.2702 - i != id; i = (i + 2) % subblossoms.size()) {
105.2703 - int sb = subblossoms[i];
105.2704 - int tb = subblossoms[(i + 1) % subblossoms.size()];
105.2705 - (*_blossom_data)[sb].next =
105.2706 - _graph.oppositeArc((*_blossom_data)[tb].next);
105.2707 - }
105.2708 -
105.2709 - for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
105.2710 - int sb = subblossoms[i];
105.2711 - int tb = subblossoms[(i + 1) % subblossoms.size()];
105.2712 - int ub = subblossoms[(i + 2) % subblossoms.size()];
105.2713 -
105.2714 - (*_blossom_data)[sb].status = ODD;
105.2715 - matchedToOdd(sb);
105.2716 - _tree_set->insert(sb, tree);
105.2717 - (*_blossom_data)[sb].next = next;
105.2718 - (*_blossom_data)[sb].pred =
105.2719 - _graph.oppositeArc((*_blossom_data)[tb].next);
105.2720 -
105.2721 - (*_blossom_data)[tb].status = EVEN;
105.2722 - matchedToEven(tb, tree);
105.2723 - _tree_set->insert(tb, tree);
105.2724 - (*_blossom_data)[tb].pred =
105.2725 - (*_blossom_data)[tb].next =
105.2726 - _graph.oppositeArc((*_blossom_data)[ub].next);
105.2727 - next = (*_blossom_data)[ub].next;
105.2728 - }
105.2729 -
105.2730 - (*_blossom_data)[subblossoms[ib]].status = ODD;
105.2731 - matchedToOdd(subblossoms[ib]);
105.2732 - _tree_set->insert(subblossoms[ib], tree);
105.2733 - (*_blossom_data)[subblossoms[ib]].next = next;
105.2734 - (*_blossom_data)[subblossoms[ib]].pred = pred;
105.2735 - }
105.2736 - _tree_set->erase(blossom);
105.2737 - }
105.2738 -
105.2739 - void extractBlossom(int blossom, const Node& base, const Arc& matching) {
105.2740 - if (_blossom_set->trivial(blossom)) {
105.2741 - int bi = (*_node_index)[base];
105.2742 - Value pot = (*_node_data)[bi].pot;
105.2743 -
105.2744 - _matching->set(base, matching);
105.2745 - _blossom_node_list.push_back(base);
105.2746 - _node_potential->set(base, pot);
105.2747 - } else {
105.2748 -
105.2749 - Value pot = (*_blossom_data)[blossom].pot;
105.2750 - int bn = _blossom_node_list.size();
105.2751 -
105.2752 - std::vector<int> subblossoms;
105.2753 - _blossom_set->split(blossom, std::back_inserter(subblossoms));
105.2754 - int b = _blossom_set->find(base);
105.2755 - int ib = -1;
105.2756 - for (int i = 0; i < int(subblossoms.size()); ++i) {
105.2757 - if (subblossoms[i] == b) { ib = i; break; }
105.2758 - }
105.2759 -
105.2760 - for (int i = 1; i < int(subblossoms.size()); i += 2) {
105.2761 - int sb = subblossoms[(ib + i) % subblossoms.size()];
105.2762 - int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
105.2763 -
105.2764 - Arc m = (*_blossom_data)[tb].next;
105.2765 - extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
105.2766 - extractBlossom(tb, _graph.source(m), m);
105.2767 - }
105.2768 - extractBlossom(subblossoms[ib], base, matching);
105.2769 -
105.2770 - int en = _blossom_node_list.size();
105.2771 -
105.2772 - _blossom_potential.push_back(BlossomVariable(bn, en, pot));
105.2773 - }
105.2774 - }
105.2775 -
105.2776 - void extractMatching() {
105.2777 - std::vector<int> blossoms;
105.2778 - for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
105.2779 - blossoms.push_back(c);
105.2780 - }
105.2781 -
105.2782 - for (int i = 0; i < int(blossoms.size()); ++i) {
105.2783 -
105.2784 - Value offset = (*_blossom_data)[blossoms[i]].offset;
105.2785 - (*_blossom_data)[blossoms[i]].pot += 2 * offset;
105.2786 - for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
105.2787 - n != INVALID; ++n) {
105.2788 - (*_node_data)[(*_node_index)[n]].pot -= offset;
105.2789 - }
105.2790 -
105.2791 - Arc matching = (*_blossom_data)[blossoms[i]].next;
105.2792 - Node base = _graph.source(matching);
105.2793 - extractBlossom(blossoms[i], base, matching);
105.2794 - }
105.2795 - }
105.2796 -
105.2797 - public:
105.2798 -
105.2799 - /// \brief Constructor
105.2800 - ///
105.2801 - /// Constructor.
105.2802 - MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
105.2803 - : _graph(graph), _weight(weight), _matching(0),
105.2804 - _node_potential(0), _blossom_potential(), _blossom_node_list(),
105.2805 - _node_num(0), _blossom_num(0),
105.2806 -
105.2807 - _blossom_index(0), _blossom_set(0), _blossom_data(0),
105.2808 - _node_index(0), _node_heap_index(0), _node_data(0),
105.2809 - _tree_set_index(0), _tree_set(0),
105.2810 -
105.2811 - _delta2_index(0), _delta2(0),
105.2812 - _delta3_index(0), _delta3(0),
105.2813 - _delta4_index(0), _delta4(0),
105.2814 -
105.2815 - _delta_sum() {}
105.2816 -
105.2817 - ~MaxWeightedPerfectMatching() {
105.2818 - destroyStructures();
105.2819 - }
105.2820 -
105.2821 - /// \name Execution control
105.2822 - /// The simplest way to execute the algorithm is to use the
105.2823 - /// \c run() member function.
105.2824 -
105.2825 - ///@{
105.2826 -
105.2827 - /// \brief Initialize the algorithm
105.2828 - ///
105.2829 - /// Initialize the algorithm
105.2830 - void init() {
105.2831 - createStructures();
105.2832 -
105.2833 - for (ArcIt e(_graph); e != INVALID; ++e) {
105.2834 - _node_heap_index->set(e, BinHeap<Value, IntArcMap>::PRE_HEAP);
105.2835 - }
105.2836 - for (EdgeIt e(_graph); e != INVALID; ++e) {
105.2837 - _delta3_index->set(e, _delta3->PRE_HEAP);
105.2838 - }
105.2839 - for (int i = 0; i < _blossom_num; ++i) {
105.2840 - _delta2_index->set(i, _delta2->PRE_HEAP);
105.2841 - _delta4_index->set(i, _delta4->PRE_HEAP);
105.2842 - }
105.2843 -
105.2844 - int index = 0;
105.2845 - for (NodeIt n(_graph); n != INVALID; ++n) {
105.2846 - Value max = - std::numeric_limits<Value>::max();
105.2847 - for (OutArcIt e(_graph, n); e != INVALID; ++e) {
105.2848 - if (_graph.target(e) == n) continue;
105.2849 - if ((dualScale * _weight[e]) / 2 > max) {
105.2850 - max = (dualScale * _weight[e]) / 2;
105.2851 - }
105.2852 - }
105.2853 - _node_index->set(n, index);
105.2854 - (*_node_data)[index].pot = max;
105.2855 - int blossom =
105.2856 - _blossom_set->insert(n, std::numeric_limits<Value>::max());
105.2857 -
105.2858 - _tree_set->insert(blossom);
105.2859 -
105.2860 - (*_blossom_data)[blossom].status = EVEN;
105.2861 - (*_blossom_data)[blossom].pred = INVALID;
105.2862 - (*_blossom_data)[blossom].next = INVALID;
105.2863 - (*_blossom_data)[blossom].pot = 0;
105.2864 - (*_blossom_data)[blossom].offset = 0;
105.2865 - ++index;
105.2866 - }
105.2867 - for (EdgeIt e(_graph); e != INVALID; ++e) {
105.2868 - int si = (*_node_index)[_graph.u(e)];
105.2869 - int ti = (*_node_index)[_graph.v(e)];
105.2870 - if (_graph.u(e) != _graph.v(e)) {
105.2871 - _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
105.2872 - dualScale * _weight[e]) / 2);
105.2873 - }
105.2874 - }
105.2875 - }
105.2876 -
105.2877 - /// \brief Starts the algorithm
105.2878 - ///
105.2879 - /// Starts the algorithm
105.2880 - bool start() {
105.2881 - enum OpType {
105.2882 - D2, D3, D4
105.2883 - };
105.2884 -
105.2885 - int unmatched = _node_num;
105.2886 - while (unmatched > 0) {
105.2887 - Value d2 = !_delta2->empty() ?
105.2888 - _delta2->prio() : std::numeric_limits<Value>::max();
105.2889 -
105.2890 - Value d3 = !_delta3->empty() ?
105.2891 - _delta3->prio() : std::numeric_limits<Value>::max();
105.2892 -
105.2893 - Value d4 = !_delta4->empty() ?
105.2894 - _delta4->prio() : std::numeric_limits<Value>::max();
105.2895 -
105.2896 - _delta_sum = d2; OpType ot = D2;
105.2897 - if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
105.2898 - if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
105.2899 -
105.2900 - if (_delta_sum == std::numeric_limits<Value>::max()) {
105.2901 - return false;
105.2902 - }
105.2903 -
105.2904 - switch (ot) {
105.2905 - case D2:
105.2906 - {
105.2907 - int blossom = _delta2->top();
105.2908 - Node n = _blossom_set->classTop(blossom);
105.2909 - Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
105.2910 - extendOnArc(e);
105.2911 - }
105.2912 - break;
105.2913 - case D3:
105.2914 - {
105.2915 - Edge e = _delta3->top();
105.2916 -
105.2917 - int left_blossom = _blossom_set->find(_graph.u(e));
105.2918 - int right_blossom = _blossom_set->find(_graph.v(e));
105.2919 -
105.2920 - if (left_blossom == right_blossom) {
105.2921 - _delta3->pop();
105.2922 - } else {
105.2923 - int left_tree = _tree_set->find(left_blossom);
105.2924 - int right_tree = _tree_set->find(right_blossom);
105.2925 -
105.2926 - if (left_tree == right_tree) {
105.2927 - shrinkOnEdge(e, left_tree);
105.2928 - } else {
105.2929 - augmentOnEdge(e);
105.2930 - unmatched -= 2;
105.2931 - }
105.2932 - }
105.2933 - } break;
105.2934 - case D4:
105.2935 - splitBlossom(_delta4->top());
105.2936 - break;
105.2937 - }
105.2938 - }
105.2939 - extractMatching();
105.2940 - return true;
105.2941 - }
105.2942 -
105.2943 - /// \brief Runs %MaxWeightedPerfectMatching algorithm.
105.2944 - ///
105.2945 - /// This method runs the %MaxWeightedPerfectMatching algorithm.
105.2946 - ///
105.2947 - /// \note mwm.run() is just a shortcut of the following code.
105.2948 - /// \code
105.2949 - /// mwm.init();
105.2950 - /// mwm.start();
105.2951 - /// \endcode
105.2952 - bool run() {
105.2953 - init();
105.2954 - return start();
105.2955 - }
105.2956 -
105.2957 - /// @}
105.2958 -
105.2959 - /// \name Primal solution
105.2960 - /// Functions to get the primal solution, ie. the matching.
105.2961 -
105.2962 - /// @{
105.2963 -
105.2964 - /// \brief Returns the matching value.
105.2965 - ///
105.2966 - /// Returns the matching value.
105.2967 - Value matchingValue() const {
105.2968 - Value sum = 0;
105.2969 - for (NodeIt n(_graph); n != INVALID; ++n) {
105.2970 - if ((*_matching)[n] != INVALID) {
105.2971 - sum += _weight[(*_matching)[n]];
105.2972 - }
105.2973 - }
105.2974 - return sum /= 2;
105.2975 - }
105.2976 -
105.2977 - /// \brief Returns true when the edge is in the matching.
105.2978 - ///
105.2979 - /// Returns true when the edge is in the matching.
105.2980 - bool matching(const Edge& edge) const {
105.2981 - return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
105.2982 - }
105.2983 -
105.2984 - /// \brief Returns the incident matching edge.
105.2985 - ///
105.2986 - /// Returns the incident matching arc from given edge.
105.2987 - Arc matching(const Node& node) const {
105.2988 - return (*_matching)[node];
105.2989 - }
105.2990 -
105.2991 - /// \brief Returns the mate of the node.
105.2992 - ///
105.2993 - /// Returns the adjancent node in a mathcing arc.
105.2994 - Node mate(const Node& node) const {
105.2995 - return _graph.target((*_matching)[node]);
105.2996 - }
105.2997 -
105.2998 - /// @}
105.2999 -
105.3000 - /// \name Dual solution
105.3001 - /// Functions to get the dual solution.
105.3002 -
105.3003 - /// @{
105.3004 -
105.3005 - /// \brief Returns the value of the dual solution.
105.3006 - ///
105.3007 - /// Returns the value of the dual solution. It should be equal to
105.3008 - /// the primal value scaled by \ref dualScale "dual scale".
105.3009 - Value dualValue() const {
105.3010 - Value sum = 0;
105.3011 - for (NodeIt n(_graph); n != INVALID; ++n) {
105.3012 - sum += nodeValue(n);
105.3013 - }
105.3014 - for (int i = 0; i < blossomNum(); ++i) {
105.3015 - sum += blossomValue(i) * (blossomSize(i) / 2);
105.3016 - }
105.3017 - return sum;
105.3018 - }
105.3019 -
105.3020 - /// \brief Returns the value of the node.
105.3021 - ///
105.3022 - /// Returns the the value of the node.
105.3023 - Value nodeValue(const Node& n) const {
105.3024 - return (*_node_potential)[n];
105.3025 - }
105.3026 -
105.3027 - /// \brief Returns the number of the blossoms in the basis.
105.3028 - ///
105.3029 - /// Returns the number of the blossoms in the basis.
105.3030 - /// \see BlossomIt
105.3031 - int blossomNum() const {
105.3032 - return _blossom_potential.size();
105.3033 - }
105.3034 -
105.3035 -
105.3036 - /// \brief Returns the number of the nodes in the blossom.
105.3037 - ///
105.3038 - /// Returns the number of the nodes in the blossom.
105.3039 - int blossomSize(int k) const {
105.3040 - return _blossom_potential[k].end - _blossom_potential[k].begin;
105.3041 - }
105.3042 -
105.3043 - /// \brief Returns the value of the blossom.
105.3044 - ///
105.3045 - /// Returns the the value of the blossom.
105.3046 - /// \see BlossomIt
105.3047 - Value blossomValue(int k) const {
105.3048 - return _blossom_potential[k].value;
105.3049 - }
105.3050 -
105.3051 - /// \brief Iterator for obtaining the nodes of the blossom.
105.3052 - ///
105.3053 - /// Iterator for obtaining the nodes of the blossom. This class
105.3054 - /// provides a common lemon style iterator for listing a
105.3055 - /// subset of the nodes.
105.3056 - class BlossomIt {
105.3057 - public:
105.3058 -
105.3059 - /// \brief Constructor.
105.3060 - ///
105.3061 - /// Constructor to get the nodes of the variable.
105.3062 - BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
105.3063 - : _algorithm(&algorithm)
105.3064 - {
105.3065 - _index = _algorithm->_blossom_potential[variable].begin;
105.3066 - _last = _algorithm->_blossom_potential[variable].end;
105.3067 - }
105.3068 -
105.3069 - /// \brief Conversion to node.
105.3070 - ///
105.3071 - /// Conversion to node.
105.3072 - operator Node() const {
105.3073 - return _algorithm->_blossom_node_list[_index];
105.3074 - }
105.3075 -
105.3076 - /// \brief Increment operator.
105.3077 - ///
105.3078 - /// Increment operator.
105.3079 - BlossomIt& operator++() {
105.3080 - ++_index;
105.3081 - return *this;
105.3082 - }
105.3083 -
105.3084 - /// \brief Validity checking
105.3085 - ///
105.3086 - /// Checks whether the iterator is invalid.
105.3087 - bool operator==(Invalid) const { return _index == _last; }
105.3088 -
105.3089 - /// \brief Validity checking
105.3090 - ///
105.3091 - /// Checks whether the iterator is valid.
105.3092 - bool operator!=(Invalid) const { return _index != _last; }
105.3093 -
105.3094 - private:
105.3095 - const MaxWeightedPerfectMatching* _algorithm;
105.3096 - int _last;
105.3097 - int _index;
105.3098 - };
105.3099 -
105.3100 - /// @}
105.3101 -
105.3102 - };
105.3103 -
105.3104 -
105.3105 -} //END OF NAMESPACE LEMON
105.3106 -
105.3107 -#endif //LEMON_MAX_MATCHING_H
106.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
106.2 +++ b/lemon/min_cost_arborescence.h Thu Nov 05 15:48:01 2009 +0100
106.3 @@ -0,0 +1,807 @@
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-2008
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_MIN_COST_ARBORESCENCE_H
106.23 +#define LEMON_MIN_COST_ARBORESCENCE_H
106.24 +
106.25 +///\ingroup spantree
106.26 +///\file
106.27 +///\brief Minimum Cost Arborescence algorithm.
106.28 +
106.29 +#include <vector>
106.30 +
106.31 +#include <lemon/list_graph.h>
106.32 +#include <lemon/bin_heap.h>
106.33 +#include <lemon/assert.h>
106.34 +
106.35 +namespace lemon {
106.36 +
106.37 +
106.38 + /// \brief Default traits class for MinCostArborescence class.
106.39 + ///
106.40 + /// Default traits class for MinCostArborescence class.
106.41 + /// \param GR Digraph type.
106.42 + /// \param CM Type of the cost map.
106.43 + template <class GR, class CM>
106.44 + struct MinCostArborescenceDefaultTraits{
106.45 +
106.46 + /// \brief The digraph type the algorithm runs on.
106.47 + typedef GR Digraph;
106.48 +
106.49 + /// \brief The type of the map that stores the arc costs.
106.50 + ///
106.51 + /// The type of the map that stores the arc costs.
106.52 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
106.53 + typedef CM CostMap;
106.54 +
106.55 + /// \brief The value type of the costs.
106.56 + ///
106.57 + /// The value type of the costs.
106.58 + typedef typename CostMap::Value Value;
106.59 +
106.60 + /// \brief The type of the map that stores which arcs are in the
106.61 + /// arborescence.
106.62 + ///
106.63 + /// The type of the map that stores which arcs are in the
106.64 + /// arborescence. It must conform to the \ref concepts::WriteMap
106.65 + /// "WriteMap" concept, and its value type must be \c bool
106.66 + /// (or convertible). Initially it will be set to \c false on each
106.67 + /// arc, then it will be set on each arborescence arc once.
106.68 + typedef typename Digraph::template ArcMap<bool> ArborescenceMap;
106.69 +
106.70 + /// \brief Instantiates a \c ArborescenceMap.
106.71 + ///
106.72 + /// This function instantiates a \c ArborescenceMap.
106.73 + /// \param digraph The digraph to which we would like to calculate
106.74 + /// the \c ArborescenceMap.
106.75 + static ArborescenceMap *createArborescenceMap(const Digraph &digraph){
106.76 + return new ArborescenceMap(digraph);
106.77 + }
106.78 +
106.79 + /// \brief The type of the \c PredMap
106.80 + ///
106.81 + /// The type of the \c PredMap. It must confrom to the
106.82 + /// \ref concepts::WriteMap "WriteMap" concept, and its value type
106.83 + /// must be the \c Arc type of the digraph.
106.84 + typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
106.85 +
106.86 + /// \brief Instantiates a \c PredMap.
106.87 + ///
106.88 + /// This function instantiates a \c PredMap.
106.89 + /// \param digraph The digraph to which we would like to define the
106.90 + /// \c PredMap.
106.91 + static PredMap *createPredMap(const Digraph &digraph){
106.92 + return new PredMap(digraph);
106.93 + }
106.94 +
106.95 + };
106.96 +
106.97 + /// \ingroup spantree
106.98 + ///
106.99 + /// \brief Minimum Cost Arborescence algorithm class.
106.100 + ///
106.101 + /// This class provides an efficient implementation of the
106.102 + /// Minimum Cost Arborescence algorithm. The arborescence is a tree
106.103 + /// which is directed from a given source node of the digraph. One or
106.104 + /// more sources should be given to the algorithm and it will calculate
106.105 + /// the minimum cost subgraph that is the union of arborescences with the
106.106 + /// given sources and spans all the nodes which are reachable from the
106.107 + /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+e).
106.108 + ///
106.109 + /// The algorithm also provides an optimal dual solution, therefore
106.110 + /// the optimality of the solution can be checked.
106.111 + ///
106.112 + /// \param GR The digraph type the algorithm runs on.
106.113 + /// \param CM A read-only arc map storing the costs of the
106.114 + /// arcs. It is read once for each arc, so the map may involve in
106.115 + /// relatively time consuming process to compute the arc costs if
106.116 + /// it is necessary. The default map type is \ref
106.117 + /// concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
106.118 + /// \param TR Traits class to set various data types used
106.119 + /// by the algorithm. The default traits class is
106.120 + /// \ref MinCostArborescenceDefaultTraits
106.121 + /// "MinCostArborescenceDefaultTraits<GR, CM>".
106.122 +#ifndef DOXYGEN
106.123 + template <typename GR,
106.124 + typename CM = typename GR::template ArcMap<int>,
106.125 + typename TR =
106.126 + MinCostArborescenceDefaultTraits<GR, CM> >
106.127 +#else
106.128 + template <typename GR, typename CM, typedef TR>
106.129 +#endif
106.130 + class MinCostArborescence {
106.131 + public:
106.132 +
106.133 + /// \brief The \ref MinCostArborescenceDefaultTraits "traits class"
106.134 + /// of the algorithm.
106.135 + typedef TR Traits;
106.136 + /// The type of the underlying digraph.
106.137 + typedef typename Traits::Digraph Digraph;
106.138 + /// The type of the map that stores the arc costs.
106.139 + typedef typename Traits::CostMap CostMap;
106.140 + ///The type of the costs of the arcs.
106.141 + typedef typename Traits::Value Value;
106.142 + ///The type of the predecessor map.
106.143 + typedef typename Traits::PredMap PredMap;
106.144 + ///The type of the map that stores which arcs are in the arborescence.
106.145 + typedef typename Traits::ArborescenceMap ArborescenceMap;
106.146 +
106.147 + typedef MinCostArborescence Create;
106.148 +
106.149 + private:
106.150 +
106.151 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
106.152 +
106.153 + struct CostArc {
106.154 +
106.155 + Arc arc;
106.156 + Value value;
106.157 +
106.158 + CostArc() {}
106.159 + CostArc(Arc _arc, Value _value) : arc(_arc), value(_value) {}
106.160 +
106.161 + };
106.162 +
106.163 + const Digraph *_digraph;
106.164 + const CostMap *_cost;
106.165 +
106.166 + PredMap *_pred;
106.167 + bool local_pred;
106.168 +
106.169 + ArborescenceMap *_arborescence;
106.170 + bool local_arborescence;
106.171 +
106.172 + typedef typename Digraph::template ArcMap<int> ArcOrder;
106.173 + ArcOrder *_arc_order;
106.174 +
106.175 + typedef typename Digraph::template NodeMap<int> NodeOrder;
106.176 + NodeOrder *_node_order;
106.177 +
106.178 + typedef typename Digraph::template NodeMap<CostArc> CostArcMap;
106.179 + CostArcMap *_cost_arcs;
106.180 +
106.181 + struct StackLevel {
106.182 +
106.183 + std::vector<CostArc> arcs;
106.184 + int node_level;
106.185 +
106.186 + };
106.187 +
106.188 + std::vector<StackLevel> level_stack;
106.189 + std::vector<Node> queue;
106.190 +
106.191 + typedef std::vector<typename Digraph::Node> DualNodeList;
106.192 +
106.193 + DualNodeList _dual_node_list;
106.194 +
106.195 + struct DualVariable {
106.196 + int begin, end;
106.197 + Value value;
106.198 +
106.199 + DualVariable(int _begin, int _end, Value _value)
106.200 + : begin(_begin), end(_end), value(_value) {}
106.201 +
106.202 + };
106.203 +
106.204 + typedef std::vector<DualVariable> DualVariables;
106.205 +
106.206 + DualVariables _dual_variables;
106.207 +
106.208 + typedef typename Digraph::template NodeMap<int> HeapCrossRef;
106.209 +
106.210 + HeapCrossRef *_heap_cross_ref;
106.211 +
106.212 + typedef BinHeap<int, HeapCrossRef> Heap;
106.213 +
106.214 + Heap *_heap;
106.215 +
106.216 + protected:
106.217 +
106.218 + MinCostArborescence() {}
106.219 +
106.220 + private:
106.221 +
106.222 + void createStructures() {
106.223 + if (!_pred) {
106.224 + local_pred = true;
106.225 + _pred = Traits::createPredMap(*_digraph);
106.226 + }
106.227 + if (!_arborescence) {
106.228 + local_arborescence = true;
106.229 + _arborescence = Traits::createArborescenceMap(*_digraph);
106.230 + }
106.231 + if (!_arc_order) {
106.232 + _arc_order = new ArcOrder(*_digraph);
106.233 + }
106.234 + if (!_node_order) {
106.235 + _node_order = new NodeOrder(*_digraph);
106.236 + }
106.237 + if (!_cost_arcs) {
106.238 + _cost_arcs = new CostArcMap(*_digraph);
106.239 + }
106.240 + if (!_heap_cross_ref) {
106.241 + _heap_cross_ref = new HeapCrossRef(*_digraph, -1);
106.242 + }
106.243 + if (!_heap) {
106.244 + _heap = new Heap(*_heap_cross_ref);
106.245 + }
106.246 + }
106.247 +
106.248 + void destroyStructures() {
106.249 + if (local_arborescence) {
106.250 + delete _arborescence;
106.251 + }
106.252 + if (local_pred) {
106.253 + delete _pred;
106.254 + }
106.255 + if (_arc_order) {
106.256 + delete _arc_order;
106.257 + }
106.258 + if (_node_order) {
106.259 + delete _node_order;
106.260 + }
106.261 + if (_cost_arcs) {
106.262 + delete _cost_arcs;
106.263 + }
106.264 + if (_heap) {
106.265 + delete _heap;
106.266 + }
106.267 + if (_heap_cross_ref) {
106.268 + delete _heap_cross_ref;
106.269 + }
106.270 + }
106.271 +
106.272 + Arc prepare(Node node) {
106.273 + std::vector<Node> nodes;
106.274 + (*_node_order)[node] = _dual_node_list.size();
106.275 + StackLevel level;
106.276 + level.node_level = _dual_node_list.size();
106.277 + _dual_node_list.push_back(node);
106.278 + for (InArcIt it(*_digraph, node); it != INVALID; ++it) {
106.279 + Arc arc = it;
106.280 + Node source = _digraph->source(arc);
106.281 + Value value = (*_cost)[it];
106.282 + if (source == node || (*_node_order)[source] == -3) continue;
106.283 + if ((*_cost_arcs)[source].arc == INVALID) {
106.284 + (*_cost_arcs)[source].arc = arc;
106.285 + (*_cost_arcs)[source].value = value;
106.286 + nodes.push_back(source);
106.287 + } else {
106.288 + if ((*_cost_arcs)[source].value > value) {
106.289 + (*_cost_arcs)[source].arc = arc;
106.290 + (*_cost_arcs)[source].value = value;
106.291 + }
106.292 + }
106.293 + }
106.294 + CostArc minimum = (*_cost_arcs)[nodes[0]];
106.295 + for (int i = 1; i < int(nodes.size()); ++i) {
106.296 + if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
106.297 + minimum = (*_cost_arcs)[nodes[i]];
106.298 + }
106.299 + }
106.300 + (*_arc_order)[minimum.arc] = _dual_variables.size();
106.301 + DualVariable var(_dual_node_list.size() - 1,
106.302 + _dual_node_list.size(), minimum.value);
106.303 + _dual_variables.push_back(var);
106.304 + for (int i = 0; i < int(nodes.size()); ++i) {
106.305 + (*_cost_arcs)[nodes[i]].value -= minimum.value;
106.306 + level.arcs.push_back((*_cost_arcs)[nodes[i]]);
106.307 + (*_cost_arcs)[nodes[i]].arc = INVALID;
106.308 + }
106.309 + level_stack.push_back(level);
106.310 + return minimum.arc;
106.311 + }
106.312 +
106.313 + Arc contract(Node node) {
106.314 + int node_bottom = bottom(node);
106.315 + std::vector<Node> nodes;
106.316 + while (!level_stack.empty() &&
106.317 + level_stack.back().node_level >= node_bottom) {
106.318 + for (int i = 0; i < int(level_stack.back().arcs.size()); ++i) {
106.319 + Arc arc = level_stack.back().arcs[i].arc;
106.320 + Node source = _digraph->source(arc);
106.321 + Value value = level_stack.back().arcs[i].value;
106.322 + if ((*_node_order)[source] >= node_bottom) continue;
106.323 + if ((*_cost_arcs)[source].arc == INVALID) {
106.324 + (*_cost_arcs)[source].arc = arc;
106.325 + (*_cost_arcs)[source].value = value;
106.326 + nodes.push_back(source);
106.327 + } else {
106.328 + if ((*_cost_arcs)[source].value > value) {
106.329 + (*_cost_arcs)[source].arc = arc;
106.330 + (*_cost_arcs)[source].value = value;
106.331 + }
106.332 + }
106.333 + }
106.334 + level_stack.pop_back();
106.335 + }
106.336 + CostArc minimum = (*_cost_arcs)[nodes[0]];
106.337 + for (int i = 1; i < int(nodes.size()); ++i) {
106.338 + if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
106.339 + minimum = (*_cost_arcs)[nodes[i]];
106.340 + }
106.341 + }
106.342 + (*_arc_order)[minimum.arc] = _dual_variables.size();
106.343 + DualVariable var(node_bottom, _dual_node_list.size(), minimum.value);
106.344 + _dual_variables.push_back(var);
106.345 + StackLevel level;
106.346 + level.node_level = node_bottom;
106.347 + for (int i = 0; i < int(nodes.size()); ++i) {
106.348 + (*_cost_arcs)[nodes[i]].value -= minimum.value;
106.349 + level.arcs.push_back((*_cost_arcs)[nodes[i]]);
106.350 + (*_cost_arcs)[nodes[i]].arc = INVALID;
106.351 + }
106.352 + level_stack.push_back(level);
106.353 + return minimum.arc;
106.354 + }
106.355 +
106.356 + int bottom(Node node) {
106.357 + int k = level_stack.size() - 1;
106.358 + while (level_stack[k].node_level > (*_node_order)[node]) {
106.359 + --k;
106.360 + }
106.361 + return level_stack[k].node_level;
106.362 + }
106.363 +
106.364 + void finalize(Arc arc) {
106.365 + Node node = _digraph->target(arc);
106.366 + _heap->push(node, (*_arc_order)[arc]);
106.367 + _pred->set(node, arc);
106.368 + while (!_heap->empty()) {
106.369 + Node source = _heap->top();
106.370 + _heap->pop();
106.371 + (*_node_order)[source] = -1;
106.372 + for (OutArcIt it(*_digraph, source); it != INVALID; ++it) {
106.373 + if ((*_arc_order)[it] < 0) continue;
106.374 + Node target = _digraph->target(it);
106.375 + switch(_heap->state(target)) {
106.376 + case Heap::PRE_HEAP:
106.377 + _heap->push(target, (*_arc_order)[it]);
106.378 + _pred->set(target, it);
106.379 + break;
106.380 + case Heap::IN_HEAP:
106.381 + if ((*_arc_order)[it] < (*_heap)[target]) {
106.382 + _heap->decrease(target, (*_arc_order)[it]);
106.383 + _pred->set(target, it);
106.384 + }
106.385 + break;
106.386 + case Heap::POST_HEAP:
106.387 + break;
106.388 + }
106.389 + }
106.390 + _arborescence->set((*_pred)[source], true);
106.391 + }
106.392 + }
106.393 +
106.394 +
106.395 + public:
106.396 +
106.397 + /// \name Named Template Parameters
106.398 +
106.399 + /// @{
106.400 +
106.401 + template <class T>
106.402 + struct SetArborescenceMapTraits : public Traits {
106.403 + typedef T ArborescenceMap;
106.404 + static ArborescenceMap *createArborescenceMap(const Digraph &)
106.405 + {
106.406 + LEMON_ASSERT(false, "ArborescenceMap is not initialized");
106.407 + return 0; // ignore warnings
106.408 + }
106.409 + };
106.410 +
106.411 + /// \brief \ref named-templ-param "Named parameter" for
106.412 + /// setting \c ArborescenceMap type
106.413 + ///
106.414 + /// \ref named-templ-param "Named parameter" for setting
106.415 + /// \c ArborescenceMap type.
106.416 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept,
106.417 + /// and its value type must be \c bool (or convertible).
106.418 + /// Initially it will be set to \c false on each arc,
106.419 + /// then it will be set on each arborescence arc once.
106.420 + template <class T>
106.421 + struct SetArborescenceMap
106.422 + : public MinCostArborescence<Digraph, CostMap,
106.423 + SetArborescenceMapTraits<T> > {
106.424 + };
106.425 +
106.426 + template <class T>
106.427 + struct SetPredMapTraits : public Traits {
106.428 + typedef T PredMap;
106.429 + static PredMap *createPredMap(const Digraph &)
106.430 + {
106.431 + LEMON_ASSERT(false, "PredMap is not initialized");
106.432 + return 0; // ignore warnings
106.433 + }
106.434 + };
106.435 +
106.436 + /// \brief \ref named-templ-param "Named parameter" for
106.437 + /// setting \c PredMap type
106.438 + ///
106.439 + /// \ref named-templ-param "Named parameter" for setting
106.440 + /// \c PredMap type.
106.441 + /// It must meet the \ref concepts::WriteMap "WriteMap" concept,
106.442 + /// and its value type must be the \c Arc type of the digraph.
106.443 + template <class T>
106.444 + struct SetPredMap
106.445 + : public MinCostArborescence<Digraph, CostMap, SetPredMapTraits<T> > {
106.446 + };
106.447 +
106.448 + /// @}
106.449 +
106.450 + /// \brief Constructor.
106.451 + ///
106.452 + /// \param digraph The digraph the algorithm will run on.
106.453 + /// \param cost The cost map used by the algorithm.
106.454 + MinCostArborescence(const Digraph& digraph, const CostMap& cost)
106.455 + : _digraph(&digraph), _cost(&cost), _pred(0), local_pred(false),
106.456 + _arborescence(0), local_arborescence(false),
106.457 + _arc_order(0), _node_order(0), _cost_arcs(0),
106.458 + _heap_cross_ref(0), _heap(0) {}
106.459 +
106.460 + /// \brief Destructor.
106.461 + ~MinCostArborescence() {
106.462 + destroyStructures();
106.463 + }
106.464 +
106.465 + /// \brief Sets the arborescence map.
106.466 + ///
106.467 + /// Sets the arborescence map.
106.468 + /// \return <tt>(*this)</tt>
106.469 + MinCostArborescence& arborescenceMap(ArborescenceMap& m) {
106.470 + if (local_arborescence) {
106.471 + delete _arborescence;
106.472 + }
106.473 + local_arborescence = false;
106.474 + _arborescence = &m;
106.475 + return *this;
106.476 + }
106.477 +
106.478 + /// \brief Sets the predecessor map.
106.479 + ///
106.480 + /// Sets the predecessor map.
106.481 + /// \return <tt>(*this)</tt>
106.482 + MinCostArborescence& predMap(PredMap& m) {
106.483 + if (local_pred) {
106.484 + delete _pred;
106.485 + }
106.486 + local_pred = false;
106.487 + _pred = &m;
106.488 + return *this;
106.489 + }
106.490 +
106.491 + /// \name Execution Control
106.492 + /// The simplest way to execute the algorithm is to use
106.493 + /// one of the member functions called \c run(...). \n
106.494 + /// If you need better control on the execution,
106.495 + /// you have to call \ref init() first, then you can add several
106.496 + /// source nodes with \ref addSource().
106.497 + /// Finally \ref start() will perform the arborescence
106.498 + /// computation.
106.499 +
106.500 + ///@{
106.501 +
106.502 + /// \brief Initializes the internal data structures.
106.503 + ///
106.504 + /// Initializes the internal data structures.
106.505 + ///
106.506 + void init() {
106.507 + createStructures();
106.508 + _heap->clear();
106.509 + for (NodeIt it(*_digraph); it != INVALID; ++it) {
106.510 + (*_cost_arcs)[it].arc = INVALID;
106.511 + (*_node_order)[it] = -3;
106.512 + (*_heap_cross_ref)[it] = Heap::PRE_HEAP;
106.513 + _pred->set(it, INVALID);
106.514 + }
106.515 + for (ArcIt it(*_digraph); it != INVALID; ++it) {
106.516 + _arborescence->set(it, false);
106.517 + (*_arc_order)[it] = -1;
106.518 + }
106.519 + _dual_node_list.clear();
106.520 + _dual_variables.clear();
106.521 + }
106.522 +
106.523 + /// \brief Adds a new source node.
106.524 + ///
106.525 + /// Adds a new source node to the algorithm.
106.526 + void addSource(Node source) {
106.527 + std::vector<Node> nodes;
106.528 + nodes.push_back(source);
106.529 + while (!nodes.empty()) {
106.530 + Node node = nodes.back();
106.531 + nodes.pop_back();
106.532 + for (OutArcIt it(*_digraph, node); it != INVALID; ++it) {
106.533 + Node target = _digraph->target(it);
106.534 + if ((*_node_order)[target] == -3) {
106.535 + (*_node_order)[target] = -2;
106.536 + nodes.push_back(target);
106.537 + queue.push_back(target);
106.538 + }
106.539 + }
106.540 + }
106.541 + (*_node_order)[source] = -1;
106.542 + }
106.543 +
106.544 + /// \brief Processes the next node in the priority queue.
106.545 + ///
106.546 + /// Processes the next node in the priority queue.
106.547 + ///
106.548 + /// \return The processed node.
106.549 + ///
106.550 + /// \warning The queue must not be empty.
106.551 + Node processNextNode() {
106.552 + Node node = queue.back();
106.553 + queue.pop_back();
106.554 + if ((*_node_order)[node] == -2) {
106.555 + Arc arc = prepare(node);
106.556 + Node source = _digraph->source(arc);
106.557 + while ((*_node_order)[source] != -1) {
106.558 + if ((*_node_order)[source] >= 0) {
106.559 + arc = contract(source);
106.560 + } else {
106.561 + arc = prepare(source);
106.562 + }
106.563 + source = _digraph->source(arc);
106.564 + }
106.565 + finalize(arc);
106.566 + level_stack.clear();
106.567 + }
106.568 + return node;
106.569 + }
106.570 +
106.571 + /// \brief Returns the number of the nodes to be processed.
106.572 + ///
106.573 + /// Returns the number of the nodes to be processed in the priority
106.574 + /// queue.
106.575 + int queueSize() const {
106.576 + return queue.size();
106.577 + }
106.578 +
106.579 + /// \brief Returns \c false if there are nodes to be processed.
106.580 + ///
106.581 + /// Returns \c false if there are nodes to be processed.
106.582 + bool emptyQueue() const {
106.583 + return queue.empty();
106.584 + }
106.585 +
106.586 + /// \brief Executes the algorithm.
106.587 + ///
106.588 + /// Executes the algorithm.
106.589 + ///
106.590 + /// \pre init() must be called and at least one node should be added
106.591 + /// with addSource() before using this function.
106.592 + ///
106.593 + ///\note mca.start() is just a shortcut of the following code.
106.594 + ///\code
106.595 + ///while (!mca.emptyQueue()) {
106.596 + /// mca.processNextNode();
106.597 + ///}
106.598 + ///\endcode
106.599 + void start() {
106.600 + while (!emptyQueue()) {
106.601 + processNextNode();
106.602 + }
106.603 + }
106.604 +
106.605 + /// \brief Runs %MinCostArborescence algorithm from node \c s.
106.606 + ///
106.607 + /// This method runs the %MinCostArborescence algorithm from
106.608 + /// a root node \c s.
106.609 + ///
106.610 + /// \note mca.run(s) is just a shortcut of the following code.
106.611 + /// \code
106.612 + /// mca.init();
106.613 + /// mca.addSource(s);
106.614 + /// mca.start();
106.615 + /// \endcode
106.616 + void run(Node s) {
106.617 + init();
106.618 + addSource(s);
106.619 + start();
106.620 + }
106.621 +
106.622 + ///@}
106.623 +
106.624 + /// \name Query Functions
106.625 + /// The result of the %MinCostArborescence algorithm can be obtained
106.626 + /// using these functions.\n
106.627 + /// Either run() or start() must be called before using them.
106.628 +
106.629 + /// @{
106.630 +
106.631 + /// \brief Returns the cost of the arborescence.
106.632 + ///
106.633 + /// Returns the cost of the arborescence.
106.634 + Value arborescenceCost() const {
106.635 + Value sum = 0;
106.636 + for (ArcIt it(*_digraph); it != INVALID; ++it) {
106.637 + if (arborescence(it)) {
106.638 + sum += (*_cost)[it];
106.639 + }
106.640 + }
106.641 + return sum;
106.642 + }
106.643 +
106.644 + /// \brief Returns \c true if the arc is in the arborescence.
106.645 + ///
106.646 + /// Returns \c true if the given arc is in the arborescence.
106.647 + /// \param arc An arc of the digraph.
106.648 + /// \pre \ref run() must be called before using this function.
106.649 + bool arborescence(Arc arc) const {
106.650 + return (*_pred)[_digraph->target(arc)] == arc;
106.651 + }
106.652 +
106.653 + /// \brief Returns a const reference to the arborescence map.
106.654 + ///
106.655 + /// Returns a const reference to the arborescence map.
106.656 + /// \pre \ref run() must be called before using this function.
106.657 + const ArborescenceMap& arborescenceMap() const {
106.658 + return *_arborescence;
106.659 + }
106.660 +
106.661 + /// \brief Returns the predecessor arc of the given node.
106.662 + ///
106.663 + /// Returns the predecessor arc of the given node.
106.664 + /// \pre \ref run() must be called before using this function.
106.665 + Arc pred(Node node) const {
106.666 + return (*_pred)[node];
106.667 + }
106.668 +
106.669 + /// \brief Returns a const reference to the pred map.
106.670 + ///
106.671 + /// Returns a const reference to the pred map.
106.672 + /// \pre \ref run() must be called before using this function.
106.673 + const PredMap& predMap() const {
106.674 + return *_pred;
106.675 + }
106.676 +
106.677 + /// \brief Indicates that a node is reachable from the sources.
106.678 + ///
106.679 + /// Indicates that a node is reachable from the sources.
106.680 + bool reached(Node node) const {
106.681 + return (*_node_order)[node] != -3;
106.682 + }
106.683 +
106.684 + /// \brief Indicates that a node is processed.
106.685 + ///
106.686 + /// Indicates that a node is processed. The arborescence path exists
106.687 + /// from the source to the given node.
106.688 + bool processed(Node node) const {
106.689 + return (*_node_order)[node] == -1;
106.690 + }
106.691 +
106.692 + /// \brief Returns the number of the dual variables in basis.
106.693 + ///
106.694 + /// Returns the number of the dual variables in basis.
106.695 + int dualNum() const {
106.696 + return _dual_variables.size();
106.697 + }
106.698 +
106.699 + /// \brief Returns the value of the dual solution.
106.700 + ///
106.701 + /// Returns the value of the dual solution. It should be
106.702 + /// equal to the arborescence value.
106.703 + Value dualValue() const {
106.704 + Value sum = 0;
106.705 + for (int i = 0; i < int(_dual_variables.size()); ++i) {
106.706 + sum += _dual_variables[i].value;
106.707 + }
106.708 + return sum;
106.709 + }
106.710 +
106.711 + /// \brief Returns the number of the nodes in the dual variable.
106.712 + ///
106.713 + /// Returns the number of the nodes in the dual variable.
106.714 + int dualSize(int k) const {
106.715 + return _dual_variables[k].end - _dual_variables[k].begin;
106.716 + }
106.717 +
106.718 + /// \brief Returns the value of the dual variable.
106.719 + ///
106.720 + /// Returns the the value of the dual variable.
106.721 + Value dualValue(int k) const {
106.722 + return _dual_variables[k].value;
106.723 + }
106.724 +
106.725 + /// \brief LEMON iterator for getting a dual variable.
106.726 + ///
106.727 + /// This class provides a common style LEMON iterator for getting a
106.728 + /// dual variable of \ref MinCostArborescence algorithm.
106.729 + /// It iterates over a subset of the nodes.
106.730 + class DualIt {
106.731 + public:
106.732 +
106.733 + /// \brief Constructor.
106.734 + ///
106.735 + /// Constructor for getting the nodeset of the dual variable
106.736 + /// of \ref MinCostArborescence algorithm.
106.737 + DualIt(const MinCostArborescence& algorithm, int variable)
106.738 + : _algorithm(&algorithm)
106.739 + {
106.740 + _index = _algorithm->_dual_variables[variable].begin;
106.741 + _last = _algorithm->_dual_variables[variable].end;
106.742 + }
106.743 +
106.744 + /// \brief Conversion to \c Node.
106.745 + ///
106.746 + /// Conversion to \c Node.
106.747 + operator Node() const {
106.748 + return _algorithm->_dual_node_list[_index];
106.749 + }
106.750 +
106.751 + /// \brief Increment operator.
106.752 + ///
106.753 + /// Increment operator.
106.754 + DualIt& operator++() {
106.755 + ++_index;
106.756 + return *this;
106.757 + }
106.758 +
106.759 + /// \brief Validity checking
106.760 + ///
106.761 + /// Checks whether the iterator is invalid.
106.762 + bool operator==(Invalid) const {
106.763 + return _index == _last;
106.764 + }
106.765 +
106.766 + /// \brief Validity checking
106.767 + ///
106.768 + /// Checks whether the iterator is valid.
106.769 + bool operator!=(Invalid) const {
106.770 + return _index != _last;
106.771 + }
106.772 +
106.773 + private:
106.774 + const MinCostArborescence* _algorithm;
106.775 + int _index, _last;
106.776 + };
106.777 +
106.778 + /// @}
106.779 +
106.780 + };
106.781 +
106.782 + /// \ingroup spantree
106.783 + ///
106.784 + /// \brief Function type interface for MinCostArborescence algorithm.
106.785 + ///
106.786 + /// Function type interface for MinCostArborescence algorithm.
106.787 + /// \param digraph The digraph the algorithm runs on.
106.788 + /// \param cost An arc map storing the costs.
106.789 + /// \param source The source node of the arborescence.
106.790 + /// \retval arborescence An arc map with \c bool (or convertible) value
106.791 + /// type that stores the arborescence.
106.792 + /// \return The total cost of the arborescence.
106.793 + ///
106.794 + /// \sa MinCostArborescence
106.795 + template <typename Digraph, typename CostMap, typename ArborescenceMap>
106.796 + typename CostMap::Value minCostArborescence(const Digraph& digraph,
106.797 + const CostMap& cost,
106.798 + typename Digraph::Node source,
106.799 + ArborescenceMap& arborescence) {
106.800 + typename MinCostArborescence<Digraph, CostMap>
106.801 + ::template SetArborescenceMap<ArborescenceMap>
106.802 + ::Create mca(digraph, cost);
106.803 + mca.arborescenceMap(arborescence);
106.804 + mca.run(source);
106.805 + return mca.arborescenceCost();
106.806 + }
106.807 +
106.808 +}
106.809 +
106.810 +#endif
107.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
107.2 +++ b/lemon/network_simplex.h Thu Nov 05 15:48:01 2009 +0100
107.3 @@ -0,0 +1,1485 @@
107.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
107.5 + *
107.6 + * This file is a part of LEMON, a generic C++ optimization library.
107.7 + *
107.8 + * Copyright (C) 2003-2009
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_NETWORK_SIMPLEX_H
107.23 +#define LEMON_NETWORK_SIMPLEX_H
107.24 +
107.25 +/// \ingroup min_cost_flow_algs
107.26 +///
107.27 +/// \file
107.28 +/// \brief Network Simplex algorithm for finding a minimum cost flow.
107.29 +
107.30 +#include <vector>
107.31 +#include <limits>
107.32 +#include <algorithm>
107.33 +
107.34 +#include <lemon/core.h>
107.35 +#include <lemon/math.h>
107.36 +
107.37 +namespace lemon {
107.38 +
107.39 + /// \addtogroup min_cost_flow_algs
107.40 + /// @{
107.41 +
107.42 + /// \brief Implementation of the primal Network Simplex algorithm
107.43 + /// for finding a \ref min_cost_flow "minimum cost flow".
107.44 + ///
107.45 + /// \ref NetworkSimplex implements the primal Network Simplex algorithm
107.46 + /// for finding a \ref min_cost_flow "minimum cost flow"
107.47 + /// \ref amo93networkflows, \ref dantzig63linearprog,
107.48 + /// \ref kellyoneill91netsimplex.
107.49 + /// This algorithm is a specialized version of the linear programming
107.50 + /// simplex method directly for the minimum cost flow problem.
107.51 + /// It is one of the most efficient solution methods.
107.52 + ///
107.53 + /// In general this class is the fastest implementation available
107.54 + /// in LEMON for the minimum cost flow problem.
107.55 + /// Moreover it supports both directions of the supply/demand inequality
107.56 + /// constraints. For more information see \ref SupplyType.
107.57 + ///
107.58 + /// Most of the parameters of the problem (except for the digraph)
107.59 + /// can be given using separate functions, and the algorithm can be
107.60 + /// executed using the \ref run() function. If some parameters are not
107.61 + /// specified, then default values will be used.
107.62 + ///
107.63 + /// \tparam GR The digraph type the algorithm runs on.
107.64 + /// \tparam V The value type used for flow amounts, capacity bounds
107.65 + /// and supply values in the algorithm. By default it is \c int.
107.66 + /// \tparam C The value type used for costs and potentials in the
107.67 + /// algorithm. By default it is the same as \c V.
107.68 + ///
107.69 + /// \warning Both value types must be signed and all input data must
107.70 + /// be integer.
107.71 + ///
107.72 + /// \note %NetworkSimplex provides five different pivot rule
107.73 + /// implementations, from which the most efficient one is used
107.74 + /// by default. For more information see \ref PivotRule.
107.75 + template <typename GR, typename V = int, typename C = V>
107.76 + class NetworkSimplex
107.77 + {
107.78 + public:
107.79 +
107.80 + /// The type of the flow amounts, capacity bounds and supply values
107.81 + typedef V Value;
107.82 + /// The type of the arc costs
107.83 + typedef C Cost;
107.84 +
107.85 + public:
107.86 +
107.87 + /// \brief Problem type constants for the \c run() function.
107.88 + ///
107.89 + /// Enum type containing the problem type constants that can be
107.90 + /// returned by the \ref run() function of the algorithm.
107.91 + enum ProblemType {
107.92 + /// The problem has no feasible solution (flow).
107.93 + INFEASIBLE,
107.94 + /// The problem has optimal solution (i.e. it is feasible and
107.95 + /// bounded), and the algorithm has found optimal flow and node
107.96 + /// potentials (primal and dual solutions).
107.97 + OPTIMAL,
107.98 + /// The objective function of the problem is unbounded, i.e.
107.99 + /// there is a directed cycle having negative total cost and
107.100 + /// infinite upper bound.
107.101 + UNBOUNDED
107.102 + };
107.103 +
107.104 + /// \brief Constants for selecting the type of the supply constraints.
107.105 + ///
107.106 + /// Enum type containing constants for selecting the supply type,
107.107 + /// i.e. the direction of the inequalities in the supply/demand
107.108 + /// constraints of the \ref min_cost_flow "minimum cost flow problem".
107.109 + ///
107.110 + /// The default supply type is \c GEQ, the \c LEQ type can be
107.111 + /// selected using \ref supplyType().
107.112 + /// The equality form is a special case of both supply types.
107.113 + enum SupplyType {
107.114 + /// This option means that there are <em>"greater or equal"</em>
107.115 + /// supply/demand constraints in the definition of the problem.
107.116 + GEQ,
107.117 + /// This option means that there are <em>"less or equal"</em>
107.118 + /// supply/demand constraints in the definition of the problem.
107.119 + LEQ
107.120 + };
107.121 +
107.122 + /// \brief Constants for selecting the pivot rule.
107.123 + ///
107.124 + /// Enum type containing constants for selecting the pivot rule for
107.125 + /// the \ref run() function.
107.126 + ///
107.127 + /// \ref NetworkSimplex provides five different pivot rule
107.128 + /// implementations that significantly affect the running time
107.129 + /// of the algorithm.
107.130 + /// By default \ref BLOCK_SEARCH "Block Search" is used, which
107.131 + /// proved to be the most efficient and the most robust on various
107.132 + /// test inputs according to our benchmark tests.
107.133 + /// However another pivot rule can be selected using the \ref run()
107.134 + /// function with the proper parameter.
107.135 + enum PivotRule {
107.136 +
107.137 + /// The First Eligible pivot rule.
107.138 + /// The next eligible arc is selected in a wraparound fashion
107.139 + /// in every iteration.
107.140 + FIRST_ELIGIBLE,
107.141 +
107.142 + /// The Best Eligible pivot rule.
107.143 + /// The best eligible arc is selected in every iteration.
107.144 + BEST_ELIGIBLE,
107.145 +
107.146 + /// The Block Search pivot rule.
107.147 + /// A specified number of arcs are examined in every iteration
107.148 + /// in a wraparound fashion and the best eligible arc is selected
107.149 + /// from this block.
107.150 + BLOCK_SEARCH,
107.151 +
107.152 + /// The Candidate List pivot rule.
107.153 + /// In a major iteration a candidate list is built from eligible arcs
107.154 + /// in a wraparound fashion and in the following minor iterations
107.155 + /// the best eligible arc is selected from this list.
107.156 + CANDIDATE_LIST,
107.157 +
107.158 + /// The Altering Candidate List pivot rule.
107.159 + /// It is a modified version of the Candidate List method.
107.160 + /// It keeps only the several best eligible arcs from the former
107.161 + /// candidate list and extends this list in every iteration.
107.162 + ALTERING_LIST
107.163 + };
107.164 +
107.165 + private:
107.166 +
107.167 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
107.168 +
107.169 + typedef std::vector<int> IntVector;
107.170 + typedef std::vector<bool> BoolVector;
107.171 + typedef std::vector<Value> ValueVector;
107.172 + typedef std::vector<Cost> CostVector;
107.173 +
107.174 + // State constants for arcs
107.175 + enum ArcStateEnum {
107.176 + STATE_UPPER = -1,
107.177 + STATE_TREE = 0,
107.178 + STATE_LOWER = 1
107.179 + };
107.180 +
107.181 + private:
107.182 +
107.183 + // Data related to the underlying digraph
107.184 + const GR &_graph;
107.185 + int _node_num;
107.186 + int _arc_num;
107.187 + int _all_arc_num;
107.188 + int _search_arc_num;
107.189 +
107.190 + // Parameters of the problem
107.191 + bool _have_lower;
107.192 + SupplyType _stype;
107.193 + Value _sum_supply;
107.194 +
107.195 + // Data structures for storing the digraph
107.196 + IntNodeMap _node_id;
107.197 + IntArcMap _arc_id;
107.198 + IntVector _source;
107.199 + IntVector _target;
107.200 +
107.201 + // Node and arc data
107.202 + ValueVector _lower;
107.203 + ValueVector _upper;
107.204 + ValueVector _cap;
107.205 + CostVector _cost;
107.206 + ValueVector _supply;
107.207 + ValueVector _flow;
107.208 + CostVector _pi;
107.209 +
107.210 + // Data for storing the spanning tree structure
107.211 + IntVector _parent;
107.212 + IntVector _pred;
107.213 + IntVector _thread;
107.214 + IntVector _rev_thread;
107.215 + IntVector _succ_num;
107.216 + IntVector _last_succ;
107.217 + IntVector _dirty_revs;
107.218 + BoolVector _forward;
107.219 + IntVector _state;
107.220 + int _root;
107.221 +
107.222 + // Temporary data used in the current pivot iteration
107.223 + int in_arc, join, u_in, v_in, u_out, v_out;
107.224 + int first, second, right, last;
107.225 + int stem, par_stem, new_stem;
107.226 + Value delta;
107.227 +
107.228 + public:
107.229 +
107.230 + /// \brief Constant for infinite upper bounds (capacities).
107.231 + ///
107.232 + /// Constant for infinite upper bounds (capacities).
107.233 + /// It is \c std::numeric_limits<Value>::infinity() if available,
107.234 + /// \c std::numeric_limits<Value>::max() otherwise.
107.235 + const Value INF;
107.236 +
107.237 + private:
107.238 +
107.239 + // Implementation of the First Eligible pivot rule
107.240 + class FirstEligiblePivotRule
107.241 + {
107.242 + private:
107.243 +
107.244 + // References to the NetworkSimplex class
107.245 + const IntVector &_source;
107.246 + const IntVector &_target;
107.247 + const CostVector &_cost;
107.248 + const IntVector &_state;
107.249 + const CostVector &_pi;
107.250 + int &_in_arc;
107.251 + int _search_arc_num;
107.252 +
107.253 + // Pivot rule data
107.254 + int _next_arc;
107.255 +
107.256 + public:
107.257 +
107.258 + // Constructor
107.259 + FirstEligiblePivotRule(NetworkSimplex &ns) :
107.260 + _source(ns._source), _target(ns._target),
107.261 + _cost(ns._cost), _state(ns._state), _pi(ns._pi),
107.262 + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
107.263 + _next_arc(0)
107.264 + {}
107.265 +
107.266 + // Find next entering arc
107.267 + bool findEnteringArc() {
107.268 + Cost c;
107.269 + for (int e = _next_arc; e < _search_arc_num; ++e) {
107.270 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
107.271 + if (c < 0) {
107.272 + _in_arc = e;
107.273 + _next_arc = e + 1;
107.274 + return true;
107.275 + }
107.276 + }
107.277 + for (int e = 0; e < _next_arc; ++e) {
107.278 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
107.279 + if (c < 0) {
107.280 + _in_arc = e;
107.281 + _next_arc = e + 1;
107.282 + return true;
107.283 + }
107.284 + }
107.285 + return false;
107.286 + }
107.287 +
107.288 + }; //class FirstEligiblePivotRule
107.289 +
107.290 +
107.291 + // Implementation of the Best Eligible pivot rule
107.292 + class BestEligiblePivotRule
107.293 + {
107.294 + private:
107.295 +
107.296 + // References to the NetworkSimplex class
107.297 + const IntVector &_source;
107.298 + const IntVector &_target;
107.299 + const CostVector &_cost;
107.300 + const IntVector &_state;
107.301 + const CostVector &_pi;
107.302 + int &_in_arc;
107.303 + int _search_arc_num;
107.304 +
107.305 + public:
107.306 +
107.307 + // Constructor
107.308 + BestEligiblePivotRule(NetworkSimplex &ns) :
107.309 + _source(ns._source), _target(ns._target),
107.310 + _cost(ns._cost), _state(ns._state), _pi(ns._pi),
107.311 + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num)
107.312 + {}
107.313 +
107.314 + // Find next entering arc
107.315 + bool findEnteringArc() {
107.316 + Cost c, min = 0;
107.317 + for (int e = 0; e < _search_arc_num; ++e) {
107.318 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
107.319 + if (c < min) {
107.320 + min = c;
107.321 + _in_arc = e;
107.322 + }
107.323 + }
107.324 + return min < 0;
107.325 + }
107.326 +
107.327 + }; //class BestEligiblePivotRule
107.328 +
107.329 +
107.330 + // Implementation of the Block Search pivot rule
107.331 + class BlockSearchPivotRule
107.332 + {
107.333 + private:
107.334 +
107.335 + // References to the NetworkSimplex class
107.336 + const IntVector &_source;
107.337 + const IntVector &_target;
107.338 + const CostVector &_cost;
107.339 + const IntVector &_state;
107.340 + const CostVector &_pi;
107.341 + int &_in_arc;
107.342 + int _search_arc_num;
107.343 +
107.344 + // Pivot rule data
107.345 + int _block_size;
107.346 + int _next_arc;
107.347 +
107.348 + public:
107.349 +
107.350 + // Constructor
107.351 + BlockSearchPivotRule(NetworkSimplex &ns) :
107.352 + _source(ns._source), _target(ns._target),
107.353 + _cost(ns._cost), _state(ns._state), _pi(ns._pi),
107.354 + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
107.355 + _next_arc(0)
107.356 + {
107.357 + // The main parameters of the pivot rule
107.358 + const double BLOCK_SIZE_FACTOR = 0.5;
107.359 + const int MIN_BLOCK_SIZE = 10;
107.360 +
107.361 + _block_size = std::max( int(BLOCK_SIZE_FACTOR *
107.362 + std::sqrt(double(_search_arc_num))),
107.363 + MIN_BLOCK_SIZE );
107.364 + }
107.365 +
107.366 + // Find next entering arc
107.367 + bool findEnteringArc() {
107.368 + Cost c, min = 0;
107.369 + int cnt = _block_size;
107.370 + int e;
107.371 + for (e = _next_arc; e < _search_arc_num; ++e) {
107.372 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
107.373 + if (c < min) {
107.374 + min = c;
107.375 + _in_arc = e;
107.376 + }
107.377 + if (--cnt == 0) {
107.378 + if (min < 0) goto search_end;
107.379 + cnt = _block_size;
107.380 + }
107.381 + }
107.382 + for (e = 0; e < _next_arc; ++e) {
107.383 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
107.384 + if (c < min) {
107.385 + min = c;
107.386 + _in_arc = e;
107.387 + }
107.388 + if (--cnt == 0) {
107.389 + if (min < 0) goto search_end;
107.390 + cnt = _block_size;
107.391 + }
107.392 + }
107.393 + if (min >= 0) return false;
107.394 +
107.395 + search_end:
107.396 + _next_arc = e;
107.397 + return true;
107.398 + }
107.399 +
107.400 + }; //class BlockSearchPivotRule
107.401 +
107.402 +
107.403 + // Implementation of the Candidate List pivot rule
107.404 + class CandidateListPivotRule
107.405 + {
107.406 + private:
107.407 +
107.408 + // References to the NetworkSimplex class
107.409 + const IntVector &_source;
107.410 + const IntVector &_target;
107.411 + const CostVector &_cost;
107.412 + const IntVector &_state;
107.413 + const CostVector &_pi;
107.414 + int &_in_arc;
107.415 + int _search_arc_num;
107.416 +
107.417 + // Pivot rule data
107.418 + IntVector _candidates;
107.419 + int _list_length, _minor_limit;
107.420 + int _curr_length, _minor_count;
107.421 + int _next_arc;
107.422 +
107.423 + public:
107.424 +
107.425 + /// Constructor
107.426 + CandidateListPivotRule(NetworkSimplex &ns) :
107.427 + _source(ns._source), _target(ns._target),
107.428 + _cost(ns._cost), _state(ns._state), _pi(ns._pi),
107.429 + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
107.430 + _next_arc(0)
107.431 + {
107.432 + // The main parameters of the pivot rule
107.433 + const double LIST_LENGTH_FACTOR = 0.25;
107.434 + const int MIN_LIST_LENGTH = 10;
107.435 + const double MINOR_LIMIT_FACTOR = 0.1;
107.436 + const int MIN_MINOR_LIMIT = 3;
107.437 +
107.438 + _list_length = std::max( int(LIST_LENGTH_FACTOR *
107.439 + std::sqrt(double(_search_arc_num))),
107.440 + MIN_LIST_LENGTH );
107.441 + _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
107.442 + MIN_MINOR_LIMIT );
107.443 + _curr_length = _minor_count = 0;
107.444 + _candidates.resize(_list_length);
107.445 + }
107.446 +
107.447 + /// Find next entering arc
107.448 + bool findEnteringArc() {
107.449 + Cost min, c;
107.450 + int e;
107.451 + if (_curr_length > 0 && _minor_count < _minor_limit) {
107.452 + // Minor iteration: select the best eligible arc from the
107.453 + // current candidate list
107.454 + ++_minor_count;
107.455 + min = 0;
107.456 + for (int i = 0; i < _curr_length; ++i) {
107.457 + e = _candidates[i];
107.458 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
107.459 + if (c < min) {
107.460 + min = c;
107.461 + _in_arc = e;
107.462 + }
107.463 + else if (c >= 0) {
107.464 + _candidates[i--] = _candidates[--_curr_length];
107.465 + }
107.466 + }
107.467 + if (min < 0) return true;
107.468 + }
107.469 +
107.470 + // Major iteration: build a new candidate list
107.471 + min = 0;
107.472 + _curr_length = 0;
107.473 + for (e = _next_arc; e < _search_arc_num; ++e) {
107.474 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
107.475 + if (c < 0) {
107.476 + _candidates[_curr_length++] = e;
107.477 + if (c < min) {
107.478 + min = c;
107.479 + _in_arc = e;
107.480 + }
107.481 + if (_curr_length == _list_length) goto search_end;
107.482 + }
107.483 + }
107.484 + for (e = 0; e < _next_arc; ++e) {
107.485 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
107.486 + if (c < 0) {
107.487 + _candidates[_curr_length++] = e;
107.488 + if (c < min) {
107.489 + min = c;
107.490 + _in_arc = e;
107.491 + }
107.492 + if (_curr_length == _list_length) goto search_end;
107.493 + }
107.494 + }
107.495 + if (_curr_length == 0) return false;
107.496 +
107.497 + search_end:
107.498 + _minor_count = 1;
107.499 + _next_arc = e;
107.500 + return true;
107.501 + }
107.502 +
107.503 + }; //class CandidateListPivotRule
107.504 +
107.505 +
107.506 + // Implementation of the Altering Candidate List pivot rule
107.507 + class AlteringListPivotRule
107.508 + {
107.509 + private:
107.510 +
107.511 + // References to the NetworkSimplex class
107.512 + const IntVector &_source;
107.513 + const IntVector &_target;
107.514 + const CostVector &_cost;
107.515 + const IntVector &_state;
107.516 + const CostVector &_pi;
107.517 + int &_in_arc;
107.518 + int _search_arc_num;
107.519 +
107.520 + // Pivot rule data
107.521 + int _block_size, _head_length, _curr_length;
107.522 + int _next_arc;
107.523 + IntVector _candidates;
107.524 + CostVector _cand_cost;
107.525 +
107.526 + // Functor class to compare arcs during sort of the candidate list
107.527 + class SortFunc
107.528 + {
107.529 + private:
107.530 + const CostVector &_map;
107.531 + public:
107.532 + SortFunc(const CostVector &map) : _map(map) {}
107.533 + bool operator()(int left, int right) {
107.534 + return _map[left] > _map[right];
107.535 + }
107.536 + };
107.537 +
107.538 + SortFunc _sort_func;
107.539 +
107.540 + public:
107.541 +
107.542 + // Constructor
107.543 + AlteringListPivotRule(NetworkSimplex &ns) :
107.544 + _source(ns._source), _target(ns._target),
107.545 + _cost(ns._cost), _state(ns._state), _pi(ns._pi),
107.546 + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
107.547 + _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
107.548 + {
107.549 + // The main parameters of the pivot rule
107.550 + const double BLOCK_SIZE_FACTOR = 1.0;
107.551 + const int MIN_BLOCK_SIZE = 10;
107.552 + const double HEAD_LENGTH_FACTOR = 0.1;
107.553 + const int MIN_HEAD_LENGTH = 3;
107.554 +
107.555 + _block_size = std::max( int(BLOCK_SIZE_FACTOR *
107.556 + std::sqrt(double(_search_arc_num))),
107.557 + MIN_BLOCK_SIZE );
107.558 + _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
107.559 + MIN_HEAD_LENGTH );
107.560 + _candidates.resize(_head_length + _block_size);
107.561 + _curr_length = 0;
107.562 + }
107.563 +
107.564 + // Find next entering arc
107.565 + bool findEnteringArc() {
107.566 + // Check the current candidate list
107.567 + int e;
107.568 + for (int i = 0; i < _curr_length; ++i) {
107.569 + e = _candidates[i];
107.570 + _cand_cost[e] = _state[e] *
107.571 + (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
107.572 + if (_cand_cost[e] >= 0) {
107.573 + _candidates[i--] = _candidates[--_curr_length];
107.574 + }
107.575 + }
107.576 +
107.577 + // Extend the list
107.578 + int cnt = _block_size;
107.579 + int limit = _head_length;
107.580 +
107.581 + for (e = _next_arc; e < _search_arc_num; ++e) {
107.582 + _cand_cost[e] = _state[e] *
107.583 + (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
107.584 + if (_cand_cost[e] < 0) {
107.585 + _candidates[_curr_length++] = e;
107.586 + }
107.587 + if (--cnt == 0) {
107.588 + if (_curr_length > limit) goto search_end;
107.589 + limit = 0;
107.590 + cnt = _block_size;
107.591 + }
107.592 + }
107.593 + for (e = 0; e < _next_arc; ++e) {
107.594 + _cand_cost[e] = _state[e] *
107.595 + (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
107.596 + if (_cand_cost[e] < 0) {
107.597 + _candidates[_curr_length++] = e;
107.598 + }
107.599 + if (--cnt == 0) {
107.600 + if (_curr_length > limit) goto search_end;
107.601 + limit = 0;
107.602 + cnt = _block_size;
107.603 + }
107.604 + }
107.605 + if (_curr_length == 0) return false;
107.606 +
107.607 + search_end:
107.608 +
107.609 + // Make heap of the candidate list (approximating a partial sort)
107.610 + make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
107.611 + _sort_func );
107.612 +
107.613 + // Pop the first element of the heap
107.614 + _in_arc = _candidates[0];
107.615 + _next_arc = e;
107.616 + pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
107.617 + _sort_func );
107.618 + _curr_length = std::min(_head_length, _curr_length - 1);
107.619 + return true;
107.620 + }
107.621 +
107.622 + }; //class AlteringListPivotRule
107.623 +
107.624 + public:
107.625 +
107.626 + /// \brief Constructor.
107.627 + ///
107.628 + /// The constructor of the class.
107.629 + ///
107.630 + /// \param graph The digraph the algorithm runs on.
107.631 + /// \param arc_mixing Indicate if the arcs have to be stored in a
107.632 + /// mixed order in the internal data structure.
107.633 + /// In special cases, it could lead to better overall performance,
107.634 + /// but it is usually slower. Therefore it is disabled by default.
107.635 + NetworkSimplex(const GR& graph, bool arc_mixing = false) :
107.636 + _graph(graph), _node_id(graph), _arc_id(graph),
107.637 + INF(std::numeric_limits<Value>::has_infinity ?
107.638 + std::numeric_limits<Value>::infinity() :
107.639 + std::numeric_limits<Value>::max())
107.640 + {
107.641 + // Check the value types
107.642 + LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
107.643 + "The flow type of NetworkSimplex must be signed");
107.644 + LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
107.645 + "The cost type of NetworkSimplex must be signed");
107.646 +
107.647 + // Resize vectors
107.648 + _node_num = countNodes(_graph);
107.649 + _arc_num = countArcs(_graph);
107.650 + int all_node_num = _node_num + 1;
107.651 + int max_arc_num = _arc_num + 2 * _node_num;
107.652 +
107.653 + _source.resize(max_arc_num);
107.654 + _target.resize(max_arc_num);
107.655 +
107.656 + _lower.resize(_arc_num);
107.657 + _upper.resize(_arc_num);
107.658 + _cap.resize(max_arc_num);
107.659 + _cost.resize(max_arc_num);
107.660 + _supply.resize(all_node_num);
107.661 + _flow.resize(max_arc_num);
107.662 + _pi.resize(all_node_num);
107.663 +
107.664 + _parent.resize(all_node_num);
107.665 + _pred.resize(all_node_num);
107.666 + _forward.resize(all_node_num);
107.667 + _thread.resize(all_node_num);
107.668 + _rev_thread.resize(all_node_num);
107.669 + _succ_num.resize(all_node_num);
107.670 + _last_succ.resize(all_node_num);
107.671 + _state.resize(max_arc_num);
107.672 +
107.673 + // Copy the graph
107.674 + int i = 0;
107.675 + for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
107.676 + _node_id[n] = i;
107.677 + }
107.678 + if (arc_mixing) {
107.679 + // Store the arcs in a mixed order
107.680 + int k = std::max(int(std::sqrt(double(_arc_num))), 10);
107.681 + int i = 0, j = 0;
107.682 + for (ArcIt a(_graph); a != INVALID; ++a) {
107.683 + _arc_id[a] = i;
107.684 + _source[i] = _node_id[_graph.source(a)];
107.685 + _target[i] = _node_id[_graph.target(a)];
107.686 + if ((i += k) >= _arc_num) i = ++j;
107.687 + }
107.688 + } else {
107.689 + // Store the arcs in the original order
107.690 + int i = 0;
107.691 + for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
107.692 + _arc_id[a] = i;
107.693 + _source[i] = _node_id[_graph.source(a)];
107.694 + _target[i] = _node_id[_graph.target(a)];
107.695 + }
107.696 + }
107.697 +
107.698 + // Reset parameters
107.699 + reset();
107.700 + }
107.701 +
107.702 + /// \name Parameters
107.703 + /// The parameters of the algorithm can be specified using these
107.704 + /// functions.
107.705 +
107.706 + /// @{
107.707 +
107.708 + /// \brief Set the lower bounds on the arcs.
107.709 + ///
107.710 + /// This function sets the lower bounds on the arcs.
107.711 + /// If it is not used before calling \ref run(), the lower bounds
107.712 + /// will be set to zero on all arcs.
107.713 + ///
107.714 + /// \param map An arc map storing the lower bounds.
107.715 + /// Its \c Value type must be convertible to the \c Value type
107.716 + /// of the algorithm.
107.717 + ///
107.718 + /// \return <tt>(*this)</tt>
107.719 + template <typename LowerMap>
107.720 + NetworkSimplex& lowerMap(const LowerMap& map) {
107.721 + _have_lower = true;
107.722 + for (ArcIt a(_graph); a != INVALID; ++a) {
107.723 + _lower[_arc_id[a]] = map[a];
107.724 + }
107.725 + return *this;
107.726 + }
107.727 +
107.728 + /// \brief Set the upper bounds (capacities) on the arcs.
107.729 + ///
107.730 + /// This function sets the upper bounds (capacities) on the arcs.
107.731 + /// If it is not used before calling \ref run(), the upper bounds
107.732 + /// will be set to \ref INF on all arcs (i.e. the flow value will be
107.733 + /// unbounded from above on each arc).
107.734 + ///
107.735 + /// \param map An arc map storing the upper bounds.
107.736 + /// Its \c Value type must be convertible to the \c Value type
107.737 + /// of the algorithm.
107.738 + ///
107.739 + /// \return <tt>(*this)</tt>
107.740 + template<typename UpperMap>
107.741 + NetworkSimplex& upperMap(const UpperMap& map) {
107.742 + for (ArcIt a(_graph); a != INVALID; ++a) {
107.743 + _upper[_arc_id[a]] = map[a];
107.744 + }
107.745 + return *this;
107.746 + }
107.747 +
107.748 + /// \brief Set the costs of the arcs.
107.749 + ///
107.750 + /// This function sets the costs of the arcs.
107.751 + /// If it is not used before calling \ref run(), the costs
107.752 + /// will be set to \c 1 on all arcs.
107.753 + ///
107.754 + /// \param map An arc map storing the costs.
107.755 + /// Its \c Value type must be convertible to the \c Cost type
107.756 + /// of the algorithm.
107.757 + ///
107.758 + /// \return <tt>(*this)</tt>
107.759 + template<typename CostMap>
107.760 + NetworkSimplex& costMap(const CostMap& map) {
107.761 + for (ArcIt a(_graph); a != INVALID; ++a) {
107.762 + _cost[_arc_id[a]] = map[a];
107.763 + }
107.764 + return *this;
107.765 + }
107.766 +
107.767 + /// \brief Set the supply values of the nodes.
107.768 + ///
107.769 + /// This function sets the supply values of the nodes.
107.770 + /// If neither this function nor \ref stSupply() is used before
107.771 + /// calling \ref run(), the supply of each node will be set to zero.
107.772 + ///
107.773 + /// \param map A node map storing the supply values.
107.774 + /// Its \c Value type must be convertible to the \c Value type
107.775 + /// of the algorithm.
107.776 + ///
107.777 + /// \return <tt>(*this)</tt>
107.778 + template<typename SupplyMap>
107.779 + NetworkSimplex& supplyMap(const SupplyMap& map) {
107.780 + for (NodeIt n(_graph); n != INVALID; ++n) {
107.781 + _supply[_node_id[n]] = map[n];
107.782 + }
107.783 + return *this;
107.784 + }
107.785 +
107.786 + /// \brief Set single source and target nodes and a supply value.
107.787 + ///
107.788 + /// This function sets a single source node and a single target node
107.789 + /// and the required flow value.
107.790 + /// If neither this function nor \ref supplyMap() is used before
107.791 + /// calling \ref run(), the supply of each node will be set to zero.
107.792 + ///
107.793 + /// Using this function has the same effect as using \ref supplyMap()
107.794 + /// with such a map in which \c k is assigned to \c s, \c -k is
107.795 + /// assigned to \c t and all other nodes have zero supply value.
107.796 + ///
107.797 + /// \param s The source node.
107.798 + /// \param t The target node.
107.799 + /// \param k The required amount of flow from node \c s to node \c t
107.800 + /// (i.e. the supply of \c s and the demand of \c t).
107.801 + ///
107.802 + /// \return <tt>(*this)</tt>
107.803 + NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
107.804 + for (int i = 0; i != _node_num; ++i) {
107.805 + _supply[i] = 0;
107.806 + }
107.807 + _supply[_node_id[s]] = k;
107.808 + _supply[_node_id[t]] = -k;
107.809 + return *this;
107.810 + }
107.811 +
107.812 + /// \brief Set the type of the supply constraints.
107.813 + ///
107.814 + /// This function sets the type of the supply/demand constraints.
107.815 + /// If it is not used before calling \ref run(), the \ref GEQ supply
107.816 + /// type will be used.
107.817 + ///
107.818 + /// For more information see \ref SupplyType.
107.819 + ///
107.820 + /// \return <tt>(*this)</tt>
107.821 + NetworkSimplex& supplyType(SupplyType supply_type) {
107.822 + _stype = supply_type;
107.823 + return *this;
107.824 + }
107.825 +
107.826 + /// @}
107.827 +
107.828 + /// \name Execution Control
107.829 + /// The algorithm can be executed using \ref run().
107.830 +
107.831 + /// @{
107.832 +
107.833 + /// \brief Run the algorithm.
107.834 + ///
107.835 + /// This function runs the algorithm.
107.836 + /// The paramters can be specified using functions \ref lowerMap(),
107.837 + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
107.838 + /// \ref supplyType().
107.839 + /// For example,
107.840 + /// \code
107.841 + /// NetworkSimplex<ListDigraph> ns(graph);
107.842 + /// ns.lowerMap(lower).upperMap(upper).costMap(cost)
107.843 + /// .supplyMap(sup).run();
107.844 + /// \endcode
107.845 + ///
107.846 + /// This function can be called more than once. All the parameters
107.847 + /// that have been given are kept for the next call, unless
107.848 + /// \ref reset() is called, thus only the modified parameters
107.849 + /// have to be set again. See \ref reset() for examples.
107.850 + /// However the underlying digraph must not be modified after this
107.851 + /// class have been constructed, since it copies and extends the graph.
107.852 + ///
107.853 + /// \param pivot_rule The pivot rule that will be used during the
107.854 + /// algorithm. For more information see \ref PivotRule.
107.855 + ///
107.856 + /// \return \c INFEASIBLE if no feasible flow exists,
107.857 + /// \n \c OPTIMAL if the problem has optimal solution
107.858 + /// (i.e. it is feasible and bounded), and the algorithm has found
107.859 + /// optimal flow and node potentials (primal and dual solutions),
107.860 + /// \n \c UNBOUNDED if the objective function of the problem is
107.861 + /// unbounded, i.e. there is a directed cycle having negative total
107.862 + /// cost and infinite upper bound.
107.863 + ///
107.864 + /// \see ProblemType, PivotRule
107.865 + ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
107.866 + if (!init()) return INFEASIBLE;
107.867 + return start(pivot_rule);
107.868 + }
107.869 +
107.870 + /// \brief Reset all the parameters that have been given before.
107.871 + ///
107.872 + /// This function resets all the paramaters that have been given
107.873 + /// before using functions \ref lowerMap(), \ref upperMap(),
107.874 + /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
107.875 + ///
107.876 + /// It is useful for multiple run() calls. If this function is not
107.877 + /// used, all the parameters given before are kept for the next
107.878 + /// \ref run() call.
107.879 + /// However the underlying digraph must not be modified after this
107.880 + /// class have been constructed, since it copies and extends the graph.
107.881 + ///
107.882 + /// For example,
107.883 + /// \code
107.884 + /// NetworkSimplex<ListDigraph> ns(graph);
107.885 + ///
107.886 + /// // First run
107.887 + /// ns.lowerMap(lower).upperMap(upper).costMap(cost)
107.888 + /// .supplyMap(sup).run();
107.889 + ///
107.890 + /// // Run again with modified cost map (reset() is not called,
107.891 + /// // so only the cost map have to be set again)
107.892 + /// cost[e] += 100;
107.893 + /// ns.costMap(cost).run();
107.894 + ///
107.895 + /// // Run again from scratch using reset()
107.896 + /// // (the lower bounds will be set to zero on all arcs)
107.897 + /// ns.reset();
107.898 + /// ns.upperMap(capacity).costMap(cost)
107.899 + /// .supplyMap(sup).run();
107.900 + /// \endcode
107.901 + ///
107.902 + /// \return <tt>(*this)</tt>
107.903 + NetworkSimplex& reset() {
107.904 + for (int i = 0; i != _node_num; ++i) {
107.905 + _supply[i] = 0;
107.906 + }
107.907 + for (int i = 0; i != _arc_num; ++i) {
107.908 + _lower[i] = 0;
107.909 + _upper[i] = INF;
107.910 + _cost[i] = 1;
107.911 + }
107.912 + _have_lower = false;
107.913 + _stype = GEQ;
107.914 + return *this;
107.915 + }
107.916 +
107.917 + /// @}
107.918 +
107.919 + /// \name Query Functions
107.920 + /// The results of the algorithm can be obtained using these
107.921 + /// functions.\n
107.922 + /// The \ref run() function must be called before using them.
107.923 +
107.924 + /// @{
107.925 +
107.926 + /// \brief Return the total cost of the found flow.
107.927 + ///
107.928 + /// This function returns the total cost of the found flow.
107.929 + /// Its complexity is O(e).
107.930 + ///
107.931 + /// \note The return type of the function can be specified as a
107.932 + /// template parameter. For example,
107.933 + /// \code
107.934 + /// ns.totalCost<double>();
107.935 + /// \endcode
107.936 + /// It is useful if the total cost cannot be stored in the \c Cost
107.937 + /// type of the algorithm, which is the default return type of the
107.938 + /// function.
107.939 + ///
107.940 + /// \pre \ref run() must be called before using this function.
107.941 + template <typename Number>
107.942 + Number totalCost() const {
107.943 + Number c = 0;
107.944 + for (ArcIt a(_graph); a != INVALID; ++a) {
107.945 + int i = _arc_id[a];
107.946 + c += Number(_flow[i]) * Number(_cost[i]);
107.947 + }
107.948 + return c;
107.949 + }
107.950 +
107.951 +#ifndef DOXYGEN
107.952 + Cost totalCost() const {
107.953 + return totalCost<Cost>();
107.954 + }
107.955 +#endif
107.956 +
107.957 + /// \brief Return the flow on the given arc.
107.958 + ///
107.959 + /// This function returns the flow on the given arc.
107.960 + ///
107.961 + /// \pre \ref run() must be called before using this function.
107.962 + Value flow(const Arc& a) const {
107.963 + return _flow[_arc_id[a]];
107.964 + }
107.965 +
107.966 + /// \brief Return the flow map (the primal solution).
107.967 + ///
107.968 + /// This function copies the flow value on each arc into the given
107.969 + /// map. The \c Value type of the algorithm must be convertible to
107.970 + /// the \c Value type of the map.
107.971 + ///
107.972 + /// \pre \ref run() must be called before using this function.
107.973 + template <typename FlowMap>
107.974 + void flowMap(FlowMap &map) const {
107.975 + for (ArcIt a(_graph); a != INVALID; ++a) {
107.976 + map.set(a, _flow[_arc_id[a]]);
107.977 + }
107.978 + }
107.979 +
107.980 + /// \brief Return the potential (dual value) of the given node.
107.981 + ///
107.982 + /// This function returns the potential (dual value) of the
107.983 + /// given node.
107.984 + ///
107.985 + /// \pre \ref run() must be called before using this function.
107.986 + Cost potential(const Node& n) const {
107.987 + return _pi[_node_id[n]];
107.988 + }
107.989 +
107.990 + /// \brief Return the potential map (the dual solution).
107.991 + ///
107.992 + /// This function copies the potential (dual value) of each node
107.993 + /// into the given map.
107.994 + /// The \c Cost type of the algorithm must be convertible to the
107.995 + /// \c Value type of the map.
107.996 + ///
107.997 + /// \pre \ref run() must be called before using this function.
107.998 + template <typename PotentialMap>
107.999 + void potentialMap(PotentialMap &map) const {
107.1000 + for (NodeIt n(_graph); n != INVALID; ++n) {
107.1001 + map.set(n, _pi[_node_id[n]]);
107.1002 + }
107.1003 + }
107.1004 +
107.1005 + /// @}
107.1006 +
107.1007 + private:
107.1008 +
107.1009 + // Initialize internal data structures
107.1010 + bool init() {
107.1011 + if (_node_num == 0) return false;
107.1012 +
107.1013 + // Check the sum of supply values
107.1014 + _sum_supply = 0;
107.1015 + for (int i = 0; i != _node_num; ++i) {
107.1016 + _sum_supply += _supply[i];
107.1017 + }
107.1018 + if ( !((_stype == GEQ && _sum_supply <= 0) ||
107.1019 + (_stype == LEQ && _sum_supply >= 0)) ) return false;
107.1020 +
107.1021 + // Remove non-zero lower bounds
107.1022 + if (_have_lower) {
107.1023 + for (int i = 0; i != _arc_num; ++i) {
107.1024 + Value c = _lower[i];
107.1025 + if (c >= 0) {
107.1026 + _cap[i] = _upper[i] < INF ? _upper[i] - c : INF;
107.1027 + } else {
107.1028 + _cap[i] = _upper[i] < INF + c ? _upper[i] - c : INF;
107.1029 + }
107.1030 + _supply[_source[i]] -= c;
107.1031 + _supply[_target[i]] += c;
107.1032 + }
107.1033 + } else {
107.1034 + for (int i = 0; i != _arc_num; ++i) {
107.1035 + _cap[i] = _upper[i];
107.1036 + }
107.1037 + }
107.1038 +
107.1039 + // Initialize artifical cost
107.1040 + Cost ART_COST;
107.1041 + if (std::numeric_limits<Cost>::is_exact) {
107.1042 + ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
107.1043 + } else {
107.1044 + ART_COST = std::numeric_limits<Cost>::min();
107.1045 + for (int i = 0; i != _arc_num; ++i) {
107.1046 + if (_cost[i] > ART_COST) ART_COST = _cost[i];
107.1047 + }
107.1048 + ART_COST = (ART_COST + 1) * _node_num;
107.1049 + }
107.1050 +
107.1051 + // Initialize arc maps
107.1052 + for (int i = 0; i != _arc_num; ++i) {
107.1053 + _flow[i] = 0;
107.1054 + _state[i] = STATE_LOWER;
107.1055 + }
107.1056 +
107.1057 + // Set data for the artificial root node
107.1058 + _root = _node_num;
107.1059 + _parent[_root] = -1;
107.1060 + _pred[_root] = -1;
107.1061 + _thread[_root] = 0;
107.1062 + _rev_thread[0] = _root;
107.1063 + _succ_num[_root] = _node_num + 1;
107.1064 + _last_succ[_root] = _root - 1;
107.1065 + _supply[_root] = -_sum_supply;
107.1066 + _pi[_root] = 0;
107.1067 +
107.1068 + // Add artificial arcs and initialize the spanning tree data structure
107.1069 + if (_sum_supply == 0) {
107.1070 + // EQ supply constraints
107.1071 + _search_arc_num = _arc_num;
107.1072 + _all_arc_num = _arc_num + _node_num;
107.1073 + for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
107.1074 + _parent[u] = _root;
107.1075 + _pred[u] = e;
107.1076 + _thread[u] = u + 1;
107.1077 + _rev_thread[u + 1] = u;
107.1078 + _succ_num[u] = 1;
107.1079 + _last_succ[u] = u;
107.1080 + _cap[e] = INF;
107.1081 + _state[e] = STATE_TREE;
107.1082 + if (_supply[u] >= 0) {
107.1083 + _forward[u] = true;
107.1084 + _pi[u] = 0;
107.1085 + _source[e] = u;
107.1086 + _target[e] = _root;
107.1087 + _flow[e] = _supply[u];
107.1088 + _cost[e] = 0;
107.1089 + } else {
107.1090 + _forward[u] = false;
107.1091 + _pi[u] = ART_COST;
107.1092 + _source[e] = _root;
107.1093 + _target[e] = u;
107.1094 + _flow[e] = -_supply[u];
107.1095 + _cost[e] = ART_COST;
107.1096 + }
107.1097 + }
107.1098 + }
107.1099 + else if (_sum_supply > 0) {
107.1100 + // LEQ supply constraints
107.1101 + _search_arc_num = _arc_num + _node_num;
107.1102 + int f = _arc_num + _node_num;
107.1103 + for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
107.1104 + _parent[u] = _root;
107.1105 + _thread[u] = u + 1;
107.1106 + _rev_thread[u + 1] = u;
107.1107 + _succ_num[u] = 1;
107.1108 + _last_succ[u] = u;
107.1109 + if (_supply[u] >= 0) {
107.1110 + _forward[u] = true;
107.1111 + _pi[u] = 0;
107.1112 + _pred[u] = e;
107.1113 + _source[e] = u;
107.1114 + _target[e] = _root;
107.1115 + _cap[e] = INF;
107.1116 + _flow[e] = _supply[u];
107.1117 + _cost[e] = 0;
107.1118 + _state[e] = STATE_TREE;
107.1119 + } else {
107.1120 + _forward[u] = false;
107.1121 + _pi[u] = ART_COST;
107.1122 + _pred[u] = f;
107.1123 + _source[f] = _root;
107.1124 + _target[f] = u;
107.1125 + _cap[f] = INF;
107.1126 + _flow[f] = -_supply[u];
107.1127 + _cost[f] = ART_COST;
107.1128 + _state[f] = STATE_TREE;
107.1129 + _source[e] = u;
107.1130 + _target[e] = _root;
107.1131 + _cap[e] = INF;
107.1132 + _flow[e] = 0;
107.1133 + _cost[e] = 0;
107.1134 + _state[e] = STATE_LOWER;
107.1135 + ++f;
107.1136 + }
107.1137 + }
107.1138 + _all_arc_num = f;
107.1139 + }
107.1140 + else {
107.1141 + // GEQ supply constraints
107.1142 + _search_arc_num = _arc_num + _node_num;
107.1143 + int f = _arc_num + _node_num;
107.1144 + for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
107.1145 + _parent[u] = _root;
107.1146 + _thread[u] = u + 1;
107.1147 + _rev_thread[u + 1] = u;
107.1148 + _succ_num[u] = 1;
107.1149 + _last_succ[u] = u;
107.1150 + if (_supply[u] <= 0) {
107.1151 + _forward[u] = false;
107.1152 + _pi[u] = 0;
107.1153 + _pred[u] = e;
107.1154 + _source[e] = _root;
107.1155 + _target[e] = u;
107.1156 + _cap[e] = INF;
107.1157 + _flow[e] = -_supply[u];
107.1158 + _cost[e] = 0;
107.1159 + _state[e] = STATE_TREE;
107.1160 + } else {
107.1161 + _forward[u] = true;
107.1162 + _pi[u] = -ART_COST;
107.1163 + _pred[u] = f;
107.1164 + _source[f] = u;
107.1165 + _target[f] = _root;
107.1166 + _cap[f] = INF;
107.1167 + _flow[f] = _supply[u];
107.1168 + _state[f] = STATE_TREE;
107.1169 + _cost[f] = ART_COST;
107.1170 + _source[e] = _root;
107.1171 + _target[e] = u;
107.1172 + _cap[e] = INF;
107.1173 + _flow[e] = 0;
107.1174 + _cost[e] = 0;
107.1175 + _state[e] = STATE_LOWER;
107.1176 + ++f;
107.1177 + }
107.1178 + }
107.1179 + _all_arc_num = f;
107.1180 + }
107.1181 +
107.1182 + return true;
107.1183 + }
107.1184 +
107.1185 + // Find the join node
107.1186 + void findJoinNode() {
107.1187 + int u = _source[in_arc];
107.1188 + int v = _target[in_arc];
107.1189 + while (u != v) {
107.1190 + if (_succ_num[u] < _succ_num[v]) {
107.1191 + u = _parent[u];
107.1192 + } else {
107.1193 + v = _parent[v];
107.1194 + }
107.1195 + }
107.1196 + join = u;
107.1197 + }
107.1198 +
107.1199 + // Find the leaving arc of the cycle and returns true if the
107.1200 + // leaving arc is not the same as the entering arc
107.1201 + bool findLeavingArc() {
107.1202 + // Initialize first and second nodes according to the direction
107.1203 + // of the cycle
107.1204 + if (_state[in_arc] == STATE_LOWER) {
107.1205 + first = _source[in_arc];
107.1206 + second = _target[in_arc];
107.1207 + } else {
107.1208 + first = _target[in_arc];
107.1209 + second = _source[in_arc];
107.1210 + }
107.1211 + delta = _cap[in_arc];
107.1212 + int result = 0;
107.1213 + Value d;
107.1214 + int e;
107.1215 +
107.1216 + // Search the cycle along the path form the first node to the root
107.1217 + for (int u = first; u != join; u = _parent[u]) {
107.1218 + e = _pred[u];
107.1219 + d = _forward[u] ?
107.1220 + _flow[e] : (_cap[e] == INF ? INF : _cap[e] - _flow[e]);
107.1221 + if (d < delta) {
107.1222 + delta = d;
107.1223 + u_out = u;
107.1224 + result = 1;
107.1225 + }
107.1226 + }
107.1227 + // Search the cycle along the path form the second node to the root
107.1228 + for (int u = second; u != join; u = _parent[u]) {
107.1229 + e = _pred[u];
107.1230 + d = _forward[u] ?
107.1231 + (_cap[e] == INF ? INF : _cap[e] - _flow[e]) : _flow[e];
107.1232 + if (d <= delta) {
107.1233 + delta = d;
107.1234 + u_out = u;
107.1235 + result = 2;
107.1236 + }
107.1237 + }
107.1238 +
107.1239 + if (result == 1) {
107.1240 + u_in = first;
107.1241 + v_in = second;
107.1242 + } else {
107.1243 + u_in = second;
107.1244 + v_in = first;
107.1245 + }
107.1246 + return result != 0;
107.1247 + }
107.1248 +
107.1249 + // Change _flow and _state vectors
107.1250 + void changeFlow(bool change) {
107.1251 + // Augment along the cycle
107.1252 + if (delta > 0) {
107.1253 + Value val = _state[in_arc] * delta;
107.1254 + _flow[in_arc] += val;
107.1255 + for (int u = _source[in_arc]; u != join; u = _parent[u]) {
107.1256 + _flow[_pred[u]] += _forward[u] ? -val : val;
107.1257 + }
107.1258 + for (int u = _target[in_arc]; u != join; u = _parent[u]) {
107.1259 + _flow[_pred[u]] += _forward[u] ? val : -val;
107.1260 + }
107.1261 + }
107.1262 + // Update the state of the entering and leaving arcs
107.1263 + if (change) {
107.1264 + _state[in_arc] = STATE_TREE;
107.1265 + _state[_pred[u_out]] =
107.1266 + (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
107.1267 + } else {
107.1268 + _state[in_arc] = -_state[in_arc];
107.1269 + }
107.1270 + }
107.1271 +
107.1272 + // Update the tree structure
107.1273 + void updateTreeStructure() {
107.1274 + int u, w;
107.1275 + int old_rev_thread = _rev_thread[u_out];
107.1276 + int old_succ_num = _succ_num[u_out];
107.1277 + int old_last_succ = _last_succ[u_out];
107.1278 + v_out = _parent[u_out];
107.1279 +
107.1280 + u = _last_succ[u_in]; // the last successor of u_in
107.1281 + right = _thread[u]; // the node after it
107.1282 +
107.1283 + // Handle the case when old_rev_thread equals to v_in
107.1284 + // (it also means that join and v_out coincide)
107.1285 + if (old_rev_thread == v_in) {
107.1286 + last = _thread[_last_succ[u_out]];
107.1287 + } else {
107.1288 + last = _thread[v_in];
107.1289 + }
107.1290 +
107.1291 + // Update _thread and _parent along the stem nodes (i.e. the nodes
107.1292 + // between u_in and u_out, whose parent have to be changed)
107.1293 + _thread[v_in] = stem = u_in;
107.1294 + _dirty_revs.clear();
107.1295 + _dirty_revs.push_back(v_in);
107.1296 + par_stem = v_in;
107.1297 + while (stem != u_out) {
107.1298 + // Insert the next stem node into the thread list
107.1299 + new_stem = _parent[stem];
107.1300 + _thread[u] = new_stem;
107.1301 + _dirty_revs.push_back(u);
107.1302 +
107.1303 + // Remove the subtree of stem from the thread list
107.1304 + w = _rev_thread[stem];
107.1305 + _thread[w] = right;
107.1306 + _rev_thread[right] = w;
107.1307 +
107.1308 + // Change the parent node and shift stem nodes
107.1309 + _parent[stem] = par_stem;
107.1310 + par_stem = stem;
107.1311 + stem = new_stem;
107.1312 +
107.1313 + // Update u and right
107.1314 + u = _last_succ[stem] == _last_succ[par_stem] ?
107.1315 + _rev_thread[par_stem] : _last_succ[stem];
107.1316 + right = _thread[u];
107.1317 + }
107.1318 + _parent[u_out] = par_stem;
107.1319 + _thread[u] = last;
107.1320 + _rev_thread[last] = u;
107.1321 + _last_succ[u_out] = u;
107.1322 +
107.1323 + // Remove the subtree of u_out from the thread list except for
107.1324 + // the case when old_rev_thread equals to v_in
107.1325 + // (it also means that join and v_out coincide)
107.1326 + if (old_rev_thread != v_in) {
107.1327 + _thread[old_rev_thread] = right;
107.1328 + _rev_thread[right] = old_rev_thread;
107.1329 + }
107.1330 +
107.1331 + // Update _rev_thread using the new _thread values
107.1332 + for (int i = 0; i < int(_dirty_revs.size()); ++i) {
107.1333 + u = _dirty_revs[i];
107.1334 + _rev_thread[_thread[u]] = u;
107.1335 + }
107.1336 +
107.1337 + // Update _pred, _forward, _last_succ and _succ_num for the
107.1338 + // stem nodes from u_out to u_in
107.1339 + int tmp_sc = 0, tmp_ls = _last_succ[u_out];
107.1340 + u = u_out;
107.1341 + while (u != u_in) {
107.1342 + w = _parent[u];
107.1343 + _pred[u] = _pred[w];
107.1344 + _forward[u] = !_forward[w];
107.1345 + tmp_sc += _succ_num[u] - _succ_num[w];
107.1346 + _succ_num[u] = tmp_sc;
107.1347 + _last_succ[w] = tmp_ls;
107.1348 + u = w;
107.1349 + }
107.1350 + _pred[u_in] = in_arc;
107.1351 + _forward[u_in] = (u_in == _source[in_arc]);
107.1352 + _succ_num[u_in] = old_succ_num;
107.1353 +
107.1354 + // Set limits for updating _last_succ form v_in and v_out
107.1355 + // towards the root
107.1356 + int up_limit_in = -1;
107.1357 + int up_limit_out = -1;
107.1358 + if (_last_succ[join] == v_in) {
107.1359 + up_limit_out = join;
107.1360 + } else {
107.1361 + up_limit_in = join;
107.1362 + }
107.1363 +
107.1364 + // Update _last_succ from v_in towards the root
107.1365 + for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
107.1366 + u = _parent[u]) {
107.1367 + _last_succ[u] = _last_succ[u_out];
107.1368 + }
107.1369 + // Update _last_succ from v_out towards the root
107.1370 + if (join != old_rev_thread && v_in != old_rev_thread) {
107.1371 + for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
107.1372 + u = _parent[u]) {
107.1373 + _last_succ[u] = old_rev_thread;
107.1374 + }
107.1375 + } else {
107.1376 + for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
107.1377 + u = _parent[u]) {
107.1378 + _last_succ[u] = _last_succ[u_out];
107.1379 + }
107.1380 + }
107.1381 +
107.1382 + // Update _succ_num from v_in to join
107.1383 + for (u = v_in; u != join; u = _parent[u]) {
107.1384 + _succ_num[u] += old_succ_num;
107.1385 + }
107.1386 + // Update _succ_num from v_out to join
107.1387 + for (u = v_out; u != join; u = _parent[u]) {
107.1388 + _succ_num[u] -= old_succ_num;
107.1389 + }
107.1390 + }
107.1391 +
107.1392 + // Update potentials
107.1393 + void updatePotential() {
107.1394 + Cost sigma = _forward[u_in] ?
107.1395 + _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
107.1396 + _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
107.1397 + // Update potentials in the subtree, which has been moved
107.1398 + int end = _thread[_last_succ[u_in]];
107.1399 + for (int u = u_in; u != end; u = _thread[u]) {
107.1400 + _pi[u] += sigma;
107.1401 + }
107.1402 + }
107.1403 +
107.1404 + // Execute the algorithm
107.1405 + ProblemType start(PivotRule pivot_rule) {
107.1406 + // Select the pivot rule implementation
107.1407 + switch (pivot_rule) {
107.1408 + case FIRST_ELIGIBLE:
107.1409 + return start<FirstEligiblePivotRule>();
107.1410 + case BEST_ELIGIBLE:
107.1411 + return start<BestEligiblePivotRule>();
107.1412 + case BLOCK_SEARCH:
107.1413 + return start<BlockSearchPivotRule>();
107.1414 + case CANDIDATE_LIST:
107.1415 + return start<CandidateListPivotRule>();
107.1416 + case ALTERING_LIST:
107.1417 + return start<AlteringListPivotRule>();
107.1418 + }
107.1419 + return INFEASIBLE; // avoid warning
107.1420 + }
107.1421 +
107.1422 + template <typename PivotRuleImpl>
107.1423 + ProblemType start() {
107.1424 + PivotRuleImpl pivot(*this);
107.1425 +
107.1426 + // Execute the Network Simplex algorithm
107.1427 + while (pivot.findEnteringArc()) {
107.1428 + findJoinNode();
107.1429 + bool change = findLeavingArc();
107.1430 + if (delta >= INF) return UNBOUNDED;
107.1431 + changeFlow(change);
107.1432 + if (change) {
107.1433 + updateTreeStructure();
107.1434 + updatePotential();
107.1435 + }
107.1436 + }
107.1437 +
107.1438 + // Check feasibility
107.1439 + for (int e = _search_arc_num; e != _all_arc_num; ++e) {
107.1440 + if (_flow[e] != 0) return INFEASIBLE;
107.1441 + }
107.1442 +
107.1443 + // Transform the solution and the supply map to the original form
107.1444 + if (_have_lower) {
107.1445 + for (int i = 0; i != _arc_num; ++i) {
107.1446 + Value c = _lower[i];
107.1447 + if (c != 0) {
107.1448 + _flow[i] += c;
107.1449 + _supply[_source[i]] += c;
107.1450 + _supply[_target[i]] -= c;
107.1451 + }
107.1452 + }
107.1453 + }
107.1454 +
107.1455 + // Shift potentials to meet the requirements of the GEQ/LEQ type
107.1456 + // optimality conditions
107.1457 + if (_sum_supply == 0) {
107.1458 + if (_stype == GEQ) {
107.1459 + Cost max_pot = std::numeric_limits<Cost>::min();
107.1460 + for (int i = 0; i != _node_num; ++i) {
107.1461 + if (_pi[i] > max_pot) max_pot = _pi[i];
107.1462 + }
107.1463 + if (max_pot > 0) {
107.1464 + for (int i = 0; i != _node_num; ++i)
107.1465 + _pi[i] -= max_pot;
107.1466 + }
107.1467 + } else {
107.1468 + Cost min_pot = std::numeric_limits<Cost>::max();
107.1469 + for (int i = 0; i != _node_num; ++i) {
107.1470 + if (_pi[i] < min_pot) min_pot = _pi[i];
107.1471 + }
107.1472 + if (min_pot < 0) {
107.1473 + for (int i = 0; i != _node_num; ++i)
107.1474 + _pi[i] -= min_pot;
107.1475 + }
107.1476 + }
107.1477 + }
107.1478 +
107.1479 + return OPTIMAL;
107.1480 + }
107.1481 +
107.1482 + }; //class NetworkSimplex
107.1483 +
107.1484 + ///@}
107.1485 +
107.1486 +} //namespace lemon
107.1487 +
107.1488 +#endif //LEMON_NETWORK_SIMPLEX_H
108.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
108.2 +++ b/lemon/pairing_heap.h Thu Nov 05 15:48:01 2009 +0100
108.3 @@ -0,0 +1,474 @@
108.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
108.5 + *
108.6 + * This file is a part of LEMON, a generic C++ optimization library.
108.7 + *
108.8 + * Copyright (C) 2003-2009
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_PAIRING_HEAP_H
108.23 +#define LEMON_PAIRING_HEAP_H
108.24 +
108.25 +///\file
108.26 +///\ingroup heaps
108.27 +///\brief Pairing heap implementation.
108.28 +
108.29 +#include <vector>
108.30 +#include <utility>
108.31 +#include <functional>
108.32 +#include <lemon/math.h>
108.33 +
108.34 +namespace lemon {
108.35 +
108.36 + /// \ingroup heaps
108.37 + ///
108.38 + ///\brief Pairing Heap.
108.39 + ///
108.40 + /// This class implements the \e pairing \e heap data structure.
108.41 + /// It fully conforms to the \ref concepts::Heap "heap concept".
108.42 + ///
108.43 + /// The methods \ref increase() and \ref erase() are not efficient
108.44 + /// in a pairing heap. In case of many calls of these operations,
108.45 + /// it is better to use other heap structure, e.g. \ref BinHeap
108.46 + /// "binary heap".
108.47 + ///
108.48 + /// \tparam PR Type of the priorities of the items.
108.49 + /// \tparam IM A read-writable item map with \c int values, used
108.50 + /// internally to handle the cross references.
108.51 + /// \tparam CMP A functor class for comparing the priorities.
108.52 + /// The default is \c std::less<PR>.
108.53 +#ifdef DOXYGEN
108.54 + template <typename PR, typename IM, typename CMP>
108.55 +#else
108.56 + template <typename PR, typename IM, typename CMP = std::less<PR> >
108.57 +#endif
108.58 + class PairingHeap {
108.59 + public:
108.60 + /// Type of the item-int map.
108.61 + typedef IM ItemIntMap;
108.62 + /// Type of the priorities.
108.63 + typedef PR Prio;
108.64 + /// Type of the items stored in the heap.
108.65 + typedef typename ItemIntMap::Key Item;
108.66 + /// Functor type for comparing the priorities.
108.67 + typedef CMP Compare;
108.68 +
108.69 + /// \brief Type to represent the states of the items.
108.70 + ///
108.71 + /// Each item has a state associated to it. It can be "in heap",
108.72 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
108.73 + /// heap's point of view, but may be useful to the user.
108.74 + ///
108.75 + /// The item-int map must be initialized in such way that it assigns
108.76 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
108.77 + enum State {
108.78 + IN_HEAP = 0, ///< = 0.
108.79 + PRE_HEAP = -1, ///< = -1.
108.80 + POST_HEAP = -2 ///< = -2.
108.81 + };
108.82 +
108.83 + private:
108.84 + class store;
108.85 +
108.86 + std::vector<store> _data;
108.87 + int _min;
108.88 + ItemIntMap &_iim;
108.89 + Compare _comp;
108.90 + int _num_items;
108.91 +
108.92 + public:
108.93 + /// \brief Constructor.
108.94 + ///
108.95 + /// Constructor.
108.96 + /// \param map A map that assigns \c int values to the items.
108.97 + /// It is used internally to handle the cross references.
108.98 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
108.99 + explicit PairingHeap(ItemIntMap &map)
108.100 + : _min(0), _iim(map), _num_items(0) {}
108.101 +
108.102 + /// \brief Constructor.
108.103 + ///
108.104 + /// Constructor.
108.105 + /// \param map A map that assigns \c int values to the items.
108.106 + /// It is used internally to handle the cross references.
108.107 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
108.108 + /// \param comp The function object used for comparing the priorities.
108.109 + PairingHeap(ItemIntMap &map, const Compare &comp)
108.110 + : _min(0), _iim(map), _comp(comp), _num_items(0) {}
108.111 +
108.112 + /// \brief The number of items stored in the heap.
108.113 + ///
108.114 + /// This function returns the number of items stored in the heap.
108.115 + int size() const { return _num_items; }
108.116 +
108.117 + /// \brief Check if the heap is empty.
108.118 + ///
108.119 + /// This function returns \c true if the heap is empty.
108.120 + bool empty() const { return _num_items==0; }
108.121 +
108.122 + /// \brief Make the heap empty.
108.123 + ///
108.124 + /// This functon makes the heap empty.
108.125 + /// It does not change the cross reference map. If you want to reuse
108.126 + /// a heap that is not surely empty, you should first clear it and
108.127 + /// then you should set the cross reference map to \c PRE_HEAP
108.128 + /// for each item.
108.129 + void clear() {
108.130 + _data.clear();
108.131 + _min = 0;
108.132 + _num_items = 0;
108.133 + }
108.134 +
108.135 + /// \brief Set the priority of an item or insert it, if it is
108.136 + /// not stored in the heap.
108.137 + ///
108.138 + /// This method sets the priority of the given item if it is
108.139 + /// already stored in the heap. Otherwise it inserts the given
108.140 + /// item into the heap with the given priority.
108.141 + /// \param item The item.
108.142 + /// \param value The priority.
108.143 + void set (const Item& item, const Prio& value) {
108.144 + int i=_iim[item];
108.145 + if ( i>=0 && _data[i].in ) {
108.146 + if ( _comp(value, _data[i].prio) ) decrease(item, value);
108.147 + if ( _comp(_data[i].prio, value) ) increase(item, value);
108.148 + } else push(item, value);
108.149 + }
108.150 +
108.151 + /// \brief Insert an item into the heap with the given priority.
108.152 + ///
108.153 + /// This function inserts the given item into the heap with the
108.154 + /// given priority.
108.155 + /// \param item The item to insert.
108.156 + /// \param value The priority of the item.
108.157 + /// \pre \e item must not be stored in the heap.
108.158 + void push (const Item& item, const Prio& value) {
108.159 + int i=_iim[item];
108.160 + if( i<0 ) {
108.161 + int s=_data.size();
108.162 + _iim.set(item, s);
108.163 + store st;
108.164 + st.name=item;
108.165 + _data.push_back(st);
108.166 + i=s;
108.167 + } else {
108.168 + _data[i].parent=_data[i].child=-1;
108.169 + _data[i].left_child=false;
108.170 + _data[i].degree=0;
108.171 + _data[i].in=true;
108.172 + }
108.173 +
108.174 + _data[i].prio=value;
108.175 +
108.176 + if ( _num_items!=0 ) {
108.177 + if ( _comp( value, _data[_min].prio) ) {
108.178 + fuse(i,_min);
108.179 + _min=i;
108.180 + }
108.181 + else fuse(_min,i);
108.182 + }
108.183 + else _min=i;
108.184 +
108.185 + ++_num_items;
108.186 + }
108.187 +
108.188 + /// \brief Return the item having minimum priority.
108.189 + ///
108.190 + /// This function returns the item having minimum priority.
108.191 + /// \pre The heap must be non-empty.
108.192 + Item top() const { return _data[_min].name; }
108.193 +
108.194 + /// \brief The minimum priority.
108.195 + ///
108.196 + /// This function returns the minimum priority.
108.197 + /// \pre The heap must be non-empty.
108.198 + const Prio& prio() const { return _data[_min].prio; }
108.199 +
108.200 + /// \brief The priority of the given item.
108.201 + ///
108.202 + /// This function returns the priority of the given item.
108.203 + /// \param item The item.
108.204 + /// \pre \e item must be in the heap.
108.205 + const Prio& operator[](const Item& item) const {
108.206 + return _data[_iim[item]].prio;
108.207 + }
108.208 +
108.209 + /// \brief Remove the item having minimum priority.
108.210 + ///
108.211 + /// This function removes the item having minimum priority.
108.212 + /// \pre The heap must be non-empty.
108.213 + void pop() {
108.214 + std::vector<int> trees;
108.215 + int i=0, child_right = 0;
108.216 + _data[_min].in=false;
108.217 +
108.218 + if( -1!=_data[_min].child ) {
108.219 + i=_data[_min].child;
108.220 + trees.push_back(i);
108.221 + _data[i].parent = -1;
108.222 + _data[_min].child = -1;
108.223 +
108.224 + int ch=-1;
108.225 + while( _data[i].child!=-1 ) {
108.226 + ch=_data[i].child;
108.227 + if( _data[ch].left_child && i==_data[ch].parent ) {
108.228 + break;
108.229 + } else {
108.230 + if( _data[ch].left_child ) {
108.231 + child_right=_data[ch].parent;
108.232 + _data[ch].parent = i;
108.233 + --_data[i].degree;
108.234 + }
108.235 + else {
108.236 + child_right=ch;
108.237 + _data[i].child=-1;
108.238 + _data[i].degree=0;
108.239 + }
108.240 + _data[child_right].parent = -1;
108.241 + trees.push_back(child_right);
108.242 + i = child_right;
108.243 + }
108.244 + }
108.245 +
108.246 + int num_child = trees.size();
108.247 + int other;
108.248 + for( i=0; i<num_child-1; i+=2 ) {
108.249 + if ( !_comp(_data[trees[i]].prio, _data[trees[i+1]].prio) ) {
108.250 + other=trees[i];
108.251 + trees[i]=trees[i+1];
108.252 + trees[i+1]=other;
108.253 + }
108.254 + fuse( trees[i], trees[i+1] );
108.255 + }
108.256 +
108.257 + i = (0==(num_child % 2)) ? num_child-2 : num_child-1;
108.258 + while(i>=2) {
108.259 + if ( _comp(_data[trees[i]].prio, _data[trees[i-2]].prio) ) {
108.260 + other=trees[i];
108.261 + trees[i]=trees[i-2];
108.262 + trees[i-2]=other;
108.263 + }
108.264 + fuse( trees[i-2], trees[i] );
108.265 + i-=2;
108.266 + }
108.267 + _min = trees[0];
108.268 + }
108.269 + else {
108.270 + _min = _data[_min].child;
108.271 + }
108.272 +
108.273 + if (_min >= 0) _data[_min].left_child = false;
108.274 + --_num_items;
108.275 + }
108.276 +
108.277 + /// \brief Remove the given item from the heap.
108.278 + ///
108.279 + /// This function removes the given item from the heap if it is
108.280 + /// already stored.
108.281 + /// \param item The item to delete.
108.282 + /// \pre \e item must be in the heap.
108.283 + void erase (const Item& item) {
108.284 + int i=_iim[item];
108.285 + if ( i>=0 && _data[i].in ) {
108.286 + decrease( item, _data[_min].prio-1 );
108.287 + pop();
108.288 + }
108.289 + }
108.290 +
108.291 + /// \brief Decrease the priority of an item to the given value.
108.292 + ///
108.293 + /// This function decreases the priority of an item to the given value.
108.294 + /// \param item The item.
108.295 + /// \param value The priority.
108.296 + /// \pre \e item must be stored in the heap with priority at least \e value.
108.297 + void decrease (Item item, const Prio& value) {
108.298 + int i=_iim[item];
108.299 + _data[i].prio=value;
108.300 + int p=_data[i].parent;
108.301 +
108.302 + if( _data[i].left_child && i!=_data[p].child ) {
108.303 + p=_data[p].parent;
108.304 + }
108.305 +
108.306 + if ( p!=-1 && _comp(value,_data[p].prio) ) {
108.307 + cut(i,p);
108.308 + if ( _comp(_data[_min].prio,value) ) {
108.309 + fuse(_min,i);
108.310 + } else {
108.311 + fuse(i,_min);
108.312 + _min=i;
108.313 + }
108.314 + }
108.315 + }
108.316 +
108.317 + /// \brief Increase the priority of an item to the given value.
108.318 + ///
108.319 + /// This function increases the priority of an item to the given value.
108.320 + /// \param item The item.
108.321 + /// \param value The priority.
108.322 + /// \pre \e item must be stored in the heap with priority at most \e value.
108.323 + void increase (Item item, const Prio& value) {
108.324 + erase(item);
108.325 + push(item,value);
108.326 + }
108.327 +
108.328 + /// \brief Return the state of an item.
108.329 + ///
108.330 + /// This method returns \c PRE_HEAP if the given item has never
108.331 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
108.332 + /// and \c POST_HEAP otherwise.
108.333 + /// In the latter case it is possible that the item will get back
108.334 + /// to the heap again.
108.335 + /// \param item The item.
108.336 + State state(const Item &item) const {
108.337 + int i=_iim[item];
108.338 + if( i>=0 ) {
108.339 + if( _data[i].in ) i=0;
108.340 + else i=-2;
108.341 + }
108.342 + return State(i);
108.343 + }
108.344 +
108.345 + /// \brief Set the state of an item in the heap.
108.346 + ///
108.347 + /// This function sets the state of the given item in the heap.
108.348 + /// It can be used to manually clear the heap when it is important
108.349 + /// to achive better time complexity.
108.350 + /// \param i The item.
108.351 + /// \param st The state. It should not be \c IN_HEAP.
108.352 + void state(const Item& i, State st) {
108.353 + switch (st) {
108.354 + case POST_HEAP:
108.355 + case PRE_HEAP:
108.356 + if (state(i) == IN_HEAP) erase(i);
108.357 + _iim[i]=st;
108.358 + break;
108.359 + case IN_HEAP:
108.360 + break;
108.361 + }
108.362 + }
108.363 +
108.364 + private:
108.365 +
108.366 + void cut(int a, int b) {
108.367 + int child_a;
108.368 + switch (_data[a].degree) {
108.369 + case 2:
108.370 + child_a = _data[_data[a].child].parent;
108.371 + if( _data[a].left_child ) {
108.372 + _data[child_a].left_child=true;
108.373 + _data[b].child=child_a;
108.374 + _data[child_a].parent=_data[a].parent;
108.375 + }
108.376 + else {
108.377 + _data[child_a].left_child=false;
108.378 + _data[child_a].parent=b;
108.379 + if( a!=_data[b].child )
108.380 + _data[_data[b].child].parent=child_a;
108.381 + else
108.382 + _data[b].child=child_a;
108.383 + }
108.384 + --_data[a].degree;
108.385 + _data[_data[a].child].parent=a;
108.386 + break;
108.387 +
108.388 + case 1:
108.389 + child_a = _data[a].child;
108.390 + if( !_data[child_a].left_child ) {
108.391 + --_data[a].degree;
108.392 + if( _data[a].left_child ) {
108.393 + _data[child_a].left_child=true;
108.394 + _data[child_a].parent=_data[a].parent;
108.395 + _data[b].child=child_a;
108.396 + }
108.397 + else {
108.398 + _data[child_a].left_child=false;
108.399 + _data[child_a].parent=b;
108.400 + if( a!=_data[b].child )
108.401 + _data[_data[b].child].parent=child_a;
108.402 + else
108.403 + _data[b].child=child_a;
108.404 + }
108.405 + _data[a].child=-1;
108.406 + }
108.407 + else {
108.408 + --_data[b].degree;
108.409 + if( _data[a].left_child ) {
108.410 + _data[b].child =
108.411 + (1==_data[b].degree) ? _data[a].parent : -1;
108.412 + } else {
108.413 + if (1==_data[b].degree)
108.414 + _data[_data[b].child].parent=b;
108.415 + else
108.416 + _data[b].child=-1;
108.417 + }
108.418 + }
108.419 + break;
108.420 +
108.421 + case 0:
108.422 + --_data[b].degree;
108.423 + if( _data[a].left_child ) {
108.424 + _data[b].child =
108.425 + (0!=_data[b].degree) ? _data[a].parent : -1;
108.426 + } else {
108.427 + if( 0!=_data[b].degree )
108.428 + _data[_data[b].child].parent=b;
108.429 + else
108.430 + _data[b].child=-1;
108.431 + }
108.432 + break;
108.433 + }
108.434 + _data[a].parent=-1;
108.435 + _data[a].left_child=false;
108.436 + }
108.437 +
108.438 + void fuse(int a, int b) {
108.439 + int child_a = _data[a].child;
108.440 + int child_b = _data[b].child;
108.441 + _data[a].child=b;
108.442 + _data[b].parent=a;
108.443 + _data[b].left_child=true;
108.444 +
108.445 + if( -1!=child_a ) {
108.446 + _data[b].child=child_a;
108.447 + _data[child_a].parent=b;
108.448 + _data[child_a].left_child=false;
108.449 + ++_data[b].degree;
108.450 +
108.451 + if( -1!=child_b ) {
108.452 + _data[b].child=child_b;
108.453 + _data[child_b].parent=child_a;
108.454 + }
108.455 + }
108.456 + else { ++_data[a].degree; }
108.457 + }
108.458 +
108.459 + class store {
108.460 + friend class PairingHeap;
108.461 +
108.462 + Item name;
108.463 + int parent;
108.464 + int child;
108.465 + bool left_child;
108.466 + int degree;
108.467 + bool in;
108.468 + Prio prio;
108.469 +
108.470 + store() : parent(-1), child(-1), left_child(false), degree(0), in(true) {}
108.471 + };
108.472 + };
108.473 +
108.474 +} //namespace lemon
108.475 +
108.476 +#endif //LEMON_PAIRING_HEAP_H
108.477 +
109.1 --- a/lemon/path.h Mon Jan 12 23:11:39 2009 +0100
109.2 +++ b/lemon/path.h Thu Nov 05 15:48:01 2009 +0100
109.3 @@ -40,7 +40,7 @@
109.4 /// \brief A structure for representing directed paths in a digraph.
109.5 ///
109.6 /// A structure for representing directed path in a digraph.
109.7 - /// \tparam _Digraph The digraph type in which the path is.
109.8 + /// \tparam GR The digraph type in which the path is.
109.9 ///
109.10 /// In a sense, the path can be treated as a list of arcs. The
109.11 /// lemon path type stores just this list. As a consequence, it
109.12 @@ -52,11 +52,11 @@
109.13 /// insertion and erase is done in O(1) (amortized) time. The
109.14 /// implementation uses two vectors for storing the front and back
109.15 /// insertions.
109.16 - template <typename _Digraph>
109.17 + template <typename GR>
109.18 class Path {
109.19 public:
109.20
109.21 - typedef _Digraph Digraph;
109.22 + typedef GR Digraph;
109.23 typedef typename Digraph::Arc Arc;
109.24
109.25 /// \brief Default constructor
109.26 @@ -137,7 +137,7 @@
109.27
109.28 /// \brief The nth arc.
109.29 ///
109.30 - /// \pre n is in the [0..length() - 1] range
109.31 + /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
109.32 const Arc& nth(int n) const {
109.33 return n < int(head.size()) ? *(head.rbegin() + n) :
109.34 *(tail.begin() + (n - head.size()));
109.35 @@ -145,7 +145,7 @@
109.36
109.37 /// \brief Initialize arc iterator to point to the nth arc
109.38 ///
109.39 - /// \pre n is in the [0..length() - 1] range
109.40 + /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
109.41 ArcIt nthIt(int n) const {
109.42 return ArcIt(*this, n);
109.43 }
109.44 @@ -228,7 +228,7 @@
109.45 /// \brief A structure for representing directed paths in a digraph.
109.46 ///
109.47 /// A structure for representing directed path in a digraph.
109.48 - /// \tparam _Digraph The digraph type in which the path is.
109.49 + /// \tparam GR The digraph type in which the path is.
109.50 ///
109.51 /// In a sense, the path can be treated as a list of arcs. The
109.52 /// lemon path type stores just this list. As a consequence it
109.53 @@ -240,11 +240,11 @@
109.54 /// erasure is amortized O(1) time. This implementation is faster
109.55 /// then the \c Path type because it use just one vector for the
109.56 /// arcs.
109.57 - template <typename _Digraph>
109.58 + template <typename GR>
109.59 class SimplePath {
109.60 public:
109.61
109.62 - typedef _Digraph Digraph;
109.63 + typedef GR Digraph;
109.64 typedef typename Digraph::Arc Arc;
109.65
109.66 /// \brief Default constructor
109.67 @@ -329,7 +329,7 @@
109.68
109.69 /// \brief The nth arc.
109.70 ///
109.71 - /// \pre n is in the [0..length() - 1] range
109.72 + /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
109.73 const Arc& nth(int n) const {
109.74 return data[n];
109.75 }
109.76 @@ -392,7 +392,7 @@
109.77 /// \brief A structure for representing directed paths in a digraph.
109.78 ///
109.79 /// A structure for representing directed path in a digraph.
109.80 - /// \tparam _Digraph The digraph type in which the path is.
109.81 + /// \tparam GR The digraph type in which the path is.
109.82 ///
109.83 /// In a sense, the path can be treated as a list of arcs. The
109.84 /// lemon path type stores just this list. As a consequence it
109.85 @@ -404,11 +404,11 @@
109.86 /// of the arc in the path. The length can be computed in O(n)
109.87 /// time. The front and back insertion and erasure is O(1) time
109.88 /// and it can be splited and spliced in O(1) time.
109.89 - template <typename _Digraph>
109.90 + template <typename GR>
109.91 class ListPath {
109.92 public:
109.93
109.94 - typedef _Digraph Digraph;
109.95 + typedef GR Digraph;
109.96 typedef typename Digraph::Arc Arc;
109.97
109.98 protected:
109.99 @@ -507,7 +507,7 @@
109.100 /// \brief The nth arc.
109.101 ///
109.102 /// This function looks for the nth arc in O(n) time.
109.103 - /// \pre n is in the [0..length() - 1] range
109.104 + /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
109.105 const Arc& nth(int n) const {
109.106 Node *node = first;
109.107 for (int i = 0; i < n; ++i) {
109.108 @@ -732,7 +732,7 @@
109.109 /// \brief A structure for representing directed paths in a digraph.
109.110 ///
109.111 /// A structure for representing directed path in a digraph.
109.112 - /// \tparam _Digraph The digraph type in which the path is.
109.113 + /// \tparam GR The digraph type in which the path is.
109.114 ///
109.115 /// In a sense, the path can be treated as a list of arcs. The
109.116 /// lemon path type stores just this list. As a consequence it
109.117 @@ -746,11 +746,11 @@
109.118 /// Being the the most memory efficient path type in LEMON,
109.119 /// it is intented to be
109.120 /// used when you want to store a large number of paths.
109.121 - template <typename _Digraph>
109.122 + template <typename GR>
109.123 class StaticPath {
109.124 public:
109.125
109.126 - typedef _Digraph Digraph;
109.127 + typedef GR Digraph;
109.128 typedef typename Digraph::Arc Arc;
109.129
109.130 /// \brief Default constructor
109.131 @@ -833,7 +833,7 @@
109.132
109.133 /// \brief The nth arc.
109.134 ///
109.135 - /// \pre n is in the [0..length() - 1] range
109.136 + /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
109.137 const Arc& nth(int n) const {
109.138 return arcs[n];
109.139 }
109.140 @@ -929,9 +929,8 @@
109.141 };
109.142
109.143 template <typename Target, typename Source,
109.144 - bool buildEnable = BuildTagIndicator<Target>::value,
109.145 - bool revEnable = RevPathTagIndicator<Source>::value>
109.146 - struct PathCopySelector {
109.147 + bool buildEnable = BuildTagIndicator<Target>::value>
109.148 + struct PathCopySelectorForward {
109.149 static void copy(Target& target, const Source& source) {
109.150 target.clear();
109.151 for (typename Source::ArcIt it(source); it != INVALID; ++it) {
109.152 @@ -941,7 +940,16 @@
109.153 };
109.154
109.155 template <typename Target, typename Source>
109.156 - struct PathCopySelector<Target, Source, false, true> {
109.157 + struct PathCopySelectorForward<Target, Source, true> {
109.158 + static void copy(Target& target, const Source& source) {
109.159 + target.clear();
109.160 + target.build(source);
109.161 + }
109.162 + };
109.163 +
109.164 + template <typename Target, typename Source,
109.165 + bool buildEnable = BuildTagIndicator<Target>::value>
109.166 + struct PathCopySelectorBackward {
109.167 static void copy(Target& target, const Source& source) {
109.168 target.clear();
109.169 for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
109.170 @@ -951,21 +959,29 @@
109.171 };
109.172
109.173 template <typename Target, typename Source>
109.174 - struct PathCopySelector<Target, Source, true, false> {
109.175 - static void copy(Target& target, const Source& source) {
109.176 - target.clear();
109.177 - target.build(source);
109.178 - }
109.179 - };
109.180 -
109.181 - template <typename Target, typename Source>
109.182 - struct PathCopySelector<Target, Source, true, true> {
109.183 + struct PathCopySelectorBackward<Target, Source, true> {
109.184 static void copy(Target& target, const Source& source) {
109.185 target.clear();
109.186 target.buildRev(source);
109.187 }
109.188 };
109.189
109.190 +
109.191 + template <typename Target, typename Source,
109.192 + bool revEnable = RevPathTagIndicator<Source>::value>
109.193 + struct PathCopySelector {
109.194 + static void copy(Target& target, const Source& source) {
109.195 + PathCopySelectorForward<Target, Source>::copy(target, source);
109.196 + }
109.197 + };
109.198 +
109.199 + template <typename Target, typename Source>
109.200 + struct PathCopySelector<Target, Source, true> {
109.201 + static void copy(Target& target, const Source& source) {
109.202 + PathCopySelectorBackward<Target, Source>::copy(target, source);
109.203 + }
109.204 + };
109.205 +
109.206 }
109.207
109.208
109.209 @@ -999,18 +1015,20 @@
109.210
109.211 /// \brief The source of a path
109.212 ///
109.213 - /// This function returns the source of the given path.
109.214 + /// This function returns the source node of the given path.
109.215 + /// If the path is empty, then it returns \c INVALID.
109.216 template <typename Digraph, typename Path>
109.217 typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
109.218 - return digraph.source(path.front());
109.219 + return path.empty() ? INVALID : digraph.source(path.front());
109.220 }
109.221
109.222 /// \brief The target of a path
109.223 ///
109.224 - /// This function returns the target of the given path.
109.225 + /// This function returns the target node of the given path.
109.226 + /// If the path is empty, then it returns \c INVALID.
109.227 template <typename Digraph, typename Path>
109.228 typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
109.229 - return digraph.target(path.back());
109.230 + return path.empty() ? INVALID : digraph.target(path.back());
109.231 }
109.232
109.233 /// \brief Class which helps to iterate through the nodes of a path
110.1 --- a/lemon/preflow.h Mon Jan 12 23:11:39 2009 +0100
110.2 +++ b/lemon/preflow.h Thu Nov 05 15:48:01 2009 +0100
110.3 @@ -31,19 +31,19 @@
110.4 /// \brief Default traits class of Preflow class.
110.5 ///
110.6 /// Default traits class of Preflow class.
110.7 - /// \tparam _Digraph Digraph type.
110.8 - /// \tparam _CapacityMap Capacity map type.
110.9 - template <typename _Digraph, typename _CapacityMap>
110.10 + /// \tparam GR Digraph type.
110.11 + /// \tparam CAP Capacity map type.
110.12 + template <typename GR, typename CAP>
110.13 struct PreflowDefaultTraits {
110.14
110.15 /// \brief The type of the digraph the algorithm runs on.
110.16 - typedef _Digraph Digraph;
110.17 + typedef GR Digraph;
110.18
110.19 /// \brief The type of the map that stores the arc capacities.
110.20 ///
110.21 /// The type of the map that stores the arc capacities.
110.22 /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
110.23 - typedef _CapacityMap CapacityMap;
110.24 + typedef CAP CapacityMap;
110.25
110.26 /// \brief The type of the flow values.
110.27 typedef typename CapacityMap::Value Value;
110.28 @@ -52,12 +52,16 @@
110.29 ///
110.30 /// The type of the map that stores the flow values.
110.31 /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
110.32 +#ifdef DOXYGEN
110.33 + typedef GR::ArcMap<Value> FlowMap;
110.34 +#else
110.35 typedef typename Digraph::template ArcMap<Value> FlowMap;
110.36 +#endif
110.37
110.38 /// \brief Instantiates a FlowMap.
110.39 ///
110.40 /// This function instantiates a \ref FlowMap.
110.41 - /// \param digraph The digraph, to which we would like to define
110.42 + /// \param digraph The digraph for which we would like to define
110.43 /// the flow map.
110.44 static FlowMap* createFlowMap(const Digraph& digraph) {
110.45 return new FlowMap(digraph);
110.46 @@ -67,14 +71,17 @@
110.47 ///
110.48 /// The elevator type used by Preflow algorithm.
110.49 ///
110.50 - /// \sa Elevator
110.51 - /// \sa LinkedElevator
110.52 - typedef LinkedElevator<Digraph, typename Digraph::Node> Elevator;
110.53 + /// \sa Elevator, LinkedElevator
110.54 +#ifdef DOXYGEN
110.55 + typedef lemon::Elevator<GR, GR::Node> Elevator;
110.56 +#else
110.57 + typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
110.58 +#endif
110.59
110.60 /// \brief Instantiates an Elevator.
110.61 ///
110.62 /// This function instantiates an \ref Elevator.
110.63 - /// \param digraph The digraph, to which we would like to define
110.64 + /// \param digraph The digraph for which we would like to define
110.65 /// the elevator.
110.66 /// \param max_level The maximum level of the elevator.
110.67 static Elevator* createElevator(const Digraph& digraph, int max_level) {
110.68 @@ -94,9 +101,11 @@
110.69 /// \brief %Preflow algorithm class.
110.70 ///
110.71 /// This class provides an implementation of Goldberg-Tarjan's \e preflow
110.72 - /// \e push-relabel algorithm producing a flow of maximum value in a
110.73 - /// digraph. The preflow algorithms are the fastest known maximum
110.74 - /// flow algorithms. The current implementation use a mixture of the
110.75 + /// \e push-relabel algorithm producing a \ref max_flow
110.76 + /// "flow of maximum value" in a digraph \ref clrs01algorithms,
110.77 + /// \ref amo93networkflows, \ref goldberg88newapproach.
110.78 + /// The preflow algorithms are the fastest known maximum
110.79 + /// flow algorithms. The current implementation uses a mixture of the
110.80 /// \e "highest label" and the \e "bound decrease" heuristics.
110.81 /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
110.82 ///
110.83 @@ -104,21 +113,21 @@
110.84 /// the maximum flow value and the minimum cut is obtained. The
110.85 /// second phase constructs a feasible maximum flow on each arc.
110.86 ///
110.87 - /// \tparam _Digraph The type of the digraph the algorithm runs on.
110.88 - /// \tparam _CapacityMap The type of the capacity map. The default map
110.89 - /// type is \ref concepts::Digraph::ArcMap "_Digraph::ArcMap<int>".
110.90 + /// \tparam GR The type of the digraph the algorithm runs on.
110.91 + /// \tparam CAP The type of the capacity map. The default map
110.92 + /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
110.93 #ifdef DOXYGEN
110.94 - template <typename _Digraph, typename _CapacityMap, typename _Traits>
110.95 + template <typename GR, typename CAP, typename TR>
110.96 #else
110.97 - template <typename _Digraph,
110.98 - typename _CapacityMap = typename _Digraph::template ArcMap<int>,
110.99 - typename _Traits = PreflowDefaultTraits<_Digraph, _CapacityMap> >
110.100 + template <typename GR,
110.101 + typename CAP = typename GR::template ArcMap<int>,
110.102 + typename TR = PreflowDefaultTraits<GR, CAP> >
110.103 #endif
110.104 class Preflow {
110.105 public:
110.106
110.107 ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
110.108 - typedef _Traits Traits;
110.109 + typedef TR Traits;
110.110 ///The type of the digraph the algorithm runs on.
110.111 typedef typename Traits::Digraph Digraph;
110.112 ///The type of the capacity map.
110.113 @@ -194,9 +203,9 @@
110.114
110.115 ///@{
110.116
110.117 - template <typename _FlowMap>
110.118 + template <typename T>
110.119 struct SetFlowMapTraits : public Traits {
110.120 - typedef _FlowMap FlowMap;
110.121 + typedef T FlowMap;
110.122 static FlowMap *createFlowMap(const Digraph&) {
110.123 LEMON_ASSERT(false, "FlowMap is not initialized");
110.124 return 0; // ignore warnings
110.125 @@ -208,16 +217,16 @@
110.126 ///
110.127 /// \ref named-templ-param "Named parameter" for setting FlowMap
110.128 /// type.
110.129 - template <typename _FlowMap>
110.130 + template <typename T>
110.131 struct SetFlowMap
110.132 - : public Preflow<Digraph, CapacityMap, SetFlowMapTraits<_FlowMap> > {
110.133 + : public Preflow<Digraph, CapacityMap, SetFlowMapTraits<T> > {
110.134 typedef Preflow<Digraph, CapacityMap,
110.135 - SetFlowMapTraits<_FlowMap> > Create;
110.136 + SetFlowMapTraits<T> > Create;
110.137 };
110.138
110.139 - template <typename _Elevator>
110.140 + template <typename T>
110.141 struct SetElevatorTraits : public Traits {
110.142 - typedef _Elevator Elevator;
110.143 + typedef T Elevator;
110.144 static Elevator *createElevator(const Digraph&, int) {
110.145 LEMON_ASSERT(false, "Elevator is not initialized");
110.146 return 0; // ignore warnings
110.147 @@ -233,16 +242,16 @@
110.148 /// \ref elevator(Elevator&) "elevator()" function before calling
110.149 /// \ref run() or \ref init().
110.150 /// \sa SetStandardElevator
110.151 - template <typename _Elevator>
110.152 + template <typename T>
110.153 struct SetElevator
110.154 - : public Preflow<Digraph, CapacityMap, SetElevatorTraits<_Elevator> > {
110.155 + : public Preflow<Digraph, CapacityMap, SetElevatorTraits<T> > {
110.156 typedef Preflow<Digraph, CapacityMap,
110.157 - SetElevatorTraits<_Elevator> > Create;
110.158 + SetElevatorTraits<T> > Create;
110.159 };
110.160
110.161 - template <typename _Elevator>
110.162 + template <typename T>
110.163 struct SetStandardElevatorTraits : public Traits {
110.164 - typedef _Elevator Elevator;
110.165 + typedef T Elevator;
110.166 static Elevator *createElevator(const Digraph& digraph, int max_level) {
110.167 return new Elevator(digraph, max_level);
110.168 }
110.169 @@ -260,12 +269,12 @@
110.170 /// algorithm with the \ref elevator(Elevator&) "elevator()" function
110.171 /// before calling \ref run() or \ref init().
110.172 /// \sa SetElevator
110.173 - template <typename _Elevator>
110.174 + template <typename T>
110.175 struct SetStandardElevator
110.176 : public Preflow<Digraph, CapacityMap,
110.177 - SetStandardElevatorTraits<_Elevator> > {
110.178 + SetStandardElevatorTraits<T> > {
110.179 typedef Preflow<Digraph, CapacityMap,
110.180 - SetStandardElevatorTraits<_Elevator> > Create;
110.181 + SetStandardElevatorTraits<T> > Create;
110.182 };
110.183
110.184 /// @}
110.185 @@ -370,26 +379,28 @@
110.186 return *_level;
110.187 }
110.188
110.189 - /// \brief Sets the tolerance used by algorithm.
110.190 + /// \brief Sets the tolerance used by the algorithm.
110.191 ///
110.192 - /// Sets the tolerance used by algorithm.
110.193 - Preflow& tolerance(const Tolerance& tolerance) const {
110.194 + /// Sets the tolerance object used by the algorithm.
110.195 + /// \return <tt>(*this)</tt>
110.196 + Preflow& tolerance(const Tolerance& tolerance) {
110.197 _tolerance = tolerance;
110.198 return *this;
110.199 }
110.200
110.201 /// \brief Returns a const reference to the tolerance.
110.202 ///
110.203 - /// Returns a const reference to the tolerance.
110.204 + /// Returns a const reference to the tolerance object used by
110.205 + /// the algorithm.
110.206 const Tolerance& tolerance() const {
110.207 - return tolerance;
110.208 + return _tolerance;
110.209 }
110.210
110.211 /// \name Execution Control
110.212 /// The simplest way to execute the preflow algorithm is to use
110.213 /// \ref run() or \ref runMinCut().\n
110.214 - /// If you need more control on the initial solution or the execution,
110.215 - /// first you have to call one of the \ref init() functions, then
110.216 + /// If you need better control on the initial solution or the execution,
110.217 + /// you have to call one of the \ref init() functions first, then
110.218 /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
110.219
110.220 ///@{
110.221 @@ -403,7 +414,7 @@
110.222
110.223 _phase = true;
110.224 for (NodeIt n(_graph); n != INVALID; ++n) {
110.225 - _excess->set(n, 0);
110.226 + (*_excess)[n] = 0;
110.227 }
110.228
110.229 for (ArcIt e(_graph); e != INVALID; ++e) {
110.230 @@ -416,10 +427,10 @@
110.231 _level->initAddItem(_target);
110.232
110.233 std::vector<Node> queue;
110.234 - reached.set(_source, true);
110.235 + reached[_source] = true;
110.236
110.237 queue.push_back(_target);
110.238 - reached.set(_target, true);
110.239 + reached[_target] = true;
110.240 while (!queue.empty()) {
110.241 _level->initNewLevel();
110.242 std::vector<Node> nqueue;
110.243 @@ -428,7 +439,7 @@
110.244 for (InArcIt e(_graph, n); e != INVALID; ++e) {
110.245 Node u = _graph.source(e);
110.246 if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
110.247 - reached.set(u, true);
110.248 + reached[u] = true;
110.249 _level->initAddItem(u);
110.250 nqueue.push_back(u);
110.251 }
110.252 @@ -443,7 +454,7 @@
110.253 Node u = _graph.target(e);
110.254 if ((*_level)[u] == _level->maxLevel()) continue;
110.255 _flow->set(e, (*_capacity)[e]);
110.256 - _excess->set(u, (*_excess)[u] + (*_capacity)[e]);
110.257 + (*_excess)[u] += (*_capacity)[e];
110.258 if (u != _target && !_level->active(u)) {
110.259 _level->activate(u);
110.260 }
110.261 @@ -477,7 +488,7 @@
110.262 excess -= (*_flow)[e];
110.263 }
110.264 if (excess < 0 && n != _source) return false;
110.265 - _excess->set(n, excess);
110.266 + (*_excess)[n] = excess;
110.267 }
110.268
110.269 typename Digraph::template NodeMap<bool> reached(_graph, false);
110.270 @@ -486,10 +497,10 @@
110.271 _level->initAddItem(_target);
110.272
110.273 std::vector<Node> queue;
110.274 - reached.set(_source, true);
110.275 + reached[_source] = true;
110.276
110.277 queue.push_back(_target);
110.278 - reached.set(_target, true);
110.279 + reached[_target] = true;
110.280 while (!queue.empty()) {
110.281 _level->initNewLevel();
110.282 std::vector<Node> nqueue;
110.283 @@ -499,7 +510,7 @@
110.284 Node u = _graph.source(e);
110.285 if (!reached[u] &&
110.286 _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
110.287 - reached.set(u, true);
110.288 + reached[u] = true;
110.289 _level->initAddItem(u);
110.290 nqueue.push_back(u);
110.291 }
110.292 @@ -507,7 +518,7 @@
110.293 for (OutArcIt e(_graph, n); e != INVALID; ++e) {
110.294 Node v = _graph.target(e);
110.295 if (!reached[v] && _tolerance.positive((*_flow)[e])) {
110.296 - reached.set(v, true);
110.297 + reached[v] = true;
110.298 _level->initAddItem(v);
110.299 nqueue.push_back(v);
110.300 }
110.301 @@ -523,7 +534,7 @@
110.302 Node u = _graph.target(e);
110.303 if ((*_level)[u] == _level->maxLevel()) continue;
110.304 _flow->set(e, (*_capacity)[e]);
110.305 - _excess->set(u, (*_excess)[u] + rem);
110.306 + (*_excess)[u] += rem;
110.307 if (u != _target && !_level->active(u)) {
110.308 _level->activate(u);
110.309 }
110.310 @@ -535,7 +546,7 @@
110.311 Node v = _graph.source(e);
110.312 if ((*_level)[v] == _level->maxLevel()) continue;
110.313 _flow->set(e, 0);
110.314 - _excess->set(v, (*_excess)[v] + rem);
110.315 + (*_excess)[v] += rem;
110.316 if (v != _target && !_level->active(v)) {
110.317 _level->activate(v);
110.318 }
110.319 @@ -576,12 +587,12 @@
110.320 }
110.321 if (!_tolerance.less(rem, excess)) {
110.322 _flow->set(e, (*_flow)[e] + excess);
110.323 - _excess->set(v, (*_excess)[v] + excess);
110.324 + (*_excess)[v] += excess;
110.325 excess = 0;
110.326 goto no_more_push_1;
110.327 } else {
110.328 excess -= rem;
110.329 - _excess->set(v, (*_excess)[v] + rem);
110.330 + (*_excess)[v] += rem;
110.331 _flow->set(e, (*_capacity)[e]);
110.332 }
110.333 } else if (new_level > (*_level)[v]) {
110.334 @@ -599,12 +610,12 @@
110.335 }
110.336 if (!_tolerance.less(rem, excess)) {
110.337 _flow->set(e, (*_flow)[e] - excess);
110.338 - _excess->set(v, (*_excess)[v] + excess);
110.339 + (*_excess)[v] += excess;
110.340 excess = 0;
110.341 goto no_more_push_1;
110.342 } else {
110.343 excess -= rem;
110.344 - _excess->set(v, (*_excess)[v] + rem);
110.345 + (*_excess)[v] += rem;
110.346 _flow->set(e, 0);
110.347 }
110.348 } else if (new_level > (*_level)[v]) {
110.349 @@ -614,7 +625,7 @@
110.350
110.351 no_more_push_1:
110.352
110.353 - _excess->set(n, excess);
110.354 + (*_excess)[n] = excess;
110.355
110.356 if (excess != 0) {
110.357 if (new_level + 1 < _level->maxLevel()) {
110.358 @@ -649,12 +660,12 @@
110.359 }
110.360 if (!_tolerance.less(rem, excess)) {
110.361 _flow->set(e, (*_flow)[e] + excess);
110.362 - _excess->set(v, (*_excess)[v] + excess);
110.363 + (*_excess)[v] += excess;
110.364 excess = 0;
110.365 goto no_more_push_2;
110.366 } else {
110.367 excess -= rem;
110.368 - _excess->set(v, (*_excess)[v] + rem);
110.369 + (*_excess)[v] += rem;
110.370 _flow->set(e, (*_capacity)[e]);
110.371 }
110.372 } else if (new_level > (*_level)[v]) {
110.373 @@ -672,12 +683,12 @@
110.374 }
110.375 if (!_tolerance.less(rem, excess)) {
110.376 _flow->set(e, (*_flow)[e] - excess);
110.377 - _excess->set(v, (*_excess)[v] + excess);
110.378 + (*_excess)[v] += excess;
110.379 excess = 0;
110.380 goto no_more_push_2;
110.381 } else {
110.382 excess -= rem;
110.383 - _excess->set(v, (*_excess)[v] + rem);
110.384 + (*_excess)[v] += rem;
110.385 _flow->set(e, 0);
110.386 }
110.387 } else if (new_level > (*_level)[v]) {
110.388 @@ -687,7 +698,7 @@
110.389
110.390 no_more_push_2:
110.391
110.392 - _excess->set(n, excess);
110.393 + (*_excess)[n] = excess;
110.394
110.395 if (excess != 0) {
110.396 if (new_level + 1 < _level->maxLevel()) {
110.397 @@ -730,7 +741,7 @@
110.398
110.399 typename Digraph::template NodeMap<bool> reached(_graph);
110.400 for (NodeIt n(_graph); n != INVALID; ++n) {
110.401 - reached.set(n, (*_level)[n] < _level->maxLevel());
110.402 + reached[n] = (*_level)[n] < _level->maxLevel();
110.403 }
110.404
110.405 _level->initStart();
110.406 @@ -738,7 +749,7 @@
110.407
110.408 std::vector<Node> queue;
110.409 queue.push_back(_source);
110.410 - reached.set(_source, true);
110.411 + reached[_source] = true;
110.412
110.413 while (!queue.empty()) {
110.414 _level->initNewLevel();
110.415 @@ -748,7 +759,7 @@
110.416 for (OutArcIt e(_graph, n); e != INVALID; ++e) {
110.417 Node v = _graph.target(e);
110.418 if (!reached[v] && _tolerance.positive((*_flow)[e])) {
110.419 - reached.set(v, true);
110.420 + reached[v] = true;
110.421 _level->initAddItem(v);
110.422 nqueue.push_back(v);
110.423 }
110.424 @@ -757,7 +768,7 @@
110.425 Node u = _graph.source(e);
110.426 if (!reached[u] &&
110.427 _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
110.428 - reached.set(u, true);
110.429 + reached[u] = true;
110.430 _level->initAddItem(u);
110.431 nqueue.push_back(u);
110.432 }
110.433 @@ -791,12 +802,12 @@
110.434 }
110.435 if (!_tolerance.less(rem, excess)) {
110.436 _flow->set(e, (*_flow)[e] + excess);
110.437 - _excess->set(v, (*_excess)[v] + excess);
110.438 + (*_excess)[v] += excess;
110.439 excess = 0;
110.440 goto no_more_push;
110.441 } else {
110.442 excess -= rem;
110.443 - _excess->set(v, (*_excess)[v] + rem);
110.444 + (*_excess)[v] += rem;
110.445 _flow->set(e, (*_capacity)[e]);
110.446 }
110.447 } else if (new_level > (*_level)[v]) {
110.448 @@ -814,12 +825,12 @@
110.449 }
110.450 if (!_tolerance.less(rem, excess)) {
110.451 _flow->set(e, (*_flow)[e] - excess);
110.452 - _excess->set(v, (*_excess)[v] + excess);
110.453 + (*_excess)[v] += excess;
110.454 excess = 0;
110.455 goto no_more_push;
110.456 } else {
110.457 excess -= rem;
110.458 - _excess->set(v, (*_excess)[v] + rem);
110.459 + (*_excess)[v] += rem;
110.460 _flow->set(e, 0);
110.461 }
110.462 } else if (new_level > (*_level)[v]) {
110.463 @@ -829,7 +840,7 @@
110.464
110.465 no_more_push:
110.466
110.467 - _excess->set(n, excess);
110.468 + (*_excess)[n] = excess;
110.469
110.470 if (excess != 0) {
110.471 if (new_level + 1 < _level->maxLevel()) {
110.472 @@ -900,9 +911,9 @@
110.473 return (*_excess)[_target];
110.474 }
110.475
110.476 - /// \brief Returns the flow on the given arc.
110.477 + /// \brief Returns the flow value on the given arc.
110.478 ///
110.479 - /// Returns the flow on the given arc. This method can
110.480 + /// Returns the flow value on the given arc. This method can
110.481 /// be called after the second phase of the algorithm.
110.482 ///
110.483 /// \pre Either \ref run() or \ref init() must be called before
110.484 @@ -946,7 +957,7 @@
110.485 /// could be slightly different if inexact computation is used.
110.486 ///
110.487 /// \note This function calls \ref minCut() for each node, so it runs in
110.488 - /// \f$O(n)\f$ time.
110.489 + /// O(n) time.
110.490 ///
110.491 /// \pre Either \ref run() or \ref init() must be called before
110.492 /// using this function.
111.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
111.2 +++ b/lemon/radix_heap.h Thu Nov 05 15:48:01 2009 +0100
111.3 @@ -0,0 +1,438 @@
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_RADIX_HEAP_H
111.23 +#define LEMON_RADIX_HEAP_H
111.24 +
111.25 +///\ingroup heaps
111.26 +///\file
111.27 +///\brief Radix heap implementation.
111.28 +
111.29 +#include <vector>
111.30 +#include <lemon/error.h>
111.31 +
111.32 +namespace lemon {
111.33 +
111.34 +
111.35 + /// \ingroup heaps
111.36 + ///
111.37 + /// \brief Radix heap data structure.
111.38 + ///
111.39 + /// This class implements the \e radix \e heap data structure.
111.40 + /// It practically conforms to the \ref concepts::Heap "heap concept",
111.41 + /// but it has some limitations due its special implementation.
111.42 + /// The type of the priorities must be \c int and the priority of an
111.43 + /// item cannot be decreased under the priority of the last removed item.
111.44 + ///
111.45 + /// \tparam IM A read-writable item map with \c int values, used
111.46 + /// internally to handle the cross references.
111.47 + template <typename IM>
111.48 + class RadixHeap {
111.49 +
111.50 + public:
111.51 +
111.52 + /// Type of the item-int map.
111.53 + typedef IM ItemIntMap;
111.54 + /// Type of the priorities.
111.55 + typedef int Prio;
111.56 + /// Type of the items stored in the heap.
111.57 + typedef typename ItemIntMap::Key Item;
111.58 +
111.59 + /// \brief Exception thrown by RadixHeap.
111.60 + ///
111.61 + /// This exception is thrown when an item is inserted into a
111.62 + /// RadixHeap with a priority smaller than the last erased one.
111.63 + /// \see RadixHeap
111.64 + class PriorityUnderflowError : public Exception {
111.65 + public:
111.66 + virtual const char* what() const throw() {
111.67 + return "lemon::RadixHeap::PriorityUnderflowError";
111.68 + }
111.69 + };
111.70 +
111.71 + /// \brief Type to represent the states of the items.
111.72 + ///
111.73 + /// Each item has a state associated to it. It can be "in heap",
111.74 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
111.75 + /// heap's point of view, but may be useful to the user.
111.76 + ///
111.77 + /// The item-int map must be initialized in such way that it assigns
111.78 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
111.79 + enum State {
111.80 + IN_HEAP = 0, ///< = 0.
111.81 + PRE_HEAP = -1, ///< = -1.
111.82 + POST_HEAP = -2 ///< = -2.
111.83 + };
111.84 +
111.85 + private:
111.86 +
111.87 + struct RadixItem {
111.88 + int prev, next, box;
111.89 + Item item;
111.90 + int prio;
111.91 + RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
111.92 + };
111.93 +
111.94 + struct RadixBox {
111.95 + int first;
111.96 + int min, size;
111.97 + RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
111.98 + };
111.99 +
111.100 + std::vector<RadixItem> _data;
111.101 + std::vector<RadixBox> _boxes;
111.102 +
111.103 + ItemIntMap &_iim;
111.104 +
111.105 + public:
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 minimum The initial minimum value of the heap.
111.114 + /// \param capacity The initial capacity of the heap.
111.115 + RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0)
111.116 + : _iim(map)
111.117 + {
111.118 + _boxes.push_back(RadixBox(minimum, 1));
111.119 + _boxes.push_back(RadixBox(minimum + 1, 1));
111.120 + while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
111.121 + extend();
111.122 + }
111.123 + }
111.124 +
111.125 + /// \brief The number of items stored in the heap.
111.126 + ///
111.127 + /// This function returns the number of items stored in the heap.
111.128 + int size() const { return _data.size(); }
111.129 +
111.130 + /// \brief Check if the heap is empty.
111.131 + ///
111.132 + /// This function returns \c true if the heap is empty.
111.133 + bool empty() const { return _data.empty(); }
111.134 +
111.135 + /// \brief Make the heap empty.
111.136 + ///
111.137 + /// This functon makes the heap empty.
111.138 + /// It does not change the cross reference map. If you want to reuse
111.139 + /// a heap that is not surely empty, you should first clear it and
111.140 + /// then you should set the cross reference map to \c PRE_HEAP
111.141 + /// for each item.
111.142 + /// \param minimum The minimum value of the heap.
111.143 + /// \param capacity The capacity of the heap.
111.144 + void clear(int minimum = 0, int capacity = 0) {
111.145 + _data.clear(); _boxes.clear();
111.146 + _boxes.push_back(RadixBox(minimum, 1));
111.147 + _boxes.push_back(RadixBox(minimum + 1, 1));
111.148 + while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
111.149 + extend();
111.150 + }
111.151 + }
111.152 +
111.153 + private:
111.154 +
111.155 + bool upper(int box, Prio pr) {
111.156 + return pr < _boxes[box].min;
111.157 + }
111.158 +
111.159 + bool lower(int box, Prio pr) {
111.160 + return pr >= _boxes[box].min + _boxes[box].size;
111.161 + }
111.162 +
111.163 + // Remove item from the box list
111.164 + void remove(int index) {
111.165 + if (_data[index].prev >= 0) {
111.166 + _data[_data[index].prev].next = _data[index].next;
111.167 + } else {
111.168 + _boxes[_data[index].box].first = _data[index].next;
111.169 + }
111.170 + if (_data[index].next >= 0) {
111.171 + _data[_data[index].next].prev = _data[index].prev;
111.172 + }
111.173 + }
111.174 +
111.175 + // Insert item into the box list
111.176 + void insert(int box, int index) {
111.177 + if (_boxes[box].first == -1) {
111.178 + _boxes[box].first = index;
111.179 + _data[index].next = _data[index].prev = -1;
111.180 + } else {
111.181 + _data[index].next = _boxes[box].first;
111.182 + _data[_boxes[box].first].prev = index;
111.183 + _data[index].prev = -1;
111.184 + _boxes[box].first = index;
111.185 + }
111.186 + _data[index].box = box;
111.187 + }
111.188 +
111.189 + // Add a new box to the box list
111.190 + void extend() {
111.191 + int min = _boxes.back().min + _boxes.back().size;
111.192 + int bs = 2 * _boxes.back().size;
111.193 + _boxes.push_back(RadixBox(min, bs));
111.194 + }
111.195 +
111.196 + // Move an item up into the proper box.
111.197 + void bubbleUp(int index) {
111.198 + if (!lower(_data[index].box, _data[index].prio)) return;
111.199 + remove(index);
111.200 + int box = findUp(_data[index].box, _data[index].prio);
111.201 + insert(box, index);
111.202 + }
111.203 +
111.204 + // Find up the proper box for the item with the given priority
111.205 + int findUp(int start, int pr) {
111.206 + while (lower(start, pr)) {
111.207 + if (++start == int(_boxes.size())) {
111.208 + extend();
111.209 + }
111.210 + }
111.211 + return start;
111.212 + }
111.213 +
111.214 + // Move an item down into the proper box
111.215 + void bubbleDown(int index) {
111.216 + if (!upper(_data[index].box, _data[index].prio)) return;
111.217 + remove(index);
111.218 + int box = findDown(_data[index].box, _data[index].prio);
111.219 + insert(box, index);
111.220 + }
111.221 +
111.222 + // Find down the proper box for the item with the given priority
111.223 + int findDown(int start, int pr) {
111.224 + while (upper(start, pr)) {
111.225 + if (--start < 0) throw PriorityUnderflowError();
111.226 + }
111.227 + return start;
111.228 + }
111.229 +
111.230 + // Find the first non-empty box
111.231 + int findFirst() {
111.232 + int first = 0;
111.233 + while (_boxes[first].first == -1) ++first;
111.234 + return first;
111.235 + }
111.236 +
111.237 + // Gives back the minimum priority of the given box
111.238 + int minValue(int box) {
111.239 + int min = _data[_boxes[box].first].prio;
111.240 + for (int k = _boxes[box].first; k != -1; k = _data[k].next) {
111.241 + if (_data[k].prio < min) min = _data[k].prio;
111.242 + }
111.243 + return min;
111.244 + }
111.245 +
111.246 + // Rearrange the items of the heap and make the first box non-empty
111.247 + void moveDown() {
111.248 + int box = findFirst();
111.249 + if (box == 0) return;
111.250 + int min = minValue(box);
111.251 + for (int i = 0; i <= box; ++i) {
111.252 + _boxes[i].min = min;
111.253 + min += _boxes[i].size;
111.254 + }
111.255 + int curr = _boxes[box].first, next;
111.256 + while (curr != -1) {
111.257 + next = _data[curr].next;
111.258 + bubbleDown(curr);
111.259 + curr = next;
111.260 + }
111.261 + }
111.262 +
111.263 + void relocateLast(int index) {
111.264 + if (index != int(_data.size()) - 1) {
111.265 + _data[index] = _data.back();
111.266 + if (_data[index].prev != -1) {
111.267 + _data[_data[index].prev].next = index;
111.268 + } else {
111.269 + _boxes[_data[index].box].first = index;
111.270 + }
111.271 + if (_data[index].next != -1) {
111.272 + _data[_data[index].next].prev = index;
111.273 + }
111.274 + _iim[_data[index].item] = index;
111.275 + }
111.276 + _data.pop_back();
111.277 + }
111.278 +
111.279 + public:
111.280 +
111.281 + /// \brief Insert an item into the heap with the given priority.
111.282 + ///
111.283 + /// This function inserts the given item into the heap with the
111.284 + /// given priority.
111.285 + /// \param i The item to insert.
111.286 + /// \param p The priority of the item.
111.287 + /// \pre \e i must not be stored in the heap.
111.288 + /// \warning This method may throw an \c UnderFlowPriorityException.
111.289 + void push(const Item &i, const Prio &p) {
111.290 + int n = _data.size();
111.291 + _iim.set(i, n);
111.292 + _data.push_back(RadixItem(i, p));
111.293 + while (lower(_boxes.size() - 1, p)) {
111.294 + extend();
111.295 + }
111.296 + int box = findDown(_boxes.size() - 1, p);
111.297 + insert(box, n);
111.298 + }
111.299 +
111.300 + /// \brief Return the item having minimum priority.
111.301 + ///
111.302 + /// This function returns the item having minimum priority.
111.303 + /// \pre The heap must be non-empty.
111.304 + Item top() const {
111.305 + const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
111.306 + return _data[_boxes[0].first].item;
111.307 + }
111.308 +
111.309 + /// \brief The minimum priority.
111.310 + ///
111.311 + /// This function returns the minimum priority.
111.312 + /// \pre The heap must be non-empty.
111.313 + Prio prio() const {
111.314 + const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
111.315 + return _data[_boxes[0].first].prio;
111.316 + }
111.317 +
111.318 + /// \brief Remove the item having minimum priority.
111.319 + ///
111.320 + /// This function removes the item having minimum priority.
111.321 + /// \pre The heap must be non-empty.
111.322 + void pop() {
111.323 + moveDown();
111.324 + int index = _boxes[0].first;
111.325 + _iim[_data[index].item] = POST_HEAP;
111.326 + remove(index);
111.327 + relocateLast(index);
111.328 + }
111.329 +
111.330 + /// \brief Remove the given item from the heap.
111.331 + ///
111.332 + /// This function removes the given item from the heap if it is
111.333 + /// already stored.
111.334 + /// \param i The item to delete.
111.335 + /// \pre \e i must be in the heap.
111.336 + void erase(const Item &i) {
111.337 + int index = _iim[i];
111.338 + _iim[i] = POST_HEAP;
111.339 + remove(index);
111.340 + relocateLast(index);
111.341 + }
111.342 +
111.343 + /// \brief The priority of the given item.
111.344 + ///
111.345 + /// This function returns the priority of the given item.
111.346 + /// \param i The item.
111.347 + /// \pre \e i must be in the heap.
111.348 + Prio operator[](const Item &i) const {
111.349 + int idx = _iim[i];
111.350 + return _data[idx].prio;
111.351 + }
111.352 +
111.353 + /// \brief Set the priority of an item or insert it, if it is
111.354 + /// not stored in the heap.
111.355 + ///
111.356 + /// This method sets the priority of the given item if it is
111.357 + /// already stored in the heap. Otherwise it inserts the given
111.358 + /// item into the heap with the given priority.
111.359 + /// \param i The item.
111.360 + /// \param p The priority.
111.361 + /// \pre \e i must be in the heap.
111.362 + /// \warning This method may throw an \c UnderFlowPriorityException.
111.363 + void set(const Item &i, const Prio &p) {
111.364 + int idx = _iim[i];
111.365 + if( idx < 0 ) {
111.366 + push(i, p);
111.367 + }
111.368 + else if( p >= _data[idx].prio ) {
111.369 + _data[idx].prio = p;
111.370 + bubbleUp(idx);
111.371 + } else {
111.372 + _data[idx].prio = p;
111.373 + bubbleDown(idx);
111.374 + }
111.375 + }
111.376 +
111.377 + /// \brief Decrease the priority of an item to the given value.
111.378 + ///
111.379 + /// This function decreases the priority of an item to the given value.
111.380 + /// \param i The item.
111.381 + /// \param p The priority.
111.382 + /// \pre \e i must be stored in the heap with priority at least \e p.
111.383 + /// \warning This method may throw an \c UnderFlowPriorityException.
111.384 + void decrease(const Item &i, const Prio &p) {
111.385 + int idx = _iim[i];
111.386 + _data[idx].prio = p;
111.387 + bubbleDown(idx);
111.388 + }
111.389 +
111.390 + /// \brief Increase the priority of an item to the given value.
111.391 + ///
111.392 + /// This function increases the priority of an item to the given value.
111.393 + /// \param i The item.
111.394 + /// \param p The priority.
111.395 + /// \pre \e i must be stored in the heap with priority at most \e p.
111.396 + void increase(const Item &i, const Prio &p) {
111.397 + int idx = _iim[i];
111.398 + _data[idx].prio = p;
111.399 + bubbleUp(idx);
111.400 + }
111.401 +
111.402 + /// \brief Return the state of an item.
111.403 + ///
111.404 + /// This method returns \c PRE_HEAP if the given item has never
111.405 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
111.406 + /// and \c POST_HEAP otherwise.
111.407 + /// In the latter case it is possible that the item will get back
111.408 + /// to the heap again.
111.409 + /// \param i The item.
111.410 + State state(const Item &i) const {
111.411 + int s = _iim[i];
111.412 + if( s >= 0 ) s = 0;
111.413 + return State(s);
111.414 + }
111.415 +
111.416 + /// \brief Set the state of an item in the heap.
111.417 + ///
111.418 + /// This function sets the state of the given item in the heap.
111.419 + /// It can be used to manually clear the heap when it is important
111.420 + /// to achive better time complexity.
111.421 + /// \param i The item.
111.422 + /// \param st The state. It should not be \c IN_HEAP.
111.423 + void state(const Item& i, State st) {
111.424 + switch (st) {
111.425 + case POST_HEAP:
111.426 + case PRE_HEAP:
111.427 + if (state(i) == IN_HEAP) {
111.428 + erase(i);
111.429 + }
111.430 + _iim[i] = st;
111.431 + break;
111.432 + case IN_HEAP:
111.433 + break;
111.434 + }
111.435 + }
111.436 +
111.437 + }; // class RadixHeap
111.438 +
111.439 +} // namespace lemon
111.440 +
111.441 +#endif // LEMON_RADIX_HEAP_H
112.1 --- a/lemon/radix_sort.h Mon Jan 12 23:11:39 2009 +0100
112.2 +++ b/lemon/radix_sort.h Thu Nov 05 15:48:01 2009 +0100
112.3 @@ -205,11 +205,11 @@
112.4 /// the identity function instead.
112.5 ///
112.6 /// This is a special quick sort algorithm where the pivot
112.7 - /// values to split the items are choosen to be \f$ 2^k \f$ for each \c k.
112.8 - /// Therefore, the time complexity of the
112.9 - /// algorithm is \f$ O(\log(c)n) \f$ and it uses \f$ O(\log(c)) \f$,
112.10 - /// additional space, where \c c is the maximal value and \c n is the
112.11 - /// number of the items in the container.
112.12 + /// values to split the items are choosen to be 2<sup>k</sup>
112.13 + /// for each \c k.
112.14 + /// Therefore, the time complexity of the algorithm is O(log(c)*n) and
112.15 + /// it uses O(log(c)) additional space, where \c c is the maximal value
112.16 + /// and \c n is the number of the items in the container.
112.17 ///
112.18 /// \param first The begin of the given range.
112.19 /// \param last The end of the given range.
112.20 @@ -430,10 +430,10 @@
112.21 /// bytes of the integer number. The algorithm sorts the items
112.22 /// byte-by-byte. First, it counts how many times a byte value occurs
112.23 /// in the container, then it copies the corresponding items to
112.24 - /// another container in asceding order in \c O(n) time.
112.25 + /// another container in asceding order in O(n) time.
112.26 ///
112.27 - /// The time complexity of the algorithm is \f$ O(\log(c)n) \f$ and
112.28 - /// it uses \f$ O(n) \f$, additional space, where \c c is the
112.29 + /// The time complexity of the algorithm is O(log(c)*n) and
112.30 + /// it uses O(n) additional space, where \c c is the
112.31 /// maximal value and \c n is the number of the items in the
112.32 /// container.
112.33 ///
113.1 --- a/lemon/random.h Mon Jan 12 23:11:39 2009 +0100
113.2 +++ b/lemon/random.h Thu Nov 05 15:48:01 2009 +0100
113.3 @@ -77,7 +77,7 @@
113.4 #include <sys/types.h>
113.5 #include <unistd.h>
113.6 #else
113.7 -#include <windows.h>
113.8 +#include <lemon/bits/windows.h>
113.9 #endif
113.10
113.11 ///\ingroup misc
113.12 @@ -344,56 +344,46 @@
113.13 }
113.14 };
113.15
113.16 - template <typename Result, int exp, bool pos = (exp >= 0)>
113.17 + template <typename Result, int exp>
113.18 struct ShiftMultiplier {
113.19 static const Result multiplier() {
113.20 Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
113.21 res *= res;
113.22 - if ((exp & 1) == 1) res *= static_cast<Result>(2.0);
113.23 - return res;
113.24 - }
113.25 - };
113.26 -
113.27 - template <typename Result, int exp>
113.28 - struct ShiftMultiplier<Result, exp, false> {
113.29 - static const Result multiplier() {
113.30 - Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
113.31 - res *= res;
113.32 if ((exp & 1) == 1) res *= static_cast<Result>(0.5);
113.33 return res;
113.34 }
113.35 };
113.36
113.37 template <typename Result>
113.38 - struct ShiftMultiplier<Result, 0, true> {
113.39 + struct ShiftMultiplier<Result, 0> {
113.40 static const Result multiplier() {
113.41 return static_cast<Result>(1.0);
113.42 }
113.43 };
113.44
113.45 template <typename Result>
113.46 - struct ShiftMultiplier<Result, -20, true> {
113.47 + struct ShiftMultiplier<Result, 20> {
113.48 static const Result multiplier() {
113.49 return static_cast<Result>(1.0/1048576.0);
113.50 }
113.51 };
113.52
113.53 template <typename Result>
113.54 - struct ShiftMultiplier<Result, -32, true> {
113.55 + struct ShiftMultiplier<Result, 32> {
113.56 static const Result multiplier() {
113.57 - return static_cast<Result>(1.0/424967296.0);
113.58 + return static_cast<Result>(1.0/4294967296.0);
113.59 }
113.60 };
113.61
113.62 template <typename Result>
113.63 - struct ShiftMultiplier<Result, -53, true> {
113.64 + struct ShiftMultiplier<Result, 53> {
113.65 static const Result multiplier() {
113.66 return static_cast<Result>(1.0/9007199254740992.0);
113.67 }
113.68 };
113.69
113.70 template <typename Result>
113.71 - struct ShiftMultiplier<Result, -64, true> {
113.72 + struct ShiftMultiplier<Result, 64> {
113.73 static const Result multiplier() {
113.74 return static_cast<Result>(1.0/18446744073709551616.0);
113.75 }
113.76 @@ -413,7 +403,7 @@
113.77 static const int bits = std::numeric_limits<Word>::digits;
113.78
113.79 static Result convert(RandomCore<Word>& rnd) {
113.80 - return Shifting<Result, - shift - rest>::
113.81 + return Shifting<Result, shift + rest>::
113.82 shift(static_cast<Result>(rnd() >> (bits - rest)));
113.83 }
113.84 };
113.85 @@ -423,7 +413,7 @@
113.86 static const int bits = std::numeric_limits<Word>::digits;
113.87
113.88 static Result convert(RandomCore<Word>& rnd) {
113.89 - return Shifting<Result, - shift - bits>::
113.90 + return Shifting<Result, shift + bits>::
113.91 shift(static_cast<Result>(rnd())) +
113.92 RealConversion<Result, Word, rest-bits, shift + bits>::
113.93 convert(rnd);
113.94 @@ -613,7 +603,7 @@
113.95 /// By default, this function calls the \c seedFromFile() member
113.96 /// function with the <tt>/dev/urandom</tt> file. If it does not success,
113.97 /// it uses the \c seedFromTime().
113.98 - /// \return Currently always true.
113.99 + /// \return Currently always \c true.
113.100 bool seed() {
113.101 #ifndef WIN32
113.102 if (seedFromFile("/dev/urandom", 0)) return true;
113.103 @@ -634,7 +624,7 @@
113.104 /// entropy).
113.105 /// \param file The source file
113.106 /// \param offset The offset, from the file read.
113.107 - /// \return True when the seeding successes.
113.108 + /// \return \c true when the seeding successes.
113.109 #ifndef WIN32
113.110 bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
113.111 #else
113.112 @@ -655,23 +645,21 @@
113.113 /// Seding from process id and time. This function uses the
113.114 /// current process id and the current time for initialize the
113.115 /// random sequence.
113.116 - /// \return Currently always true.
113.117 + /// \return Currently always \c true.
113.118 bool seedFromTime() {
113.119 #ifndef WIN32
113.120 timeval tv;
113.121 gettimeofday(&tv, 0);
113.122 seed(getpid() + tv.tv_sec + tv.tv_usec);
113.123 #else
113.124 - FILETIME time;
113.125 - GetSystemTimeAsFileTime(&time);
113.126 - seed(GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime);
113.127 + seed(bits::getWinRndSeed());
113.128 #endif
113.129 return true;
113.130 }
113.131
113.132 /// @}
113.133
113.134 - ///\name Uniform distributions
113.135 + ///\name Uniform Distributions
113.136 ///
113.137 /// @{
113.138
113.139 @@ -774,7 +762,7 @@
113.140
113.141 /// @}
113.142
113.143 - ///\name Non-uniform distributions
113.144 + ///\name Non-uniform Distributions
113.145 ///
113.146 ///@{
113.147
113.148 @@ -950,7 +938,7 @@
113.149
113.150 ///@}
113.151
113.152 - ///\name Two dimensional distributions
113.153 + ///\name Two Dimensional Distributions
113.154 ///
113.155 ///@{
113.156
114.1 --- a/lemon/smart_graph.h Mon Jan 12 23:11:39 2009 +0100
114.2 +++ b/lemon/smart_graph.h Thu Nov 05 15:48:01 2009 +0100
114.3 @@ -32,10 +32,7 @@
114.4 namespace lemon {
114.5
114.6 class SmartDigraph;
114.7 - ///Base of SmartDigraph
114.8
114.9 - ///Base of SmartDigraph
114.10 - ///
114.11 class SmartDigraphBase {
114.12 protected:
114.13
114.14 @@ -55,7 +52,7 @@
114.15
114.16 public:
114.17
114.18 - typedef SmartDigraphBase Graph;
114.19 + typedef SmartDigraphBase Digraph;
114.20
114.21 class Node;
114.22 class Arc;
114.23 @@ -187,32 +184,26 @@
114.24 ///
114.25 ///\brief A smart directed graph class.
114.26 ///
114.27 - ///This is a simple and fast digraph implementation.
114.28 - ///It is also quite memory efficient, but at the price
114.29 - ///that <b> it does support only limited (only stack-like)
114.30 - ///node and arc deletions</b>.
114.31 - ///It conforms to the \ref concepts::Digraph "Digraph concept" with
114.32 - ///an important extra feature that its maps are real \ref
114.33 - ///concepts::ReferenceMap "reference map"s.
114.34 + ///\ref SmartDigraph is a simple and fast digraph implementation.
114.35 + ///It is also quite memory efficient but at the price
114.36 + ///that it does not support node and arc deletion
114.37 + ///(except for the Snapshot feature).
114.38 ///
114.39 - ///\sa concepts::Digraph.
114.40 + ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
114.41 + ///and it also provides some additional functionalities.
114.42 + ///Most of its member functions and nested classes are documented
114.43 + ///only in the concept class.
114.44 + ///
114.45 + ///\sa concepts::Digraph
114.46 + ///\sa SmartGraph
114.47 class SmartDigraph : public ExtendedSmartDigraphBase {
114.48 - public:
114.49 -
114.50 typedef ExtendedSmartDigraphBase Parent;
114.51
114.52 private:
114.53 -
114.54 - ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
114.55 -
114.56 - ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
114.57 - ///
114.58 + /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
114.59 SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
114.60 - ///\brief Assignment of SmartDigraph to another one is \e not allowed.
114.61 - ///Use DigraphCopy() instead.
114.62 -
114.63 - ///Assignment of SmartDigraph to another one is \e not allowed.
114.64 - ///Use DigraphCopy() instead.
114.65 + /// \brief Assignment of a digraph to another one is \e not allowed.
114.66 + /// Use DigraphCopy instead.
114.67 void operator=(const SmartDigraph &) {}
114.68
114.69 public:
114.70 @@ -225,79 +216,49 @@
114.71
114.72 ///Add a new node to the digraph.
114.73
114.74 - /// \return the new node.
114.75 - ///
114.76 + ///This function adds a new node to the digraph.
114.77 + ///\return The new node.
114.78 Node addNode() { return Parent::addNode(); }
114.79
114.80 ///Add a new arc to the digraph.
114.81
114.82 - ///Add a new arc to the digraph with source node \c s
114.83 + ///This function adds a new arc to the digraph with source node \c s
114.84 ///and target node \c t.
114.85 - ///\return the new arc.
114.86 - Arc addArc(const Node& s, const Node& t) {
114.87 + ///\return The new arc.
114.88 + Arc addArc(Node s, Node t) {
114.89 return Parent::addArc(s, t);
114.90 }
114.91
114.92 - /// \brief Using this it is possible to avoid the superfluous memory
114.93 - /// allocation.
114.94 -
114.95 - /// Using this it is possible to avoid the superfluous memory
114.96 - /// allocation: if you know that the digraph you want to build will
114.97 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
114.98 - /// then it is worth reserving space for this amount before starting
114.99 - /// to build the digraph.
114.100 - /// \sa reserveArc
114.101 - void reserveNode(int n) { nodes.reserve(n); };
114.102 -
114.103 - /// \brief Using this it is possible to avoid the superfluous memory
114.104 - /// allocation.
114.105 -
114.106 - /// Using this it is possible to avoid the superfluous memory
114.107 - /// allocation: if you know that the digraph you want to build will
114.108 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
114.109 - /// then it is worth reserving space for this amount before starting
114.110 - /// to build the digraph.
114.111 - /// \sa reserveNode
114.112 - void reserveArc(int m) { arcs.reserve(m); };
114.113 -
114.114 /// \brief Node validity check
114.115 ///
114.116 - /// This function gives back true if the given node is valid,
114.117 - /// ie. it is a real node of the graph.
114.118 + /// This function gives back \c true if the given node is valid,
114.119 + /// i.e. it is a real node of the digraph.
114.120 ///
114.121 /// \warning A removed node (using Snapshot) could become valid again
114.122 - /// when new nodes are added to the graph.
114.123 + /// if new nodes are added to the digraph.
114.124 bool valid(Node n) const { return Parent::valid(n); }
114.125
114.126 /// \brief Arc validity check
114.127 ///
114.128 - /// This function gives back true if the given arc is valid,
114.129 - /// ie. it is a real arc of the graph.
114.130 + /// This function gives back \c true if the given arc is valid,
114.131 + /// i.e. it is a real arc of the digraph.
114.132 ///
114.133 /// \warning A removed arc (using Snapshot) could become valid again
114.134 - /// when new arcs are added to the graph.
114.135 + /// if new arcs are added to the graph.
114.136 bool valid(Arc a) const { return Parent::valid(a); }
114.137
114.138 - ///Clear the digraph.
114.139 -
114.140 - ///Erase all the nodes and arcs from the digraph.
114.141 - ///
114.142 - void clear() {
114.143 - Parent::clear();
114.144 - }
114.145 -
114.146 ///Split a node.
114.147
114.148 - ///This function splits a node. First a new node is added to the digraph,
114.149 - ///then the source of each outgoing arc of \c n is moved to this new node.
114.150 - ///If \c connect is \c true (this is the default value), then a new arc
114.151 - ///from \c n to the newly created node is also added.
114.152 + ///This function splits the given node. First, a new node is added
114.153 + ///to the digraph, then the source of each outgoing arc of node \c n
114.154 + ///is moved to this new node.
114.155 + ///If the second parameter \c connect is \c true (this is the default
114.156 + ///value), then a new arc from node \c n to the newly created node
114.157 + ///is also added.
114.158 ///\return The newly created node.
114.159 ///
114.160 - ///\note The <tt>Arc</tt>s
114.161 - ///referencing a moved arc remain
114.162 - ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
114.163 - ///may be invalidated.
114.164 + ///\note All iterators remain valid.
114.165 + ///
114.166 ///\warning This functionality cannot be used together with the Snapshot
114.167 ///feature.
114.168 Node split(Node n, bool connect = true)
114.169 @@ -312,6 +273,34 @@
114.170 return b;
114.171 }
114.172
114.173 + ///Clear the digraph.
114.174 +
114.175 + ///This function erases all nodes and arcs from the digraph.
114.176 + ///
114.177 + void clear() {
114.178 + Parent::clear();
114.179 + }
114.180 +
114.181 + /// Reserve memory for nodes.
114.182 +
114.183 + /// Using this function, it is possible to avoid superfluous memory
114.184 + /// allocation: if you know that the digraph you want to build will
114.185 + /// be large (e.g. it will contain millions of nodes and/or arcs),
114.186 + /// then it is worth reserving space for this amount before starting
114.187 + /// to build the digraph.
114.188 + /// \sa reserveArc()
114.189 + void reserveNode(int n) { nodes.reserve(n); };
114.190 +
114.191 + /// Reserve memory for arcs.
114.192 +
114.193 + /// Using this function, it is possible to avoid superfluous memory
114.194 + /// allocation: if you know that the digraph you want to build will
114.195 + /// be large (e.g. it will contain millions of nodes and/or arcs),
114.196 + /// then it is worth reserving space for this amount before starting
114.197 + /// to build the digraph.
114.198 + /// \sa reserveNode()
114.199 + void reserveArc(int m) { arcs.reserve(m); };
114.200 +
114.201 public:
114.202
114.203 class Snapshot;
114.204 @@ -336,20 +325,23 @@
114.205
114.206 public:
114.207
114.208 - ///Class to make a snapshot of the digraph and to restrore to it later.
114.209 + ///Class to make a snapshot of the digraph and to restore it later.
114.210
114.211 - ///Class to make a snapshot of the digraph and to restrore to it later.
114.212 + ///Class to make a snapshot of the digraph and to restore it later.
114.213 ///
114.214 ///The newly added nodes and arcs can be removed using the
114.215 - ///restore() function.
114.216 - ///\note After you restore a state, you cannot restore
114.217 - ///a later state, in other word you cannot add again the arcs deleted
114.218 - ///by restore() using another one Snapshot instance.
114.219 + ///restore() function. This is the only way for deleting nodes and/or
114.220 + ///arcs from a SmartDigraph structure.
114.221 ///
114.222 - ///\warning If you do not use correctly the snapshot that can cause
114.223 - ///either broken program, invalid state of the digraph, valid but
114.224 - ///not the restored digraph or no change. Because the runtime performance
114.225 - ///the validity of the snapshot is not stored.
114.226 + ///\note After a state is restored, you cannot restore a later state,
114.227 + ///i.e. you cannot add the removed nodes and arcs again using
114.228 + ///another Snapshot instance.
114.229 + ///
114.230 + ///\warning Node splitting cannot be restored.
114.231 + ///\warning The validity of the snapshot is not stored due to
114.232 + ///performance reasons. If you do not use the snapshot correctly,
114.233 + ///it can cause broken program, invalid or not restored state of
114.234 + ///the digraph or no change.
114.235 class Snapshot
114.236 {
114.237 SmartDigraph *_graph;
114.238 @@ -361,39 +353,32 @@
114.239 ///Default constructor.
114.240
114.241 ///Default constructor.
114.242 - ///To actually make a snapshot you must call save().
114.243 - ///
114.244 + ///You have to call save() to actually make a snapshot.
114.245 Snapshot() : _graph(0) {}
114.246 ///Constructor that immediately makes a snapshot
114.247
114.248 - ///This constructor immediately makes a snapshot of the digraph.
114.249 - ///\param graph The digraph we make a snapshot of.
114.250 - Snapshot(SmartDigraph &graph) : _graph(&graph) {
114.251 + ///This constructor immediately makes a snapshot of the given digraph.
114.252 + ///
114.253 + Snapshot(SmartDigraph &gr) : _graph(&gr) {
114.254 node_num=_graph->nodes.size();
114.255 arc_num=_graph->arcs.size();
114.256 }
114.257
114.258 ///Make a snapshot.
114.259
114.260 - ///Make a snapshot of the digraph.
114.261 - ///
114.262 - ///This function can be called more than once. In case of a repeated
114.263 + ///This function makes a snapshot of the given digraph.
114.264 + ///It can be called more than once. In case of a repeated
114.265 ///call, the previous snapshot gets lost.
114.266 - ///\param graph The digraph we make the snapshot of.
114.267 - void save(SmartDigraph &graph)
114.268 - {
114.269 - _graph=&graph;
114.270 + void save(SmartDigraph &gr) {
114.271 + _graph=&gr;
114.272 node_num=_graph->nodes.size();
114.273 arc_num=_graph->arcs.size();
114.274 }
114.275
114.276 ///Undo the changes until a snapshot.
114.277
114.278 - ///Undo the changes until a snapshot created by save().
114.279 - ///
114.280 - ///\note After you restored a state, you cannot restore
114.281 - ///a later state, in other word you cannot add again the arcs deleted
114.282 - ///by restore().
114.283 + ///This function undos the changes until the last snapshot
114.284 + ///created by save() or Snapshot(SmartDigraph&).
114.285 void restore()
114.286 {
114.287 _graph->restoreSnapshot(*this);
114.288 @@ -422,7 +407,7 @@
114.289
114.290 public:
114.291
114.292 - typedef SmartGraphBase Digraph;
114.293 + typedef SmartGraphBase Graph;
114.294
114.295 class Node;
114.296 class Arc;
114.297 @@ -512,7 +497,7 @@
114.298 node._id = nodes.size() - 1;
114.299 }
114.300
114.301 - void next(Node& node) const {
114.302 + static void next(Node& node) {
114.303 --node._id;
114.304 }
114.305
114.306 @@ -520,7 +505,7 @@
114.307 arc._id = arcs.size() - 1;
114.308 }
114.309
114.310 - void next(Arc& arc) const {
114.311 + static void next(Arc& arc) {
114.312 --arc._id;
114.313 }
114.314
114.315 @@ -528,7 +513,7 @@
114.316 arc._id = arcs.size() / 2 - 1;
114.317 }
114.318
114.319 - void next(Edge& arc) const {
114.320 + static void next(Edge& arc) {
114.321 --arc._id;
114.322 }
114.323
114.324 @@ -625,95 +610,107 @@
114.325 ///
114.326 /// \brief A smart undirected graph class.
114.327 ///
114.328 - /// This is a simple and fast graph implementation.
114.329 - /// It is also quite memory efficient, but at the price
114.330 - /// that <b> it does support only limited (only stack-like)
114.331 - /// node and arc deletions</b>.
114.332 - /// Except from this it conforms to
114.333 - /// the \ref concepts::Graph "Graph concept".
114.334 + /// \ref SmartGraph is a simple and fast graph implementation.
114.335 + /// It is also quite memory efficient but at the price
114.336 + /// that it does not support node and edge deletion
114.337 + /// (except for the Snapshot feature).
114.338 ///
114.339 - /// It also has an
114.340 - /// important extra feature that
114.341 - /// its maps are real \ref concepts::ReferenceMap "reference map"s.
114.342 + /// This type fully conforms to the \ref concepts::Graph "Graph concept"
114.343 + /// and it also provides some additional functionalities.
114.344 + /// Most of its member functions and nested classes are documented
114.345 + /// only in the concept class.
114.346 ///
114.347 - /// \sa concepts::Graph.
114.348 - ///
114.349 + /// \sa concepts::Graph
114.350 + /// \sa SmartDigraph
114.351 class SmartGraph : public ExtendedSmartGraphBase {
114.352 + typedef ExtendedSmartGraphBase Parent;
114.353 +
114.354 private:
114.355 -
114.356 - ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
114.357 -
114.358 - ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
114.359 - ///
114.360 + /// Graphs are \e not copy constructible. Use GraphCopy instead.
114.361 SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
114.362 -
114.363 - ///\brief Assignment of SmartGraph to another one is \e not allowed.
114.364 - ///Use GraphCopy() instead.
114.365 -
114.366 - ///Assignment of SmartGraph to another one is \e not allowed.
114.367 - ///Use GraphCopy() instead.
114.368 + /// \brief Assignment of a graph to another one is \e not allowed.
114.369 + /// Use GraphCopy instead.
114.370 void operator=(const SmartGraph &) {}
114.371
114.372 public:
114.373
114.374 - typedef ExtendedSmartGraphBase Parent;
114.375 -
114.376 /// Constructor
114.377
114.378 /// Constructor.
114.379 ///
114.380 SmartGraph() {}
114.381
114.382 - ///Add a new node to the graph.
114.383 -
114.384 - /// \return the new node.
114.385 + /// \brief Add a new node to the graph.
114.386 ///
114.387 + /// This function adds a new node to the graph.
114.388 + /// \return The new node.
114.389 Node addNode() { return Parent::addNode(); }
114.390
114.391 - ///Add a new edge to the graph.
114.392 -
114.393 - ///Add a new edge to the graph with node \c s
114.394 - ///and \c t.
114.395 - ///\return the new edge.
114.396 - Edge addEdge(const Node& s, const Node& t) {
114.397 - return Parent::addEdge(s, t);
114.398 + /// \brief Add a new edge to the graph.
114.399 + ///
114.400 + /// This function adds a new edge to the graph between nodes
114.401 + /// \c u and \c v with inherent orientation from node \c u to
114.402 + /// node \c v.
114.403 + /// \return The new edge.
114.404 + Edge addEdge(Node u, Node v) {
114.405 + return Parent::addEdge(u, v);
114.406 }
114.407
114.408 /// \brief Node validity check
114.409 ///
114.410 - /// This function gives back true if the given node is valid,
114.411 - /// ie. it is a real node of the graph.
114.412 + /// This function gives back \c true if the given node is valid,
114.413 + /// i.e. it is a real node of the graph.
114.414 ///
114.415 /// \warning A removed node (using Snapshot) could become valid again
114.416 - /// when new nodes are added to the graph.
114.417 + /// if new nodes are added to the graph.
114.418 bool valid(Node n) const { return Parent::valid(n); }
114.419
114.420 + /// \brief Edge validity check
114.421 + ///
114.422 + /// This function gives back \c true if the given edge is valid,
114.423 + /// i.e. it is a real edge of the graph.
114.424 + ///
114.425 + /// \warning A removed edge (using Snapshot) could become valid again
114.426 + /// if new edges are added to the graph.
114.427 + bool valid(Edge e) const { return Parent::valid(e); }
114.428 +
114.429 /// \brief Arc validity check
114.430 ///
114.431 - /// This function gives back true if the given arc is valid,
114.432 - /// ie. it is a real arc of the graph.
114.433 + /// This function gives back \c true if the given arc is valid,
114.434 + /// i.e. it is a real arc of the graph.
114.435 ///
114.436 /// \warning A removed arc (using Snapshot) could become valid again
114.437 - /// when new edges are added to the graph.
114.438 + /// if new edges are added to the graph.
114.439 bool valid(Arc a) const { return Parent::valid(a); }
114.440
114.441 - /// \brief Edge validity check
114.442 - ///
114.443 - /// This function gives back true if the given edge is valid,
114.444 - /// ie. it is a real edge of the graph.
114.445 - ///
114.446 - /// \warning A removed edge (using Snapshot) could become valid again
114.447 - /// when new edges are added to the graph.
114.448 - bool valid(Edge e) const { return Parent::valid(e); }
114.449 -
114.450 ///Clear the graph.
114.451
114.452 - ///Erase all the nodes and edges from the graph.
114.453 + ///This function erases all nodes and arcs from the graph.
114.454 ///
114.455 void clear() {
114.456 Parent::clear();
114.457 }
114.458
114.459 + /// Reserve memory for nodes.
114.460 +
114.461 + /// Using this function, it is possible to avoid superfluous memory
114.462 + /// allocation: if you know that the graph you want to build will
114.463 + /// be large (e.g. it will contain millions of nodes and/or edges),
114.464 + /// then it is worth reserving space for this amount before starting
114.465 + /// to build the graph.
114.466 + /// \sa reserveEdge()
114.467 + void reserveNode(int n) { nodes.reserve(n); };
114.468 +
114.469 + /// Reserve memory for edges.
114.470 +
114.471 + /// Using this function, it is possible to avoid superfluous memory
114.472 + /// allocation: if you know that the graph you want to build will
114.473 + /// be large (e.g. it will contain millions of nodes and/or edges),
114.474 + /// then it is worth reserving space for this amount before starting
114.475 + /// to build the graph.
114.476 + /// \sa reserveNode()
114.477 + void reserveEdge(int m) { arcs.reserve(2 * m); };
114.478 +
114.479 public:
114.480
114.481 class Snapshot;
114.482 @@ -752,21 +749,22 @@
114.483
114.484 public:
114.485
114.486 - ///Class to make a snapshot of the digraph and to restrore to it later.
114.487 + ///Class to make a snapshot of the graph and to restore it later.
114.488
114.489 - ///Class to make a snapshot of the digraph and to restrore to it later.
114.490 + ///Class to make a snapshot of the graph and to restore it later.
114.491 ///
114.492 - ///The newly added nodes and arcs can be removed using the
114.493 - ///restore() function.
114.494 + ///The newly added nodes and edges can be removed using the
114.495 + ///restore() function. This is the only way for deleting nodes and/or
114.496 + ///edges from a SmartGraph structure.
114.497 ///
114.498 - ///\note After you restore a state, you cannot restore
114.499 - ///a later state, in other word you cannot add again the arcs deleted
114.500 - ///by restore() using another one Snapshot instance.
114.501 + ///\note After a state is restored, you cannot restore a later state,
114.502 + ///i.e. you cannot add the removed nodes and edges again using
114.503 + ///another Snapshot instance.
114.504 ///
114.505 - ///\warning If you do not use correctly the snapshot that can cause
114.506 - ///either broken program, invalid state of the digraph, valid but
114.507 - ///not the restored digraph or no change. Because the runtime performance
114.508 - ///the validity of the snapshot is not stored.
114.509 + ///\warning The validity of the snapshot is not stored due to
114.510 + ///performance reasons. If you do not use the snapshot correctly,
114.511 + ///it can cause broken program, invalid or not restored state of
114.512 + ///the graph or no change.
114.513 class Snapshot
114.514 {
114.515 SmartGraph *_graph;
114.516 @@ -778,36 +776,30 @@
114.517 ///Default constructor.
114.518
114.519 ///Default constructor.
114.520 - ///To actually make a snapshot you must call save().
114.521 - ///
114.522 + ///You have to call save() to actually make a snapshot.
114.523 Snapshot() : _graph(0) {}
114.524 ///Constructor that immediately makes a snapshot
114.525
114.526 - ///This constructor immediately makes a snapshot of the digraph.
114.527 - ///\param graph The digraph we make a snapshot of.
114.528 - Snapshot(SmartGraph &graph) {
114.529 - graph.saveSnapshot(*this);
114.530 + /// This constructor immediately makes a snapshot of the given graph.
114.531 + ///
114.532 + Snapshot(SmartGraph &gr) {
114.533 + gr.saveSnapshot(*this);
114.534 }
114.535
114.536 ///Make a snapshot.
114.537
114.538 - ///Make a snapshot of the graph.
114.539 - ///
114.540 - ///This function can be called more than once. In case of a repeated
114.541 + ///This function makes a snapshot of the given graph.
114.542 + ///It can be called more than once. In case of a repeated
114.543 ///call, the previous snapshot gets lost.
114.544 - ///\param graph The digraph we make the snapshot of.
114.545 - void save(SmartGraph &graph)
114.546 + void save(SmartGraph &gr)
114.547 {
114.548 - graph.saveSnapshot(*this);
114.549 + gr.saveSnapshot(*this);
114.550 }
114.551
114.552 - ///Undo the changes until a snapshot.
114.553 + ///Undo the changes until the last snapshot.
114.554
114.555 - ///Undo the changes until a snapshot created by save().
114.556 - ///
114.557 - ///\note After you restored a state, you cannot restore
114.558 - ///a later state, in other word you cannot add again the arcs deleted
114.559 - ///by restore().
114.560 + ///This function undos the changes until the last snapshot
114.561 + ///created by save() or Snapshot(SmartGraph&).
114.562 void restore()
114.563 {
114.564 _graph->restoreSnapshot(*this);
115.1 --- a/lemon/soplex.cc Mon Jan 12 23:11:39 2009 +0100
115.2 +++ b/lemon/soplex.cc Thu Nov 05 15:48:01 2009 +0100
115.3 @@ -19,7 +19,8 @@
115.4 #include <iostream>
115.5 #include <lemon/soplex.h>
115.6
115.7 -#include <soplex/soplex.h>
115.8 +#include <soplex.h>
115.9 +#include <spxout.h>
115.10
115.11
115.12 ///\file
115.13 @@ -28,6 +29,7 @@
115.14
115.15 SoplexLp::SoplexLp() {
115.16 soplex = new soplex::SoPlex;
115.17 + messageLevel(MESSAGE_NOTHING);
115.18 }
115.19
115.20 SoplexLp::~SoplexLp() {
115.21 @@ -47,6 +49,7 @@
115.22 _row_names = lp._row_names;
115.23 _row_names_ref = lp._row_names_ref;
115.24
115.25 + messageLevel(MESSAGE_NOTHING);
115.26 }
115.27
115.28 void SoplexLp::_clear_temporals() {
115.29 @@ -54,12 +57,12 @@
115.30 _dual_values.clear();
115.31 }
115.32
115.33 - SoplexLp* SoplexLp::_newSolver() const {
115.34 + SoplexLp* SoplexLp::newSolver() const {
115.35 SoplexLp* newlp = new SoplexLp();
115.36 return newlp;
115.37 }
115.38
115.39 - SoplexLp* SoplexLp::_cloneSolver() const {
115.40 + SoplexLp* SoplexLp::cloneSolver() const {
115.41 SoplexLp* newlp = new SoplexLp(*this);
115.42 return newlp;
115.43 }
115.44 @@ -88,6 +91,19 @@
115.45 return soplex->nRows() - 1;
115.46 }
115.47
115.48 + int SoplexLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
115.49 + soplex::DSVector v;
115.50 + for (ExprIterator it = b; it != e; ++it) {
115.51 + v.add(it->first, it->second);
115.52 + }
115.53 + soplex::LPRow r(l, v, u);
115.54 + soplex->addRow(r);
115.55 +
115.56 + _row_names.push_back(std::string());
115.57 +
115.58 + return soplex->nRows() - 1;
115.59 + }
115.60 +
115.61
115.62 void SoplexLp::_eraseCol(int i) {
115.63 soplex->removeCol(i);
115.64 @@ -271,6 +287,8 @@
115.65 SoplexLp::SolveExitStatus SoplexLp::_solve() {
115.66
115.67 _clear_temporals();
115.68 +
115.69 + _applyMessageLevel();
115.70
115.71 soplex::SPxSolver::Status status = soplex->solve();
115.72
115.73 @@ -419,5 +437,29 @@
115.74 _clear_temporals();
115.75 }
115.76
115.77 + void SoplexLp::_messageLevel(MessageLevel level) {
115.78 + switch (level) {
115.79 + case MESSAGE_NOTHING:
115.80 + _message_level = -1;
115.81 + break;
115.82 + case MESSAGE_ERROR:
115.83 + _message_level = soplex::SPxOut::ERROR;
115.84 + break;
115.85 + case MESSAGE_WARNING:
115.86 + _message_level = soplex::SPxOut::WARNING;
115.87 + break;
115.88 + case MESSAGE_NORMAL:
115.89 + _message_level = soplex::SPxOut::INFO2;
115.90 + break;
115.91 + case MESSAGE_VERBOSE:
115.92 + _message_level = soplex::SPxOut::DEBUG;
115.93 + break;
115.94 + }
115.95 + }
115.96 +
115.97 + void SoplexLp::_applyMessageLevel() {
115.98 + soplex::Param::setVerbose(_message_level);
115.99 + }
115.100 +
115.101 } //namespace lemon
115.102
116.1 --- a/lemon/soplex.h Mon Jan 12 23:11:39 2009 +0100
116.2 +++ b/lemon/soplex.h Thu Nov 05 15:48:01 2009 +0100
116.3 @@ -73,16 +73,18 @@
116.4 SoplexLp(const SoplexLp&);
116.5 /// \e
116.6 ~SoplexLp();
116.7 + /// \e
116.8 + virtual SoplexLp* newSolver() const;
116.9 + /// \e
116.10 + virtual SoplexLp* cloneSolver() const;
116.11
116.12 protected:
116.13
116.14 - virtual SoplexLp* _newSolver() const;
116.15 - virtual SoplexLp* _cloneSolver() const;
116.16 -
116.17 virtual const char* _solverName() const;
116.18
116.19 virtual int _addCol();
116.20 virtual int _addRow();
116.21 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
116.22
116.23 virtual void _eraseCol(int i);
116.24 virtual void _eraseRow(int i);
116.25 @@ -143,6 +145,11 @@
116.26
116.27 virtual void _clear();
116.28
116.29 + void _messageLevel(MessageLevel m);
116.30 + void _applyMessageLevel();
116.31 +
116.32 + int _message_level;
116.33 +
116.34 };
116.35
116.36 } //END OF NAMESPACE LEMON
117.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
117.2 +++ b/lemon/static_graph.h Thu Nov 05 15:48:01 2009 +0100
117.3 @@ -0,0 +1,474 @@
117.4 +/* -*- C++ -*-
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_STATIC_GRAPH_H
117.23 +#define LEMON_STATIC_GRAPH_H
117.24 +
117.25 +///\ingroup graphs
117.26 +///\file
117.27 +///\brief StaticDigraph class.
117.28 +
117.29 +#include <lemon/core.h>
117.30 +#include <lemon/bits/graph_extender.h>
117.31 +
117.32 +namespace lemon {
117.33 +
117.34 + class StaticDigraphBase {
117.35 + public:
117.36 +
117.37 + StaticDigraphBase()
117.38 + : built(false), node_num(0), arc_num(0),
117.39 + node_first_out(NULL), node_first_in(NULL),
117.40 + arc_source(NULL), arc_target(NULL),
117.41 + arc_next_in(NULL), arc_next_out(NULL) {}
117.42 +
117.43 + ~StaticDigraphBase() {
117.44 + if (built) {
117.45 + delete[] node_first_out;
117.46 + delete[] node_first_in;
117.47 + delete[] arc_source;
117.48 + delete[] arc_target;
117.49 + delete[] arc_next_out;
117.50 + delete[] arc_next_in;
117.51 + }
117.52 + }
117.53 +
117.54 + class Node {
117.55 + friend class StaticDigraphBase;
117.56 + protected:
117.57 + int id;
117.58 + Node(int _id) : id(_id) {}
117.59 + public:
117.60 + Node() {}
117.61 + Node (Invalid) : id(-1) {}
117.62 + bool operator==(const Node& node) const { return id == node.id; }
117.63 + bool operator!=(const Node& node) const { return id != node.id; }
117.64 + bool operator<(const Node& node) const { return id < node.id; }
117.65 + };
117.66 +
117.67 + class Arc {
117.68 + friend class StaticDigraphBase;
117.69 + protected:
117.70 + int id;
117.71 + Arc(int _id) : id(_id) {}
117.72 + public:
117.73 + Arc() { }
117.74 + Arc (Invalid) : id(-1) {}
117.75 + bool operator==(const Arc& arc) const { return id == arc.id; }
117.76 + bool operator!=(const Arc& arc) const { return id != arc.id; }
117.77 + bool operator<(const Arc& arc) const { return id < arc.id; }
117.78 + };
117.79 +
117.80 + Node source(const Arc& e) const { return Node(arc_source[e.id]); }
117.81 + Node target(const Arc& e) const { return Node(arc_target[e.id]); }
117.82 +
117.83 + void first(Node& n) const { n.id = node_num - 1; }
117.84 + static void next(Node& n) { --n.id; }
117.85 +
117.86 + void first(Arc& e) const { e.id = arc_num - 1; }
117.87 + static void next(Arc& e) { --e.id; }
117.88 +
117.89 + void firstOut(Arc& e, const Node& n) const {
117.90 + e.id = node_first_out[n.id] != node_first_out[n.id + 1] ?
117.91 + node_first_out[n.id] : -1;
117.92 + }
117.93 + void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; }
117.94 +
117.95 + void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; }
117.96 + void nextIn(Arc& e) const { e.id = arc_next_in[e.id]; }
117.97 +
117.98 + static int id(const Node& n) { return n.id; }
117.99 + static Node nodeFromId(int id) { return Node(id); }
117.100 + int maxNodeId() const { return node_num - 1; }
117.101 +
117.102 + static int id(const Arc& e) { return e.id; }
117.103 + static Arc arcFromId(int id) { return Arc(id); }
117.104 + int maxArcId() const { return arc_num - 1; }
117.105 +
117.106 + typedef True NodeNumTag;
117.107 + typedef True ArcNumTag;
117.108 +
117.109 + int nodeNum() const { return node_num; }
117.110 + int arcNum() const { return arc_num; }
117.111 +
117.112 + private:
117.113 +
117.114 + template <typename Digraph, typename NodeRefMap>
117.115 + class ArcLess {
117.116 + public:
117.117 + typedef typename Digraph::Arc Arc;
117.118 +
117.119 + ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef)
117.120 + : digraph(_graph), nodeRef(_nodeRef) {}
117.121 +
117.122 + bool operator()(const Arc& left, const Arc& right) const {
117.123 + return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
117.124 + }
117.125 + private:
117.126 + const Digraph& digraph;
117.127 + const NodeRefMap& nodeRef;
117.128 + };
117.129 +
117.130 + public:
117.131 +
117.132 + typedef True BuildTag;
117.133 +
117.134 + void clear() {
117.135 + if (built) {
117.136 + delete[] node_first_out;
117.137 + delete[] node_first_in;
117.138 + delete[] arc_source;
117.139 + delete[] arc_target;
117.140 + delete[] arc_next_out;
117.141 + delete[] arc_next_in;
117.142 + }
117.143 + built = false;
117.144 + node_num = 0;
117.145 + arc_num = 0;
117.146 + }
117.147 +
117.148 + template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
117.149 + void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
117.150 + typedef typename Digraph::Node GNode;
117.151 + typedef typename Digraph::Arc GArc;
117.152 +
117.153 + built = true;
117.154 +
117.155 + node_num = countNodes(digraph);
117.156 + arc_num = countArcs(digraph);
117.157 +
117.158 + node_first_out = new int[node_num + 1];
117.159 + node_first_in = new int[node_num];
117.160 +
117.161 + arc_source = new int[arc_num];
117.162 + arc_target = new int[arc_num];
117.163 + arc_next_out = new int[arc_num];
117.164 + arc_next_in = new int[arc_num];
117.165 +
117.166 + int node_index = 0;
117.167 + for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
117.168 + nodeRef[n] = Node(node_index);
117.169 + node_first_in[node_index] = -1;
117.170 + ++node_index;
117.171 + }
117.172 +
117.173 + ArcLess<Digraph, NodeRefMap> arcLess(digraph, nodeRef);
117.174 +
117.175 + int arc_index = 0;
117.176 + for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
117.177 + int source = nodeRef[n].id;
117.178 + std::vector<GArc> arcs;
117.179 + for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) {
117.180 + arcs.push_back(e);
117.181 + }
117.182 + if (!arcs.empty()) {
117.183 + node_first_out[source] = arc_index;
117.184 + std::sort(arcs.begin(), arcs.end(), arcLess);
117.185 + for (typename std::vector<GArc>::iterator it = arcs.begin();
117.186 + it != arcs.end(); ++it) {
117.187 + int target = nodeRef[digraph.target(*it)].id;
117.188 + arcRef[*it] = Arc(arc_index);
117.189 + arc_source[arc_index] = source;
117.190 + arc_target[arc_index] = target;
117.191 + arc_next_in[arc_index] = node_first_in[target];
117.192 + node_first_in[target] = arc_index;
117.193 + arc_next_out[arc_index] = arc_index + 1;
117.194 + ++arc_index;
117.195 + }
117.196 + arc_next_out[arc_index - 1] = -1;
117.197 + } else {
117.198 + node_first_out[source] = arc_index;
117.199 + }
117.200 + }
117.201 + node_first_out[node_num] = arc_num;
117.202 + }
117.203 +
117.204 + template <typename ArcListIterator>
117.205 + void build(int n, ArcListIterator first, ArcListIterator last) {
117.206 + built = true;
117.207 +
117.208 + node_num = n;
117.209 + arc_num = std::distance(first, last);
117.210 +
117.211 + node_first_out = new int[node_num + 1];
117.212 + node_first_in = new int[node_num];
117.213 +
117.214 + arc_source = new int[arc_num];
117.215 + arc_target = new int[arc_num];
117.216 + arc_next_out = new int[arc_num];
117.217 + arc_next_in = new int[arc_num];
117.218 +
117.219 + for (int i = 0; i != node_num; ++i) {
117.220 + node_first_in[i] = -1;
117.221 + }
117.222 +
117.223 + int arc_index = 0;
117.224 + for (int i = 0; i != node_num; ++i) {
117.225 + node_first_out[i] = arc_index;
117.226 + for ( ; first != last && (*first).first == i; ++first) {
117.227 + int j = (*first).second;
117.228 + LEMON_ASSERT(j >= 0 && j < node_num,
117.229 + "Wrong arc list for StaticDigraph::build()");
117.230 + arc_source[arc_index] = i;
117.231 + arc_target[arc_index] = j;
117.232 + arc_next_in[arc_index] = node_first_in[j];
117.233 + node_first_in[j] = arc_index;
117.234 + arc_next_out[arc_index] = arc_index + 1;
117.235 + ++arc_index;
117.236 + }
117.237 + if (arc_index > node_first_out[i])
117.238 + arc_next_out[arc_index - 1] = -1;
117.239 + }
117.240 + LEMON_ASSERT(first == last,
117.241 + "Wrong arc list for StaticDigraph::build()");
117.242 + node_first_out[node_num] = arc_num;
117.243 + }
117.244 +
117.245 + protected:
117.246 +
117.247 + void fastFirstOut(Arc& e, const Node& n) const {
117.248 + e.id = node_first_out[n.id];
117.249 + }
117.250 +
117.251 + static void fastNextOut(Arc& e) {
117.252 + ++e.id;
117.253 + }
117.254 + void fastLastOut(Arc& e, const Node& n) const {
117.255 + e.id = node_first_out[n.id + 1];
117.256 + }
117.257 +
117.258 + protected:
117.259 + bool built;
117.260 + int node_num;
117.261 + int arc_num;
117.262 + int *node_first_out;
117.263 + int *node_first_in;
117.264 + int *arc_source;
117.265 + int *arc_target;
117.266 + int *arc_next_in;
117.267 + int *arc_next_out;
117.268 + };
117.269 +
117.270 + typedef DigraphExtender<StaticDigraphBase> ExtendedStaticDigraphBase;
117.271 +
117.272 +
117.273 + /// \ingroup graphs
117.274 + ///
117.275 + /// \brief A static directed graph class.
117.276 + ///
117.277 + /// \ref StaticDigraph is a highly efficient digraph implementation,
117.278 + /// but it is fully static.
117.279 + /// It stores only two \c int values for each node and only four \c int
117.280 + /// values for each arc. Moreover it provides faster item iteration than
117.281 + /// \ref ListDigraph and \ref SmartDigraph, especially using \c OutArcIt
117.282 + /// iterators, since its arcs are stored in an appropriate order.
117.283 + /// However it only provides build() and clear() functions and does not
117.284 + /// support any other modification of the digraph.
117.285 + ///
117.286 + /// Since this digraph structure is completely static, its nodes and arcs
117.287 + /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt>
117.288 + /// and <tt>[0..arcNum()-1]</tt>, respectively.
117.289 + /// The index of an item is the same as its ID, it can be obtained
117.290 + /// using the corresponding \ref index() or \ref concepts::Digraph::id()
117.291 + /// "id()" function. A node or arc with a certain index can be obtained
117.292 + /// using node() or arc().
117.293 + ///
117.294 + /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
117.295 + /// Most of its member functions and nested classes are documented
117.296 + /// only in the concept class.
117.297 + ///
117.298 + /// \sa concepts::Digraph
117.299 + class StaticDigraph : public ExtendedStaticDigraphBase {
117.300 + public:
117.301 +
117.302 + typedef ExtendedStaticDigraphBase Parent;
117.303 +
117.304 + public:
117.305 +
117.306 + /// \brief Constructor
117.307 + ///
117.308 + /// Default constructor.
117.309 + StaticDigraph() : Parent() {}
117.310 +
117.311 + /// \brief The node with the given index.
117.312 + ///
117.313 + /// This function returns the node with the given index.
117.314 + /// \sa index()
117.315 + static Node node(int ix) { return Parent::nodeFromId(ix); }
117.316 +
117.317 + /// \brief The arc with the given index.
117.318 + ///
117.319 + /// This function returns the arc with the given index.
117.320 + /// \sa index()
117.321 + static Arc arc(int ix) { return Parent::arcFromId(ix); }
117.322 +
117.323 + /// \brief The index of the given node.
117.324 + ///
117.325 + /// This function returns the index of the the given node.
117.326 + /// \sa node()
117.327 + static int index(Node node) { return Parent::id(node); }
117.328 +
117.329 + /// \brief The index of the given arc.
117.330 + ///
117.331 + /// This function returns the index of the the given arc.
117.332 + /// \sa arc()
117.333 + static int index(Arc arc) { return Parent::id(arc); }
117.334 +
117.335 + /// \brief Number of nodes.
117.336 + ///
117.337 + /// This function returns the number of nodes.
117.338 + int nodeNum() const { return node_num; }
117.339 +
117.340 + /// \brief Number of arcs.
117.341 + ///
117.342 + /// This function returns the number of arcs.
117.343 + int arcNum() const { return arc_num; }
117.344 +
117.345 + /// \brief Build the digraph copying another digraph.
117.346 + ///
117.347 + /// This function builds the digraph copying another digraph of any
117.348 + /// kind. It can be called more than once, but in such case, the whole
117.349 + /// structure and all maps will be cleared and rebuilt.
117.350 + ///
117.351 + /// This method also makes possible to copy a digraph to a StaticDigraph
117.352 + /// structure using \ref DigraphCopy.
117.353 + ///
117.354 + /// \param digraph An existing digraph to be copied.
117.355 + /// \param nodeRef The node references will be copied into this map.
117.356 + /// Its key type must be \c Digraph::Node and its value type must be
117.357 + /// \c StaticDigraph::Node.
117.358 + /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
117.359 + /// concept.
117.360 + /// \param arcRef The arc references will be copied into this map.
117.361 + /// Its key type must be \c Digraph::Arc and its value type must be
117.362 + /// \c StaticDigraph::Arc.
117.363 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
117.364 + ///
117.365 + /// \note If you do not need the arc references, then you could use
117.366 + /// \ref NullMap for the last parameter. However the node references
117.367 + /// are required by the function itself, thus they must be readable
117.368 + /// from the map.
117.369 + template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
117.370 + void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
117.371 + if (built) Parent::clear();
117.372 + Parent::build(digraph, nodeRef, arcRef);
117.373 + }
117.374 +
117.375 + /// \brief Build the digraph from an arc list.
117.376 + ///
117.377 + /// This function builds the digraph from the given arc list.
117.378 + /// It can be called more than once, but in such case, the whole
117.379 + /// structure and all maps will be cleared and rebuilt.
117.380 + ///
117.381 + /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
117.382 + /// specified by STL compatible itartors whose \c value_type must be
117.383 + /// <tt>std::pair<int,int></tt>.
117.384 + /// Each arc must be specified by a pair of integer indices
117.385 + /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
117.386 + /// non-decreasing order with respect to their first values.</i>
117.387 + /// If the k-th pair in the list is <tt>(i,j)</tt>, then
117.388 + /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
117.389 + ///
117.390 + /// \param n The number of nodes.
117.391 + /// \param begin An iterator pointing to the beginning of the arc list.
117.392 + /// \param end An iterator pointing to the end of the arc list.
117.393 + ///
117.394 + /// For example, a simple digraph can be constructed like this.
117.395 + /// \code
117.396 + /// std::vector<std::pair<int,int> > arcs;
117.397 + /// arcs.push_back(std::make_pair(0,1));
117.398 + /// arcs.push_back(std::make_pair(0,2));
117.399 + /// arcs.push_back(std::make_pair(1,3));
117.400 + /// arcs.push_back(std::make_pair(1,2));
117.401 + /// arcs.push_back(std::make_pair(3,0));
117.402 + /// StaticDigraph gr;
117.403 + /// gr.build(4, arcs.begin(), arcs.end());
117.404 + /// \endcode
117.405 + template <typename ArcListIterator>
117.406 + void build(int n, ArcListIterator begin, ArcListIterator end) {
117.407 + if (built) Parent::clear();
117.408 + StaticDigraphBase::build(n, begin, end);
117.409 + notifier(Node()).build();
117.410 + notifier(Arc()).build();
117.411 + }
117.412 +
117.413 + /// \brief Clear the digraph.
117.414 + ///
117.415 + /// This function erases all nodes and arcs from the digraph.
117.416 + void clear() {
117.417 + Parent::clear();
117.418 + }
117.419 +
117.420 + protected:
117.421 +
117.422 + using Parent::fastFirstOut;
117.423 + using Parent::fastNextOut;
117.424 + using Parent::fastLastOut;
117.425 +
117.426 + public:
117.427 +
117.428 + class OutArcIt : public Arc {
117.429 + public:
117.430 +
117.431 + OutArcIt() { }
117.432 +
117.433 + OutArcIt(Invalid i) : Arc(i) { }
117.434 +
117.435 + OutArcIt(const StaticDigraph& digraph, const Node& node) {
117.436 + digraph.fastFirstOut(*this, node);
117.437 + digraph.fastLastOut(last, node);
117.438 + if (last == *this) *this = INVALID;
117.439 + }
117.440 +
117.441 + OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) {
117.442 + if (arc != INVALID) {
117.443 + digraph.fastLastOut(last, digraph.source(arc));
117.444 + }
117.445 + }
117.446 +
117.447 + OutArcIt& operator++() {
117.448 + StaticDigraph::fastNextOut(*this);
117.449 + if (last == *this) *this = INVALID;
117.450 + return *this;
117.451 + }
117.452 +
117.453 + private:
117.454 + Arc last;
117.455 + };
117.456 +
117.457 + Node baseNode(const OutArcIt &arc) const {
117.458 + return Parent::source(static_cast<const Arc&>(arc));
117.459 + }
117.460 +
117.461 + Node runningNode(const OutArcIt &arc) const {
117.462 + return Parent::target(static_cast<const Arc&>(arc));
117.463 + }
117.464 +
117.465 + Node baseNode(const InArcIt &arc) const {
117.466 + return Parent::target(static_cast<const Arc&>(arc));
117.467 + }
117.468 +
117.469 + Node runningNode(const InArcIt &arc) const {
117.470 + return Parent::source(static_cast<const Arc&>(arc));
117.471 + }
117.472 +
117.473 + };
117.474 +
117.475 +}
117.476 +
117.477 +#endif
118.1 --- a/lemon/suurballe.h Mon Jan 12 23:11:39 2009 +0100
118.2 +++ b/lemon/suurballe.h Thu Nov 05 15:48:01 2009 +0100
118.3 @@ -25,8 +25,11 @@
118.4 /// nodes having minimum total length.
118.5
118.6 #include <vector>
118.7 +#include <limits>
118.8 #include <lemon/bin_heap.h>
118.9 #include <lemon/path.h>
118.10 +#include <lemon/list_graph.h>
118.11 +#include <lemon/maps.h>
118.12
118.13 namespace lemon {
118.14
118.15 @@ -40,51 +43,65 @@
118.16 /// finding arc-disjoint paths having minimum total length (cost)
118.17 /// from a given source node to a given target node in a digraph.
118.18 ///
118.19 - /// In fact, this implementation is the specialization of the
118.20 - /// \ref CapacityScaling "successive shortest path" algorithm.
118.21 + /// Note that this problem is a special case of the \ref min_cost_flow
118.22 + /// "minimum cost flow problem". This implementation is actually an
118.23 + /// efficient specialized version of the \ref CapacityScaling
118.24 + /// "Successive Shortest Path" algorithm directly for this problem.
118.25 + /// Therefore this class provides query functions for flow values and
118.26 + /// node potentials (the dual solution) just like the minimum cost flow
118.27 + /// algorithms.
118.28 ///
118.29 - /// \tparam Digraph The digraph type the algorithm runs on.
118.30 - /// The default value is \c ListDigraph.
118.31 - /// \tparam LengthMap The type of the length (cost) map.
118.32 - /// The default value is <tt>Digraph::ArcMap<int></tt>.
118.33 + /// \tparam GR The digraph type the algorithm runs on.
118.34 + /// \tparam LEN The type of the length map.
118.35 + /// The default value is <tt>GR::ArcMap<int></tt>.
118.36 ///
118.37 /// \warning Length values should be \e non-negative \e integers.
118.38 ///
118.39 /// \note For finding node-disjoint paths this algorithm can be used
118.40 - /// with \ref SplitNodes.
118.41 + /// along with the \ref SplitNodes adaptor.
118.42 #ifdef DOXYGEN
118.43 - template <typename Digraph, typename LengthMap>
118.44 + template <typename GR, typename LEN>
118.45 #else
118.46 - template < typename Digraph = ListDigraph,
118.47 - typename LengthMap = typename Digraph::template ArcMap<int> >
118.48 + template < typename GR,
118.49 + typename LEN = typename GR::template ArcMap<int> >
118.50 #endif
118.51 class Suurballe
118.52 {
118.53 - TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
118.54 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
118.55
118.56 - typedef typename LengthMap::Value Length;
118.57 typedef ConstMap<Arc, int> ConstArcMap;
118.58 - typedef typename Digraph::template NodeMap<Arc> PredMap;
118.59 + typedef typename GR::template NodeMap<Arc> PredMap;
118.60
118.61 public:
118.62
118.63 + /// The type of the digraph the algorithm runs on.
118.64 + typedef GR Digraph;
118.65 + /// The type of the length map.
118.66 + typedef LEN LengthMap;
118.67 + /// The type of the lengths.
118.68 + typedef typename LengthMap::Value Length;
118.69 +#ifdef DOXYGEN
118.70 + /// The type of the flow map.
118.71 + typedef GR::ArcMap<int> FlowMap;
118.72 + /// The type of the potential map.
118.73 + typedef GR::NodeMap<Length> PotentialMap;
118.74 +#else
118.75 /// The type of the flow map.
118.76 typedef typename Digraph::template ArcMap<int> FlowMap;
118.77 /// The type of the potential map.
118.78 typedef typename Digraph::template NodeMap<Length> PotentialMap;
118.79 +#endif
118.80 +
118.81 /// The type of the path structures.
118.82 - typedef SimplePath<Digraph> Path;
118.83 + typedef SimplePath<GR> Path;
118.84
118.85 private:
118.86
118.87 - /// \brief Special implementation of the Dijkstra algorithm
118.88 - /// for finding shortest paths in the residual network.
118.89 - ///
118.90 - /// \ref ResidualDijkstra is a special implementation of the
118.91 - /// \ref Dijkstra algorithm for finding shortest paths in the
118.92 - /// residual network of the digraph with respect to the reduced arc
118.93 - /// lengths and modifying the node potentials according to the
118.94 - /// distance of the nodes.
118.95 + // ResidualDijkstra is a special implementation of the
118.96 + // Dijkstra algorithm for finding shortest paths in the
118.97 + // residual network with respect to the reduced arc lengths
118.98 + // and modifying the node potentials according to the
118.99 + // distance of the nodes.
118.100 class ResidualDijkstra
118.101 {
118.102 typedef typename Digraph::template NodeMap<int> HeapCrossRef;
118.103 @@ -113,14 +130,14 @@
118.104 public:
118.105
118.106 /// Constructor.
118.107 - ResidualDijkstra( const Digraph &digraph,
118.108 + ResidualDijkstra( const Digraph &graph,
118.109 const FlowMap &flow,
118.110 const LengthMap &length,
118.111 PotentialMap &potential,
118.112 PredMap &pred,
118.113 Node s, Node t ) :
118.114 - _graph(digraph), _flow(flow), _length(length), _potential(potential),
118.115 - _dist(digraph), _pred(pred), _s(s), _t(t) {}
118.116 + _graph(graph), _flow(flow), _length(length), _potential(potential),
118.117 + _dist(graph), _pred(pred), _s(s), _t(t) {}
118.118
118.119 /// \brief Run the algorithm. It returns \c true if a path is found
118.120 /// from the source node to the target node.
118.121 @@ -229,16 +246,16 @@
118.122 ///
118.123 /// Constructor.
118.124 ///
118.125 - /// \param digraph The digraph the algorithm runs on.
118.126 + /// \param graph The digraph the algorithm runs on.
118.127 /// \param length The length (cost) values of the arcs.
118.128 - /// \param s The source node.
118.129 - /// \param t The target node.
118.130 - Suurballe( const Digraph &digraph,
118.131 - const LengthMap &length,
118.132 - Node s, Node t ) :
118.133 - _graph(digraph), _length(length), _flow(0), _local_flow(false),
118.134 - _potential(0), _local_potential(false), _source(s), _target(t),
118.135 - _pred(digraph) {}
118.136 + Suurballe( const Digraph &graph,
118.137 + const LengthMap &length ) :
118.138 + _graph(graph), _length(length), _flow(0), _local_flow(false),
118.139 + _potential(0), _local_potential(false), _pred(graph)
118.140 + {
118.141 + LEMON_ASSERT(std::numeric_limits<Length>::is_integer,
118.142 + "The length type of Suurballe must be integer");
118.143 + }
118.144
118.145 /// Destructor.
118.146 ~Suurballe() {
118.147 @@ -250,11 +267,14 @@
118.148 /// \brief Set the flow map.
118.149 ///
118.150 /// This function sets the flow map.
118.151 + /// If it is not used before calling \ref run() or \ref init(),
118.152 + /// an instance will be allocated automatically. The destructor
118.153 + /// deallocates this automatically allocated map, of course.
118.154 ///
118.155 - /// The found flow contains only 0 and 1 values. It is the union of
118.156 - /// the found arc-disjoint paths.
118.157 + /// The found flow contains only 0 and 1 values, since it is the
118.158 + /// union of the found arc-disjoint paths.
118.159 ///
118.160 - /// \return \c (*this)
118.161 + /// \return <tt>(*this)</tt>
118.162 Suurballe& flowMap(FlowMap &map) {
118.163 if (_local_flow) {
118.164 delete _flow;
118.165 @@ -267,11 +287,14 @@
118.166 /// \brief Set the potential map.
118.167 ///
118.168 /// This function sets the potential map.
118.169 + /// If it is not used before calling \ref run() or \ref init(),
118.170 + /// an instance will be allocated automatically. The destructor
118.171 + /// deallocates this automatically allocated map, of course.
118.172 ///
118.173 - /// The potentials provide the dual solution of the underlying
118.174 - /// minimum cost flow problem.
118.175 + /// The node potentials provide the dual solution of the underlying
118.176 + /// \ref min_cost_flow "minimum cost flow problem".
118.177 ///
118.178 - /// \return \c (*this)
118.179 + /// \return <tt>(*this)</tt>
118.180 Suurballe& potentialMap(PotentialMap &map) {
118.181 if (_local_potential) {
118.182 delete _potential;
118.183 @@ -281,7 +304,7 @@
118.184 return *this;
118.185 }
118.186
118.187 - /// \name Execution control
118.188 + /// \name Execution Control
118.189 /// The simplest way to execute the algorithm is to call the run()
118.190 /// function.
118.191 /// \n
118.192 @@ -294,22 +317,24 @@
118.193 ///
118.194 /// This function runs the algorithm.
118.195 ///
118.196 + /// \param s The source node.
118.197 + /// \param t The target node.
118.198 /// \param k The number of paths to be found.
118.199 ///
118.200 /// \return \c k if there are at least \c k arc-disjoint paths from
118.201 /// \c s to \c t in the digraph. Otherwise it returns the number of
118.202 /// arc-disjoint paths found.
118.203 ///
118.204 - /// \note Apart from the return value, <tt>s.run(k)</tt> is just a
118.205 - /// shortcut of the following code.
118.206 + /// \note Apart from the return value, <tt>s.run(s, t, k)</tt> is
118.207 + /// just a shortcut of the following code.
118.208 /// \code
118.209 - /// s.init();
118.210 - /// s.findFlow(k);
118.211 + /// s.init(s);
118.212 + /// s.findFlow(t, k);
118.213 /// s.findPaths();
118.214 /// \endcode
118.215 - int run(int k = 2) {
118.216 - init();
118.217 - findFlow(k);
118.218 + int run(const Node& s, const Node& t, int k = 2) {
118.219 + init(s);
118.220 + findFlow(t, k);
118.221 findPaths();
118.222 return _path_num;
118.223 }
118.224 @@ -317,7 +342,11 @@
118.225 /// \brief Initialize the algorithm.
118.226 ///
118.227 /// This function initializes the algorithm.
118.228 - void init() {
118.229 + ///
118.230 + /// \param s The source node.
118.231 + void init(const Node& s) {
118.232 + _source = s;
118.233 +
118.234 // Initialize maps
118.235 if (!_flow) {
118.236 _flow = new FlowMap(_graph);
118.237 @@ -329,25 +358,28 @@
118.238 }
118.239 for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
118.240 for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
118.241 -
118.242 - _dijkstra = new ResidualDijkstra( _graph, *_flow, _length,
118.243 - *_potential, _pred,
118.244 - _source, _target );
118.245 }
118.246
118.247 - /// \brief Execute the successive shortest path algorithm to find
118.248 - /// an optimal flow.
118.249 + /// \brief Execute the algorithm to find an optimal flow.
118.250 ///
118.251 /// This function executes the successive shortest path algorithm to
118.252 - /// find a minimum cost flow, which is the union of \c k or less
118.253 + /// find a minimum cost flow, which is the union of \c k (or less)
118.254 /// arc-disjoint paths.
118.255 ///
118.256 + /// \param t The target node.
118.257 + /// \param k The number of paths to be found.
118.258 + ///
118.259 /// \return \c k if there are at least \c k arc-disjoint paths from
118.260 - /// \c s to \c t in the digraph. Otherwise it returns the number of
118.261 - /// arc-disjoint paths found.
118.262 + /// the source node to the given node \c t in the digraph.
118.263 + /// Otherwise it returns the number of arc-disjoint paths found.
118.264 ///
118.265 /// \pre \ref init() must be called before using this function.
118.266 - int findFlow(int k = 2) {
118.267 + int findFlow(const Node& t, int k = 2) {
118.268 + _target = t;
118.269 + _dijkstra =
118.270 + new ResidualDijkstra( _graph, *_flow, _length, *_potential, _pred,
118.271 + _source, _target );
118.272 +
118.273 // Find shortest paths
118.274 _path_num = 0;
118.275 while (_path_num < k) {
118.276 @@ -373,13 +405,12 @@
118.277
118.278 /// \brief Compute the paths from the flow.
118.279 ///
118.280 - /// This function computes the paths from the flow.
118.281 + /// This function computes the paths from the found minimum cost flow,
118.282 + /// which is the union of some arc-disjoint paths.
118.283 ///
118.284 /// \pre \ref init() and \ref findFlow() must be called before using
118.285 /// this function.
118.286 void findPaths() {
118.287 - // Create the residual flow map (the union of the paths not found
118.288 - // so far)
118.289 FlowMap res_flow(_graph);
118.290 for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
118.291
118.292 @@ -406,10 +437,37 @@
118.293
118.294 /// @{
118.295
118.296 - /// \brief Return a const reference to the arc map storing the
118.297 + /// \brief Return the total length of the found paths.
118.298 + ///
118.299 + /// This function returns the total length of the found paths, i.e.
118.300 + /// the total cost of the found flow.
118.301 + /// The complexity of the function is O(e).
118.302 + ///
118.303 + /// \pre \ref run() or \ref findFlow() must be called before using
118.304 + /// this function.
118.305 + Length totalLength() const {
118.306 + Length c = 0;
118.307 + for (ArcIt e(_graph); e != INVALID; ++e)
118.308 + c += (*_flow)[e] * _length[e];
118.309 + return c;
118.310 + }
118.311 +
118.312 + /// \brief Return the flow value on the given arc.
118.313 + ///
118.314 + /// This function returns the flow value on the given arc.
118.315 + /// It is \c 1 if the arc is involved in one of the found arc-disjoint
118.316 + /// paths, otherwise it is \c 0.
118.317 + ///
118.318 + /// \pre \ref run() or \ref findFlow() must be called before using
118.319 + /// this function.
118.320 + int flow(const Arc& arc) const {
118.321 + return (*_flow)[arc];
118.322 + }
118.323 +
118.324 + /// \brief Return a const reference to an arc map storing the
118.325 /// found flow.
118.326 ///
118.327 - /// This function returns a const reference to the arc map storing
118.328 + /// This function returns a const reference to an arc map storing
118.329 /// the flow that is the union of the found arc-disjoint paths.
118.330 ///
118.331 /// \pre \ref run() or \ref findFlow() must be called before using
118.332 @@ -418,34 +476,11 @@
118.333 return *_flow;
118.334 }
118.335
118.336 - /// \brief Return a const reference to the node map storing the
118.337 - /// found potentials (the dual solution).
118.338 - ///
118.339 - /// This function returns a const reference to the node map storing
118.340 - /// the found potentials that provide the dual solution of the
118.341 - /// underlying minimum cost flow problem.
118.342 - ///
118.343 - /// \pre \ref run() or \ref findFlow() must be called before using
118.344 - /// this function.
118.345 - const PotentialMap& potentialMap() const {
118.346 - return *_potential;
118.347 - }
118.348 -
118.349 - /// \brief Return the flow on the given arc.
118.350 - ///
118.351 - /// This function returns the flow on the given arc.
118.352 - /// It is \c 1 if the arc is involved in one of the found paths,
118.353 - /// otherwise it is \c 0.
118.354 - ///
118.355 - /// \pre \ref run() or \ref findFlow() must be called before using
118.356 - /// this function.
118.357 - int flow(const Arc& arc) const {
118.358 - return (*_flow)[arc];
118.359 - }
118.360 -
118.361 /// \brief Return the potential of the given node.
118.362 ///
118.363 /// This function returns the potential of the given node.
118.364 + /// The node potentials provide the dual solution of the
118.365 + /// underlying \ref min_cost_flow "minimum cost flow problem".
118.366 ///
118.367 /// \pre \ref run() or \ref findFlow() must be called before using
118.368 /// this function.
118.369 @@ -453,18 +488,17 @@
118.370 return (*_potential)[node];
118.371 }
118.372
118.373 - /// \brief Return the total length (cost) of the found paths (flow).
118.374 + /// \brief Return a const reference to a node map storing the
118.375 + /// found potentials (the dual solution).
118.376 ///
118.377 - /// This function returns the total length (cost) of the found paths
118.378 - /// (flow). The complexity of the function is \f$ O(e) \f$.
118.379 + /// This function returns a const reference to a node map storing
118.380 + /// the found potentials that provide the dual solution of the
118.381 + /// underlying \ref min_cost_flow "minimum cost flow problem".
118.382 ///
118.383 /// \pre \ref run() or \ref findFlow() must be called before using
118.384 /// this function.
118.385 - Length totalLength() const {
118.386 - Length c = 0;
118.387 - for (ArcIt e(_graph); e != INVALID; ++e)
118.388 - c += (*_flow)[e] * _length[e];
118.389 - return c;
118.390 + const PotentialMap& potentialMap() const {
118.391 + return *_potential;
118.392 }
118.393
118.394 /// \brief Return the number of the found paths.
118.395 @@ -481,7 +515,7 @@
118.396 ///
118.397 /// This function returns a const reference to the specified path.
118.398 ///
118.399 - /// \param i The function returns the \c i-th path.
118.400 + /// \param i The function returns the <tt>i</tt>-th path.
118.401 /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
118.402 ///
118.403 /// \pre \ref run() or \ref findPaths() must be called before using
119.1 --- a/lemon/time_measure.h Mon Jan 12 23:11:39 2009 +0100
119.2 +++ b/lemon/time_measure.h Thu Nov 05 15:48:01 2009 +0100
119.3 @@ -24,11 +24,9 @@
119.4 ///\brief Tools for measuring cpu usage
119.5
119.6 #ifdef WIN32
119.7 -#define WIN32_LEAN_AND_MEAN
119.8 -#define NOMINMAX
119.9 -#include <windows.h>
119.10 -#include <cmath>
119.11 +#include <lemon/bits/windows.h>
119.12 #else
119.13 +#include <unistd.h>
119.14 #include <sys/times.h>
119.15 #include <sys/time.h>
119.16 #endif
119.17 @@ -87,26 +85,7 @@
119.18 cutime=ts.tms_cutime/tck;
119.19 cstime=ts.tms_cstime/tck;
119.20 #else
119.21 - static const double ch = 4294967296.0e-7;
119.22 - static const double cl = 1.0e-7;
119.23 -
119.24 - FILETIME system;
119.25 - GetSystemTimeAsFileTime(&system);
119.26 - rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
119.27 -
119.28 - FILETIME create, exit, kernel, user;
119.29 - if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
119.30 - utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
119.31 - stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
119.32 - cutime = 0;
119.33 - cstime = 0;
119.34 - } else {
119.35 - rtime = 0;
119.36 - utime = 0;
119.37 - stime = 0;
119.38 - cutime = 0;
119.39 - cstime = 0;
119.40 - }
119.41 + bits::getWinProcTimes(rtime, utime, stime, cutime, cstime);
119.42 #endif
119.43 }
119.44
119.45 @@ -223,7 +202,7 @@
119.46 double realTime() const {return rtime;}
119.47 };
119.48
119.49 - TimeStamp operator*(double b,const TimeStamp &t)
119.50 + inline TimeStamp operator*(double b,const TimeStamp &t)
119.51 {
119.52 return t*b;
119.53 }
119.54 @@ -308,7 +287,7 @@
119.55 ///
119.56 Timer(bool run=true) :_running(run) {_reset();}
119.57
119.58 - ///\name Control the state of the timer
119.59 + ///\name Control the State of the Timer
119.60 ///Basically a Timer can be either running or stopped,
119.61 ///but it provides a bit finer control on the execution.
119.62 ///The \ref lemon::Timer "Timer" also counts the number of
119.63 @@ -416,7 +395,7 @@
119.64
119.65 ///@}
119.66
119.67 - ///\name Query Functions for the ellapsed time
119.68 + ///\name Query Functions for the Ellapsed Time
119.69
119.70 ///@{
119.71
120.1 --- a/lemon/tolerance.h Mon Jan 12 23:11:39 2009 +0100
120.2 +++ b/lemon/tolerance.h Thu Nov 05 15:48:01 2009 +0100
120.3 @@ -38,17 +38,14 @@
120.4 ///handle the comparison of numbers that are obtained
120.5 ///as a result of a probably inexact computation.
120.6 ///
120.7 - ///This is an abstract class, it should be specialized for all
120.8 - ///numerical data types. These specialized classes like
120.9 + ///The general implementation is suitable only if the data type is exact,
120.10 + ///like the integer types, otherwise a specialized version must be
120.11 + ///implemented. These specialized classes like
120.12 ///Tolerance<double> may offer additional tuning parameters.
120.13 ///
120.14 ///\sa Tolerance<float>
120.15 ///\sa Tolerance<double>
120.16 ///\sa Tolerance<long double>
120.17 - ///\sa Tolerance<int>
120.18 - ///\sa Tolerance<long long int>
120.19 - ///\sa Tolerance<unsigned int>
120.20 - ///\sa Tolerance<unsigned long long int>
120.21
120.22 template<class T>
120.23 class Tolerance
120.24 @@ -64,20 +61,20 @@
120.25 ///@{
120.26
120.27 ///Returns \c true if \c a is \e surely strictly less than \c b
120.28 - static bool less(Value a,Value b) {return false;}
120.29 + static bool less(Value a,Value b) {return a<b;}
120.30 ///Returns \c true if \c a is \e surely different from \c b
120.31 - static bool different(Value a,Value b) {return false;}
120.32 + static bool different(Value a,Value b) {return a!=b;}
120.33 ///Returns \c true if \c a is \e surely positive
120.34 - static bool positive(Value a) {return false;}
120.35 + static bool positive(Value a) {return static_cast<Value>(0) < a;}
120.36 ///Returns \c true if \c a is \e surely negative
120.37 - static bool negative(Value a) {return false;}
120.38 + static bool negative(Value a) {return a < static_cast<Value>(0);}
120.39 ///Returns \c true if \c a is \e surely non-zero
120.40 - static bool nonZero(Value a) {return false;}
120.41 + static bool nonZero(Value a) {return a != static_cast<Value>(0);}
120.42
120.43 ///@}
120.44
120.45 ///Returns the zero value.
120.46 - static Value zero() {return T();}
120.47 + static Value zero() {return static_cast<Value>(0);}
120.48
120.49 // static bool finite(Value a) {}
120.50 // static Value big() {}
120.51 @@ -238,213 +235,6 @@
120.52 static Value zero() {return 0;}
120.53 };
120.54
120.55 - ///Integer specialization of Tolerance.
120.56 -
120.57 - ///Integer specialization of Tolerance.
120.58 - ///\sa Tolerance
120.59 - template<>
120.60 - class Tolerance<int>
120.61 - {
120.62 - public:
120.63 - ///\e
120.64 - typedef int Value;
120.65 -
120.66 - ///\name Comparisons
120.67 - ///See \ref lemon::Tolerance "Tolerance" for more details.
120.68 -
120.69 - ///@{
120.70 -
120.71 - ///Returns \c true if \c a is \e surely strictly less than \c b
120.72 - static bool less(Value a,Value b) { return a<b;}
120.73 - ///Returns \c true if \c a is \e surely different from \c b
120.74 - static bool different(Value a,Value b) { return a!=b; }
120.75 - ///Returns \c true if \c a is \e surely positive
120.76 - static bool positive(Value a) { return 0<a; }
120.77 - ///Returns \c true if \c a is \e surely negative
120.78 - static bool negative(Value a) { return 0>a; }
120.79 - ///Returns \c true if \c a is \e surely non-zero
120.80 - static bool nonZero(Value a) { return a!=0; }
120.81 -
120.82 - ///@}
120.83 -
120.84 - ///Returns zero
120.85 - static Value zero() {return 0;}
120.86 - };
120.87 -
120.88 - ///Unsigned integer specialization of Tolerance.
120.89 -
120.90 - ///Unsigned integer specialization of Tolerance.
120.91 - ///\sa Tolerance
120.92 - template<>
120.93 - class Tolerance<unsigned int>
120.94 - {
120.95 - public:
120.96 - ///\e
120.97 - typedef unsigned int Value;
120.98 -
120.99 - ///\name Comparisons
120.100 - ///See \ref lemon::Tolerance "Tolerance" for more details.
120.101 -
120.102 - ///@{
120.103 -
120.104 - ///Returns \c true if \c a is \e surely strictly less than \c b
120.105 - static bool less(Value a,Value b) { return a<b;}
120.106 - ///Returns \c true if \c a is \e surely different from \c b
120.107 - static bool different(Value a,Value b) { return a!=b; }
120.108 - ///Returns \c true if \c a is \e surely positive
120.109 - static bool positive(Value a) { return 0<a; }
120.110 - ///Returns \c true if \c a is \e surely negative
120.111 - static bool negative(Value) { return false; }
120.112 - ///Returns \c true if \c a is \e surely non-zero
120.113 - static bool nonZero(Value a) { return a!=0; }
120.114 -
120.115 - ///@}
120.116 -
120.117 - ///Returns zero
120.118 - static Value zero() {return 0;}
120.119 - };
120.120 -
120.121 -
120.122 - ///Long integer specialization of Tolerance.
120.123 -
120.124 - ///Long integer specialization of Tolerance.
120.125 - ///\sa Tolerance
120.126 - template<>
120.127 - class Tolerance<long int>
120.128 - {
120.129 - public:
120.130 - ///\e
120.131 - typedef long int Value;
120.132 -
120.133 - ///\name Comparisons
120.134 - ///See \ref lemon::Tolerance "Tolerance" for more details.
120.135 -
120.136 - ///@{
120.137 -
120.138 - ///Returns \c true if \c a is \e surely strictly less than \c b
120.139 - static bool less(Value a,Value b) { return a<b;}
120.140 - ///Returns \c true if \c a is \e surely different from \c b
120.141 - static bool different(Value a,Value b) { return a!=b; }
120.142 - ///Returns \c true if \c a is \e surely positive
120.143 - static bool positive(Value a) { return 0<a; }
120.144 - ///Returns \c true if \c a is \e surely negative
120.145 - static bool negative(Value a) { return 0>a; }
120.146 - ///Returns \c true if \c a is \e surely non-zero
120.147 - static bool nonZero(Value a) { return a!=0;}
120.148 -
120.149 - ///@}
120.150 -
120.151 - ///Returns zero
120.152 - static Value zero() {return 0;}
120.153 - };
120.154 -
120.155 - ///Unsigned long integer specialization of Tolerance.
120.156 -
120.157 - ///Unsigned long integer specialization of Tolerance.
120.158 - ///\sa Tolerance
120.159 - template<>
120.160 - class Tolerance<unsigned long int>
120.161 - {
120.162 - public:
120.163 - ///\e
120.164 - typedef unsigned long int Value;
120.165 -
120.166 - ///\name Comparisons
120.167 - ///See \ref lemon::Tolerance "Tolerance" for more details.
120.168 -
120.169 - ///@{
120.170 -
120.171 - ///Returns \c true if \c a is \e surely strictly less than \c b
120.172 - static bool less(Value a,Value b) { return a<b;}
120.173 - ///Returns \c true if \c a is \e surely different from \c b
120.174 - static bool different(Value a,Value b) { return a!=b; }
120.175 - ///Returns \c true if \c a is \e surely positive
120.176 - static bool positive(Value a) { return 0<a; }
120.177 - ///Returns \c true if \c a is \e surely negative
120.178 - static bool negative(Value) { return false; }
120.179 - ///Returns \c true if \c a is \e surely non-zero
120.180 - static bool nonZero(Value a) { return a!=0;}
120.181 -
120.182 - ///@}
120.183 -
120.184 - ///Returns zero
120.185 - static Value zero() {return 0;}
120.186 - };
120.187 -
120.188 -#if defined __GNUC__ && !defined __STRICT_ANSI__
120.189 -
120.190 - ///Long long integer specialization of Tolerance.
120.191 -
120.192 - ///Long long integer specialization of Tolerance.
120.193 - ///\warning This class (more exactly, type <tt>long long</tt>)
120.194 - ///is not ansi compatible.
120.195 - ///\sa Tolerance
120.196 - template<>
120.197 - class Tolerance<long long int>
120.198 - {
120.199 - public:
120.200 - ///\e
120.201 - typedef long long int Value;
120.202 -
120.203 - ///\name Comparisons
120.204 - ///See \ref lemon::Tolerance "Tolerance" for more details.
120.205 -
120.206 - ///@{
120.207 -
120.208 - ///Returns \c true if \c a is \e surely strictly less than \c b
120.209 - static bool less(Value a,Value b) { return a<b;}
120.210 - ///Returns \c true if \c a is \e surely different from \c b
120.211 - static bool different(Value a,Value b) { return a!=b; }
120.212 - ///Returns \c true if \c a is \e surely positive
120.213 - static bool positive(Value a) { return 0<a; }
120.214 - ///Returns \c true if \c a is \e surely negative
120.215 - static bool negative(Value a) { return 0>a; }
120.216 - ///Returns \c true if \c a is \e surely non-zero
120.217 - static bool nonZero(Value a) { return a!=0;}
120.218 -
120.219 - ///@}
120.220 -
120.221 - ///Returns zero
120.222 - static Value zero() {return 0;}
120.223 - };
120.224 -
120.225 - ///Unsigned long long integer specialization of Tolerance.
120.226 -
120.227 - ///Unsigned long long integer specialization of Tolerance.
120.228 - ///\warning This class (more exactly, type <tt>unsigned long long</tt>)
120.229 - ///is not ansi compatible.
120.230 - ///\sa Tolerance
120.231 - template<>
120.232 - class Tolerance<unsigned long long int>
120.233 - {
120.234 - public:
120.235 - ///\e
120.236 - typedef unsigned long long int Value;
120.237 -
120.238 - ///\name Comparisons
120.239 - ///See \ref lemon::Tolerance "Tolerance" for more details.
120.240 -
120.241 - ///@{
120.242 -
120.243 - ///Returns \c true if \c a is \e surely strictly less than \c b
120.244 - static bool less(Value a,Value b) { return a<b;}
120.245 - ///Returns \c true if \c a is \e surely different from \c b
120.246 - static bool different(Value a,Value b) { return a!=b; }
120.247 - ///Returns \c true if \c a is \e surely positive
120.248 - static bool positive(Value a) { return 0<a; }
120.249 - ///Returns \c true if \c a is \e surely negative
120.250 - static bool negative(Value) { return false; }
120.251 - ///Returns \c true if \c a is \e surely non-zero
120.252 - static bool nonZero(Value a) { return a!=0;}
120.253 -
120.254 - ///@}
120.255 -
120.256 - ///Returns zero
120.257 - static Value zero() {return 0;}
120.258 - };
120.259 -
120.260 -#endif
120.261 -
120.262 /// @}
120.263
120.264 } //namespace lemon
121.1 --- a/lemon/unionfind.h Mon Jan 12 23:11:39 2009 +0100
121.2 +++ b/lemon/unionfind.h Thu Nov 05 15:48:01 2009 +0100
121.3 @@ -51,11 +51,13 @@
121.4 ///
121.5 /// \pre You need to add all the elements by the \ref insert()
121.6 /// method.
121.7 - template <typename _ItemIntMap>
121.8 + template <typename IM>
121.9 class UnionFind {
121.10 public:
121.11
121.12 - typedef _ItemIntMap ItemIntMap;
121.13 + ///\e
121.14 + typedef IM ItemIntMap;
121.15 + ///\e
121.16 typedef typename ItemIntMap::Key Item;
121.17
121.18 private:
121.19 @@ -170,11 +172,13 @@
121.20 /// \pre You need to add all the elements by the \ref insert()
121.21 /// method.
121.22 ///
121.23 - template <typename _ItemIntMap>
121.24 + template <typename IM>
121.25 class UnionFindEnum {
121.26 public:
121.27
121.28 - typedef _ItemIntMap ItemIntMap;
121.29 + ///\e
121.30 + typedef IM ItemIntMap;
121.31 + ///\e
121.32 typedef typename ItemIntMap::Key Item;
121.33
121.34 private:
121.35 @@ -627,11 +631,13 @@
121.36 ///
121.37 /// \pre You need to add all the elements by the \ref insert()
121.38 /// method.
121.39 - template <typename _ItemIntMap>
121.40 + template <typename IM>
121.41 class ExtendFindEnum {
121.42 public:
121.43
121.44 - typedef _ItemIntMap ItemIntMap;
121.45 + ///\e
121.46 + typedef IM ItemIntMap;
121.47 + ///\e
121.48 typedef typename ItemIntMap::Key Item;
121.49
121.50 private:
121.51 @@ -948,18 +954,18 @@
121.52 ///
121.53 /// \pre You need to add all the elements by the \ref insert()
121.54 /// method.
121.55 - ///
121.56 - template <typename _Value, typename _ItemIntMap,
121.57 - typename _Comp = std::less<_Value> >
121.58 + template <typename V, typename IM, typename Comp = std::less<V> >
121.59 class HeapUnionFind {
121.60 public:
121.61
121.62 - typedef _Value Value;
121.63 - typedef typename _ItemIntMap::Key Item;
121.64 -
121.65 - typedef _ItemIntMap ItemIntMap;
121.66 -
121.67 - typedef _Comp Comp;
121.68 + ///\e
121.69 + typedef V Value;
121.70 + ///\e
121.71 + typedef typename IM::Key Item;
121.72 + ///\e
121.73 + typedef IM ItemIntMap;
121.74 + ///\e
121.75 + typedef Comp Compare;
121.76
121.77 private:
121.78
121.79 @@ -1601,7 +1607,7 @@
121.80
121.81 /// \brief Gives back the priority of the current item.
121.82 ///
121.83 - /// \return Gives back the priority of the current item.
121.84 + /// Gives back the priority of the current item.
121.85 const Value& operator[](const Item& item) const {
121.86 return nodes[index[item]].prio;
121.87 }
121.88 @@ -1646,7 +1652,7 @@
121.89
121.90 /// \brief Gives back the minimum priority of the class.
121.91 ///
121.92 - /// \return Gives back the minimum priority of the class.
121.93 + /// Gives back the minimum priority of the class.
121.94 const Value& classPrio(int cls) const {
121.95 return nodes[~(classes[cls].parent)].prio;
121.96 }
121.97 @@ -1660,9 +1666,9 @@
121.98
121.99 /// \brief Gives back a representant item of the class.
121.100 ///
121.101 + /// Gives back a representant item of the class.
121.102 /// The representant is indpendent from the priorities of the
121.103 /// items.
121.104 - /// \return Gives back a representant item of the class.
121.105 const Item& classRep(int id) const {
121.106 int parent = classes[id].parent;
121.107 return nodes[parent >= 0 ? classes[id].depth : leftNode(id)].item;
122.1 --- a/m4/lx_check_clp.m4 Mon Jan 12 23:11:39 2009 +0100
122.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
122.3 @@ -1,73 +0,0 @@
122.4 -AC_DEFUN([LX_CHECK_CLP],
122.5 -[
122.6 - AC_ARG_WITH([clp],
122.7 -AS_HELP_STRING([--with-clp@<:@=PREFIX@:>@], [search for CLP under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
122.8 -AS_HELP_STRING([--without-clp], [disable checking for CLP]),
122.9 - [], [with_clp=yes])
122.10 -
122.11 - AC_ARG_WITH([clp-includedir],
122.12 -AS_HELP_STRING([--with-clp-includedir=DIR], [search for CLP headers in DIR]),
122.13 - [], [with_clp_includedir=no])
122.14 -
122.15 - AC_ARG_WITH([clp-libdir],
122.16 -AS_HELP_STRING([--with-clp-libdir=DIR], [search for CLP libraries in DIR]),
122.17 - [], [with_clp_libdir=no])
122.18 -
122.19 - lx_clp_found=no
122.20 - if test x"$with_clp" != x"no"; then
122.21 - AC_MSG_CHECKING([for CLP])
122.22 -
122.23 - if test x"$with_clp_includedir" != x"no"; then
122.24 - CLP_CXXFLAGS="-I$with_clp_includedir"
122.25 - elif test x"$with_clp" != x"yes"; then
122.26 - CLP_CXXFLAGS="-I$with_clp/include"
122.27 - fi
122.28 -
122.29 - if test x"$with_clp_libdir" != x"no"; then
122.30 - CLP_LDFLAGS="-L$with_clp_libdir"
122.31 - elif test x"$with_clp" != x"yes"; then
122.32 - CLP_LDFLAGS="-L$with_clp/lib"
122.33 - fi
122.34 - CLP_LIBS="-lClp -lCoinUtils -lm"
122.35 -
122.36 - lx_save_cxxflags="$CXXFLAGS"
122.37 - lx_save_ldflags="$LDFLAGS"
122.38 - lx_save_libs="$LIBS"
122.39 - CXXFLAGS="$CLP_CXXFLAGS"
122.40 - LDFLAGS="$CLP_LDFLAGS"
122.41 - LIBS="$CLP_LIBS"
122.42 -
122.43 - lx_clp_test_prog='
122.44 - #include <coin/ClpModel.hpp>
122.45 -
122.46 - int main(int argc, char** argv)
122.47 - {
122.48 - ClpModel clp;
122.49 - return 0;
122.50 - }'
122.51 -
122.52 - AC_LANG_PUSH(C++)
122.53 - AC_LINK_IFELSE([$lx_clp_test_prog], [lx_clp_found=yes], [lx_clp_found=no])
122.54 - AC_LANG_POP(C++)
122.55 -
122.56 - CXXFLAGS="$lx_save_cxxflags"
122.57 - LDFLAGS="$lx_save_ldflags"
122.58 - LIBS="$lx_save_libs"
122.59 -
122.60 - if test x"$lx_clp_found" = x"yes"; then
122.61 - AC_DEFINE([HAVE_CLP], [1], [Define to 1 if you have CLP.])
122.62 - lx_lp_found=yes
122.63 - AC_DEFINE([HAVE_LP], [1], [Define to 1 if you have any LP solver.])
122.64 - AC_MSG_RESULT([yes])
122.65 - else
122.66 - CLP_CXXFLAGS=""
122.67 - CLP_LDFLAGS=""
122.68 - CLP_LIBS=""
122.69 - AC_MSG_RESULT([no])
122.70 - fi
122.71 - fi
122.72 - CLP_LIBS="$CLP_LDFLAGS $CLP_LIBS"
122.73 - AC_SUBST(CLP_CXXFLAGS)
122.74 - AC_SUBST(CLP_LIBS)
122.75 - AM_CONDITIONAL([HAVE_CLP], [test x"$lx_clp_found" = x"yes"])
122.76 -])
123.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
123.2 +++ b/m4/lx_check_coin.m4 Thu Nov 05 15:48:01 2009 +0100
123.3 @@ -0,0 +1,136 @@
123.4 +AC_DEFUN([LX_CHECK_COIN],
123.5 +[
123.6 + AC_ARG_WITH([coin],
123.7 +AS_HELP_STRING([--with-coin@<:@=PREFIX@:>@], [search for CLP under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
123.8 +AS_HELP_STRING([--without-coin], [disable checking for CLP]),
123.9 + [], [with_coin=yes])
123.10 +
123.11 + AC_ARG_WITH([coin-includedir],
123.12 +AS_HELP_STRING([--with-coin-includedir=DIR], [search for CLP headers in DIR]),
123.13 + [], [with_coin_includedir=no])
123.14 +
123.15 + AC_ARG_WITH([coin-libdir],
123.16 +AS_HELP_STRING([--with-coin-libdir=DIR], [search for CLP libraries in DIR]),
123.17 + [], [with_coin_libdir=no])
123.18 +
123.19 + lx_clp_found=no
123.20 + if test x"$with_coin" != x"no"; then
123.21 + AC_MSG_CHECKING([for CLP])
123.22 +
123.23 + if test x"$with_coin_includedir" != x"no"; then
123.24 + CLP_CXXFLAGS="-I$with_coin_includedir"
123.25 + elif test x"$with_coin" != x"yes"; then
123.26 + CLP_CXXFLAGS="-I$with_coin/include"
123.27 + fi
123.28 +
123.29 + if test x"$with_coin_libdir" != x"no"; then
123.30 + CLP_LDFLAGS="-L$with_coin_libdir"
123.31 + elif test x"$with_coin" != x"yes"; then
123.32 + CLP_LDFLAGS="-L$with_coin/lib"
123.33 + fi
123.34 + CLP_LIBS="-lClp -lCoinUtils -lm"
123.35 +
123.36 + lx_save_cxxflags="$CXXFLAGS"
123.37 + lx_save_ldflags="$LDFLAGS"
123.38 + lx_save_libs="$LIBS"
123.39 + CXXFLAGS="$CLP_CXXFLAGS"
123.40 + LDFLAGS="$CLP_LDFLAGS"
123.41 + LIBS="$CLP_LIBS"
123.42 +
123.43 + lx_clp_test_prog='
123.44 + #include <coin/ClpModel.hpp>
123.45 +
123.46 + int main(int argc, char** argv)
123.47 + {
123.48 + ClpModel clp;
123.49 + return 0;
123.50 + }'
123.51 +
123.52 + AC_LANG_PUSH(C++)
123.53 + AC_LINK_IFELSE([$lx_clp_test_prog], [lx_clp_found=yes], [lx_clp_found=no])
123.54 + AC_LANG_POP(C++)
123.55 +
123.56 + CXXFLAGS="$lx_save_cxxflags"
123.57 + LDFLAGS="$lx_save_ldflags"
123.58 + LIBS="$lx_save_libs"
123.59 +
123.60 + if test x"$lx_clp_found" = x"yes"; then
123.61 + AC_DEFINE([LEMON_HAVE_CLP], [1], [Define to 1 if you have CLP.])
123.62 + lx_lp_found=yes
123.63 + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
123.64 + AC_MSG_RESULT([yes])
123.65 + else
123.66 + CLP_CXXFLAGS=""
123.67 + CLP_LDFLAGS=""
123.68 + CLP_LIBS=""
123.69 + AC_MSG_RESULT([no])
123.70 + fi
123.71 + fi
123.72 + CLP_LIBS="$CLP_LDFLAGS $CLP_LIBS"
123.73 + AC_SUBST(CLP_CXXFLAGS)
123.74 + AC_SUBST(CLP_LIBS)
123.75 + AM_CONDITIONAL([HAVE_CLP], [test x"$lx_clp_found" = x"yes"])
123.76 +
123.77 +
123.78 + lx_cbc_found=no
123.79 + if test x"$lx_clp_found" = x"yes"; then
123.80 + if test x"$with_coin" != x"no"; then
123.81 + AC_MSG_CHECKING([for CBC])
123.82 +
123.83 + if test x"$with_coin_includedir" != x"no"; then
123.84 + CBC_CXXFLAGS="-I$with_coin_includedir"
123.85 + elif test x"$with_coin" != x"yes"; then
123.86 + CBC_CXXFLAGS="-I$with_coin/include"
123.87 + fi
123.88 +
123.89 + if test x"$with_coin_libdir" != x"no"; then
123.90 + CBC_LDFLAGS="-L$with_coin_libdir"
123.91 + elif test x"$with_coin" != x"yes"; then
123.92 + CBC_LDFLAGS="-L$with_coin/lib"
123.93 + fi
123.94 + CBC_LIBS="-lOsi -lCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
123.95 +
123.96 + lx_save_cxxflags="$CXXFLAGS"
123.97 + lx_save_ldflags="$LDFLAGS"
123.98 + lx_save_libs="$LIBS"
123.99 + CXXFLAGS="$CBC_CXXFLAGS"
123.100 + LDFLAGS="$CBC_LDFLAGS"
123.101 + LIBS="$CBC_LIBS"
123.102 +
123.103 + lx_cbc_test_prog='
123.104 + #include <coin/CbcModel.hpp>
123.105 +
123.106 + int main(int argc, char** argv)
123.107 + {
123.108 + CbcModel cbc;
123.109 + return 0;
123.110 + }'
123.111 +
123.112 + AC_LANG_PUSH(C++)
123.113 + AC_LINK_IFELSE([$lx_cbc_test_prog], [lx_cbc_found=yes], [lx_cbc_found=no])
123.114 + AC_LANG_POP(C++)
123.115 +
123.116 + CXXFLAGS="$lx_save_cxxflags"
123.117 + LDFLAGS="$lx_save_ldflags"
123.118 + LIBS="$lx_save_libs"
123.119 +
123.120 + if test x"$lx_cbc_found" = x"yes"; then
123.121 + AC_DEFINE([LEMON_HAVE_CBC], [1], [Define to 1 if you have CBC.])
123.122 + lx_lp_found=yes
123.123 + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
123.124 + lx_mip_found=yes
123.125 + AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
123.126 + AC_MSG_RESULT([yes])
123.127 + else
123.128 + CBC_CXXFLAGS=""
123.129 + CBC_LDFLAGS=""
123.130 + CBC_LIBS=""
123.131 + AC_MSG_RESULT([no])
123.132 + fi
123.133 + fi
123.134 + fi
123.135 + CBC_LIBS="$CBC_LDFLAGS $CBC_LIBS"
123.136 + AC_SUBST(CBC_CXXFLAGS)
123.137 + AC_SUBST(CBC_LIBS)
123.138 + AM_CONDITIONAL([HAVE_CBC], [test x"$lx_cbc_found" = x"yes"])
123.139 +])
124.1 --- a/m4/lx_check_cplex.m4 Mon Jan 12 23:11:39 2009 +0100
124.2 +++ b/m4/lx_check_cplex.m4 Thu Nov 05 15:48:01 2009 +0100
124.3 @@ -61,11 +61,11 @@
124.4 LIBS="$lx_save_libs"
124.5
124.6 if test x"$lx_cplex_found" = x"yes"; then
124.7 - AC_DEFINE([HAVE_CPLEX], [1], [Define to 1 if you have CPLEX.])
124.8 + AC_DEFINE([LEMON_HAVE_CPLEX], [1], [Define to 1 if you have CPLEX.])
124.9 lx_lp_found=yes
124.10 - AC_DEFINE([HAVE_LP], [1], [Define to 1 if you have any LP solver.])
124.11 + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
124.12 lx_mip_found=yes
124.13 - AC_DEFINE([HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
124.14 + AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
124.15 AC_MSG_RESULT([yes])
124.16 else
124.17 CPLEX_CFLAGS=""
125.1 --- a/m4/lx_check_glpk.m4 Mon Jan 12 23:11:39 2009 +0100
125.2 +++ b/m4/lx_check_glpk.m4 Thu Nov 05 15:48:01 2009 +0100
125.3 @@ -64,11 +64,11 @@
125.4 LIBS="$lx_save_libs"
125.5
125.6 if test x"$lx_glpk_found" = x"yes"; then
125.7 - AC_DEFINE([HAVE_GLPK], [1], [Define to 1 if you have GLPK.])
125.8 + AC_DEFINE([LEMON_HAVE_GLPK], [1], [Define to 1 if you have GLPK.])
125.9 lx_lp_found=yes
125.10 - AC_DEFINE([HAVE_LP], [1], [Define to 1 if you have any LP solver.])
125.11 + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
125.12 lx_mip_found=yes
125.13 - AC_DEFINE([HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
125.14 + AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
125.15 AC_MSG_RESULT([yes])
125.16 else
125.17 GLPK_CFLAGS=""
126.1 --- a/m4/lx_check_soplex.m4 Mon Jan 12 23:11:39 2009 +0100
126.2 +++ b/m4/lx_check_soplex.m4 Thu Nov 05 15:48:01 2009 +0100
126.3 @@ -20,7 +20,7 @@
126.4 if test x"$with_soplex_includedir" != x"no"; then
126.5 SOPLEX_CXXFLAGS="-I$with_soplex_includedir"
126.6 elif test x"$with_soplex" != x"yes"; then
126.7 - SOPLEX_CXXFLAGS="-I$with_soplex/include"
126.8 + SOPLEX_CXXFLAGS="-I$with_soplex/src"
126.9 fi
126.10
126.11 if test x"$with_soplex_libdir" != x"no"; then
126.12 @@ -38,7 +38,7 @@
126.13 LIBS="$SOPLEX_LIBS"
126.14
126.15 lx_soplex_test_prog='
126.16 - #include <soplex/soplex.h>
126.17 + #include <soplex.h>
126.18
126.19 int main(int argc, char** argv)
126.20 {
126.21 @@ -55,9 +55,9 @@
126.22 LIBS="$lx_save_libs"
126.23
126.24 if test x"$lx_soplex_found" = x"yes"; then
126.25 - AC_DEFINE([HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.])
126.26 + AC_DEFINE([LEMON_HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.])
126.27 lx_lp_found=yes
126.28 - AC_DEFINE([HAVE_LP], [1], [Define to 1 if you have any LP solver.])
126.29 + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
126.30 AC_MSG_RESULT([yes])
126.31 else
126.32 SOPLEX_CXXFLAGS=""
127.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
127.2 +++ b/scripts/bib2dox.py Thu Nov 05 15:48:01 2009 +0100
127.3 @@ -0,0 +1,811 @@
127.4 +#!/usr/bin/env /usr/local/Python/bin/python2.1
127.5 +"""
127.6 + BibTeX to Doxygen converter
127.7 + Usage: python bib2dox.py bibfile.bib > bibfile.dox
127.8 +
127.9 + This code is the modification of the BibTeX to XML converter
127.10 + by Vidar Bronken Gundersen et al. See the original copyright notices below.
127.11 +
127.12 + **********************************************************************
127.13 +
127.14 + Decoder for bibliographic data, BibTeX
127.15 + Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
127.16 +
127.17 + v.8
127.18 + (c)2002-06-23 Vidar Bronken Gundersen
127.19 + http://bibtexml.sf.net/
127.20 + Reuse approved as long as this notification is kept.
127.21 + Licence: GPL.
127.22 +
127.23 + Contributions/thanks to:
127.24 + Egon Willighagen, http://sf.net/projects/jreferences/
127.25 + Richard Mahoney (for providing a test case)
127.26 +
127.27 + Editted by Sara Sprenkle to be more robust and handle more bibtex features.
127.28 + (c) 2003-01-15
127.29 +
127.30 + 1. Changed bibtex: tags to bibxml: tags.
127.31 + 2. Use xmlns:bibxml="http://bibtexml.sf.net/"
127.32 + 3. Allow spaces between @type and first {
127.33 + 4. "author" fields with multiple authors split by " and "
127.34 + are put in separate xml "bibxml:author" tags.
127.35 + 5. Option for Titles: words are capitalized
127.36 + only if first letter in title or capitalized inside braces
127.37 + 6. Removes braces from within field values
127.38 + 7. Ignores comments in bibtex file (including @comment{ or % )
127.39 + 8. Replaces some special latex tags, e.g., replaces ~ with ' '
127.40 + 9. Handles bibtex @string abbreviations
127.41 + --> includes bibtex's default abbreviations for months
127.42 + --> does concatenation of abbr # " more " and " more " # abbr
127.43 + 10. Handles @type( ... ) or @type{ ... }
127.44 + 11. The keywords field is split on , or ; and put into separate xml
127.45 + "bibxml:keywords" tags
127.46 + 12. Ignores @preamble
127.47 +
127.48 + Known Limitations
127.49 + 1. Does not transform Latex encoding like math mode and special
127.50 + latex symbols.
127.51 + 2. Does not parse author fields into first and last names.
127.52 + E.g., It does not do anything special to an author whose name is
127.53 + in the form LAST_NAME, FIRST_NAME
127.54 + In "author" tag, will show up as
127.55 + <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
127.56 + 3. Does not handle "crossref" fields other than to print
127.57 + <bibxml:crossref>...</bibxml:crossref>
127.58 + 4. Does not inform user of the input's format errors. You just won't
127.59 + be able to transform the file later with XSL
127.60 +
127.61 + You will have to manually edit the XML output if you need to handle
127.62 + these (and unknown) limitations.
127.63 +
127.64 +"""
127.65 +
127.66 +import string, re
127.67 +
127.68 +# set of valid name characters
127.69 +valid_name_chars = '[\w\-:]'
127.70 +
127.71 +#
127.72 +# define global regular expression variables
127.73 +#
127.74 +author_rex = re.compile('\s+and\s+')
127.75 +rembraces_rex = re.compile('[{}]')
127.76 +capitalize_rex = re.compile('({[^}]*})')
127.77 +
127.78 +# used by bibtexkeywords(data)
127.79 +keywords_rex = re.compile('[,;]')
127.80 +
127.81 +# used by concat_line(line)
127.82 +concatsplit_rex = re.compile('\s*#\s*')
127.83 +
127.84 +# split on {, }, or " in verify_out_of_braces
127.85 +delimiter_rex = re.compile('([{}"])',re.I)
127.86 +
127.87 +field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
127.88 +data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
127.89 +
127.90 +url_rex = re.compile('\\\url\{([^}]*)\}')
127.91 +
127.92 +#
127.93 +# styles for html formatting
127.94 +#
127.95 +divstyle = 'margin-top: -4ex; margin-left: 8em;'
127.96 +
127.97 +#
127.98 +# return the string parameter without braces
127.99 +#
127.100 +def transformurls(str):
127.101 + return url_rex.sub(r'<a href="\1">\1</a>', str)
127.102 +
127.103 +#
127.104 +# return the string parameter without braces
127.105 +#
127.106 +def removebraces(str):
127.107 + return rembraces_rex.sub('', str)
127.108 +
127.109 +#
127.110 +# latex-specific replacements
127.111 +# (do this after braces were removed)
127.112 +#
127.113 +def latexreplacements(line):
127.114 + line = string.replace(line, '~', ' ')
127.115 + line = string.replace(line, '\\\'a', 'á')
127.116 + line = string.replace(line, '\\"a', 'ä')
127.117 + line = string.replace(line, '\\\'e', 'é')
127.118 + line = string.replace(line, '\\"e', 'ë')
127.119 + line = string.replace(line, '\\\'i', 'í')
127.120 + line = string.replace(line, '\\"i', 'ï')
127.121 + line = string.replace(line, '\\\'o', 'ó')
127.122 + line = string.replace(line, '\\"o', 'ö')
127.123 + line = string.replace(line, '\\\'u', 'ú')
127.124 + line = string.replace(line, '\\"u', 'ü')
127.125 + line = string.replace(line, '\\H o', 'õ')
127.126 + line = string.replace(line, '\\H u', 'ü') # ũ does not exist
127.127 + line = string.replace(line, '\\\'A', 'Á')
127.128 + line = string.replace(line, '\\"A', 'Ä')
127.129 + line = string.replace(line, '\\\'E', 'É')
127.130 + line = string.replace(line, '\\"E', 'Ë')
127.131 + line = string.replace(line, '\\\'I', 'Í')
127.132 + line = string.replace(line, '\\"I', 'Ï')
127.133 + line = string.replace(line, '\\\'O', 'Ó')
127.134 + line = string.replace(line, '\\"O', 'Ö')
127.135 + line = string.replace(line, '\\\'U', 'Ú')
127.136 + line = string.replace(line, '\\"U', 'Ü')
127.137 + line = string.replace(line, '\\H O', 'Õ')
127.138 + line = string.replace(line, '\\H U', 'Ü') # Ũ does not exist
127.139 +
127.140 + return line
127.141 +
127.142 +#
127.143 +# copy characters form a string decoding html expressions (&xyz;)
127.144 +#
127.145 +def copychars(str, ifrom, count):
127.146 + result = ''
127.147 + i = ifrom
127.148 + c = 0
127.149 + html_spec = False
127.150 + while (i < len(str)) and (c < count):
127.151 + if str[i] == '&':
127.152 + html_spec = True;
127.153 + if i+1 < len(str):
127.154 + result += str[i+1]
127.155 + c += 1
127.156 + i += 2
127.157 + else:
127.158 + if not html_spec:
127.159 + if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
127.160 + ((str[i] >= 'a') and (str[i] <= 'z')):
127.161 + result += str[i]
127.162 + c += 1
127.163 + elif str[i] == ';':
127.164 + html_spec = False;
127.165 + i += 1
127.166 +
127.167 + return result
127.168 +
127.169 +
127.170 +#
127.171 +# Handle a list of authors (separated by 'and').
127.172 +# It gives back an array of the follwing values:
127.173 +# - num: the number of authors,
127.174 +# - list: the list of the author names,
127.175 +# - text: the bibtex text (separated by commas and/or 'and')
127.176 +# - abbrev: abbreviation that can be used for indicate the
127.177 +# bibliography entries
127.178 +#
127.179 +def bibtexauthor(data):
127.180 + result = {}
127.181 + bibtex = ''
127.182 + result['list'] = author_rex.split(data)
127.183 + result['num'] = len(result['list'])
127.184 + for i, author in enumerate(result['list']):
127.185 + # general transformations
127.186 + author = latexreplacements(removebraces(author.strip()))
127.187 + # transform "Xyz, A. B." to "A. B. Xyz"
127.188 + pos = author.find(',')
127.189 + if pos != -1:
127.190 + author = author[pos+1:].strip() + ' ' + author[:pos].strip()
127.191 + result['list'][i] = author
127.192 + bibtex += author + '#'
127.193 + bibtex = bibtex[:-1]
127.194 + if result['num'] > 1:
127.195 + ix = bibtex.rfind('#')
127.196 + if result['num'] == 2:
127.197 + bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
127.198 + else:
127.199 + bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
127.200 + bibtex = bibtex.replace('#', ', ')
127.201 + result['text'] = bibtex
127.202 +
127.203 + result['abbrev'] = ''
127.204 + for author in result['list']:
127.205 + pos = author.rfind(' ') + 1
127.206 + count = 1
127.207 + if result['num'] == 1:
127.208 + count = 3
127.209 + result['abbrev'] += copychars(author, pos, count)
127.210 +
127.211 + return result
127.212 +
127.213 +
127.214 +#
127.215 +# data = title string
127.216 +# @return the capitalized title (first letter is capitalized), rest are capitalized
127.217 +# only if capitalized inside braces
127.218 +#
127.219 +def capitalizetitle(data):
127.220 + title_list = capitalize_rex.split(data)
127.221 + title = ''
127.222 + count = 0
127.223 + for phrase in title_list:
127.224 + check = string.lstrip(phrase)
127.225 +
127.226 + # keep phrase's capitalization the same
127.227 + if check.find('{') == 0:
127.228 + title += removebraces(phrase)
127.229 + else:
127.230 + # first word --> capitalize first letter (after spaces)
127.231 + if count == 0:
127.232 + title += check.capitalize()
127.233 + else:
127.234 + title += phrase.lower()
127.235 + count = count + 1
127.236 +
127.237 + return title
127.238 +
127.239 +
127.240 +#
127.241 +# @return the bibtex for the title
127.242 +# @param data --> title string
127.243 +# braces are removed from title
127.244 +#
127.245 +def bibtextitle(data, entrytype):
127.246 + if entrytype in ('book', 'inbook'):
127.247 + title = removebraces(data.strip())
127.248 + else:
127.249 + title = removebraces(capitalizetitle(data.strip()))
127.250 + bibtex = title
127.251 + return bibtex
127.252 +
127.253 +
127.254 +#
127.255 +# function to compare entry lists
127.256 +#
127.257 +def entry_cmp(x, y):
127.258 + return cmp(x[0], y[0])
127.259 +
127.260 +
127.261 +#
127.262 +# print the XML for the transformed "filecont_source"
127.263 +#
127.264 +def bibtexdecoder(filecont_source):
127.265 + filecont = []
127.266 + file = []
127.267 +
127.268 + # want @<alphanumeric chars><spaces>{<spaces><any chars>,
127.269 + pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
127.270 + endtype_rex = re.compile('}\s*$')
127.271 + endtag_rex = re.compile('^\s*}\s*$')
127.272 +
127.273 + bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
127.274 + bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
127.275 +
127.276 + quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
127.277 + quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
127.278 +
127.279 + for line in filecont_source:
127.280 + line = line[:-1]
127.281 +
127.282 + # encode character entities
127.283 + line = string.replace(line, '&', '&')
127.284 + line = string.replace(line, '<', '<')
127.285 + line = string.replace(line, '>', '>')
127.286 +
127.287 + # start entry: publication type (store for later use)
127.288 + if pubtype_rex.match(line):
127.289 + # want @<alphanumeric chars><spaces>{<spaces><any chars>,
127.290 + entrycont = {}
127.291 + entry = []
127.292 + entrytype = pubtype_rex.sub('\g<1>',line)
127.293 + entrytype = string.lower(entrytype)
127.294 + entryid = pubtype_rex.sub('\g<2>', line)
127.295 +
127.296 + # end entry if just a }
127.297 + elif endtype_rex.match(line):
127.298 + # generate doxygen code for the entry
127.299 +
127.300 + # enty type related formattings
127.301 + if entrytype in ('book', 'inbook'):
127.302 + entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
127.303 + if not entrycont.has_key('author'):
127.304 + entrycont['author'] = entrycont['editor']
127.305 + entrycont['author']['text'] += ', editors'
127.306 + elif entrytype == 'article':
127.307 + entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
127.308 + elif entrytype in ('inproceedings', 'incollection', 'conference'):
127.309 + entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
127.310 + elif entrytype == 'techreport':
127.311 + if not entrycont.has_key('type'):
127.312 + entrycont['type'] = 'Technical report'
127.313 + elif entrytype == 'mastersthesis':
127.314 + entrycont['type'] = 'Master\'s thesis'
127.315 + elif entrytype == 'phdthesis':
127.316 + entrycont['type'] = 'PhD thesis'
127.317 +
127.318 + for eline in entrycont:
127.319 + if eline != '':
127.320 + eline = latexreplacements(eline)
127.321 +
127.322 + if entrycont.has_key('pages') and (entrycont['pages'] != ''):
127.323 + entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
127.324 +
127.325 + if entrycont.has_key('author') and (entrycont['author'] != ''):
127.326 + entry.append(entrycont['author']['text'] + '.')
127.327 + if entrycont.has_key('title') and (entrycont['title'] != ''):
127.328 + entry.append(entrycont['title'] + '.')
127.329 + if entrycont.has_key('journal') and (entrycont['journal'] != ''):
127.330 + entry.append(entrycont['journal'] + ',')
127.331 + if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
127.332 + entry.append('In ' + entrycont['booktitle'] + ',')
127.333 + if entrycont.has_key('type') and (entrycont['type'] != ''):
127.334 + eline = entrycont['type']
127.335 + if entrycont.has_key('number') and (entrycont['number'] != ''):
127.336 + eline += ' ' + entrycont['number']
127.337 + eline += ','
127.338 + entry.append(eline)
127.339 + if entrycont.has_key('institution') and (entrycont['institution'] != ''):
127.340 + entry.append(entrycont['institution'] + ',')
127.341 + if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
127.342 + entry.append(entrycont['publisher'] + ',')
127.343 + if entrycont.has_key('school') and (entrycont['school'] != ''):
127.344 + entry.append(entrycont['school'] + ',')
127.345 + if entrycont.has_key('address') and (entrycont['address'] != ''):
127.346 + entry.append(entrycont['address'] + ',')
127.347 + if entrycont.has_key('edition') and (entrycont['edition'] != ''):
127.348 + entry.append(entrycont['edition'] + ' edition,')
127.349 + if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
127.350 + entry.append(entrycont['howpublished'] + ',')
127.351 + if entrycont.has_key('volume') and (entrycont['volume'] != ''):
127.352 + eline = entrycont['volume'];
127.353 + if entrycont.has_key('number') and (entrycont['number'] != ''):
127.354 + eline += '(' + entrycont['number'] + ')'
127.355 + if entrycont.has_key('pages') and (entrycont['pages'] != ''):
127.356 + eline += ':' + entrycont['pages']
127.357 + eline += ','
127.358 + entry.append(eline)
127.359 + else:
127.360 + if entrycont.has_key('pages') and (entrycont['pages'] != ''):
127.361 + entry.append('pages ' + entrycont['pages'] + ',')
127.362 + if entrycont.has_key('year') and (entrycont['year'] != ''):
127.363 + if entrycont.has_key('month') and (entrycont['month'] != ''):
127.364 + entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
127.365 + else:
127.366 + entry.append(entrycont['year'] + '.')
127.367 + if entrycont.has_key('note') and (entrycont['note'] != ''):
127.368 + entry.append(entrycont['note'] + '.')
127.369 + if entrycont.has_key('url') and (entrycont['url'] != ''):
127.370 + entry.append(entrycont['url'] + '.')
127.371 +
127.372 + # generate keys for sorting and for the output
127.373 + sortkey = ''
127.374 + bibkey = ''
127.375 + if entrycont.has_key('author'):
127.376 + for author in entrycont['author']['list']:
127.377 + sortkey += copychars(author, author.rfind(' ')+1, len(author))
127.378 + bibkey = entrycont['author']['abbrev']
127.379 + else:
127.380 + bibkey = 'x'
127.381 + if entrycont.has_key('year'):
127.382 + sortkey += entrycont['year']
127.383 + bibkey += entrycont['year'][-2:]
127.384 + if entrycont.has_key('title'):
127.385 + sortkey += entrycont['title']
127.386 + if entrycont.has_key('key'):
127.387 + sortkey = entrycont['key'] + sortkey
127.388 + bibkey = entrycont['key']
127.389 + entry.insert(0, sortkey)
127.390 + entry.insert(1, bibkey)
127.391 + entry.insert(2, entryid)
127.392 +
127.393 + # add the entry to the file contents
127.394 + filecont.append(entry)
127.395 +
127.396 + else:
127.397 + # field, publication info
127.398 + field = ''
127.399 + data = ''
127.400 +
127.401 + # field = {data} entries
127.402 + if bracedata_rex.match(line):
127.403 + field = bracefield_rex.sub('\g<1>', line)
127.404 + field = string.lower(field)
127.405 + data = bracedata_rex.sub('\g<2>', line)
127.406 +
127.407 + # field = "data" entries
127.408 + elif quotedata_rex.match(line):
127.409 + field = quotefield_rex.sub('\g<1>', line)
127.410 + field = string.lower(field)
127.411 + data = quotedata_rex.sub('\g<2>', line)
127.412 +
127.413 + # field = data entries
127.414 + elif data_rex.match(line):
127.415 + field = field_rex.sub('\g<1>', line)
127.416 + field = string.lower(field)
127.417 + data = data_rex.sub('\g<2>', line)
127.418 +
127.419 + if field == 'url':
127.420 + data = '\\url{' + data.strip() + '}'
127.421 +
127.422 + if field in ('author', 'editor'):
127.423 + entrycont[field] = bibtexauthor(data)
127.424 + line = ''
127.425 + elif field == 'title':
127.426 + line = bibtextitle(data, entrytype)
127.427 + elif field != '':
127.428 + line = removebraces(transformurls(data.strip()))
127.429 +
127.430 + if line != '':
127.431 + line = latexreplacements(line)
127.432 + entrycont[field] = line
127.433 +
127.434 +
127.435 + # sort entries
127.436 + filecont.sort(entry_cmp)
127.437 +
127.438 + # count the bibtex keys
127.439 + keytable = {}
127.440 + counttable = {}
127.441 + for entry in filecont:
127.442 + bibkey = entry[1]
127.443 + if not keytable.has_key(bibkey):
127.444 + keytable[bibkey] = 1
127.445 + else:
127.446 + keytable[bibkey] += 1
127.447 +
127.448 + for bibkey in keytable.keys():
127.449 + counttable[bibkey] = 0
127.450 +
127.451 + # generate output
127.452 + for entry in filecont:
127.453 + # generate output key form the bibtex key
127.454 + bibkey = entry[1]
127.455 + entryid = entry[2]
127.456 + if keytable[bibkey] == 1:
127.457 + outkey = bibkey
127.458 + else:
127.459 + outkey = bibkey + chr(97 + counttable[bibkey])
127.460 + counttable[bibkey] += 1
127.461 +
127.462 + # append the entry code to the output
127.463 + file.append('\\section ' + entryid + ' [' + outkey + ']')
127.464 + file.append('<div style="' + divstyle + '">')
127.465 + for line in entry[3:]:
127.466 + file.append(line)
127.467 + file.append('</div>')
127.468 + file.append('')
127.469 +
127.470 + return file
127.471 +
127.472 +
127.473 +#
127.474 +# return 1 iff abbr is in line but not inside braces or quotes
127.475 +# assumes that abbr appears only once on the line (out of braces and quotes)
127.476 +#
127.477 +def verify_out_of_braces(line, abbr):
127.478 +
127.479 + phrase_split = delimiter_rex.split(line)
127.480 +
127.481 + abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
127.482 +
127.483 + open_brace = 0
127.484 + open_quote = 0
127.485 +
127.486 + for phrase in phrase_split:
127.487 + if phrase == "{":
127.488 + open_brace = open_brace + 1
127.489 + elif phrase == "}":
127.490 + open_brace = open_brace - 1
127.491 + elif phrase == '"':
127.492 + if open_quote == 1:
127.493 + open_quote = 0
127.494 + else:
127.495 + open_quote = 1
127.496 + elif abbr_rex.search(phrase):
127.497 + if open_brace == 0 and open_quote == 0:
127.498 + return 1
127.499 +
127.500 + return 0
127.501 +
127.502 +
127.503 +#
127.504 +# a line in the form phrase1 # phrase2 # ... # phrasen
127.505 +# is returned as phrase1 phrase2 ... phrasen
127.506 +# with the correct punctuation
127.507 +# Bug: Doesn't always work with multiple abbreviations plugged in
127.508 +#
127.509 +def concat_line(line):
127.510 + # only look at part after equals
127.511 + field = field_rex.sub('\g<1>',line)
127.512 + rest = field_rex.sub('\g<2>',line)
127.513 +
127.514 + concat_line = field + ' ='
127.515 +
127.516 + pound_split = concatsplit_rex.split(rest)
127.517 +
127.518 + phrase_count = 0
127.519 + length = len(pound_split)
127.520 +
127.521 + for phrase in pound_split:
127.522 + phrase = phrase.strip()
127.523 + if phrase_count != 0:
127.524 + if phrase.startswith('"') or phrase.startswith('{'):
127.525 + phrase = phrase[1:]
127.526 + elif phrase.startswith('"'):
127.527 + phrase = phrase.replace('"','{',1)
127.528 +
127.529 + if phrase_count != length-1:
127.530 + if phrase.endswith('"') or phrase.endswith('}'):
127.531 + phrase = phrase[:-1]
127.532 + else:
127.533 + if phrase.endswith('"'):
127.534 + phrase = phrase[:-1]
127.535 + phrase = phrase + "}"
127.536 + elif phrase.endswith('",'):
127.537 + phrase = phrase[:-2]
127.538 + phrase = phrase + "},"
127.539 +
127.540 + # if phrase did have \#, add the \# back
127.541 + if phrase.endswith('\\'):
127.542 + phrase = phrase + "#"
127.543 + concat_line = concat_line + ' ' + phrase
127.544 +
127.545 + phrase_count = phrase_count + 1
127.546 +
127.547 + return concat_line
127.548 +
127.549 +
127.550 +#
127.551 +# substitute abbreviations into filecont
127.552 +# @param filecont_source - string of data from file
127.553 +#
127.554 +def bibtex_replace_abbreviations(filecont_source):
127.555 + filecont = filecont_source.splitlines()
127.556 +
127.557 + # These are defined in bibtex, so we'll define them too
127.558 + abbr_list = ['jan','feb','mar','apr','may','jun',
127.559 + 'jul','aug','sep','oct','nov','dec']
127.560 + value_list = ['January','February','March','April',
127.561 + 'May','June','July','August','September',
127.562 + 'October','November','December']
127.563 +
127.564 + abbr_rex = []
127.565 + total_abbr_count = 0
127.566 +
127.567 + front = '\\b'
127.568 + back = '(,?)\\b'
127.569 +
127.570 + for x in abbr_list:
127.571 + abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
127.572 + total_abbr_count = total_abbr_count + 1
127.573 +
127.574 +
127.575 + abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
127.576 + re.I)
127.577 +
127.578 + comment_rex = re.compile('@comment\s*{',re.I)
127.579 + preamble_rex = re.compile('@preamble\s*{',re.I)
127.580 +
127.581 + waiting_for_end_string = 0
127.582 + i = 0
127.583 + filecont2 = ''
127.584 +
127.585 + for line in filecont:
127.586 + if line == ' ' or line == '':
127.587 + continue
127.588 +
127.589 + if waiting_for_end_string:
127.590 + if re.search('}',line):
127.591 + waiting_for_end_string = 0
127.592 + continue
127.593 +
127.594 + if abbrdef_rex.search(line):
127.595 + abbr = abbrdef_rex.sub('\g<1>', line)
127.596 +
127.597 + if abbr_list.count(abbr) == 0:
127.598 + val = abbrdef_rex.sub('\g<2>', line)
127.599 + abbr_list.append(abbr)
127.600 + value_list.append(string.strip(val))
127.601 + abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
127.602 + total_abbr_count = total_abbr_count + 1
127.603 + waiting_for_end_string = 1
127.604 + continue
127.605 +
127.606 + if comment_rex.search(line):
127.607 + waiting_for_end_string = 1
127.608 + continue
127.609 +
127.610 + if preamble_rex.search(line):
127.611 + waiting_for_end_string = 1
127.612 + continue
127.613 +
127.614 +
127.615 + # replace subsequent abbreviations with the value
127.616 + abbr_count = 0
127.617 +
127.618 + for x in abbr_list:
127.619 +
127.620 + if abbr_rex[abbr_count].search(line):
127.621 + if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
127.622 + line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
127.623 + # Check for # concatenations
127.624 + if concatsplit_rex.search(line):
127.625 + line = concat_line(line)
127.626 + abbr_count = abbr_count + 1
127.627 +
127.628 +
127.629 + filecont2 = filecont2 + line + '\n'
127.630 + i = i+1
127.631 +
127.632 +
127.633 + # Do one final pass over file
127.634 +
127.635 + # make sure that didn't end up with {" or }" after the substitution
127.636 + filecont2 = filecont2.replace('{"','{{')
127.637 + filecont2 = filecont2.replace('"}','}}')
127.638 +
127.639 + afterquotevalue_rex = re.compile('"\s*,\s*')
127.640 + afterbrace_rex = re.compile('"\s*}')
127.641 + afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
127.642 +
127.643 + # add new lines to data that changed because of abbreviation substitutions
127.644 + filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
127.645 + filecont2 = afterbrace_rex.sub('"\n}', filecont2)
127.646 + filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
127.647 +
127.648 + return filecont2
127.649 +
127.650 +#
127.651 +# convert @type( ... ) to @type{ ... }
127.652 +#
127.653 +def no_outer_parens(filecont):
127.654 +
127.655 + # do checking for open parens
127.656 + # will convert to braces
127.657 + paren_split = re.split('([(){}])',filecont)
127.658 +
127.659 + open_paren_count = 0
127.660 + open_type = 0
127.661 + look_next = 0
127.662 +
127.663 + # rebuild filecont
127.664 + filecont = ''
127.665 +
127.666 + at_rex = re.compile('@\w*')
127.667 +
127.668 + for phrase in paren_split:
127.669 + if look_next == 1:
127.670 + if phrase == '(':
127.671 + phrase = '{'
127.672 + open_paren_count = open_paren_count + 1
127.673 + else:
127.674 + open_type = 0
127.675 + look_next = 0
127.676 +
127.677 + if phrase == '(':
127.678 + open_paren_count = open_paren_count + 1
127.679 +
127.680 + elif phrase == ')':
127.681 + open_paren_count = open_paren_count - 1
127.682 + if open_type == 1 and open_paren_count == 0:
127.683 + phrase = '}'
127.684 + open_type = 0
127.685 +
127.686 + elif at_rex.search( phrase ):
127.687 + open_type = 1
127.688 + look_next = 1
127.689 +
127.690 + filecont = filecont + phrase
127.691 +
127.692 + return filecont
127.693 +
127.694 +
127.695 +#
127.696 +# make all whitespace into just one space
127.697 +# format the bibtex file into a usable form.
127.698 +#
127.699 +def bibtexwasher(filecont_source):
127.700 +
127.701 + space_rex = re.compile('\s+')
127.702 + comment_rex = re.compile('\s*%')
127.703 +
127.704 + filecont = []
127.705 +
127.706 + # remove trailing and excessive whitespace
127.707 + # ignore comments
127.708 + for line in filecont_source:
127.709 + line = string.strip(line)
127.710 + line = space_rex.sub(' ', line)
127.711 + # ignore comments
127.712 + if not comment_rex.match(line) and line != '':
127.713 + filecont.append(' '+ line)
127.714 +
127.715 + filecont = string.join(filecont, '')
127.716 +
127.717 + # the file is in one long string
127.718 +
127.719 + filecont = no_outer_parens(filecont)
127.720 +
127.721 + #
127.722 + # split lines according to preferred syntax scheme
127.723 + #
127.724 + filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
127.725 +
127.726 + # add new lines after commas that are after values
127.727 + filecont = re.sub('"\s*,', '",\n', filecont)
127.728 + filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
127.729 + filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
127.730 + '\n\n\g<1>\g<2>,\n', filecont)
127.731 +
127.732 + # add new lines after }
127.733 + filecont = re.sub('"\s*}','"\n}\n', filecont)
127.734 + filecont = re.sub('}\s*,','},\n', filecont)
127.735 +
127.736 +
127.737 + filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
127.738 +
127.739 + # character encoding, reserved latex characters
127.740 + filecont = re.sub('{\\\&}', '&', filecont)
127.741 + filecont = re.sub('\\\&', '&', filecont)
127.742 +
127.743 + # do checking for open braces to get format correct
127.744 + open_brace_count = 0
127.745 + brace_split = re.split('([{}])',filecont)
127.746 +
127.747 + # rebuild filecont
127.748 + filecont = ''
127.749 +
127.750 + for phrase in brace_split:
127.751 + if phrase == '{':
127.752 + open_brace_count = open_brace_count + 1
127.753 + elif phrase == '}':
127.754 + open_brace_count = open_brace_count - 1
127.755 + if open_brace_count == 0:
127.756 + filecont = filecont + '\n'
127.757 +
127.758 + filecont = filecont + phrase
127.759 +
127.760 + filecont2 = bibtex_replace_abbreviations(filecont)
127.761 +
127.762 + # gather
127.763 + filecont = filecont2.splitlines()
127.764 + i=0
127.765 + j=0 # count the number of blank lines
127.766 + for line in filecont:
127.767 + # ignore blank lines
127.768 + if line == '' or line == ' ':
127.769 + j = j+1
127.770 + continue
127.771 + filecont[i] = line + '\n'
127.772 + i = i+1
127.773 +
127.774 + # get rid of the extra stuff at the end of the array
127.775 + # (The extra stuff are duplicates that are in the array because
127.776 + # blank lines were removed.)
127.777 + length = len( filecont)
127.778 + filecont[length-j:length] = []
127.779 +
127.780 + return filecont
127.781 +
127.782 +
127.783 +def filehandler(filepath):
127.784 + try:
127.785 + fd = open(filepath, 'r')
127.786 + filecont_source = fd.readlines()
127.787 + fd.close()
127.788 + except:
127.789 + print 'Could not open file:', filepath
127.790 + washeddata = bibtexwasher(filecont_source)
127.791 + outdata = bibtexdecoder(washeddata)
127.792 + print '/**'
127.793 + print '\page references References'
127.794 + print
127.795 + for line in outdata:
127.796 + print line
127.797 + print '*/'
127.798 +
127.799 +
127.800 +# main program
127.801 +
127.802 +def main():
127.803 + import sys
127.804 + if sys.argv[1:]:
127.805 + filepath = sys.argv[1]
127.806 + else:
127.807 + print "No input file"
127.808 + sys.exit()
127.809 + filehandler(filepath)
127.810 +
127.811 +if __name__ == "__main__": main()
127.812 +
127.813 +
127.814 +# end python script
128.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
128.2 +++ b/scripts/bootstrap.sh Thu Nov 05 15:48:01 2009 +0100
128.3 @@ -0,0 +1,134 @@
128.4 +#!/bin/bash
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 +if [ ! -f ~/.lemon-bootstrap ]; then
128.22 + echo 'Create ~/.lemon-bootstrap'.
128.23 + cat >~/.lemon-bootstrap <<EOF
128.24 +#
128.25 +# Default settings for bootstraping the LEMON source code repository
128.26 +#
128.27 +EOF
128.28 +fi
128.29 +
128.30 +source ~/.lemon-bootstrap
128.31 +if [ -f ../../../.lemon-bootstrap ]; then source ../../../.lemon-bootstrap; fi
128.32 +if [ -f ../../.lemon-bootstrap ]; then source ../../.lemon-bootstrap; fi
128.33 +if [ -f ../.lemon-bootstrap ]; then source ../.lemon-bootstrap; fi
128.34 +if [ -f ./.lemon-bootstrap ]; then source ./.lemon-bootstrap; fi
128.35 +
128.36 +
128.37 +function augment_config() {
128.38 + if [ "x${!1}" == "x" ]; then
128.39 + eval $1=$2
128.40 + echo Add "'$1'" to '~/.lemon-bootstrap'.
128.41 + echo >>~/.lemon-bootstrap
128.42 + echo $3 >>~/.lemon-bootstrap
128.43 + echo $1=$2 >>~/.lemon-bootstrap
128.44 + fi
128.45 +}
128.46 +
128.47 +augment_config LEMON_INSTALL_PREFIX /usr/local \
128.48 + "# LEMON installation prefix"
128.49 +
128.50 +augment_config COIN_OR_PREFIX /usr/local/coin-or \
128.51 + "# COIN-OR installation root prefix (used for CLP/CBC)"
128.52 +
128.53 +augment_config SOPLEX_PREFIX /usr/local/soplex \
128.54 + "# Soplex build prefix"
128.55 +
128.56 +
128.57 +function ask() {
128.58 +echo -n "$1 [$2]? "
128.59 +read _an
128.60 +if [ "x$_an" == "x" ]; then
128.61 + ret="$2"
128.62 +else
128.63 + ret=$_an
128.64 +fi
128.65 +}
128.66 +
128.67 +function yesorno() {
128.68 + ret='rossz'
128.69 + while [ "$ret" != "y" -a "$ret" != "n" -a "$ret" != "yes" -a "$ret" != "no" ]; do
128.70 + ask "$1" "$2"
128.71 + done
128.72 + if [ "$ret" != "y" -a "$ret" != "yes" ]; then
128.73 + return 1
128.74 + else
128.75 + return 0
128.76 + fi
128.77 +}
128.78 +
128.79 +if yesorno "External build" "n"
128.80 +then
128.81 + CONFIGURE_PATH=".."
128.82 +else
128.83 + CONFIGURE_PATH="."
128.84 + if yesorno "Autoreconf" "y"
128.85 + then
128.86 + AUTORE=yes
128.87 + else
128.88 + AUTORE=no
128.89 + fi
128.90 +fi
128.91 +
128.92 +if yesorno "Optimize" "n"
128.93 +then
128.94 + opt_flags=' -O2'
128.95 +else
128.96 + opt_flags=''
128.97 +fi
128.98 +
128.99 +if yesorno "Stop on warning" "y"
128.100 +then
128.101 + werror_flags=' -Werror'
128.102 +else
128.103 + werror_flags=''
128.104 +fi
128.105 +
128.106 +cxx_flags="CXXFLAGS=-ggdb$opt_flags$werror_flags"
128.107 +
128.108 +if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then
128.109 + if yesorno "Use COIN-OR (CBC/CLP)" "n"
128.110 + then
128.111 + coin_flag="--with-coin=$COIN_OR_PREFIX"
128.112 + else
128.113 + coin_flag=""
128.114 + fi
128.115 +else
128.116 + coin_flag=""
128.117 +fi
128.118 +
128.119 +if [ -f ${SOPLEX_PREFIX}/src/soplex.h ]; then
128.120 + if yesorno "Use Soplex" "n"
128.121 + then
128.122 + soplex_flag="--with-soplex=$SOPLEX_PREFIX"
128.123 + else
128.124 + soplex_flag=""
128.125 + fi
128.126 +else
128.127 + soplex_flag=""
128.128 +fi
128.129 +
128.130 +if [ "x$AUTORE" == "xyes" ]; then
128.131 + autoreconf -vif;
128.132 +fi
128.133 +${CONFIGURE_PATH}/configure --prefix=$LEMON_INSTALL_PREFIX \
128.134 +"$cxx_flags" \
128.135 +$coin_flag \
128.136 +$soplex_flag \
128.137 +$*
129.1 --- a/scripts/chg-len.py Mon Jan 12 23:11:39 2009 +0100
129.2 +++ b/scripts/chg-len.py Thu Nov 05 15:48:01 2009 +0100
129.3 @@ -1,4 +1,18 @@
129.4 #! /usr/bin/env python
129.5 +#
129.6 +# This file is a part of LEMON, a generic C++ optimization library.
129.7 +#
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 +# Permission to use, modify and distribute this software is granted
129.13 +# provided that this copyright notice appears in all copies. For
129.14 +# precise terms see the accompanying LICENSE file.
129.15 +#
129.16 +# This software is provided "AS IS" with no warranty of any kind,
129.17 +# express or implied, and with no claim as to its suitability for any
129.18 +# purpose.
129.19
129.20 import sys
129.21
130.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
130.2 +++ b/scripts/mk-release.sh Thu Nov 05 15:48:01 2009 +0100
130.3 @@ -0,0 +1,49 @@
130.4 +#!/bin/bash
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 +set -e
130.21 +
130.22 +if [ $# = 0 ]; then
130.23 + echo "Usage: $0 release-id"
130.24 + exit 1
130.25 +else
130.26 + export LEMON_VERSION=$1
130.27 +fi
130.28 +
130.29 +echo '*****************************************************************'
130.30 +echo ' Start making release tarballs for version '${LEMON_VERSION}
130.31 +echo '*****************************************************************'
130.32 +
130.33 +autoreconf -vif
130.34 +./configure
130.35 +
130.36 +make
130.37 +make html
130.38 +make distcheck
130.39 +tar xf lemon-${LEMON_VERSION}.tar.gz
130.40 +zip -r lemon-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
130.41 +mv lemon-${LEMON_VERSION}/doc/html lemon-doc-${LEMON_VERSION}
130.42 +tar czf lemon-doc-${LEMON_VERSION}.tar.gz lemon-doc-${LEMON_VERSION}
130.43 +zip -r lemon-doc-${LEMON_VERSION}.zip lemon-doc-${LEMON_VERSION}
130.44 +tar czf lemon-nodoc-${LEMON_VERSION}.tar.gz lemon-${LEMON_VERSION}
130.45 +zip -r lemon-nodoc-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
130.46 +hg tag -m 'LEMON '${LEMON_VERSION}' released ('$(hg par --template="{node|short}")' tagged as r'${LEMON_VERSION}')' r${LEMON_VERSION}
130.47 +
130.48 +rm -rf lemon-${LEMON_VERSION} lemon-doc-${LEMON_VERSION}
130.49 +
130.50 +echo '*****************************************************************'
130.51 +echo ' Release '${LEMON_VERSION}' has been created'
130.52 +echo '*****************************************************************'
131.1 --- a/scripts/unify-sources.sh Mon Jan 12 23:11:39 2009 +0100
131.2 +++ b/scripts/unify-sources.sh Thu Nov 05 15:48:01 2009 +0100
131.3 @@ -1,8 +1,31 @@
131.4 #!/bin/bash
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 -YEAR=`date +2003-%Y`
131.21 +YEAR=`date +%Y`
131.22 HGROOT=`hg root`
131.23
131.24 +function hg_year() {
131.25 + if [ -n "$(hg st $1)" ]; then
131.26 + echo $YEAR
131.27 + else
131.28 + hg log -l 1 --template='{date|isodate}\n' $1 |
131.29 + cut -d '-' -f 1
131.30 + fi
131.31 +}
131.32 +
131.33 # file enumaration modes
131.34
131.35 function all_files() {
131.36 @@ -88,7 +111,12 @@
131.37 function check_action() {
131.38 if [ "$3" == 'tabs' ]
131.39 then
131.40 - PATTERN=$(echo -e '\t')
131.41 + if echo $2 | grep -q -v -E 'Makefile\.am$'
131.42 + then
131.43 + PATTERN=$(echo -e '\t')
131.44 + else
131.45 + PATTERN=' '
131.46 + fi
131.47 elif [ "$3" == 'trailing spaces' ]
131.48 then
131.49 PATTERN='\ +$'
131.50 @@ -186,7 +214,7 @@
131.51 *
131.52 * This file is a part of LEMON, a generic C++ optimization library.
131.53 *
131.54 - * Copyright (C) "$YEAR"
131.55 + * Copyright (C) 2003-"$(hg_year $1)"
131.56 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
131.57 * (Egervary Research Group on Combinatorial Optimization, EGRES).
131.58 *
132.1 --- a/test/CMakeLists.txt Mon Jan 12 23:11:39 2009 +0100
132.2 +++ b/test/CMakeLists.txt Thu Nov 05 15:48:01 2009 +0100
132.3 @@ -1,38 +1,121 @@
132.4 -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
132.5 +INCLUDE_DIRECTORIES(
132.6 + ${PROJECT_SOURCE_DIR}
132.7 + ${PROJECT_BINARY_DIR}
132.8 +)
132.9
132.10 -LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
132.11 +LINK_DIRECTORIES(
132.12 + ${PROJECT_BINARY_DIR}/lemon
132.13 +)
132.14
132.15 SET(TESTS
132.16 adaptors_test
132.17 + bellman_ford_test
132.18 bfs_test
132.19 circulation_test
132.20 + connectivity_test
132.21 counter_test
132.22 dfs_test
132.23 digraph_test
132.24 dijkstra_test
132.25 dim_test
132.26 + edge_set_test
132.27 error_test
132.28 - edge_set_test
132.29 + euler_test
132.30 + gomory_hu_test
132.31 graph_copy_test
132.32 graph_test
132.33 graph_utils_test
132.34 hao_orlin_test
132.35 heap_test
132.36 kruskal_test
132.37 - lp_test
132.38 - mip_test
132.39 maps_test
132.40 - max_matching_test
132.41 - radix_sort_test
132.42 + matching_test
132.43 + min_cost_arborescence_test
132.44 + min_cost_flow_test
132.45 + min_mean_cycle_test
132.46 path_test
132.47 preflow_test
132.48 + radix_sort_test
132.49 random_test
132.50 suurballe_test
132.51 time_measure_test
132.52 - unionfind_test)
132.53 + unionfind_test
132.54 +)
132.55 +
132.56 +IF(LEMON_HAVE_LP)
132.57 + ADD_EXECUTABLE(lp_test lp_test.cc)
132.58 + SET(LP_TEST_LIBS lemon)
132.59 +
132.60 + IF(LEMON_HAVE_GLPK)
132.61 + SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
132.62 + ENDIF()
132.63 + IF(LEMON_HAVE_CPLEX)
132.64 + SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
132.65 + ENDIF()
132.66 + IF(LEMON_HAVE_CLP)
132.67 + SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
132.68 + ENDIF()
132.69 +
132.70 + TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
132.71 + ADD_TEST(lp_test lp_test)
132.72 +
132.73 + IF(WIN32 AND LEMON_HAVE_GLPK)
132.74 + GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
132.75 + GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
132.76 + ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
132.77 + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
132.78 + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
132.79 + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
132.80 + )
132.81 + ENDIF()
132.82 +
132.83 + IF(WIN32 AND LEMON_HAVE_CPLEX)
132.84 + GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
132.85 + GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
132.86 + ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
132.87 + COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
132.88 + )
132.89 + ENDIF()
132.90 +ENDIF()
132.91 +
132.92 +IF(LEMON_HAVE_MIP)
132.93 + ADD_EXECUTABLE(mip_test mip_test.cc)
132.94 + SET(MIP_TEST_LIBS lemon)
132.95 +
132.96 + IF(LEMON_HAVE_GLPK)
132.97 + SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
132.98 + ENDIF()
132.99 + IF(LEMON_HAVE_CPLEX)
132.100 + SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
132.101 + ENDIF()
132.102 + IF(LEMON_HAVE_CBC)
132.103 + SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
132.104 + ENDIF()
132.105 +
132.106 + TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
132.107 + ADD_TEST(mip_test mip_test)
132.108 +
132.109 + IF(WIN32 AND LEMON_HAVE_GLPK)
132.110 + GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
132.111 + GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
132.112 + ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
132.113 + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
132.114 + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
132.115 + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
132.116 + )
132.117 + ENDIF()
132.118 +
132.119 + IF(WIN32 AND LEMON_HAVE_CPLEX)
132.120 + GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
132.121 + GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
132.122 + ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
132.123 + COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
132.124 + )
132.125 + ENDIF()
132.126 +ENDIF()
132.127
132.128 FOREACH(TEST_NAME ${TESTS})
132.129 ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
132.130 TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
132.131 ADD_TEST(${TEST_NAME} ${TEST_NAME})
132.132 -ENDFOREACH(TEST_NAME)
132.133 +ENDFOREACH()
133.1 --- a/test/Makefile.am Mon Jan 12 23:11:39 2009 +0100
133.2 +++ b/test/Makefile.am Thu Nov 05 15:48:01 2009 +0100
133.3 @@ -7,8 +7,10 @@
133.4
133.5 check_PROGRAMS += \
133.6 test/adaptors_test \
133.7 + test/bellman_ford_test \
133.8 test/bfs_test \
133.9 test/circulation_test \
133.10 + test/connectivity_test \
133.11 test/counter_test \
133.12 test/dfs_test \
133.13 test/digraph_test \
133.14 @@ -16,6 +18,8 @@
133.15 test/dim_test \
133.16 test/edge_set_test \
133.17 test/error_test \
133.18 + test/euler_test \
133.19 + test/gomory_hu_test \
133.20 test/graph_copy_test \
133.21 test/graph_test \
133.22 test/graph_utils_test \
133.23 @@ -23,7 +27,10 @@
133.24 test/heap_test \
133.25 test/kruskal_test \
133.26 test/maps_test \
133.27 - test/max_matching_test \
133.28 + test/matching_test \
133.29 + test/min_cost_arborescence_test \
133.30 + test/min_cost_flow_test \
133.31 + test/min_mean_cycle_test \
133.32 test/path_test \
133.33 test/preflow_test \
133.34 test/radix_sort_test \
133.35 @@ -34,6 +41,8 @@
133.36 test/time_measure_test \
133.37 test/unionfind_test
133.38
133.39 +test_test_tools_pass_DEPENDENCIES = demo
133.40 +
133.41 if HAVE_LP
133.42 check_PROGRAMS += test/lp_test
133.43 endif HAVE_LP
133.44 @@ -45,15 +54,19 @@
133.45 XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
133.46
133.47 test_adaptors_test_SOURCES = test/adaptors_test.cc
133.48 +test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
133.49 test_bfs_test_SOURCES = test/bfs_test.cc
133.50 test_circulation_test_SOURCES = test/circulation_test.cc
133.51 test_counter_test_SOURCES = test/counter_test.cc
133.52 +test_connectivity_test_SOURCES = test/connectivity_test.cc
133.53 test_dfs_test_SOURCES = test/dfs_test.cc
133.54 test_digraph_test_SOURCES = test/digraph_test.cc
133.55 test_dijkstra_test_SOURCES = test/dijkstra_test.cc
133.56 test_dim_test_SOURCES = test/dim_test.cc
133.57 test_edge_set_test_SOURCES = test/edge_set_test.cc
133.58 test_error_test_SOURCES = test/error_test.cc
133.59 +test_euler_test_SOURCES = test/euler_test.cc
133.60 +test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
133.61 test_graph_copy_test_SOURCES = test/graph_copy_test.cc
133.62 test_graph_test_SOURCES = test/graph_test.cc
133.63 test_graph_utils_test_SOURCES = test/graph_utils_test.cc
133.64 @@ -63,7 +76,10 @@
133.65 test_lp_test_SOURCES = test/lp_test.cc
133.66 test_maps_test_SOURCES = test/maps_test.cc
133.67 test_mip_test_SOURCES = test/mip_test.cc
133.68 -test_max_matching_test_SOURCES = test/max_matching_test.cc
133.69 +test_matching_test_SOURCES = test/matching_test.cc
133.70 +test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
133.71 +test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
133.72 +test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
133.73 test_path_test_SOURCES = test/path_test.cc
133.74 test_preflow_test_SOURCES = test/preflow_test.cc
133.75 test_radix_sort_test_SOURCES = test/radix_sort_test.cc
134.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
134.2 +++ b/test/bellman_ford_test.cc Thu Nov 05 15:48:01 2009 +0100
134.3 @@ -0,0 +1,285 @@
134.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
134.5 + *
134.6 + * This file is a part of LEMON, a generic C++ optimization library.
134.7 + *
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 + * Permission to use, modify and distribute this software is granted
134.13 + * provided that this copyright notice appears in all copies. For
134.14 + * precise terms see the accompanying LICENSE file.
134.15 + *
134.16 + * This software is provided "AS IS" with no warranty of any kind,
134.17 + * express or implied, and with no claim as to its suitability for any
134.18 + * purpose.
134.19 + *
134.20 + */
134.21 +
134.22 +#include <lemon/concepts/digraph.h>
134.23 +#include <lemon/smart_graph.h>
134.24 +#include <lemon/list_graph.h>
134.25 +#include <lemon/lgf_reader.h>
134.26 +#include <lemon/bellman_ford.h>
134.27 +#include <lemon/path.h>
134.28 +
134.29 +#include "graph_test.h"
134.30 +#include "test_tools.h"
134.31 +
134.32 +using namespace lemon;
134.33 +
134.34 +char test_lgf[] =
134.35 + "@nodes\n"
134.36 + "label\n"
134.37 + "0\n"
134.38 + "1\n"
134.39 + "2\n"
134.40 + "3\n"
134.41 + "4\n"
134.42 + "@arcs\n"
134.43 + " length\n"
134.44 + "0 1 3\n"
134.45 + "1 2 -3\n"
134.46 + "1 2 -5\n"
134.47 + "1 3 -2\n"
134.48 + "0 2 -1\n"
134.49 + "1 2 -4\n"
134.50 + "0 3 2\n"
134.51 + "4 2 -5\n"
134.52 + "2 3 1\n"
134.53 + "@attributes\n"
134.54 + "source 0\n"
134.55 + "target 3\n";
134.56 +
134.57 +
134.58 +void checkBellmanFordCompile()
134.59 +{
134.60 + typedef int Value;
134.61 + typedef concepts::Digraph Digraph;
134.62 + typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
134.63 + typedef BellmanFord<Digraph, LengthMap> BF;
134.64 + typedef Digraph::Node Node;
134.65 + typedef Digraph::Arc Arc;
134.66 +
134.67 + Digraph gr;
134.68 + Node s, t, n;
134.69 + Arc e;
134.70 + Value l;
134.71 + int k;
134.72 + bool b;
134.73 + BF::DistMap d(gr);
134.74 + BF::PredMap p(gr);
134.75 + LengthMap length;
134.76 + concepts::Path<Digraph> pp;
134.77 +
134.78 + {
134.79 + BF bf_test(gr,length);
134.80 + const BF& const_bf_test = bf_test;
134.81 +
134.82 + bf_test.run(s);
134.83 + bf_test.run(s,k);
134.84 +
134.85 + bf_test.init();
134.86 + bf_test.addSource(s);
134.87 + bf_test.addSource(s, 1);
134.88 + b = bf_test.processNextRound();
134.89 + b = bf_test.processNextWeakRound();
134.90 +
134.91 + bf_test.start();
134.92 + bf_test.checkedStart();
134.93 + bf_test.limitedStart(k);
134.94 +
134.95 + l = const_bf_test.dist(t);
134.96 + e = const_bf_test.predArc(t);
134.97 + s = const_bf_test.predNode(t);
134.98 + b = const_bf_test.reached(t);
134.99 + d = const_bf_test.distMap();
134.100 + p = const_bf_test.predMap();
134.101 + pp = const_bf_test.path(t);
134.102 + pp = const_bf_test.negativeCycle();
134.103 +
134.104 + for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {}
134.105 + }
134.106 + {
134.107 + BF::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
134.108 + ::SetDistMap<concepts::ReadWriteMap<Node,Value> >
134.109 + ::SetOperationTraits<BellmanFordDefaultOperationTraits<Value> >
134.110 + ::Create bf_test(gr,length);
134.111 +
134.112 + LengthMap length_map;
134.113 + concepts::ReadWriteMap<Node,Arc> pred_map;
134.114 + concepts::ReadWriteMap<Node,Value> dist_map;
134.115 +
134.116 + bf_test
134.117 + .lengthMap(length_map)
134.118 + .predMap(pred_map)
134.119 + .distMap(dist_map);
134.120 +
134.121 + bf_test.run(s);
134.122 + bf_test.run(s,k);
134.123 +
134.124 + bf_test.init();
134.125 + bf_test.addSource(s);
134.126 + bf_test.addSource(s, 1);
134.127 + b = bf_test.processNextRound();
134.128 + b = bf_test.processNextWeakRound();
134.129 +
134.130 + bf_test.start();
134.131 + bf_test.checkedStart();
134.132 + bf_test.limitedStart(k);
134.133 +
134.134 + l = bf_test.dist(t);
134.135 + e = bf_test.predArc(t);
134.136 + s = bf_test.predNode(t);
134.137 + b = bf_test.reached(t);
134.138 + pp = bf_test.path(t);
134.139 + pp = bf_test.negativeCycle();
134.140 + }
134.141 +}
134.142 +
134.143 +void checkBellmanFordFunctionCompile()
134.144 +{
134.145 + typedef int Value;
134.146 + typedef concepts::Digraph Digraph;
134.147 + typedef Digraph::Arc Arc;
134.148 + typedef Digraph::Node Node;
134.149 + typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
134.150 +
134.151 + Digraph g;
134.152 + bool b;
134.153 + bellmanFord(g,LengthMap()).run(Node());
134.154 + b = bellmanFord(g,LengthMap()).run(Node(),Node());
134.155 + bellmanFord(g,LengthMap())
134.156 + .predMap(concepts::ReadWriteMap<Node,Arc>())
134.157 + .distMap(concepts::ReadWriteMap<Node,Value>())
134.158 + .run(Node());
134.159 + b=bellmanFord(g,LengthMap())
134.160 + .predMap(concepts::ReadWriteMap<Node,Arc>())
134.161 + .distMap(concepts::ReadWriteMap<Node,Value>())
134.162 + .path(concepts::Path<Digraph>())
134.163 + .dist(Value())
134.164 + .run(Node(),Node());
134.165 +}
134.166 +
134.167 +
134.168 +template <typename Digraph, typename Value>
134.169 +void checkBellmanFord() {
134.170 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
134.171 + typedef typename Digraph::template ArcMap<Value> LengthMap;
134.172 +
134.173 + Digraph gr;
134.174 + Node s, t;
134.175 + LengthMap length(gr);
134.176 +
134.177 + std::istringstream input(test_lgf);
134.178 + digraphReader(gr, input).
134.179 + arcMap("length", length).
134.180 + node("source", s).
134.181 + node("target", t).
134.182 + run();
134.183 +
134.184 + BellmanFord<Digraph, LengthMap>
134.185 + bf(gr, length);
134.186 + bf.run(s);
134.187 + Path<Digraph> p = bf.path(t);
134.188 +
134.189 + check(bf.reached(t) && bf.dist(t) == -1, "Bellman-Ford found a wrong path.");
134.190 + check(p.length() == 3, "path() found a wrong path.");
134.191 + check(checkPath(gr, p), "path() found a wrong path.");
134.192 + check(pathSource(gr, p) == s, "path() found a wrong path.");
134.193 + check(pathTarget(gr, p) == t, "path() found a wrong path.");
134.194 +
134.195 + ListPath<Digraph> path;
134.196 + Value dist;
134.197 + bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t);
134.198 +
134.199 + check(reached && dist == -1, "Bellman-Ford found a wrong path.");
134.200 + check(path.length() == 3, "path() found a wrong path.");
134.201 + check(checkPath(gr, path), "path() found a wrong path.");
134.202 + check(pathSource(gr, path) == s, "path() found a wrong path.");
134.203 + check(pathTarget(gr, path) == t, "path() found a wrong path.");
134.204 +
134.205 + for(ArcIt e(gr); e!=INVALID; ++e) {
134.206 + Node u=gr.source(e);
134.207 + Node v=gr.target(e);
134.208 + check(!bf.reached(u) || (bf.dist(v) - bf.dist(u) <= length[e]),
134.209 + "Wrong output. dist(target)-dist(source)-arc_length=" <<
134.210 + bf.dist(v) - bf.dist(u) - length[e]);
134.211 + }
134.212 +
134.213 + for(NodeIt v(gr); v!=INVALID; ++v) {
134.214 + if (bf.reached(v)) {
134.215 + check(v==s || bf.predArc(v)!=INVALID, "Wrong tree.");
134.216 + if (bf.predArc(v)!=INVALID ) {
134.217 + Arc e=bf.predArc(v);
134.218 + Node u=gr.source(e);
134.219 + check(u==bf.predNode(v),"Wrong tree.");
134.220 + check(bf.dist(v) - bf.dist(u) == length[e],
134.221 + "Wrong distance! Difference: " <<
134.222 + bf.dist(v) - bf.dist(u) - length[e]);
134.223 + }
134.224 + }
134.225 + }
134.226 +}
134.227 +
134.228 +void checkBellmanFordNegativeCycle() {
134.229 + DIGRAPH_TYPEDEFS(SmartDigraph);
134.230 +
134.231 + SmartDigraph gr;
134.232 + IntArcMap length(gr);
134.233 +
134.234 + Node n1 = gr.addNode();
134.235 + Node n2 = gr.addNode();
134.236 + Node n3 = gr.addNode();
134.237 + Node n4 = gr.addNode();
134.238 +
134.239 + Arc a1 = gr.addArc(n1, n2);
134.240 + Arc a2 = gr.addArc(n2, n2);
134.241 +
134.242 + length[a1] = 2;
134.243 + length[a2] = -1;
134.244 +
134.245 + {
134.246 + BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
134.247 + bf.run(n1);
134.248 + StaticPath<SmartDigraph> p = bf.negativeCycle();
134.249 + check(p.length() == 1 && p.front() == p.back() && p.front() == a2,
134.250 + "Wrong negative cycle.");
134.251 + }
134.252 +
134.253 + length[a2] = 0;
134.254 +
134.255 + {
134.256 + BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
134.257 + bf.run(n1);
134.258 + check(bf.negativeCycle().empty(),
134.259 + "Negative cycle should not be found.");
134.260 + }
134.261 +
134.262 + length[gr.addArc(n1, n3)] = 5;
134.263 + length[gr.addArc(n4, n3)] = 1;
134.264 + length[gr.addArc(n2, n4)] = 2;
134.265 + length[gr.addArc(n3, n2)] = -4;
134.266 +
134.267 + {
134.268 + BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
134.269 + bf.init();
134.270 + bf.addSource(n1);
134.271 + for (int i = 0; i < 4; ++i) {
134.272 + check(bf.negativeCycle().empty(),
134.273 + "Negative cycle should not be found.");
134.274 + bf.processNextRound();
134.275 + }
134.276 + StaticPath<SmartDigraph> p = bf.negativeCycle();
134.277 + check(p.length() == 3, "Wrong negative cycle.");
134.278 + check(length[p.nth(0)] + length[p.nth(1)] + length[p.nth(2)] == -1,
134.279 + "Wrong negative cycle.");
134.280 + }
134.281 +}
134.282 +
134.283 +int main() {
134.284 + checkBellmanFord<ListDigraph, int>();
134.285 + checkBellmanFord<SmartDigraph, double>();
134.286 + checkBellmanFordNegativeCycle();
134.287 + return 0;
134.288 +}
135.1 --- a/test/bfs_test.cc Mon Jan 12 23:11:39 2009 +0100
135.2 +++ b/test/bfs_test.cc Thu Nov 05 15:48:01 2009 +0100
135.3 @@ -58,41 +58,80 @@
135.4 typedef Digraph::Arc Arc;
135.5
135.6 Digraph G;
135.7 - Node s, t;
135.8 + Node s, t, n;
135.9 Arc e;
135.10 - int l;
135.11 + int l, i;
135.12 bool b;
135.13 BType::DistMap d(G);
135.14 BType::PredMap p(G);
135.15 Path<Digraph> pp;
135.16 + concepts::ReadMap<Node,bool> nm;
135.17
135.18 {
135.19 BType bfs_test(G);
135.20 + const BType& const_bfs_test = bfs_test;
135.21
135.22 bfs_test.run(s);
135.23 bfs_test.run(s,t);
135.24 bfs_test.run();
135.25
135.26 - l = bfs_test.dist(t);
135.27 - e = bfs_test.predArc(t);
135.28 - s = bfs_test.predNode(t);
135.29 - b = bfs_test.reached(t);
135.30 - d = bfs_test.distMap();
135.31 - p = bfs_test.predMap();
135.32 - pp = bfs_test.path(t);
135.33 + bfs_test.init();
135.34 + bfs_test.addSource(s);
135.35 + n = bfs_test.processNextNode();
135.36 + n = bfs_test.processNextNode(t, b);
135.37 + n = bfs_test.processNextNode(nm, n);
135.38 + n = const_bfs_test.nextNode();
135.39 + b = const_bfs_test.emptyQueue();
135.40 + i = const_bfs_test.queueSize();
135.41 +
135.42 + bfs_test.start();
135.43 + bfs_test.start(t);
135.44 + bfs_test.start(nm);
135.45 +
135.46 + l = const_bfs_test.dist(t);
135.47 + e = const_bfs_test.predArc(t);
135.48 + s = const_bfs_test.predNode(t);
135.49 + b = const_bfs_test.reached(t);
135.50 + d = const_bfs_test.distMap();
135.51 + p = const_bfs_test.predMap();
135.52 + pp = const_bfs_test.path(t);
135.53 }
135.54 {
135.55 BType
135.56 ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
135.57 ::SetDistMap<concepts::ReadWriteMap<Node,int> >
135.58 ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
135.59 + ::SetStandardProcessedMap
135.60 ::SetProcessedMap<concepts::WriteMap<Node,bool> >
135.61 - ::SetStandardProcessedMap
135.62 ::Create bfs_test(G);
135.63 +
135.64 + concepts::ReadWriteMap<Node,Arc> pred_map;
135.65 + concepts::ReadWriteMap<Node,int> dist_map;
135.66 + concepts::ReadWriteMap<Node,bool> reached_map;
135.67 + concepts::WriteMap<Node,bool> processed_map;
135.68 +
135.69 + bfs_test
135.70 + .predMap(pred_map)
135.71 + .distMap(dist_map)
135.72 + .reachedMap(reached_map)
135.73 + .processedMap(processed_map);
135.74
135.75 bfs_test.run(s);
135.76 bfs_test.run(s,t);
135.77 bfs_test.run();
135.78 +
135.79 + bfs_test.init();
135.80 + bfs_test.addSource(s);
135.81 + n = bfs_test.processNextNode();
135.82 + n = bfs_test.processNextNode(t, b);
135.83 + n = bfs_test.processNextNode(nm, n);
135.84 + n = bfs_test.nextNode();
135.85 + b = bfs_test.emptyQueue();
135.86 + i = bfs_test.queueSize();
135.87 +
135.88 + bfs_test.start();
135.89 + bfs_test.start(t);
135.90 + bfs_test.start(nm);
135.91
135.92 l = bfs_test.dist(t);
135.93 e = bfs_test.predArc(t);
136.1 --- a/test/circulation_test.cc Mon Jan 12 23:11:39 2009 +0100
136.2 +++ b/test/circulation_test.cc Thu Nov 05 15:48:01 2009 +0100
136.3 @@ -57,7 +57,7 @@
136.4 typedef Digraph::Node Node;
136.5 typedef Digraph::Arc Arc;
136.6 typedef concepts::ReadMap<Arc,VType> CapMap;
136.7 - typedef concepts::ReadMap<Node,VType> DeltaMap;
136.8 + typedef concepts::ReadMap<Node,VType> SupplyMap;
136.9 typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
136.10 typedef concepts::WriteMap<Node,bool> BarrierMap;
136.11
136.12 @@ -68,30 +68,42 @@
136.13 Node n;
136.14 Arc a;
136.15 CapMap lcap, ucap;
136.16 - DeltaMap delta;
136.17 + SupplyMap supply;
136.18 FlowMap flow;
136.19 BarrierMap bar;
136.20 + VType v;
136.21 + bool b;
136.22
136.23 - Circulation<Digraph, CapMap, CapMap, DeltaMap>
136.24 - ::SetFlowMap<FlowMap>
136.25 - ::SetElevator<Elev>
136.26 - ::SetStandardElevator<LinkedElev>
136.27 - ::Create circ_test(g,lcap,ucap,delta);
136.28 -
136.29 - circ_test.lowerCapMap(lcap);
136.30 - circ_test.upperCapMap(ucap);
136.31 - circ_test.deltaMap(delta);
136.32 - flow = circ_test.flowMap();
136.33 - circ_test.flowMap(flow);
136.34 + typedef Circulation<Digraph, CapMap, CapMap, SupplyMap>
136.35 + ::SetFlowMap<FlowMap>
136.36 + ::SetElevator<Elev>
136.37 + ::SetStandardElevator<LinkedElev>
136.38 + ::Create CirculationType;
136.39 + CirculationType circ_test(g, lcap, ucap, supply);
136.40 + const CirculationType& const_circ_test = circ_test;
136.41 +
136.42 + circ_test
136.43 + .lowerMap(lcap)
136.44 + .upperMap(ucap)
136.45 + .supplyMap(supply)
136.46 + .flowMap(flow);
136.47 +
136.48 + const CirculationType::Elevator& elev = const_circ_test.elevator();
136.49 + circ_test.elevator(const_cast<CirculationType::Elevator&>(elev));
136.50 + CirculationType::Tolerance tol = const_circ_test.tolerance();
136.51 + circ_test.tolerance(tol);
136.52
136.53 circ_test.init();
136.54 circ_test.greedyInit();
136.55 circ_test.start();
136.56 circ_test.run();
136.57
136.58 - circ_test.barrier(n);
136.59 - circ_test.barrierMap(bar);
136.60 - circ_test.flow(a);
136.61 + v = const_circ_test.flow(a);
136.62 + const FlowMap& fm = const_circ_test.flowMap();
136.63 + b = const_circ_test.barrier(n);
136.64 + const_circ_test.barrierMap(bar);
136.65 +
136.66 + ignore_unused_variable_warning(fm);
136.67 }
136.68
136.69 template <class G, class LM, class UM, class DM>
137.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
137.2 +++ b/test/connectivity_test.cc Thu Nov 05 15:48:01 2009 +0100
137.3 @@ -0,0 +1,297 @@
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-2009
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 +#include <lemon/connectivity.h>
137.23 +#include <lemon/list_graph.h>
137.24 +#include <lemon/adaptors.h>
137.25 +
137.26 +#include "test_tools.h"
137.27 +
137.28 +using namespace lemon;
137.29 +
137.30 +
137.31 +int main()
137.32 +{
137.33 + typedef ListDigraph Digraph;
137.34 + typedef Undirector<Digraph> Graph;
137.35 +
137.36 + {
137.37 + Digraph d;
137.38 + Digraph::NodeMap<int> order(d);
137.39 + Graph g(d);
137.40 +
137.41 + check(stronglyConnected(d), "The empty digraph is strongly connected");
137.42 + check(countStronglyConnectedComponents(d) == 0,
137.43 + "The empty digraph has 0 strongly connected component");
137.44 + check(connected(g), "The empty graph is connected");
137.45 + check(countConnectedComponents(g) == 0,
137.46 + "The empty graph has 0 connected component");
137.47 +
137.48 + check(biNodeConnected(g), "The empty graph is bi-node-connected");
137.49 + check(countBiNodeConnectedComponents(g) == 0,
137.50 + "The empty graph has 0 bi-node-connected component");
137.51 + check(biEdgeConnected(g), "The empty graph is bi-edge-connected");
137.52 + check(countBiEdgeConnectedComponents(g) == 0,
137.53 + "The empty graph has 0 bi-edge-connected component");
137.54 +
137.55 + check(dag(d), "The empty digraph is DAG.");
137.56 + check(checkedTopologicalSort(d, order), "The empty digraph is DAG.");
137.57 + check(loopFree(d), "The empty digraph is loop-free.");
137.58 + check(parallelFree(d), "The empty digraph is parallel-free.");
137.59 + check(simpleGraph(d), "The empty digraph is simple.");
137.60 +
137.61 + check(acyclic(g), "The empty graph is acyclic.");
137.62 + check(tree(g), "The empty graph is tree.");
137.63 + check(bipartite(g), "The empty graph is bipartite.");
137.64 + check(loopFree(g), "The empty graph is loop-free.");
137.65 + check(parallelFree(g), "The empty graph is parallel-free.");
137.66 + check(simpleGraph(g), "The empty graph is simple.");
137.67 + }
137.68 +
137.69 + {
137.70 + Digraph d;
137.71 + Digraph::NodeMap<int> order(d);
137.72 + Graph g(d);
137.73 + Digraph::Node n = d.addNode();
137.74 +
137.75 + check(stronglyConnected(d), "This digraph is strongly connected");
137.76 + check(countStronglyConnectedComponents(d) == 1,
137.77 + "This digraph has 1 strongly connected component");
137.78 + check(connected(g), "This graph is connected");
137.79 + check(countConnectedComponents(g) == 1,
137.80 + "This graph has 1 connected component");
137.81 +
137.82 + check(biNodeConnected(g), "This graph is bi-node-connected");
137.83 + check(countBiNodeConnectedComponents(g) == 0,
137.84 + "This graph has 0 bi-node-connected component");
137.85 + check(biEdgeConnected(g), "This graph is bi-edge-connected");
137.86 + check(countBiEdgeConnectedComponents(g) == 1,
137.87 + "This graph has 1 bi-edge-connected component");
137.88 +
137.89 + check(dag(d), "This digraph is DAG.");
137.90 + check(checkedTopologicalSort(d, order), "This digraph is DAG.");
137.91 + check(loopFree(d), "This digraph is loop-free.");
137.92 + check(parallelFree(d), "This digraph is parallel-free.");
137.93 + check(simpleGraph(d), "This digraph is simple.");
137.94 +
137.95 + check(acyclic(g), "This graph is acyclic.");
137.96 + check(tree(g), "This graph is tree.");
137.97 + check(bipartite(g), "This graph is bipartite.");
137.98 + check(loopFree(g), "This graph is loop-free.");
137.99 + check(parallelFree(g), "This graph is parallel-free.");
137.100 + check(simpleGraph(g), "This graph is simple.");
137.101 + }
137.102 +
137.103 + {
137.104 + Digraph d;
137.105 + Digraph::NodeMap<int> order(d);
137.106 + Graph g(d);
137.107 +
137.108 + Digraph::Node n1 = d.addNode();
137.109 + Digraph::Node n2 = d.addNode();
137.110 + Digraph::Node n3 = d.addNode();
137.111 + Digraph::Node n4 = d.addNode();
137.112 + Digraph::Node n5 = d.addNode();
137.113 + Digraph::Node n6 = d.addNode();
137.114 +
137.115 + d.addArc(n1, n3);
137.116 + d.addArc(n3, n2);
137.117 + d.addArc(n2, n1);
137.118 + d.addArc(n4, n2);
137.119 + d.addArc(n4, n3);
137.120 + d.addArc(n5, n6);
137.121 + d.addArc(n6, n5);
137.122 +
137.123 + check(!stronglyConnected(d), "This digraph is not strongly connected");
137.124 + check(countStronglyConnectedComponents(d) == 3,
137.125 + "This digraph has 3 strongly connected components");
137.126 + check(!connected(g), "This graph is not connected");
137.127 + check(countConnectedComponents(g) == 2,
137.128 + "This graph has 2 connected components");
137.129 +
137.130 + check(!dag(d), "This digraph is not DAG.");
137.131 + check(!checkedTopologicalSort(d, order), "This digraph is not DAG.");
137.132 + check(loopFree(d), "This digraph is loop-free.");
137.133 + check(parallelFree(d), "This digraph is parallel-free.");
137.134 + check(simpleGraph(d), "This digraph is simple.");
137.135 +
137.136 + check(!acyclic(g), "This graph is not acyclic.");
137.137 + check(!tree(g), "This graph is not tree.");
137.138 + check(!bipartite(g), "This graph is not bipartite.");
137.139 + check(loopFree(g), "This graph is loop-free.");
137.140 + check(!parallelFree(g), "This graph is not parallel-free.");
137.141 + check(!simpleGraph(g), "This graph is not simple.");
137.142 +
137.143 + d.addArc(n3, n3);
137.144 +
137.145 + check(!loopFree(d), "This digraph is not loop-free.");
137.146 + check(!loopFree(g), "This graph is not loop-free.");
137.147 + check(!simpleGraph(d), "This digraph is not simple.");
137.148 +
137.149 + d.addArc(n3, n2);
137.150 +
137.151 + check(!parallelFree(d), "This digraph is not parallel-free.");
137.152 + }
137.153 +
137.154 + {
137.155 + Digraph d;
137.156 + Digraph::ArcMap<bool> cutarcs(d, false);
137.157 + Graph g(d);
137.158 +
137.159 + Digraph::Node n1 = d.addNode();
137.160 + Digraph::Node n2 = d.addNode();
137.161 + Digraph::Node n3 = d.addNode();
137.162 + Digraph::Node n4 = d.addNode();
137.163 + Digraph::Node n5 = d.addNode();
137.164 + Digraph::Node n6 = d.addNode();
137.165 + Digraph::Node n7 = d.addNode();
137.166 + Digraph::Node n8 = d.addNode();
137.167 +
137.168 + d.addArc(n1, n2);
137.169 + d.addArc(n5, n1);
137.170 + d.addArc(n2, n8);
137.171 + d.addArc(n8, n5);
137.172 + d.addArc(n6, n4);
137.173 + d.addArc(n4, n6);
137.174 + d.addArc(n2, n5);
137.175 + d.addArc(n1, n8);
137.176 + d.addArc(n6, n7);
137.177 + d.addArc(n7, n6);
137.178 +
137.179 + check(!stronglyConnected(d), "This digraph is not strongly connected");
137.180 + check(countStronglyConnectedComponents(d) == 3,
137.181 + "This digraph has 3 strongly connected components");
137.182 + Digraph::NodeMap<int> scomp1(d);
137.183 + check(stronglyConnectedComponents(d, scomp1) == 3,
137.184 + "This digraph has 3 strongly connected components");
137.185 + check(scomp1[n1] != scomp1[n3] && scomp1[n1] != scomp1[n4] &&
137.186 + scomp1[n3] != scomp1[n4], "Wrong stronglyConnectedComponents()");
137.187 + check(scomp1[n1] == scomp1[n2] && scomp1[n1] == scomp1[n5] &&
137.188 + scomp1[n1] == scomp1[n8], "Wrong stronglyConnectedComponents()");
137.189 + check(scomp1[n4] == scomp1[n6] && scomp1[n4] == scomp1[n7],
137.190 + "Wrong stronglyConnectedComponents()");
137.191 + Digraph::ArcMap<bool> scut1(d, false);
137.192 + check(stronglyConnectedCutArcs(d, scut1) == 0,
137.193 + "This digraph has 0 strongly connected cut arc.");
137.194 + for (Digraph::ArcIt a(d); a != INVALID; ++a) {
137.195 + check(!scut1[a], "Wrong stronglyConnectedCutArcs()");
137.196 + }
137.197 +
137.198 + check(!connected(g), "This graph is not connected");
137.199 + check(countConnectedComponents(g) == 3,
137.200 + "This graph has 3 connected components");
137.201 + Graph::NodeMap<int> comp(g);
137.202 + check(connectedComponents(g, comp) == 3,
137.203 + "This graph has 3 connected components");
137.204 + check(comp[n1] != comp[n3] && comp[n1] != comp[n4] &&
137.205 + comp[n3] != comp[n4], "Wrong connectedComponents()");
137.206 + check(comp[n1] == comp[n2] && comp[n1] == comp[n5] &&
137.207 + comp[n1] == comp[n8], "Wrong connectedComponents()");
137.208 + check(comp[n4] == comp[n6] && comp[n4] == comp[n7],
137.209 + "Wrong connectedComponents()");
137.210 +
137.211 + cutarcs[d.addArc(n3, n1)] = true;
137.212 + cutarcs[d.addArc(n3, n5)] = true;
137.213 + cutarcs[d.addArc(n3, n8)] = true;
137.214 + cutarcs[d.addArc(n8, n6)] = true;
137.215 + cutarcs[d.addArc(n8, n7)] = true;
137.216 +
137.217 + check(!stronglyConnected(d), "This digraph is not strongly connected");
137.218 + check(countStronglyConnectedComponents(d) == 3,
137.219 + "This digraph has 3 strongly connected components");
137.220 + Digraph::NodeMap<int> scomp2(d);
137.221 + check(stronglyConnectedComponents(d, scomp2) == 3,
137.222 + "This digraph has 3 strongly connected components");
137.223 + check(scomp2[n3] == 0, "Wrong stronglyConnectedComponents()");
137.224 + check(scomp2[n1] == 1 && scomp2[n2] == 1 && scomp2[n5] == 1 &&
137.225 + scomp2[n8] == 1, "Wrong stronglyConnectedComponents()");
137.226 + check(scomp2[n4] == 2 && scomp2[n6] == 2 && scomp2[n7] == 2,
137.227 + "Wrong stronglyConnectedComponents()");
137.228 + Digraph::ArcMap<bool> scut2(d, false);
137.229 + check(stronglyConnectedCutArcs(d, scut2) == 5,
137.230 + "This digraph has 5 strongly connected cut arcs.");
137.231 + for (Digraph::ArcIt a(d); a != INVALID; ++a) {
137.232 + check(scut2[a] == cutarcs[a], "Wrong stronglyConnectedCutArcs()");
137.233 + }
137.234 + }
137.235 +
137.236 + {
137.237 + // DAG example for topological sort from the book New Algorithms
137.238 + // (T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein)
137.239 + Digraph d;
137.240 + Digraph::NodeMap<int> order(d);
137.241 +
137.242 + Digraph::Node belt = d.addNode();
137.243 + Digraph::Node trousers = d.addNode();
137.244 + Digraph::Node necktie = d.addNode();
137.245 + Digraph::Node coat = d.addNode();
137.246 + Digraph::Node socks = d.addNode();
137.247 + Digraph::Node shirt = d.addNode();
137.248 + Digraph::Node shoe = d.addNode();
137.249 + Digraph::Node watch = d.addNode();
137.250 + Digraph::Node pants = d.addNode();
137.251 +
137.252 + d.addArc(socks, shoe);
137.253 + d.addArc(pants, shoe);
137.254 + d.addArc(pants, trousers);
137.255 + d.addArc(trousers, shoe);
137.256 + d.addArc(trousers, belt);
137.257 + d.addArc(belt, coat);
137.258 + d.addArc(shirt, belt);
137.259 + d.addArc(shirt, necktie);
137.260 + d.addArc(necktie, coat);
137.261 +
137.262 + check(dag(d), "This digraph is DAG.");
137.263 + topologicalSort(d, order);
137.264 + for (Digraph::ArcIt a(d); a != INVALID; ++a) {
137.265 + check(order[d.source(a)] < order[d.target(a)],
137.266 + "Wrong topologicalSort()");
137.267 + }
137.268 + }
137.269 +
137.270 + {
137.271 + ListGraph g;
137.272 + ListGraph::NodeMap<bool> map(g);
137.273 +
137.274 + ListGraph::Node n1 = g.addNode();
137.275 + ListGraph::Node n2 = g.addNode();
137.276 + ListGraph::Node n3 = g.addNode();
137.277 + ListGraph::Node n4 = g.addNode();
137.278 + ListGraph::Node n5 = g.addNode();
137.279 + ListGraph::Node n6 = g.addNode();
137.280 + ListGraph::Node n7 = g.addNode();
137.281 +
137.282 + g.addEdge(n1, n3);
137.283 + g.addEdge(n1, n4);
137.284 + g.addEdge(n2, n5);
137.285 + g.addEdge(n3, n6);
137.286 + g.addEdge(n4, n6);
137.287 + g.addEdge(n4, n7);
137.288 + g.addEdge(n5, n7);
137.289 +
137.290 + check(bipartite(g), "This graph is bipartite");
137.291 + check(bipartitePartitions(g, map), "This graph is bipartite");
137.292 +
137.293 + check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7],
137.294 + "Wrong bipartitePartitions()");
137.295 + check(map[n3] == map[n4] && map[n3] == map[n5],
137.296 + "Wrong bipartitePartitions()");
137.297 + }
137.298 +
137.299 + return 0;
137.300 +}
138.1 --- a/test/counter_test.cc Mon Jan 12 23:11:39 2009 +0100
138.2 +++ b/test/counter_test.cc Thu Nov 05 15:48:01 2009 +0100
138.3 @@ -18,59 +18,86 @@
138.4
138.5 #include <lemon/counter.h>
138.6 #include <vector>
138.7 +#include <sstream>
138.8 +
138.9 +#include "test/test_tools.h"
138.10
138.11 using namespace lemon;
138.12
138.13 template <typename T>
138.14 void bubbleSort(std::vector<T>& v) {
138.15 - Counter op("Bubble Sort - Operations: ");
138.16 - Counter::NoSubCounter as(op, "Assignments: ");
138.17 - Counter::NoSubCounter co(op, "Comparisons: ");
138.18 - for (int i = v.size()-1; i > 0; --i) {
138.19 - for (int j = 0; j < i; ++j) {
138.20 - if (v[j] > v[j+1]) {
138.21 - T tmp = v[j];
138.22 - v[j] = v[j+1];
138.23 - v[j+1] = tmp;
138.24 - as += 3;
138.25 + std::stringstream s1, s2, s3;
138.26 + {
138.27 + Counter op("Bubble Sort - Operations: ", s1);
138.28 + Counter::SubCounter as(op, "Assignments: ", s2);
138.29 + Counter::SubCounter co(op, "Comparisons: ", s3);
138.30 + for (int i = v.size()-1; i > 0; --i) {
138.31 + for (int j = 0; j < i; ++j) {
138.32 + if (v[j] > v[j+1]) {
138.33 + T tmp = v[j];
138.34 + v[j] = v[j+1];
138.35 + v[j+1] = tmp;
138.36 + as += 3;
138.37 + }
138.38 + ++co;
138.39 }
138.40 - ++co;
138.41 }
138.42 }
138.43 + check(s1.str() == "Bubble Sort - Operations: 102\n", "Wrong counter");
138.44 + check(s2.str() == "Assignments: 57\n", "Wrong subcounter");
138.45 + check(s3.str() == "Comparisons: 45\n", "Wrong subcounter");
138.46 }
138.47
138.48 template <typename T>
138.49 void insertionSort(std::vector<T>& v) {
138.50 - Counter op("Insertion Sort - Operations: ");
138.51 - Counter::NoSubCounter as(op, "Assignments: ");
138.52 - Counter::NoSubCounter co(op, "Comparisons: ");
138.53 - for (int i = 1; i < int(v.size()); ++i) {
138.54 - T value = v[i];
138.55 - ++as;
138.56 - int j = i;
138.57 - while (j > 0 && v[j-1] > value) {
138.58 - v[j] = v[j-1];
138.59 - --j;
138.60 - ++co; ++as;
138.61 + std::stringstream s1, s2, s3;
138.62 + {
138.63 + Counter op("Insertion Sort - Operations: ", s1);
138.64 + Counter::SubCounter as(op, "Assignments: ", s2);
138.65 + Counter::SubCounter co(op, "Comparisons: ", s3);
138.66 + for (int i = 1; i < int(v.size()); ++i) {
138.67 + T value = v[i];
138.68 + ++as;
138.69 + int j = i;
138.70 + while (j > 0 && v[j-1] > value) {
138.71 + v[j] = v[j-1];
138.72 + --j;
138.73 + ++co; ++as;
138.74 + }
138.75 + v[j] = value;
138.76 + ++as;
138.77 }
138.78 - v[j] = value;
138.79 - ++as;
138.80 }
138.81 + check(s1.str() == "Insertion Sort - Operations: 56\n", "Wrong counter");
138.82 + check(s2.str() == "Assignments: 37\n", "Wrong subcounter");
138.83 + check(s3.str() == "Comparisons: 19\n", "Wrong subcounter");
138.84 }
138.85
138.86 template <typename MyCounter>
138.87 -void counterTest() {
138.88 - MyCounter c("Main Counter: ");
138.89 - c++;
138.90 - typename MyCounter::SubCounter d(c, "SubCounter: ");
138.91 - d++;
138.92 - typename MyCounter::SubCounter::NoSubCounter e(d, "SubSubCounter: ");
138.93 - e++;
138.94 - d+=3;
138.95 - c-=4;
138.96 - e-=2;
138.97 - c.reset(2);
138.98 - c.reset();
138.99 +void counterTest(bool output) {
138.100 + std::stringstream s1, s2, s3;
138.101 + {
138.102 + MyCounter c("Main Counter: ", s1);
138.103 + c++;
138.104 + typename MyCounter::SubCounter d(c, "SubCounter: ", s2);
138.105 + d++;
138.106 + typename MyCounter::SubCounter::NoSubCounter e(d, "SubSubCounter: ", s3);
138.107 + e++;
138.108 + d+=3;
138.109 + c-=4;
138.110 + e-=2;
138.111 + c.reset(2);
138.112 + c.reset();
138.113 + }
138.114 + if (output) {
138.115 + check(s1.str() == "Main Counter: 3\n", "Wrong Counter");
138.116 + check(s2.str() == "SubCounter: 3\n", "Wrong SubCounter");
138.117 + check(s3.str() == "", "Wrong NoSubCounter");
138.118 + } else {
138.119 + check(s1.str() == "", "Wrong NoCounter");
138.120 + check(s2.str() == "", "Wrong SubCounter");
138.121 + check(s3.str() == "", "Wrong NoSubCounter");
138.122 + }
138.123 }
138.124
138.125 void init(std::vector<int>& v) {
138.126 @@ -80,8 +107,8 @@
138.127
138.128 int main()
138.129 {
138.130 - counterTest<Counter>();
138.131 - counterTest<NoCounter>();
138.132 + counterTest<Counter>(true);
138.133 + counterTest<NoCounter>(false);
138.134
138.135 std::vector<int> x(10);
138.136 init(x); bubbleSort(x);
139.1 --- a/test/dfs_test.cc Mon Jan 12 23:11:39 2009 +0100
139.2 +++ b/test/dfs_test.cc Thu Nov 05 15:48:01 2009 +0100
139.3 @@ -62,39 +62,74 @@
139.4 Digraph G;
139.5 Node s, t;
139.6 Arc e;
139.7 - int l;
139.8 + int l, i;
139.9 bool b;
139.10 DType::DistMap d(G);
139.11 DType::PredMap p(G);
139.12 Path<Digraph> pp;
139.13 + concepts::ReadMap<Arc,bool> am;
139.14
139.15 {
139.16 DType dfs_test(G);
139.17 + const DType& const_dfs_test = dfs_test;
139.18
139.19 dfs_test.run(s);
139.20 dfs_test.run(s,t);
139.21 dfs_test.run();
139.22
139.23 - l = dfs_test.dist(t);
139.24 - e = dfs_test.predArc(t);
139.25 - s = dfs_test.predNode(t);
139.26 - b = dfs_test.reached(t);
139.27 - d = dfs_test.distMap();
139.28 - p = dfs_test.predMap();
139.29 - pp = dfs_test.path(t);
139.30 + dfs_test.init();
139.31 + dfs_test.addSource(s);
139.32 + e = dfs_test.processNextArc();
139.33 + e = const_dfs_test.nextArc();
139.34 + b = const_dfs_test.emptyQueue();
139.35 + i = const_dfs_test.queueSize();
139.36 +
139.37 + dfs_test.start();
139.38 + dfs_test.start(t);
139.39 + dfs_test.start(am);
139.40 +
139.41 + l = const_dfs_test.dist(t);
139.42 + e = const_dfs_test.predArc(t);
139.43 + s = const_dfs_test.predNode(t);
139.44 + b = const_dfs_test.reached(t);
139.45 + d = const_dfs_test.distMap();
139.46 + p = const_dfs_test.predMap();
139.47 + pp = const_dfs_test.path(t);
139.48 }
139.49 {
139.50 DType
139.51 ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
139.52 ::SetDistMap<concepts::ReadWriteMap<Node,int> >
139.53 ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
139.54 + ::SetStandardProcessedMap
139.55 ::SetProcessedMap<concepts::WriteMap<Node,bool> >
139.56 - ::SetStandardProcessedMap
139.57 ::Create dfs_test(G);
139.58
139.59 + concepts::ReadWriteMap<Node,Arc> pred_map;
139.60 + concepts::ReadWriteMap<Node,int> dist_map;
139.61 + concepts::ReadWriteMap<Node,bool> reached_map;
139.62 + concepts::WriteMap<Node,bool> processed_map;
139.63 +
139.64 + dfs_test
139.65 + .predMap(pred_map)
139.66 + .distMap(dist_map)
139.67 + .reachedMap(reached_map)
139.68 + .processedMap(processed_map);
139.69 +
139.70 dfs_test.run(s);
139.71 dfs_test.run(s,t);
139.72 dfs_test.run();
139.73 + dfs_test.init();
139.74 +
139.75 + dfs_test.addSource(s);
139.76 + e = dfs_test.processNextArc();
139.77 + e = dfs_test.nextArc();
139.78 + b = dfs_test.emptyQueue();
139.79 + i = dfs_test.queueSize();
139.80 +
139.81 + dfs_test.start();
139.82 + dfs_test.start(t);
139.83 + dfs_test.start(am);
139.84
139.85 l = dfs_test.dist(t);
139.86 e = dfs_test.predArc(t);
140.1 --- a/test/digraph_test.cc Mon Jan 12 23:11:39 2009 +0100
140.2 +++ b/test/digraph_test.cc Thu Nov 05 15:48:01 2009 +0100
140.3 @@ -19,6 +19,7 @@
140.4 #include <lemon/concepts/digraph.h>
140.5 #include <lemon/list_graph.h>
140.6 #include <lemon/smart_graph.h>
140.7 +#include <lemon/static_graph.h>
140.8 #include <lemon/full_graph.h>
140.9
140.10 #include "test_tools.h"
140.11 @@ -35,6 +36,9 @@
140.12 checkGraphNodeList(G, 0);
140.13 checkGraphArcList(G, 0);
140.14
140.15 + G.reserveNode(3);
140.16 + G.reserveArc(4);
140.17 +
140.18 Node
140.19 n1 = G.addNode(),
140.20 n2 = G.addNode(),
140.21 @@ -283,6 +287,14 @@
140.22 G.addArc(G.addNode(), G.addNode());
140.23
140.24 snapshot.restore();
140.25 + snapshot.save(G);
140.26 +
140.27 + checkGraphNodeList(G, 4);
140.28 + checkGraphArcList(G, 4);
140.29 +
140.30 + G.addArc(G.addNode(), G.addNode());
140.31 +
140.32 + snapshot.restore();
140.33
140.34 checkGraphNodeList(G, 4);
140.35 checkGraphArcList(G, 4);
140.36 @@ -317,6 +329,10 @@
140.37 checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
140.38 checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
140.39 }
140.40 + { // Checking StaticDigraph
140.41 + checkConcept<Digraph, StaticDigraph>();
140.42 + checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
140.43 + }
140.44 { // Checking FullDigraph
140.45 checkConcept<Digraph, FullDigraph>();
140.46 }
140.47 @@ -372,10 +388,122 @@
140.48 check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
140.49 }
140.50
140.51 +void checkStaticDigraph() {
140.52 + SmartDigraph g;
140.53 + SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
140.54 + SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
140.55 +
140.56 + StaticDigraph G;
140.57 +
140.58 + checkGraphNodeList(G, 0);
140.59 + checkGraphArcList(G, 0);
140.60 +
140.61 + G.build(g, nref, aref);
140.62 +
140.63 + checkGraphNodeList(G, 0);
140.64 + checkGraphArcList(G, 0);
140.65 +
140.66 + SmartDigraph::Node
140.67 + n1 = g.addNode(),
140.68 + n2 = g.addNode(),
140.69 + n3 = g.addNode();
140.70 +
140.71 + G.build(g, nref, aref);
140.72 +
140.73 + checkGraphNodeList(G, 3);
140.74 + checkGraphArcList(G, 0);
140.75 +
140.76 + SmartDigraph::Arc a1 = g.addArc(n1, n2);
140.77 +
140.78 + G.build(g, nref, aref);
140.79 +
140.80 + check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2],
140.81 + "Wrong arc or wrong references");
140.82 + checkGraphNodeList(G, 3);
140.83 + checkGraphArcList(G, 1);
140.84 +
140.85 + checkGraphOutArcList(G, nref[n1], 1);
140.86 + checkGraphOutArcList(G, nref[n2], 0);
140.87 + checkGraphOutArcList(G, nref[n3], 0);
140.88 +
140.89 + checkGraphInArcList(G, nref[n1], 0);
140.90 + checkGraphInArcList(G, nref[n2], 1);
140.91 + checkGraphInArcList(G, nref[n3], 0);
140.92 +
140.93 + checkGraphConArcList(G, 1);
140.94 +
140.95 + SmartDigraph::Arc
140.96 + a2 = g.addArc(n2, n1),
140.97 + a3 = g.addArc(n2, n3),
140.98 + a4 = g.addArc(n2, n3);
140.99 +
140.100 + digraphCopy(g, G).nodeRef(nref).run();
140.101 +
140.102 + checkGraphNodeList(G, 3);
140.103 + checkGraphArcList(G, 4);
140.104 +
140.105 + checkGraphOutArcList(G, nref[n1], 1);
140.106 + checkGraphOutArcList(G, nref[n2], 3);
140.107 + checkGraphOutArcList(G, nref[n3], 0);
140.108 +
140.109 + checkGraphInArcList(G, nref[n1], 1);
140.110 + checkGraphInArcList(G, nref[n2], 1);
140.111 + checkGraphInArcList(G, nref[n3], 2);
140.112 +
140.113 + checkGraphConArcList(G, 4);
140.114 +
140.115 + std::vector<std::pair<int,int> > arcs;
140.116 + arcs.push_back(std::make_pair(0,1));
140.117 + arcs.push_back(std::make_pair(0,2));
140.118 + arcs.push_back(std::make_pair(1,3));
140.119 + arcs.push_back(std::make_pair(1,2));
140.120 + arcs.push_back(std::make_pair(3,0));
140.121 + arcs.push_back(std::make_pair(3,3));
140.122 + arcs.push_back(std::make_pair(4,2));
140.123 + arcs.push_back(std::make_pair(4,3));
140.124 + arcs.push_back(std::make_pair(4,1));
140.125 +
140.126 + G.build(6, arcs.begin(), arcs.end());
140.127 +
140.128 + checkGraphNodeList(G, 6);
140.129 + checkGraphArcList(G, 9);
140.130 +
140.131 + checkGraphOutArcList(G, G.node(0), 2);
140.132 + checkGraphOutArcList(G, G.node(1), 2);
140.133 + checkGraphOutArcList(G, G.node(2), 0);
140.134 + checkGraphOutArcList(G, G.node(3), 2);
140.135 + checkGraphOutArcList(G, G.node(4), 3);
140.136 + checkGraphOutArcList(G, G.node(5), 0);
140.137 +
140.138 + checkGraphInArcList(G, G.node(0), 1);
140.139 + checkGraphInArcList(G, G.node(1), 2);
140.140 + checkGraphInArcList(G, G.node(2), 3);
140.141 + checkGraphInArcList(G, G.node(3), 3);
140.142 + checkGraphInArcList(G, G.node(4), 0);
140.143 + checkGraphInArcList(G, G.node(5), 0);
140.144 +
140.145 + checkGraphConArcList(G, 9);
140.146 +
140.147 + checkNodeIds(G);
140.148 + checkArcIds(G);
140.149 + checkGraphNodeMap(G);
140.150 + checkGraphArcMap(G);
140.151 +
140.152 + int n = G.nodeNum();
140.153 + int m = G.arcNum();
140.154 + check(G.index(G.node(n-1)) == n-1, "Wrong index.");
140.155 + check(G.index(G.arc(m-1)) == m-1, "Wrong index.");
140.156 +}
140.157 +
140.158 void checkFullDigraph(int num) {
140.159 typedef FullDigraph Digraph;
140.160 DIGRAPH_TYPEDEFS(Digraph);
140.161 +
140.162 Digraph G(num);
140.163 + check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
140.164 +
140.165 + G.resize(num);
140.166 + check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
140.167
140.168 checkGraphNodeList(G, num);
140.169 checkGraphArcList(G, num * num);
140.170 @@ -419,6 +547,9 @@
140.171 checkDigraphSnapshot<SmartDigraph>();
140.172 checkDigraphValidity<SmartDigraph>();
140.173 }
140.174 + { // Checking StaticDigraph
140.175 + checkStaticDigraph();
140.176 + }
140.177 { // Checking FullDigraph
140.178 checkFullDigraph(8);
140.179 }
141.1 --- a/test/dijkstra_test.cc Mon Jan 12 23:11:39 2009 +0100
141.2 +++ b/test/dijkstra_test.cc Thu Nov 05 15:48:01 2009 +0100
141.3 @@ -60,48 +60,94 @@
141.4 typedef Digraph::Arc Arc;
141.5
141.6 Digraph G;
141.7 - Node s, t;
141.8 + Node s, t, n;
141.9 Arc e;
141.10 VType l;
141.11 + int i;
141.12 bool b;
141.13 DType::DistMap d(G);
141.14 DType::PredMap p(G);
141.15 LengthMap length;
141.16 Path<Digraph> pp;
141.17 + concepts::ReadMap<Node,bool> nm;
141.18
141.19 {
141.20 DType dijkstra_test(G,length);
141.21 + const DType& const_dijkstra_test = dijkstra_test;
141.22
141.23 dijkstra_test.run(s);
141.24 dijkstra_test.run(s,t);
141.25
141.26 + dijkstra_test.init();
141.27 + dijkstra_test.addSource(s);
141.28 + dijkstra_test.addSource(s, 1);
141.29 + n = dijkstra_test.processNextNode();
141.30 + n = const_dijkstra_test.nextNode();
141.31 + b = const_dijkstra_test.emptyQueue();
141.32 + i = const_dijkstra_test.queueSize();
141.33 +
141.34 + dijkstra_test.start();
141.35 + dijkstra_test.start(t);
141.36 + dijkstra_test.start(nm);
141.37 +
141.38 + l = const_dijkstra_test.dist(t);
141.39 + e = const_dijkstra_test.predArc(t);
141.40 + s = const_dijkstra_test.predNode(t);
141.41 + b = const_dijkstra_test.reached(t);
141.42 + b = const_dijkstra_test.processed(t);
141.43 + d = const_dijkstra_test.distMap();
141.44 + p = const_dijkstra_test.predMap();
141.45 + pp = const_dijkstra_test.path(t);
141.46 + l = const_dijkstra_test.currentDist(t);
141.47 + }
141.48 + {
141.49 + DType
141.50 + ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
141.51 + ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
141.52 + ::SetStandardProcessedMap
141.53 + ::SetProcessedMap<concepts::WriteMap<Node,bool> >
141.54 + ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
141.55 + ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
141.56 + ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
141.57 + ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >,
141.58 + concepts::ReadWriteMap<Node,int> >
141.59 + ::Create dijkstra_test(G,length);
141.60 +
141.61 + LengthMap length_map;
141.62 + concepts::ReadWriteMap<Node,Arc> pred_map;
141.63 + concepts::ReadWriteMap<Node,VType> dist_map;
141.64 + concepts::WriteMap<Node,bool> processed_map;
141.65 + concepts::ReadWriteMap<Node,int> heap_cross_ref;
141.66 + BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
141.67 +
141.68 + dijkstra_test
141.69 + .lengthMap(length_map)
141.70 + .predMap(pred_map)
141.71 + .distMap(dist_map)
141.72 + .processedMap(processed_map)
141.73 + .heap(heap, heap_cross_ref);
141.74 +
141.75 + dijkstra_test.run(s);
141.76 + dijkstra_test.run(s,t);
141.77 +
141.78 + dijkstra_test.addSource(s);
141.79 + dijkstra_test.addSource(s, 1);
141.80 + n = dijkstra_test.processNextNode();
141.81 + n = dijkstra_test.nextNode();
141.82 + b = dijkstra_test.emptyQueue();
141.83 + i = dijkstra_test.queueSize();
141.84 +
141.85 + dijkstra_test.start();
141.86 + dijkstra_test.start(t);
141.87 + dijkstra_test.start(nm);
141.88 +
141.89 l = dijkstra_test.dist(t);
141.90 e = dijkstra_test.predArc(t);
141.91 s = dijkstra_test.predNode(t);
141.92 b = dijkstra_test.reached(t);
141.93 - d = dijkstra_test.distMap();
141.94 - p = dijkstra_test.predMap();
141.95 + b = dijkstra_test.processed(t);
141.96 pp = dijkstra_test.path(t);
141.97 - }
141.98 - {
141.99 - DType
141.100 - ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
141.101 - ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
141.102 - ::SetProcessedMap<concepts::WriteMap<Node,bool> >
141.103 - ::SetStandardProcessedMap
141.104 - ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
141.105 - ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
141.106 - ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
141.107 - ::Create dijkstra_test(G,length);
141.108 -
141.109 - dijkstra_test.run(s);
141.110 - dijkstra_test.run(s,t);
141.111 -
141.112 - l = dijkstra_test.dist(t);
141.113 - e = dijkstra_test.predArc(t);
141.114 - s = dijkstra_test.predNode(t);
141.115 - b = dijkstra_test.reached(t);
141.116 - pp = dijkstra_test.path(t);
141.117 + l = dijkstra_test.currentDist(t);
141.118 }
141.119
141.120 }
142.1 --- a/test/edge_set_test.cc Mon Jan 12 23:11:39 2009 +0100
142.2 +++ b/test/edge_set_test.cc Thu Nov 05 15:48:01 2009 +0100
142.3 @@ -33,7 +33,7 @@
142.4 using namespace lemon;
142.5
142.6 void checkSmartArcSet() {
142.7 - checkConcept<concepts::Digraph, SmartArcSet<concepts::Digraph> >();
142.8 + checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
142.9
142.10 typedef ListDigraph Digraph;
142.11 typedef SmartArcSet<Digraph> ArcSet;
142.12 @@ -99,7 +99,7 @@
142.13 }
142.14
142.15 void checkListArcSet() {
142.16 - checkConcept<concepts::Digraph, SmartArcSet<concepts::Digraph> >();
142.17 + checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
142.18
142.19 typedef ListDigraph Digraph;
142.20 typedef ListArcSet<Digraph> ArcSet;
142.21 @@ -179,7 +179,7 @@
142.22 }
142.23
142.24 void checkSmartEdgeSet() {
142.25 - checkConcept<concepts::Digraph, SmartEdgeSet<concepts::Digraph> >();
142.26 + checkConcept<concepts::Digraph, SmartEdgeSet<ListDigraph> >();
142.27
142.28 typedef ListDigraph Digraph;
142.29 typedef SmartEdgeSet<Digraph> EdgeSet;
142.30 @@ -263,7 +263,7 @@
142.31 }
142.32
142.33 void checkListEdgeSet() {
142.34 - checkConcept<concepts::Digraph, ListEdgeSet<concepts::Digraph> >();
142.35 + checkConcept<concepts::Digraph, ListEdgeSet<ListDigraph> >();
142.36
142.37 typedef ListDigraph Digraph;
142.38 typedef ListEdgeSet<Digraph> EdgeSet;
143.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
143.2 +++ b/test/euler_test.cc Thu Nov 05 15:48:01 2009 +0100
143.3 @@ -0,0 +1,223 @@
143.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
143.5 + *
143.6 + * This file is a part of LEMON, a generic C++ optimization library.
143.7 + *
143.8 + * Copyright (C) 2003-2009
143.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
143.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
143.11 + *
143.12 + * Permission to use, modify and distribute this software is granted
143.13 + * provided that this copyright notice appears in all copies. For
143.14 + * precise terms see the accompanying LICENSE file.
143.15 + *
143.16 + * This software is provided "AS IS" with no warranty of any kind,
143.17 + * express or implied, and with no claim as to its suitability for any
143.18 + * purpose.
143.19 + *
143.20 + */
143.21 +
143.22 +#include <lemon/euler.h>
143.23 +#include <lemon/list_graph.h>
143.24 +#include <lemon/adaptors.h>
143.25 +#include "test_tools.h"
143.26 +
143.27 +using namespace lemon;
143.28 +
143.29 +template <typename Digraph>
143.30 +void checkDiEulerIt(const Digraph& g,
143.31 + const typename Digraph::Node& start = INVALID)
143.32 +{
143.33 + typename Digraph::template ArcMap<int> visitationNumber(g, 0);
143.34 +
143.35 + DiEulerIt<Digraph> e(g, start);
143.36 + if (e == INVALID) return;
143.37 + typename Digraph::Node firstNode = g.source(e);
143.38 + typename Digraph::Node lastNode = g.target(e);
143.39 + if (start != INVALID) {
143.40 + check(firstNode == start, "checkDiEulerIt: Wrong first node");
143.41 + }
143.42 +
143.43 + for (; e != INVALID; ++e) {
143.44 + if (e != INVALID) lastNode = g.target(e);
143.45 + ++visitationNumber[e];
143.46 + }
143.47 +
143.48 + check(firstNode == lastNode,
143.49 + "checkDiEulerIt: First and last nodes are not the same");
143.50 +
143.51 + for (typename Digraph::ArcIt a(g); a != INVALID; ++a)
143.52 + {
143.53 + check(visitationNumber[a] == 1,
143.54 + "checkDiEulerIt: Not visited or multiple times visited arc found");
143.55 + }
143.56 +}
143.57 +
143.58 +template <typename Graph>
143.59 +void checkEulerIt(const Graph& g,
143.60 + const typename Graph::Node& start = INVALID)
143.61 +{
143.62 + typename Graph::template EdgeMap<int> visitationNumber(g, 0);
143.63 +
143.64 + EulerIt<Graph> e(g, start);
143.65 + if (e == INVALID) return;
143.66 + typename Graph::Node firstNode = g.source(typename Graph::Arc(e));
143.67 + typename Graph::Node lastNode = g.target(typename Graph::Arc(e));
143.68 + if (start != INVALID) {
143.69 + check(firstNode == start, "checkEulerIt: Wrong first node");
143.70 + }
143.71 +
143.72 + for (; e != INVALID; ++e) {
143.73 + if (e != INVALID) lastNode = g.target(typename Graph::Arc(e));
143.74 + ++visitationNumber[e];
143.75 + }
143.76 +
143.77 + check(firstNode == lastNode,
143.78 + "checkEulerIt: First and last nodes are not the same");
143.79 +
143.80 + for (typename Graph::EdgeIt e(g); e != INVALID; ++e)
143.81 + {
143.82 + check(visitationNumber[e] == 1,
143.83 + "checkEulerIt: Not visited or multiple times visited edge found");
143.84 + }
143.85 +}
143.86 +
143.87 +int main()
143.88 +{
143.89 + typedef ListDigraph Digraph;
143.90 + typedef Undirector<Digraph> Graph;
143.91 +
143.92 + {
143.93 + Digraph d;
143.94 + Graph g(d);
143.95 +
143.96 + checkDiEulerIt(d);
143.97 + checkDiEulerIt(g);
143.98 + checkEulerIt(g);
143.99 +
143.100 + check(eulerian(d), "This graph is Eulerian");
143.101 + check(eulerian(g), "This graph is Eulerian");
143.102 + }
143.103 + {
143.104 + Digraph d;
143.105 + Graph g(d);
143.106 + Digraph::Node n = d.addNode();
143.107 +
143.108 + checkDiEulerIt(d);
143.109 + checkDiEulerIt(g);
143.110 + checkEulerIt(g);
143.111 +
143.112 + check(eulerian(d), "This graph is Eulerian");
143.113 + check(eulerian(g), "This graph is Eulerian");
143.114 + }
143.115 + {
143.116 + Digraph d;
143.117 + Graph g(d);
143.118 + Digraph::Node n = d.addNode();
143.119 + d.addArc(n, n);
143.120 +
143.121 + checkDiEulerIt(d);
143.122 + checkDiEulerIt(g);
143.123 + checkEulerIt(g);
143.124 +
143.125 + check(eulerian(d), "This graph is Eulerian");
143.126 + check(eulerian(g), "This graph is Eulerian");
143.127 + }
143.128 + {
143.129 + Digraph d;
143.130 + Graph g(d);
143.131 + Digraph::Node n1 = d.addNode();
143.132 + Digraph::Node n2 = d.addNode();
143.133 + Digraph::Node n3 = d.addNode();
143.134 +
143.135 + d.addArc(n1, n2);
143.136 + d.addArc(n2, n1);
143.137 + d.addArc(n2, n3);
143.138 + d.addArc(n3, n2);
143.139 +
143.140 + checkDiEulerIt(d);
143.141 + checkDiEulerIt(d, n2);
143.142 + checkDiEulerIt(g);
143.143 + checkDiEulerIt(g, n2);
143.144 + checkEulerIt(g);
143.145 + checkEulerIt(g, n2);
143.146 +
143.147 + check(eulerian(d), "This graph is Eulerian");
143.148 + check(eulerian(g), "This graph is Eulerian");
143.149 + }
143.150 + {
143.151 + Digraph d;
143.152 + Graph g(d);
143.153 + Digraph::Node n1 = d.addNode();
143.154 + Digraph::Node n2 = d.addNode();
143.155 + Digraph::Node n3 = d.addNode();
143.156 + Digraph::Node n4 = d.addNode();
143.157 + Digraph::Node n5 = d.addNode();
143.158 + Digraph::Node n6 = d.addNode();
143.159 +
143.160 + d.addArc(n1, n2);
143.161 + d.addArc(n2, n4);
143.162 + d.addArc(n1, n3);
143.163 + d.addArc(n3, n4);
143.164 + d.addArc(n4, n1);
143.165 + d.addArc(n3, n5);
143.166 + d.addArc(n5, n2);
143.167 + d.addArc(n4, n6);
143.168 + d.addArc(n2, n6);
143.169 + d.addArc(n6, n1);
143.170 + d.addArc(n6, n3);
143.171 +
143.172 + checkDiEulerIt(d);
143.173 + checkDiEulerIt(d, n1);
143.174 + checkDiEulerIt(d, n5);
143.175 +
143.176 + checkDiEulerIt(g);
143.177 + checkDiEulerIt(g, n1);
143.178 + checkDiEulerIt(g, n5);
143.179 + checkEulerIt(g);
143.180 + checkEulerIt(g, n1);
143.181 + checkEulerIt(g, n5);
143.182 +
143.183 + check(eulerian(d), "This graph is Eulerian");
143.184 + check(eulerian(g), "This graph is Eulerian");
143.185 + }
143.186 + {
143.187 + Digraph d;
143.188 + Graph g(d);
143.189 + Digraph::Node n0 = d.addNode();
143.190 + Digraph::Node n1 = d.addNode();
143.191 + Digraph::Node n2 = d.addNode();
143.192 + Digraph::Node n3 = d.addNode();
143.193 + Digraph::Node n4 = d.addNode();
143.194 + Digraph::Node n5 = d.addNode();
143.195 +
143.196 + d.addArc(n1, n2);
143.197 + d.addArc(n2, n3);
143.198 + d.addArc(n3, n1);
143.199 +
143.200 + checkDiEulerIt(d);
143.201 + checkDiEulerIt(d, n2);
143.202 +
143.203 + checkDiEulerIt(g);
143.204 + checkDiEulerIt(g, n2);
143.205 + checkEulerIt(g);
143.206 + checkEulerIt(g, n2);
143.207 +
143.208 + check(!eulerian(d), "This graph is not Eulerian");
143.209 + check(!eulerian(g), "This graph is not Eulerian");
143.210 + }
143.211 + {
143.212 + Digraph d;
143.213 + Graph g(d);
143.214 + Digraph::Node n1 = d.addNode();
143.215 + Digraph::Node n2 = d.addNode();
143.216 + Digraph::Node n3 = d.addNode();
143.217 +
143.218 + d.addArc(n1, n2);
143.219 + d.addArc(n2, n3);
143.220 +
143.221 + check(!eulerian(d), "This graph is not Eulerian");
143.222 + check(!eulerian(g), "This graph is not Eulerian");
143.223 + }
143.224 +
143.225 + return 0;
143.226 +}
144.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
144.2 +++ b/test/gomory_hu_test.cc Thu Nov 05 15:48:01 2009 +0100
144.3 @@ -0,0 +1,123 @@
144.4 +#include <iostream>
144.5 +
144.6 +#include "test_tools.h"
144.7 +#include <lemon/smart_graph.h>
144.8 +#include <lemon/concepts/graph.h>
144.9 +#include <lemon/concepts/maps.h>
144.10 +#include <lemon/lgf_reader.h>
144.11 +#include <lemon/gomory_hu.h>
144.12 +#include <cstdlib>
144.13 +
144.14 +using namespace std;
144.15 +using namespace lemon;
144.16 +
144.17 +typedef SmartGraph Graph;
144.18 +
144.19 +char test_lgf[] =
144.20 + "@nodes\n"
144.21 + "label\n"
144.22 + "0\n"
144.23 + "1\n"
144.24 + "2\n"
144.25 + "3\n"
144.26 + "4\n"
144.27 + "@arcs\n"
144.28 + " label capacity\n"
144.29 + "0 1 0 1\n"
144.30 + "1 2 1 1\n"
144.31 + "2 3 2 1\n"
144.32 + "0 3 4 5\n"
144.33 + "0 3 5 10\n"
144.34 + "0 3 6 7\n"
144.35 + "4 2 7 1\n"
144.36 + "@attributes\n"
144.37 + "source 0\n"
144.38 + "target 3\n";
144.39 +
144.40 +void checkGomoryHuCompile()
144.41 +{
144.42 + typedef int Value;
144.43 + typedef concepts::Graph Graph;
144.44 +
144.45 + typedef Graph::Node Node;
144.46 + typedef Graph::Edge Edge;
144.47 + typedef concepts::ReadMap<Edge, Value> CapMap;
144.48 + typedef concepts::ReadWriteMap<Node, bool> CutMap;
144.49 +
144.50 + Graph g;
144.51 + Node n;
144.52 + CapMap cap;
144.53 + CutMap cut;
144.54 + Value v;
144.55 + int d;
144.56 +
144.57 + GomoryHu<Graph, CapMap> gh_test(g, cap);
144.58 + const GomoryHu<Graph, CapMap>&
144.59 + const_gh_test = gh_test;
144.60 +
144.61 + gh_test.run();
144.62 +
144.63 + n = const_gh_test.predNode(n);
144.64 + v = const_gh_test.predValue(n);
144.65 + d = const_gh_test.rootDist(n);
144.66 + v = const_gh_test.minCutValue(n, n);
144.67 + v = const_gh_test.minCutMap(n, n, cut);
144.68 +}
144.69 +
144.70 +GRAPH_TYPEDEFS(Graph);
144.71 +typedef Graph::EdgeMap<int> IntEdgeMap;
144.72 +typedef Graph::NodeMap<bool> BoolNodeMap;
144.73 +
144.74 +int cutValue(const Graph& graph, const BoolNodeMap& cut,
144.75 + const IntEdgeMap& capacity) {
144.76 +
144.77 + int sum = 0;
144.78 + for (EdgeIt e(graph); e != INVALID; ++e) {
144.79 + Node s = graph.u(e);
144.80 + Node t = graph.v(e);
144.81 +
144.82 + if (cut[s] != cut[t]) {
144.83 + sum += capacity[e];
144.84 + }
144.85 + }
144.86 + return sum;
144.87 +}
144.88 +
144.89 +
144.90 +int main() {
144.91 + Graph graph;
144.92 + IntEdgeMap capacity(graph);
144.93 +
144.94 + std::istringstream input(test_lgf);
144.95 + GraphReader<Graph>(graph, input).
144.96 + edgeMap("capacity", capacity).run();
144.97 +
144.98 + GomoryHu<Graph> ght(graph, capacity);
144.99 + ght.run();
144.100 +
144.101 + for (NodeIt u(graph); u != INVALID; ++u) {
144.102 + for (NodeIt v(graph); v != u; ++v) {
144.103 + Preflow<Graph, IntEdgeMap> pf(graph, capacity, u, v);
144.104 + pf.runMinCut();
144.105 + BoolNodeMap cm(graph);
144.106 + ght.minCutMap(u, v, cm);
144.107 + check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1");
144.108 + check(cm[u] != cm[v], "Wrong cut 2");
144.109 + check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 3");
144.110 +
144.111 + int sum=0;
144.112 + for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
144.113 + sum+=capacity[a];
144.114 + check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
144.115 +
144.116 + sum=0;
144.117 + for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,true);n!=INVALID;++n)
144.118 + sum++;
144.119 + for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,false);n!=INVALID;++n)
144.120 + sum++;
144.121 + check(sum == countNodes(graph), "Problem with MinCutNodeIt");
144.122 + }
144.123 + }
144.124 +
144.125 + return 0;
144.126 +}
145.1 --- a/test/graph_test.cc Mon Jan 12 23:11:39 2009 +0100
145.2 +++ b/test/graph_test.cc Thu Nov 05 15:48:01 2009 +0100
145.3 @@ -38,6 +38,9 @@
145.4 checkGraphEdgeList(G, 0);
145.5 checkGraphArcList(G, 0);
145.6
145.7 + G.reserveNode(3);
145.8 + G.reserveEdge(3);
145.9 +
145.10 Node
145.11 n1 = G.addNode(),
145.12 n2 = G.addNode(),
145.13 @@ -256,6 +259,15 @@
145.14 G.addEdge(G.addNode(), G.addNode());
145.15
145.16 snapshot.restore();
145.17 + snapshot.save(G);
145.18 +
145.19 + checkGraphNodeList(G, 4);
145.20 + checkGraphEdgeList(G, 3);
145.21 + checkGraphArcList(G, 6);
145.22 +
145.23 + G.addEdge(G.addNode(), G.addNode());
145.24 +
145.25 + snapshot.restore();
145.26
145.27 checkGraphNodeList(G, 4);
145.28 checkGraphEdgeList(G, 3);
145.29 @@ -267,6 +279,13 @@
145.30 GRAPH_TYPEDEFS(Graph);
145.31
145.32 Graph G(num);
145.33 + check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
145.34 + "Wrong size");
145.35 +
145.36 + G.resize(num);
145.37 + check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
145.38 + "Wrong size");
145.39 +
145.40 checkGraphNodeList(G, num);
145.41 checkGraphEdgeList(G, num * (num - 1) / 2);
145.42
145.43 @@ -411,6 +430,10 @@
145.44 check(G.width() == width, "Wrong column number");
145.45 check(G.height() == height, "Wrong row number");
145.46
145.47 + G.resize(width, height);
145.48 + check(G.width() == width, "Wrong column number");
145.49 + check(G.height() == height, "Wrong row number");
145.50 +
145.51 for (int i = 0; i < width; ++i) {
145.52 for (int j = 0; j < height; ++j) {
145.53 check(G.col(G(i, j)) == i, "Wrong column");
145.54 @@ -486,6 +509,11 @@
145.55 GRAPH_TYPEDEFS(HypercubeGraph);
145.56
145.57 HypercubeGraph G(dim);
145.58 + check(G.dimension() == dim, "Wrong dimension");
145.59 +
145.60 + G.resize(dim);
145.61 + check(G.dimension() == dim, "Wrong dimension");
145.62 +
145.63 checkGraphNodeList(G, 1 << dim);
145.64 checkGraphEdgeList(G, dim * (1 << (dim-1)));
145.65 checkGraphArcList(G, dim * (1 << dim));
146.1 --- a/test/graph_utils_test.cc Mon Jan 12 23:11:39 2009 +0100
146.2 +++ b/test/graph_utils_test.cc Thu Nov 05 15:48:01 2009 +0100
146.3 @@ -38,15 +38,15 @@
146.4 for (int i = 0; i < 10; ++i) {
146.5 digraph.addNode();
146.6 }
146.7 - DescriptorMap<Digraph, Node> nodes(digraph);
146.8 - typename DescriptorMap<Digraph, Node>::InverseMap invNodes(nodes);
146.9 + RangeIdMap<Digraph, Node> nodes(digraph);
146.10 + typename RangeIdMap<Digraph, Node>::InverseMap invNodes(nodes);
146.11 for (int i = 0; i < 100; ++i) {
146.12 int src = rnd[invNodes.size()];
146.13 int trg = rnd[invNodes.size()];
146.14 digraph.addArc(invNodes[src], invNodes[trg]);
146.15 }
146.16 typename Digraph::template ArcMap<bool> found(digraph, false);
146.17 - DescriptorMap<Digraph, Arc> arcs(digraph);
146.18 + RangeIdMap<Digraph, Arc> arcs(digraph);
146.19 for (NodeIt src(digraph); src != INVALID; ++src) {
146.20 for (NodeIt trg(digraph); trg != INVALID; ++trg) {
146.21 for (ConArcIt<Digraph> con(digraph, src, trg); con != INVALID; ++con) {
146.22 @@ -113,15 +113,15 @@
146.23 for (int i = 0; i < 10; ++i) {
146.24 graph.addNode();
146.25 }
146.26 - DescriptorMap<Graph, Node> nodes(graph);
146.27 - typename DescriptorMap<Graph, Node>::InverseMap invNodes(nodes);
146.28 + RangeIdMap<Graph, Node> nodes(graph);
146.29 + typename RangeIdMap<Graph, Node>::InverseMap invNodes(nodes);
146.30 for (int i = 0; i < 100; ++i) {
146.31 int src = rnd[invNodes.size()];
146.32 int trg = rnd[invNodes.size()];
146.33 graph.addEdge(invNodes[src], invNodes[trg]);
146.34 }
146.35 typename Graph::template EdgeMap<int> found(graph, 0);
146.36 - DescriptorMap<Graph, Edge> edges(graph);
146.37 + RangeIdMap<Graph, Edge> edges(graph);
146.38 for (NodeIt src(graph); src != INVALID; ++src) {
146.39 for (NodeIt trg(graph); trg != INVALID; ++trg) {
146.40 for (ConEdgeIt<Graph> con(graph, src, trg); con != INVALID; ++con) {
147.1 --- a/test/hao_orlin_test.cc Mon Jan 12 23:11:39 2009 +0100
147.2 +++ b/test/hao_orlin_test.cc Thu Nov 05 15:48:01 2009 +0100
147.3 @@ -19,9 +19,12 @@
147.4 #include <sstream>
147.5
147.6 #include <lemon/smart_graph.h>
147.7 +#include <lemon/adaptors.h>
147.8 +#include <lemon/concepts/digraph.h>
147.9 +#include <lemon/concepts/maps.h>
147.10 +#include <lemon/lgf_reader.h>
147.11 #include <lemon/hao_orlin.h>
147.12
147.13 -#include <lemon/lgf_reader.h>
147.14 #include "test_tools.h"
147.15
147.16 using namespace lemon;
147.17 @@ -37,27 +40,124 @@
147.18 "4\n"
147.19 "5\n"
147.20 "@edges\n"
147.21 - " label capacity\n"
147.22 - "0 1 0 2\n"
147.23 - "1 2 1 2\n"
147.24 - "2 0 2 2\n"
147.25 - "3 4 3 2\n"
147.26 - "4 5 4 2\n"
147.27 - "5 3 5 2\n"
147.28 - "2 3 6 3\n";
147.29 + " cap1 cap2 cap3\n"
147.30 + "0 1 1 1 1 \n"
147.31 + "0 2 2 2 4 \n"
147.32 + "1 2 4 4 4 \n"
147.33 + "3 4 1 1 1 \n"
147.34 + "3 5 2 2 4 \n"
147.35 + "4 5 4 4 4 \n"
147.36 + "5 4 4 4 4 \n"
147.37 + "2 3 1 6 6 \n"
147.38 + "4 0 1 6 6 \n";
147.39 +
147.40 +void checkHaoOrlinCompile()
147.41 +{
147.42 + typedef int Value;
147.43 + typedef concepts::Digraph Digraph;
147.44 +
147.45 + typedef Digraph::Node Node;
147.46 + typedef Digraph::Arc Arc;
147.47 + typedef concepts::ReadMap<Arc, Value> CapMap;
147.48 + typedef concepts::WriteMap<Node, bool> CutMap;
147.49 +
147.50 + Digraph g;
147.51 + Node n;
147.52 + CapMap cap;
147.53 + CutMap cut;
147.54 + Value v;
147.55 +
147.56 + HaoOrlin<Digraph, CapMap> ho_test(g, cap);
147.57 + const HaoOrlin<Digraph, CapMap>&
147.58 + const_ho_test = ho_test;
147.59 +
147.60 + ho_test.init();
147.61 + ho_test.init(n);
147.62 + ho_test.calculateOut();
147.63 + ho_test.calculateIn();
147.64 + ho_test.run();
147.65 + ho_test.run(n);
147.66 +
147.67 + v = const_ho_test.minCutValue();
147.68 + v = const_ho_test.minCutMap(cut);
147.69 +}
147.70 +
147.71 +template <typename Graph, typename CapMap, typename CutMap>
147.72 +typename CapMap::Value
147.73 + cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
147.74 +{
147.75 + typename CapMap::Value sum = 0;
147.76 + for (typename Graph::ArcIt a(graph); a != INVALID; ++a) {
147.77 + if (cut[graph.source(a)] && !cut[graph.target(a)])
147.78 + sum += cap[a];
147.79 + }
147.80 + return sum;
147.81 +}
147.82
147.83 int main() {
147.84 - SmartGraph graph;
147.85 - SmartGraph::EdgeMap<int> capacity(graph);
147.86 + SmartDigraph graph;
147.87 + SmartDigraph::ArcMap<int> cap1(graph), cap2(graph), cap3(graph);
147.88 + SmartDigraph::NodeMap<bool> cut(graph);
147.89
147.90 - istringstream lgfs(lgf);
147.91 - graphReader(graph, lgfs).
147.92 - edgeMap("capacity", capacity).run();
147.93 + istringstream input(lgf);
147.94 + digraphReader(graph, input)
147.95 + .arcMap("cap1", cap1)
147.96 + .arcMap("cap2", cap2)
147.97 + .arcMap("cap3", cap3)
147.98 + .run();
147.99
147.100 - HaoOrlin<SmartGraph, SmartGraph::EdgeMap<int> > ho(graph, capacity);
147.101 - ho.run();
147.102 + {
147.103 + HaoOrlin<SmartDigraph> ho(graph, cap1);
147.104 + ho.run();
147.105 + ho.minCutMap(cut);
147.106 +
147.107 + check(ho.minCutValue() == 1, "Wrong cut value");
147.108 + check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
147.109 + }
147.110 + {
147.111 + HaoOrlin<SmartDigraph> ho(graph, cap2);
147.112 + ho.run();
147.113 + ho.minCutMap(cut);
147.114
147.115 - check(ho.minCutValue() == 3, "Wrong cut value");
147.116 + check(ho.minCutValue() == 1, "Wrong cut value");
147.117 + check(ho.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
147.118 + }
147.119 + {
147.120 + HaoOrlin<SmartDigraph> ho(graph, cap3);
147.121 + ho.run();
147.122 + ho.minCutMap(cut);
147.123 +
147.124 + check(ho.minCutValue() == 1, "Wrong cut value");
147.125 + check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
147.126 + }
147.127 +
147.128 + typedef Undirector<SmartDigraph> UGraph;
147.129 + UGraph ugraph(graph);
147.130 +
147.131 + {
147.132 + HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1);
147.133 + ho.run();
147.134 + ho.minCutMap(cut);
147.135 +
147.136 + check(ho.minCutValue() == 2, "Wrong cut value");
147.137 + check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value");
147.138 + }
147.139 + {
147.140 + HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap2);
147.141 + ho.run();
147.142 + ho.minCutMap(cut);
147.143 +
147.144 + check(ho.minCutValue() == 5, "Wrong cut value");
147.145 + check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value");
147.146 + }
147.147 + {
147.148 + HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap3);
147.149 + ho.run();
147.150 + ho.minCutMap(cut);
147.151 +
147.152 + check(ho.minCutValue() == 5, "Wrong cut value");
147.153 + check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value");
147.154 + }
147.155
147.156 return 0;
147.157 }
148.1 --- a/test/heap_test.cc Mon Jan 12 23:11:39 2009 +0100
148.2 +++ b/test/heap_test.cc Thu Nov 05 15:48:01 2009 +0100
148.3 @@ -25,12 +25,18 @@
148.4 #include <lemon/concepts/heap.h>
148.5
148.6 #include <lemon/smart_graph.h>
148.7 -
148.8 #include <lemon/lgf_reader.h>
148.9 #include <lemon/dijkstra.h>
148.10 #include <lemon/maps.h>
148.11
148.12 #include <lemon/bin_heap.h>
148.13 +#include <lemon/fourary_heap.h>
148.14 +#include <lemon/kary_heap.h>
148.15 +#include <lemon/fib_heap.h>
148.16 +#include <lemon/pairing_heap.h>
148.17 +#include <lemon/radix_heap.h>
148.18 +#include <lemon/binom_heap.h>
148.19 +#include <lemon/bucket_heap.h>
148.20
148.21 #include "test_tools.h"
148.22
148.23 @@ -86,18 +92,16 @@
148.24 template <typename Heap>
148.25 void heapSortTest() {
148.26 RangeMap<int> map(test_len, -1);
148.27 -
148.28 Heap heap(map);
148.29
148.30 std::vector<int> v(test_len);
148.31 -
148.32 for (int i = 0; i < test_len; ++i) {
148.33 v[i] = test_seq[i];
148.34 heap.push(i, v[i]);
148.35 }
148.36 std::sort(v.begin(), v.end());
148.37 for (int i = 0; i < test_len; ++i) {
148.38 - check(v[i] == heap.prio() ,"Wrong order in heap sort.");
148.39 + check(v[i] == heap.prio(), "Wrong order in heap sort.");
148.40 heap.pop();
148.41 }
148.42 }
148.43 @@ -109,7 +113,6 @@
148.44 Heap heap(map);
148.45
148.46 std::vector<int> v(test_len);
148.47 -
148.48 for (int i = 0; i < test_len; ++i) {
148.49 v[i] = test_seq[i];
148.50 heap.push(i, v[i]);
148.51 @@ -120,13 +123,11 @@
148.52 }
148.53 std::sort(v.begin(), v.end());
148.54 for (int i = 0; i < test_len; ++i) {
148.55 - check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
148.56 + check(v[i] == heap.prio(), "Wrong order in heap increase test.");
148.57 heap.pop();
148.58 }
148.59 }
148.60
148.61 -
148.62 -
148.63 template <typename Heap>
148.64 void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
148.65 Node source) {
148.66 @@ -141,7 +142,7 @@
148.67 Node t = digraph.target(a);
148.68 if (dijkstra.reached(s)) {
148.69 check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
148.70 - "Error in a shortest path tree!");
148.71 + "Error in shortest path tree.");
148.72 }
148.73 }
148.74
148.75 @@ -150,7 +151,7 @@
148.76 Arc a = dijkstra.predArc(n);
148.77 Node s = digraph.source(a);
148.78 check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
148.79 - "Error in a shortest path tree!");
148.80 + "Error in shortest path tree.");
148.81 }
148.82 }
148.83
148.84 @@ -172,6 +173,7 @@
148.85 node("source", source).
148.86 run();
148.87
148.88 + // BinHeap
148.89 {
148.90 typedef BinHeap<Prio, ItemIntMap> IntHeap;
148.91 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
148.92 @@ -183,5 +185,92 @@
148.93 dijkstraHeapTest<NodeHeap>(digraph, length, source);
148.94 }
148.95
148.96 + // FouraryHeap
148.97 + {
148.98 + typedef FouraryHeap<Prio, ItemIntMap> IntHeap;
148.99 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
148.100 + heapSortTest<IntHeap>();
148.101 + heapIncreaseTest<IntHeap>();
148.102 +
148.103 + typedef FouraryHeap<Prio, IntNodeMap > NodeHeap;
148.104 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
148.105 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
148.106 + }
148.107 +
148.108 + // KaryHeap
148.109 + {
148.110 + typedef KaryHeap<Prio, ItemIntMap> IntHeap;
148.111 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
148.112 + heapSortTest<IntHeap>();
148.113 + heapIncreaseTest<IntHeap>();
148.114 +
148.115 + typedef KaryHeap<Prio, IntNodeMap > NodeHeap;
148.116 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
148.117 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
148.118 + }
148.119 +
148.120 + // FibHeap
148.121 + {
148.122 + typedef FibHeap<Prio, ItemIntMap> IntHeap;
148.123 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
148.124 + heapSortTest<IntHeap>();
148.125 + heapIncreaseTest<IntHeap>();
148.126 +
148.127 + typedef FibHeap<Prio, IntNodeMap > NodeHeap;
148.128 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
148.129 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
148.130 + }
148.131 +
148.132 + // PairingHeap
148.133 + {
148.134 + typedef PairingHeap<Prio, ItemIntMap> IntHeap;
148.135 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
148.136 + heapSortTest<IntHeap>();
148.137 + heapIncreaseTest<IntHeap>();
148.138 +
148.139 + typedef PairingHeap<Prio, IntNodeMap > NodeHeap;
148.140 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
148.141 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
148.142 + }
148.143 +
148.144 + // RadixHeap
148.145 + {
148.146 + typedef RadixHeap<ItemIntMap> IntHeap;
148.147 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
148.148 + heapSortTest<IntHeap>();
148.149 + heapIncreaseTest<IntHeap>();
148.150 +
148.151 + typedef RadixHeap<IntNodeMap > NodeHeap;
148.152 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
148.153 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
148.154 + }
148.155 +
148.156 + // BinomHeap
148.157 + {
148.158 + typedef BinomHeap<Prio, ItemIntMap> IntHeap;
148.159 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
148.160 + heapSortTest<IntHeap>();
148.161 + heapIncreaseTest<IntHeap>();
148.162 +
148.163 + typedef BinomHeap<Prio, IntNodeMap > NodeHeap;
148.164 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
148.165 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
148.166 + }
148.167 +
148.168 + // BucketHeap, SimpleBucketHeap
148.169 + {
148.170 + typedef BucketHeap<ItemIntMap> IntHeap;
148.171 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
148.172 + heapSortTest<IntHeap>();
148.173 + heapIncreaseTest<IntHeap>();
148.174 +
148.175 + typedef BucketHeap<IntNodeMap > NodeHeap;
148.176 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
148.177 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
148.178 +
148.179 + typedef SimpleBucketHeap<ItemIntMap> SimpleIntHeap;
148.180 + heapSortTest<SimpleIntHeap>();
148.181 + }
148.182 +
148.183 return 0;
148.184 }
149.1 --- a/test/kruskal_test.cc Mon Jan 12 23:11:39 2009 +0100
149.2 +++ b/test/kruskal_test.cc Thu Nov 05 15:48:01 2009 +0100
149.3 @@ -99,16 +99,16 @@
149.4 check(kruskal(G, edge_cost_map, tree_map)==10,
149.5 "Total cost should be 10");
149.6
149.7 - edge_cost_map.set(e1, -10);
149.8 - edge_cost_map.set(e2, -9);
149.9 - edge_cost_map.set(e3, -8);
149.10 - edge_cost_map.set(e4, -7);
149.11 - edge_cost_map.set(e5, -6);
149.12 - edge_cost_map.set(e6, -5);
149.13 - edge_cost_map.set(e7, -4);
149.14 - edge_cost_map.set(e8, -3);
149.15 - edge_cost_map.set(e9, -2);
149.16 - edge_cost_map.set(e10, -1);
149.17 + edge_cost_map[e1] = -10;
149.18 + edge_cost_map[e2] = -9;
149.19 + edge_cost_map[e3] = -8;
149.20 + edge_cost_map[e4] = -7;
149.21 + edge_cost_map[e5] = -6;
149.22 + edge_cost_map[e6] = -5;
149.23 + edge_cost_map[e7] = -4;
149.24 + edge_cost_map[e8] = -3;
149.25 + edge_cost_map[e9] = -2;
149.26 + edge_cost_map[e10] = -1;
149.27
149.28 vector<Edge> tree_edge_vec(5);
149.29
150.1 --- a/test/lp_test.cc Mon Jan 12 23:11:39 2009 +0100
150.2 +++ b/test/lp_test.cc Thu Nov 05 15:48:01 2009 +0100
150.3 @@ -2,7 +2,7 @@
150.4 *
150.5 * This file is a part of LEMON, a generic C++ optimization library.
150.6 *
150.7 - * Copyright (C) 2003-2008
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 @@ -21,23 +21,21 @@
150.13 #include "test_tools.h"
150.14 #include <lemon/tolerance.h>
150.15
150.16 -#ifdef HAVE_CONFIG_H
150.17 #include <lemon/config.h>
150.18 -#endif
150.19
150.20 -#ifdef HAVE_GLPK
150.21 +#ifdef LEMON_HAVE_GLPK
150.22 #include <lemon/glpk.h>
150.23 #endif
150.24
150.25 -#ifdef HAVE_CPLEX
150.26 +#ifdef LEMON_HAVE_CPLEX
150.27 #include <lemon/cplex.h>
150.28 #endif
150.29
150.30 -#ifdef HAVE_SOPLEX
150.31 +#ifdef LEMON_HAVE_SOPLEX
150.32 #include <lemon/soplex.h>
150.33 #endif
150.34
150.35 -#ifdef HAVE_CLP
150.36 +#ifdef LEMON_HAVE_CLP
150.37 #include <lemon/clp.h>
150.38 #endif
150.39
150.40 @@ -197,6 +195,11 @@
150.41 buf << "Coeff. of p2 should be 0";
150.42 check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
150.43
150.44 + //Test for clone/new
150.45 + LP* lpnew = lp.newSolver();
150.46 + LP* lpclone = lp.cloneSolver();
150.47 + delete lpnew;
150.48 + delete lpclone;
150.49
150.50 }
150.51
150.52 @@ -247,7 +250,8 @@
150.53
150.54 if (stat == LpSolver::OPTIMAL) {
150.55 std::ostringstream sbuf;
150.56 - sbuf << "Wrong optimal value: the right optimum is " << exp_opt;
150.57 + sbuf << "Wrong optimal value (" << lp.primal() <<") with "
150.58 + << lp.solverName() <<"\n the right optimum is " << exp_opt;
150.59 check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
150.60 }
150.61 }
150.62 @@ -355,47 +359,59 @@
150.63
150.64 }
150.65
150.66 +template<class LP>
150.67 +void cloneTest()
150.68 +{
150.69 + //Test for clone/new
150.70 +
150.71 + LP* lp = new LP();
150.72 + LP* lpnew = lp->newSolver();
150.73 + LP* lpclone = lp->cloneSolver();
150.74 + delete lp;
150.75 + delete lpnew;
150.76 + delete lpclone;
150.77 +}
150.78 +
150.79 int main()
150.80 {
150.81 LpSkeleton lp_skel;
150.82 lpTest(lp_skel);
150.83
150.84 -#ifdef HAVE_GLPK
150.85 +#ifdef LEMON_HAVE_GLPK
150.86 {
150.87 GlpkLp lp_glpk1,lp_glpk2;
150.88 lpTest(lp_glpk1);
150.89 aTest(lp_glpk2);
150.90 + cloneTest<GlpkLp>();
150.91 }
150.92 #endif
150.93
150.94 -#ifdef HAVE_CPLEX
150.95 +#ifdef LEMON_HAVE_CPLEX
150.96 try {
150.97 CplexLp lp_cplex1,lp_cplex2;
150.98 lpTest(lp_cplex1);
150.99 aTest(lp_cplex2);
150.100 + cloneTest<CplexLp>();
150.101 } catch (CplexEnv::LicenseError& error) {
150.102 -#ifdef LEMON_FORCE_CPLEX_CHECK
150.103 check(false, error.what());
150.104 -#else
150.105 - std::cerr << error.what() << std::endl;
150.106 - std::cerr << "Cplex license check failed, lp check skipped" << std::endl;
150.107 -#endif
150.108 }
150.109 #endif
150.110
150.111 -#ifdef HAVE_SOPLEX
150.112 +#ifdef LEMON_HAVE_SOPLEX
150.113 {
150.114 SoplexLp lp_soplex1,lp_soplex2;
150.115 lpTest(lp_soplex1);
150.116 aTest(lp_soplex2);
150.117 + cloneTest<SoplexLp>();
150.118 }
150.119 #endif
150.120
150.121 -#ifdef HAVE_CLP
150.122 +#ifdef LEMON_HAVE_CLP
150.123 {
150.124 ClpLp lp_clp1,lp_clp2;
150.125 lpTest(lp_clp1);
150.126 aTest(lp_clp2);
150.127 + cloneTest<ClpLp>();
150.128 }
150.129 #endif
150.130
151.1 --- a/test/maps_test.cc Mon Jan 12 23:11:39 2009 +0100
151.2 +++ b/test/maps_test.cc Thu Nov 05 15:48:01 2009 +0100
151.3 @@ -22,6 +22,10 @@
151.4 #include <lemon/concept_check.h>
151.5 #include <lemon/concepts/maps.h>
151.6 #include <lemon/maps.h>
151.7 +#include <lemon/list_graph.h>
151.8 +#include <lemon/smart_graph.h>
151.9 +#include <lemon/adaptors.h>
151.10 +#include <lemon/dfs.h>
151.11
151.12 #include "test_tools.h"
151.13
151.14 @@ -60,6 +64,12 @@
151.15 typedef ReadWriteMap<A, bool> BoolWriteMap;
151.16 typedef ReferenceMap<A, bool, bool&, const bool&> BoolRefMap;
151.17
151.18 +template<typename Map1, typename Map2, typename ItemIt>
151.19 +void compareMap(const Map1& map1, const Map2& map2, ItemIt it) {
151.20 + for (; it != INVALID; ++it)
151.21 + check(map1[it] == map2[it], "The maps are not equal");
151.22 +}
151.23 +
151.24 int main()
151.25 {
151.26 // Map concepts
151.27 @@ -170,7 +180,7 @@
151.28 {
151.29 typedef ComposeMap<DoubleMap, ReadMap<B,A> > CompMap;
151.30 checkConcept<ReadMap<B,double>, CompMap>();
151.31 - CompMap map1(DoubleMap(),ReadMap<B,A>());
151.32 + CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
151.33 CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
151.34
151.35 SparseMap<double, bool> m1(false); m1[3.14] = true;
151.36 @@ -183,7 +193,7 @@
151.37 {
151.38 typedef CombineMap<DoubleMap, DoubleMap, std::plus<double> > CombMap;
151.39 checkConcept<ReadMap<A,double>, CombMap>();
151.40 - CombMap map1(DoubleMap(), DoubleMap());
151.41 + CombMap map1 = CombMap(DoubleMap(), DoubleMap());
151.42 CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
151.43
151.44 check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3,
151.45 @@ -195,11 +205,11 @@
151.46 checkConcept<ReadMap<A,B>, FunctorToMap<F,A,B> >();
151.47 checkConcept<ReadMap<A,B>, FunctorToMap<F> >();
151.48 FunctorToMap<F> map1;
151.49 - FunctorToMap<F> map2(F());
151.50 + FunctorToMap<F> map2 = FunctorToMap<F>(F());
151.51 B b = functorToMap(F())[A()];
151.52
151.53 checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
151.54 - MapToFunctor<ReadMap<A,B> > map(ReadMap<A,B>());
151.55 + MapToFunctor<ReadMap<A,B> > map = MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
151.56
151.57 check(functorToMap(&func)[A()] == 3,
151.58 "Something is wrong with FunctorToMap");
151.59 @@ -328,6 +338,10 @@
151.60 // LoggerBoolMap
151.61 {
151.62 typedef std::vector<int> vec;
151.63 + checkConcept<WriteMap<int, bool>, LoggerBoolMap<vec::iterator> >();
151.64 + checkConcept<WriteMap<int, bool>,
151.65 + LoggerBoolMap<std::back_insert_iterator<vec> > >();
151.66 +
151.67 vec v1;
151.68 vec v2(10);
151.69 LoggerBoolMap<std::back_insert_iterator<vec> >
151.70 @@ -347,7 +361,444 @@
151.71 for ( LoggerBoolMap<vec::iterator>::Iterator it = map2.begin();
151.72 it != map2.end(); ++it )
151.73 check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
151.74 +
151.75 + typedef ListDigraph Graph;
151.76 + DIGRAPH_TYPEDEFS(Graph);
151.77 + Graph gr;
151.78 +
151.79 + Node n0 = gr.addNode();
151.80 + Node n1 = gr.addNode();
151.81 + Node n2 = gr.addNode();
151.82 + Node n3 = gr.addNode();
151.83 +
151.84 + gr.addArc(n3, n0);
151.85 + gr.addArc(n3, n2);
151.86 + gr.addArc(n0, n2);
151.87 + gr.addArc(n2, n1);
151.88 + gr.addArc(n0, n1);
151.89 +
151.90 + {
151.91 + std::vector<Node> v;
151.92 + dfs(gr).processedMap(loggerBoolMap(std::back_inserter(v))).run();
151.93 +
151.94 + check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
151.95 + "Something is wrong with LoggerBoolMap");
151.96 + }
151.97 + {
151.98 + std::vector<Node> v(countNodes(gr));
151.99 + dfs(gr).processedMap(loggerBoolMap(v.begin())).run();
151.100 +
151.101 + check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
151.102 + "Something is wrong with LoggerBoolMap");
151.103 + }
151.104 + }
151.105 +
151.106 + // IdMap, RangeIdMap
151.107 + {
151.108 + typedef ListDigraph Graph;
151.109 + DIGRAPH_TYPEDEFS(Graph);
151.110 +
151.111 + checkConcept<ReadMap<Node, int>, IdMap<Graph, Node> >();
151.112 + checkConcept<ReadMap<Arc, int>, IdMap<Graph, Arc> >();
151.113 + checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >();
151.114 + checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >();
151.115 +
151.116 + Graph gr;
151.117 + IdMap<Graph, Node> nmap(gr);
151.118 + IdMap<Graph, Arc> amap(gr);
151.119 + RangeIdMap<Graph, Node> nrmap(gr);
151.120 + RangeIdMap<Graph, Arc> armap(gr);
151.121 +
151.122 + Node n0 = gr.addNode();
151.123 + Node n1 = gr.addNode();
151.124 + Node n2 = gr.addNode();
151.125 +
151.126 + Arc a0 = gr.addArc(n0, n1);
151.127 + Arc a1 = gr.addArc(n0, n2);
151.128 + Arc a2 = gr.addArc(n2, n1);
151.129 + Arc a3 = gr.addArc(n2, n0);
151.130 +
151.131 + check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap");
151.132 + check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap");
151.133 + check(nmap[n2] == gr.id(n2) && nmap(gr.id(n2)) == n2, "Wrong IdMap");
151.134 +
151.135 + check(amap[a0] == gr.id(a0) && amap(gr.id(a0)) == a0, "Wrong IdMap");
151.136 + check(amap[a1] == gr.id(a1) && amap(gr.id(a1)) == a1, "Wrong IdMap");
151.137 + check(amap[a2] == gr.id(a2) && amap(gr.id(a2)) == a2, "Wrong IdMap");
151.138 + check(amap[a3] == gr.id(a3) && amap(gr.id(a3)) == a3, "Wrong IdMap");
151.139 +
151.140 + check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap");
151.141 + check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap");
151.142 +
151.143 + check(nrmap.size() == 3 && armap.size() == 4,
151.144 + "Wrong RangeIdMap::size()");
151.145 +
151.146 + check(nrmap[n0] == 0 && nrmap(0) == n0, "Wrong RangeIdMap");
151.147 + check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap");
151.148 + check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap");
151.149 +
151.150 + check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap");
151.151 + check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
151.152 + check(armap[a2] == 2 && armap(2) == a2, "Wrong RangeIdMap");
151.153 + check(armap[a3] == 3 && armap(3) == a3, "Wrong RangeIdMap");
151.154 +
151.155 + check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap");
151.156 + check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap");
151.157 +
151.158 + gr.erase(n1);
151.159 +
151.160 + if (nrmap[n0] == 1) nrmap.swap(n0, n2);
151.161 + nrmap.swap(n2, n0);
151.162 + if (armap[a1] == 1) armap.swap(a1, a3);
151.163 + armap.swap(a3, a1);
151.164 +
151.165 + check(nrmap.size() == 2 && armap.size() == 2,
151.166 + "Wrong RangeIdMap::size()");
151.167 +
151.168 + check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap");
151.169 + check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap");
151.170 +
151.171 + check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
151.172 + check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap");
151.173 +
151.174 + check(nrmap.inverse()[0] == n2, "Wrong RangeIdMap::InverseMap");
151.175 + check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap");
151.176 + }
151.177 +
151.178 + // SourceMap, TargetMap, ForwardMap, BackwardMap, InDegMap, OutDegMap
151.179 + {
151.180 + typedef ListGraph Graph;
151.181 + GRAPH_TYPEDEFS(Graph);
151.182 +
151.183 + checkConcept<ReadMap<Arc, Node>, SourceMap<Graph> >();
151.184 + checkConcept<ReadMap<Arc, Node>, TargetMap<Graph> >();
151.185 + checkConcept<ReadMap<Edge, Arc>, ForwardMap<Graph> >();
151.186 + checkConcept<ReadMap<Edge, Arc>, BackwardMap<Graph> >();
151.187 + checkConcept<ReadMap<Node, int>, InDegMap<Graph> >();
151.188 + checkConcept<ReadMap<Node, int>, OutDegMap<Graph> >();
151.189 +
151.190 + Graph gr;
151.191 + Node n0 = gr.addNode();
151.192 + Node n1 = gr.addNode();
151.193 + Node n2 = gr.addNode();
151.194 +
151.195 + gr.addEdge(n0,n1);
151.196 + gr.addEdge(n1,n2);
151.197 + gr.addEdge(n0,n2);
151.198 + gr.addEdge(n2,n1);
151.199 + gr.addEdge(n1,n2);
151.200 + gr.addEdge(n0,n1);
151.201 +
151.202 + for (EdgeIt e(gr); e != INVALID; ++e) {
151.203 + check(forwardMap(gr)[e] == gr.direct(e, true), "Wrong ForwardMap");
151.204 + check(backwardMap(gr)[e] == gr.direct(e, false), "Wrong BackwardMap");
151.205 + }
151.206 +
151.207 + compareMap(sourceMap(orienter(gr, constMap<Edge, bool>(true))),
151.208 + targetMap(orienter(gr, constMap<Edge, bool>(false))),
151.209 + EdgeIt(gr));
151.210 +
151.211 + typedef Orienter<Graph, const ConstMap<Edge, bool> > Digraph;
151.212 + Digraph dgr(gr, constMap<Edge, bool>(true));
151.213 + OutDegMap<Digraph> odm(dgr);
151.214 + InDegMap<Digraph> idm(dgr);
151.215 +
151.216 + check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 1, "Wrong OutDegMap");
151.217 + check(idm[n0] == 0 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
151.218 +
151.219 + gr.addEdge(n2, n0);
151.220 +
151.221 + check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 2, "Wrong OutDegMap");
151.222 + check(idm[n0] == 1 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
151.223 + }
151.224 +
151.225 + // CrossRefMap
151.226 + {
151.227 + typedef ListDigraph Graph;
151.228 + DIGRAPH_TYPEDEFS(Graph);
151.229 +
151.230 + checkConcept<ReadWriteMap<Node, int>,
151.231 + CrossRefMap<Graph, Node, int> >();
151.232 + checkConcept<ReadWriteMap<Node, bool>,
151.233 + CrossRefMap<Graph, Node, bool> >();
151.234 + checkConcept<ReadWriteMap<Node, double>,
151.235 + CrossRefMap<Graph, Node, double> >();
151.236 +
151.237 + Graph gr;
151.238 + typedef CrossRefMap<Graph, Node, char> CRMap;
151.239 + CRMap map(gr);
151.240 +
151.241 + Node n0 = gr.addNode();
151.242 + Node n1 = gr.addNode();
151.243 + Node n2 = gr.addNode();
151.244 +
151.245 + map.set(n0, 'A');
151.246 + map.set(n1, 'B');
151.247 + map.set(n2, 'C');
151.248 +
151.249 + check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0,
151.250 + "Wrong CrossRefMap");
151.251 + check(map[n1] == 'B' && map('B') == n1 && map.inverse()['B'] == n1,
151.252 + "Wrong CrossRefMap");
151.253 + check(map[n2] == 'C' && map('C') == n2 && map.inverse()['C'] == n2,
151.254 + "Wrong CrossRefMap");
151.255 + check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
151.256 + "Wrong CrossRefMap::count()");
151.257 +
151.258 + CRMap::ValueIt it = map.beginValue();
151.259 + check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
151.260 + it == map.endValue(), "Wrong value iterator");
151.261 +
151.262 + map.set(n2, 'A');
151.263 +
151.264 + check(map[n0] == 'A' && map[n1] == 'B' && map[n2] == 'A',
151.265 + "Wrong CrossRefMap");
151.266 + check(map('A') == n0 && map.inverse()['A'] == n0, "Wrong CrossRefMap");
151.267 + check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
151.268 + check(map('C') == INVALID && map.inverse()['C'] == INVALID,
151.269 + "Wrong CrossRefMap");
151.270 + check(map.count('A') == 2 && map.count('B') == 1 && map.count('C') == 0,
151.271 + "Wrong CrossRefMap::count()");
151.272 +
151.273 + it = map.beginValue();
151.274 + check(*it++ == 'A' && *it++ == 'A' && *it++ == 'B' &&
151.275 + it == map.endValue(), "Wrong value iterator");
151.276 +
151.277 + map.set(n0, 'C');
151.278 +
151.279 + check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
151.280 + "Wrong CrossRefMap");
151.281 + check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
151.282 + check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
151.283 + check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
151.284 + check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
151.285 + "Wrong CrossRefMap::count()");
151.286 +
151.287 + it = map.beginValue();
151.288 + check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
151.289 + it == map.endValue(), "Wrong value iterator");
151.290 }
151.291
151.292 + // CrossRefMap
151.293 + {
151.294 + typedef SmartDigraph Graph;
151.295 + DIGRAPH_TYPEDEFS(Graph);
151.296 +
151.297 + checkConcept<ReadWriteMap<Node, int>,
151.298 + CrossRefMap<Graph, Node, int> >();
151.299 +
151.300 + Graph gr;
151.301 + typedef CrossRefMap<Graph, Node, char> CRMap;
151.302 + typedef CRMap::ValueIterator ValueIt;
151.303 + CRMap map(gr);
151.304 +
151.305 + Node n0 = gr.addNode();
151.306 + Node n1 = gr.addNode();
151.307 + Node n2 = gr.addNode();
151.308 +
151.309 + map.set(n0, 'A');
151.310 + map.set(n1, 'B');
151.311 + map.set(n2, 'C');
151.312 + map.set(n2, 'A');
151.313 + map.set(n0, 'C');
151.314 +
151.315 + check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
151.316 + "Wrong CrossRefMap");
151.317 + check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
151.318 + check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
151.319 + check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
151.320 +
151.321 + ValueIt it = map.beginValue();
151.322 + check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
151.323 + it == map.endValue(), "Wrong value iterator");
151.324 + }
151.325 +
151.326 + // Iterable bool map
151.327 + {
151.328 + typedef SmartGraph Graph;
151.329 + typedef SmartGraph::Node Item;
151.330 +
151.331 + typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;
151.332 + checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();
151.333 +
151.334 + const int num = 10;
151.335 + Graph g;
151.336 + std::vector<Item> items;
151.337 + for (int i = 0; i < num; ++i) {
151.338 + items.push_back(g.addNode());
151.339 + }
151.340 +
151.341 + Ibm map1(g, true);
151.342 + int n = 0;
151.343 + for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
151.344 + check(map1[static_cast<Item>(it)], "Wrong TrueIt");
151.345 + ++n;
151.346 + }
151.347 + check(n == num, "Wrong number");
151.348 +
151.349 + n = 0;
151.350 + for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
151.351 + check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
151.352 + ++n;
151.353 + }
151.354 + check(n == num, "Wrong number");
151.355 + check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");
151.356 + check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");
151.357 +
151.358 + map1[items[5]] = true;
151.359 +
151.360 + n = 0;
151.361 + for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
151.362 + check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
151.363 + ++n;
151.364 + }
151.365 + check(n == num, "Wrong number");
151.366 +
151.367 + map1[items[num / 2]] = false;
151.368 + check(map1[items[num / 2]] == false, "Wrong map value");
151.369 +
151.370 + n = 0;
151.371 + for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
151.372 + check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
151.373 + ++n;
151.374 + }
151.375 + check(n == num - 1, "Wrong number");
151.376 +
151.377 + n = 0;
151.378 + for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
151.379 + check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
151.380 + ++n;
151.381 + }
151.382 + check(n == 1, "Wrong number");
151.383 +
151.384 + map1[items[0]] = false;
151.385 + check(map1[items[0]] == false, "Wrong map value");
151.386 +
151.387 + map1[items[num - 1]] = false;
151.388 + check(map1[items[num - 1]] == false, "Wrong map value");
151.389 +
151.390 + n = 0;
151.391 + for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
151.392 + check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
151.393 + ++n;
151.394 + }
151.395 + check(n == num - 3, "Wrong number");
151.396 + check(map1.trueNum() == num - 3, "Wrong number");
151.397 +
151.398 + n = 0;
151.399 + for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
151.400 + check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
151.401 + ++n;
151.402 + }
151.403 + check(n == 3, "Wrong number");
151.404 + check(map1.falseNum() == 3, "Wrong number");
151.405 + }
151.406 +
151.407 + // Iterable int map
151.408 + {
151.409 + typedef SmartGraph Graph;
151.410 + typedef SmartGraph::Node Item;
151.411 + typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;
151.412 +
151.413 + checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();
151.414 +
151.415 + const int num = 10;
151.416 + Graph g;
151.417 + std::vector<Item> items;
151.418 + for (int i = 0; i < num; ++i) {
151.419 + items.push_back(g.addNode());
151.420 + }
151.421 +
151.422 + Iim map1(g);
151.423 + check(map1.size() == 0, "Wrong size");
151.424 +
151.425 + for (int i = 0; i < num; ++i) {
151.426 + map1[items[i]] = i;
151.427 + }
151.428 + check(map1.size() == num, "Wrong size");
151.429 +
151.430 + for (int i = 0; i < num; ++i) {
151.431 + Iim::ItemIt it(map1, i);
151.432 + check(static_cast<Item>(it) == items[i], "Wrong value");
151.433 + ++it;
151.434 + check(static_cast<Item>(it) == INVALID, "Wrong value");
151.435 + }
151.436 +
151.437 + for (int i = 0; i < num; ++i) {
151.438 + map1[items[i]] = i % 2;
151.439 + }
151.440 + check(map1.size() == 2, "Wrong size");
151.441 +
151.442 + int n = 0;
151.443 + for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
151.444 + check(map1[static_cast<Item>(it)] == 0, "Wrong value");
151.445 + ++n;
151.446 + }
151.447 + check(n == (num + 1) / 2, "Wrong number");
151.448 +
151.449 + for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
151.450 + check(map1[static_cast<Item>(it)] == 1, "Wrong value");
151.451 + ++n;
151.452 + }
151.453 + check(n == num, "Wrong number");
151.454 +
151.455 + }
151.456 +
151.457 + // Iterable value map
151.458 + {
151.459 + typedef SmartGraph Graph;
151.460 + typedef SmartGraph::Node Item;
151.461 + typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;
151.462 +
151.463 + checkConcept<ReadWriteMap<Item, double>, Ivm>();
151.464 +
151.465 + const int num = 10;
151.466 + Graph g;
151.467 + std::vector<Item> items;
151.468 + for (int i = 0; i < num; ++i) {
151.469 + items.push_back(g.addNode());
151.470 + }
151.471 +
151.472 + Ivm map1(g, 0.0);
151.473 + check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");
151.474 + check(*map1.beginValue() == 0.0, "Wrong value");
151.475 +
151.476 + for (int i = 0; i < num; ++i) {
151.477 + map1.set(items[i], static_cast<double>(i));
151.478 + }
151.479 + check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");
151.480 +
151.481 + for (int i = 0; i < num; ++i) {
151.482 + Ivm::ItemIt it(map1, static_cast<double>(i));
151.483 + check(static_cast<Item>(it) == items[i], "Wrong value");
151.484 + ++it;
151.485 + check(static_cast<Item>(it) == INVALID, "Wrong value");
151.486 + }
151.487 +
151.488 + for (Ivm::ValueIt vit = map1.beginValue();
151.489 + vit != map1.endValue(); ++vit) {
151.490 + check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,
151.491 + "Wrong ValueIt");
151.492 + }
151.493 +
151.494 + for (int i = 0; i < num; ++i) {
151.495 + map1.set(items[i], static_cast<double>(i % 2));
151.496 + }
151.497 + check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");
151.498 +
151.499 + int n = 0;
151.500 + for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
151.501 + check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");
151.502 + ++n;
151.503 + }
151.504 + check(n == (num + 1) / 2, "Wrong number");
151.505 +
151.506 + for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
151.507 + check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");
151.508 + ++n;
151.509 + }
151.510 + check(n == num, "Wrong number");
151.511 +
151.512 + }
151.513 return 0;
151.514 }
152.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
152.2 +++ b/test/matching_test.cc Thu Nov 05 15:48:01 2009 +0100
152.3 @@ -0,0 +1,424 @@
152.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
152.5 + *
152.6 + * This file is a part of LEMON, a generic C++ optimization library.
152.7 + *
152.8 + * Copyright (C) 2003-2009
152.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
152.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
152.11 + *
152.12 + * Permission to use, modify and distribute this software is granted
152.13 + * provided that this copyright notice appears in all copies. For
152.14 + * precise terms see the accompanying LICENSE file.
152.15 + *
152.16 + * This software is provided "AS IS" with no warranty of any kind,
152.17 + * express or implied, and with no claim as to its suitability for any
152.18 + * purpose.
152.19 + *
152.20 + */
152.21 +
152.22 +#include <iostream>
152.23 +#include <sstream>
152.24 +#include <vector>
152.25 +#include <queue>
152.26 +#include <cstdlib>
152.27 +
152.28 +#include <lemon/matching.h>
152.29 +#include <lemon/smart_graph.h>
152.30 +#include <lemon/concepts/graph.h>
152.31 +#include <lemon/concepts/maps.h>
152.32 +#include <lemon/lgf_reader.h>
152.33 +#include <lemon/math.h>
152.34 +
152.35 +#include "test_tools.h"
152.36 +
152.37 +using namespace std;
152.38 +using namespace lemon;
152.39 +
152.40 +GRAPH_TYPEDEFS(SmartGraph);
152.41 +
152.42 +
152.43 +const int lgfn = 3;
152.44 +const std::string lgf[lgfn] = {
152.45 + "@nodes\n"
152.46 + "label\n"
152.47 + "0\n"
152.48 + "1\n"
152.49 + "2\n"
152.50 + "3\n"
152.51 + "4\n"
152.52 + "5\n"
152.53 + "6\n"
152.54 + "7\n"
152.55 + "@edges\n"
152.56 + " label weight\n"
152.57 + "7 4 0 984\n"
152.58 + "0 7 1 73\n"
152.59 + "7 1 2 204\n"
152.60 + "2 3 3 583\n"
152.61 + "2 7 4 565\n"
152.62 + "2 1 5 582\n"
152.63 + "0 4 6 551\n"
152.64 + "2 5 7 385\n"
152.65 + "1 5 8 561\n"
152.66 + "5 3 9 484\n"
152.67 + "7 5 10 904\n"
152.68 + "3 6 11 47\n"
152.69 + "7 6 12 888\n"
152.70 + "3 0 13 747\n"
152.71 + "6 1 14 310\n",
152.72 +
152.73 + "@nodes\n"
152.74 + "label\n"
152.75 + "0\n"
152.76 + "1\n"
152.77 + "2\n"
152.78 + "3\n"
152.79 + "4\n"
152.80 + "5\n"
152.81 + "6\n"
152.82 + "7\n"
152.83 + "@edges\n"
152.84 + " label weight\n"
152.85 + "2 5 0 710\n"
152.86 + "0 5 1 241\n"
152.87 + "2 4 2 856\n"
152.88 + "2 6 3 762\n"
152.89 + "4 1 4 747\n"
152.90 + "6 1 5 962\n"
152.91 + "4 7 6 723\n"
152.92 + "1 7 7 661\n"
152.93 + "2 3 8 376\n"
152.94 + "1 0 9 416\n"
152.95 + "6 7 10 391\n",
152.96 +
152.97 + "@nodes\n"
152.98 + "label\n"
152.99 + "0\n"
152.100 + "1\n"
152.101 + "2\n"
152.102 + "3\n"
152.103 + "4\n"
152.104 + "5\n"
152.105 + "6\n"
152.106 + "7\n"
152.107 + "@edges\n"
152.108 + " label weight\n"
152.109 + "6 2 0 553\n"
152.110 + "0 7 1 653\n"
152.111 + "6 3 2 22\n"
152.112 + "4 7 3 846\n"
152.113 + "7 2 4 981\n"
152.114 + "7 6 5 250\n"
152.115 + "5 2 6 539\n",
152.116 +};
152.117 +
152.118 +void checkMaxMatchingCompile()
152.119 +{
152.120 + typedef concepts::Graph Graph;
152.121 + typedef Graph::Node Node;
152.122 + typedef Graph::Edge Edge;
152.123 + typedef Graph::EdgeMap<bool> MatMap;
152.124 +
152.125 + Graph g;
152.126 + Node n;
152.127 + Edge e;
152.128 + MatMap mat(g);
152.129 +
152.130 + MaxMatching<Graph> mat_test(g);
152.131 + const MaxMatching<Graph>&
152.132 + const_mat_test = mat_test;
152.133 +
152.134 + mat_test.init();
152.135 + mat_test.greedyInit();
152.136 + mat_test.matchingInit(mat);
152.137 + mat_test.startSparse();
152.138 + mat_test.startDense();
152.139 + mat_test.run();
152.140 +
152.141 + const_mat_test.matchingSize();
152.142 + const_mat_test.matching(e);
152.143 + const_mat_test.matching(n);
152.144 + const MaxMatching<Graph>::MatchingMap& mmap =
152.145 + const_mat_test.matchingMap();
152.146 + e = mmap[n];
152.147 + const_mat_test.mate(n);
152.148 +
152.149 + MaxMatching<Graph>::Status stat =
152.150 + const_mat_test.status(n);
152.151 + const MaxMatching<Graph>::StatusMap& smap =
152.152 + const_mat_test.statusMap();
152.153 + stat = smap[n];
152.154 + const_mat_test.barrier(n);
152.155 +}
152.156 +
152.157 +void checkMaxWeightedMatchingCompile()
152.158 +{
152.159 + typedef concepts::Graph Graph;
152.160 + typedef Graph::Node Node;
152.161 + typedef Graph::Edge Edge;
152.162 + typedef Graph::EdgeMap<int> WeightMap;
152.163 +
152.164 + Graph g;
152.165 + Node n;
152.166 + Edge e;
152.167 + WeightMap w(g);
152.168 +
152.169 + MaxWeightedMatching<Graph> mat_test(g, w);
152.170 + const MaxWeightedMatching<Graph>&
152.171 + const_mat_test = mat_test;
152.172 +
152.173 + mat_test.init();
152.174 + mat_test.start();
152.175 + mat_test.run();
152.176 +
152.177 + const_mat_test.matchingWeight();
152.178 + const_mat_test.matchingSize();
152.179 + const_mat_test.matching(e);
152.180 + const_mat_test.matching(n);
152.181 + const MaxWeightedMatching<Graph>::MatchingMap& mmap =
152.182 + const_mat_test.matchingMap();
152.183 + e = mmap[n];
152.184 + const_mat_test.mate(n);
152.185 +
152.186 + int k = 0;
152.187 + const_mat_test.dualValue();
152.188 + const_mat_test.nodeValue(n);
152.189 + const_mat_test.blossomNum();
152.190 + const_mat_test.blossomSize(k);
152.191 + const_mat_test.blossomValue(k);
152.192 +}
152.193 +
152.194 +void checkMaxWeightedPerfectMatchingCompile()
152.195 +{
152.196 + typedef concepts::Graph Graph;
152.197 + typedef Graph::Node Node;
152.198 + typedef Graph::Edge Edge;
152.199 + typedef Graph::EdgeMap<int> WeightMap;
152.200 +
152.201 + Graph g;
152.202 + Node n;
152.203 + Edge e;
152.204 + WeightMap w(g);
152.205 +
152.206 + MaxWeightedPerfectMatching<Graph> mat_test(g, w);
152.207 + const MaxWeightedPerfectMatching<Graph>&
152.208 + const_mat_test = mat_test;
152.209 +
152.210 + mat_test.init();
152.211 + mat_test.start();
152.212 + mat_test.run();
152.213 +
152.214 + const_mat_test.matchingWeight();
152.215 + const_mat_test.matching(e);
152.216 + const_mat_test.matching(n);
152.217 + const MaxWeightedPerfectMatching<Graph>::MatchingMap& mmap =
152.218 + const_mat_test.matchingMap();
152.219 + e = mmap[n];
152.220 + const_mat_test.mate(n);
152.221 +
152.222 + int k = 0;
152.223 + const_mat_test.dualValue();
152.224 + const_mat_test.nodeValue(n);
152.225 + const_mat_test.blossomNum();
152.226 + const_mat_test.blossomSize(k);
152.227 + const_mat_test.blossomValue(k);
152.228 +}
152.229 +
152.230 +void checkMatching(const SmartGraph& graph,
152.231 + const MaxMatching<SmartGraph>& mm) {
152.232 + int num = 0;
152.233 +
152.234 + IntNodeMap comp_index(graph);
152.235 + UnionFind<IntNodeMap> comp(comp_index);
152.236 +
152.237 + int barrier_num = 0;
152.238 +
152.239 + for (NodeIt n(graph); n != INVALID; ++n) {
152.240 + check(mm.status(n) == MaxMatching<SmartGraph>::EVEN ||
152.241 + mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
152.242 + if (mm.status(n) == MaxMatching<SmartGraph>::ODD) {
152.243 + ++barrier_num;
152.244 + } else {
152.245 + comp.insert(n);
152.246 + }
152.247 + }
152.248 +
152.249 + for (EdgeIt e(graph); e != INVALID; ++e) {
152.250 + if (mm.matching(e)) {
152.251 + check(e == mm.matching(graph.u(e)), "Wrong matching");
152.252 + check(e == mm.matching(graph.v(e)), "Wrong matching");
152.253 + ++num;
152.254 + }
152.255 + check(mm.status(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
152.256 + mm.status(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
152.257 + "Wrong Gallai-Edmonds decomposition");
152.258 +
152.259 + check(mm.status(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
152.260 + mm.status(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
152.261 + "Wrong Gallai-Edmonds decomposition");
152.262 +
152.263 + if (mm.status(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
152.264 + mm.status(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
152.265 + comp.join(graph.u(e), graph.v(e));
152.266 + }
152.267 + }
152.268 +
152.269 + std::set<int> comp_root;
152.270 + int odd_comp_num = 0;
152.271 + for (NodeIt n(graph); n != INVALID; ++n) {
152.272 + if (mm.status(n) != MaxMatching<SmartGraph>::ODD) {
152.273 + int root = comp.find(n);
152.274 + if (comp_root.find(root) == comp_root.end()) {
152.275 + comp_root.insert(root);
152.276 + if (comp.size(n) % 2 == 1) {
152.277 + ++odd_comp_num;
152.278 + }
152.279 + }
152.280 + }
152.281 + }
152.282 +
152.283 + check(mm.matchingSize() == num, "Wrong matching");
152.284 + check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num),
152.285 + "Wrong matching");
152.286 + return;
152.287 +}
152.288 +
152.289 +void checkWeightedMatching(const SmartGraph& graph,
152.290 + const SmartGraph::EdgeMap<int>& weight,
152.291 + const MaxWeightedMatching<SmartGraph>& mwm) {
152.292 + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
152.293 + if (graph.u(e) == graph.v(e)) continue;
152.294 + int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e));
152.295 +
152.296 + for (int i = 0; i < mwm.blossomNum(); ++i) {
152.297 + bool s = false, t = false;
152.298 + for (MaxWeightedMatching<SmartGraph>::BlossomIt n(mwm, i);
152.299 + n != INVALID; ++n) {
152.300 + if (graph.u(e) == n) s = true;
152.301 + if (graph.v(e) == n) t = true;
152.302 + }
152.303 + if (s == true && t == true) {
152.304 + rw += mwm.blossomValue(i);
152.305 + }
152.306 + }
152.307 + rw -= weight[e] * mwm.dualScale;
152.308 +
152.309 + check(rw >= 0, "Negative reduced weight");
152.310 + check(rw == 0 || !mwm.matching(e),
152.311 + "Non-zero reduced weight on matching edge");
152.312 + }
152.313 +
152.314 + int pv = 0;
152.315 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
152.316 + if (mwm.matching(n) != INVALID) {
152.317 + check(mwm.nodeValue(n) >= 0, "Invalid node value");
152.318 + pv += weight[mwm.matching(n)];
152.319 + SmartGraph::Node o = graph.target(mwm.matching(n));
152.320 + check(mwm.mate(n) == o, "Invalid matching");
152.321 + check(mwm.matching(n) == graph.oppositeArc(mwm.matching(o)),
152.322 + "Invalid matching");
152.323 + } else {
152.324 + check(mwm.mate(n) == INVALID, "Invalid matching");
152.325 + check(mwm.nodeValue(n) == 0, "Invalid matching");
152.326 + }
152.327 + }
152.328 +
152.329 + int dv = 0;
152.330 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
152.331 + dv += mwm.nodeValue(n);
152.332 + }
152.333 +
152.334 + for (int i = 0; i < mwm.blossomNum(); ++i) {
152.335 + check(mwm.blossomValue(i) >= 0, "Invalid blossom value");
152.336 + check(mwm.blossomSize(i) % 2 == 1, "Even blossom size");
152.337 + dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2);
152.338 + }
152.339 +
152.340 + check(pv * mwm.dualScale == dv * 2, "Wrong duality");
152.341 +
152.342 + return;
152.343 +}
152.344 +
152.345 +void checkWeightedPerfectMatching(const SmartGraph& graph,
152.346 + const SmartGraph::EdgeMap<int>& weight,
152.347 + const MaxWeightedPerfectMatching<SmartGraph>& mwpm) {
152.348 + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
152.349 + if (graph.u(e) == graph.v(e)) continue;
152.350 + int rw = mwpm.nodeValue(graph.u(e)) + mwpm.nodeValue(graph.v(e));
152.351 +
152.352 + for (int i = 0; i < mwpm.blossomNum(); ++i) {
152.353 + bool s = false, t = false;
152.354 + for (MaxWeightedPerfectMatching<SmartGraph>::BlossomIt n(mwpm, i);
152.355 + n != INVALID; ++n) {
152.356 + if (graph.u(e) == n) s = true;
152.357 + if (graph.v(e) == n) t = true;
152.358 + }
152.359 + if (s == true && t == true) {
152.360 + rw += mwpm.blossomValue(i);
152.361 + }
152.362 + }
152.363 + rw -= weight[e] * mwpm.dualScale;
152.364 +
152.365 + check(rw >= 0, "Negative reduced weight");
152.366 + check(rw == 0 || !mwpm.matching(e),
152.367 + "Non-zero reduced weight on matching edge");
152.368 + }
152.369 +
152.370 + int pv = 0;
152.371 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
152.372 + check(mwpm.matching(n) != INVALID, "Non perfect");
152.373 + pv += weight[mwpm.matching(n)];
152.374 + SmartGraph::Node o = graph.target(mwpm.matching(n));
152.375 + check(mwpm.mate(n) == o, "Invalid matching");
152.376 + check(mwpm.matching(n) == graph.oppositeArc(mwpm.matching(o)),
152.377 + "Invalid matching");
152.378 + }
152.379 +
152.380 + int dv = 0;
152.381 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
152.382 + dv += mwpm.nodeValue(n);
152.383 + }
152.384 +
152.385 + for (int i = 0; i < mwpm.blossomNum(); ++i) {
152.386 + check(mwpm.blossomValue(i) >= 0, "Invalid blossom value");
152.387 + check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size");
152.388 + dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2);
152.389 + }
152.390 +
152.391 + check(pv * mwpm.dualScale == dv * 2, "Wrong duality");
152.392 +
152.393 + return;
152.394 +}
152.395 +
152.396 +
152.397 +int main() {
152.398 +
152.399 + for (int i = 0; i < lgfn; ++i) {
152.400 + SmartGraph graph;
152.401 + SmartGraph::EdgeMap<int> weight(graph);
152.402 +
152.403 + istringstream lgfs(lgf[i]);
152.404 + graphReader(graph, lgfs).
152.405 + edgeMap("weight", weight).run();
152.406 +
152.407 + MaxMatching<SmartGraph> mm(graph);
152.408 + mm.run();
152.409 + checkMatching(graph, mm);
152.410 +
152.411 + MaxWeightedMatching<SmartGraph> mwm(graph, weight);
152.412 + mwm.run();
152.413 + checkWeightedMatching(graph, weight, mwm);
152.414 +
152.415 + MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
152.416 + bool perfect = mwpm.run();
152.417 +
152.418 + check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
152.419 + "Perfect matching found");
152.420 +
152.421 + if (perfect) {
152.422 + checkWeightedPerfectMatching(graph, weight, mwpm);
152.423 + }
152.424 + }
152.425 +
152.426 + return 0;
152.427 +}
153.1 --- a/test/max_matching_test.cc Mon Jan 12 23:11:39 2009 +0100
153.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
153.3 @@ -1,310 +0,0 @@
153.4 -/* -*- mode: C++; indent-tabs-mode: nil; -*-
153.5 - *
153.6 - * This file is a part of LEMON, a generic C++ optimization library.
153.7 - *
153.8 - * Copyright (C) 2003-2009
153.9 - * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
153.10 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
153.11 - *
153.12 - * Permission to use, modify and distribute this software is granted
153.13 - * provided that this copyright notice appears in all copies. For
153.14 - * precise terms see the accompanying LICENSE file.
153.15 - *
153.16 - * This software is provided "AS IS" with no warranty of any kind,
153.17 - * express or implied, and with no claim as to its suitability for any
153.18 - * purpose.
153.19 - *
153.20 - */
153.21 -
153.22 -#include <iostream>
153.23 -#include <sstream>
153.24 -#include <vector>
153.25 -#include <queue>
153.26 -#include <lemon/math.h>
153.27 -#include <cstdlib>
153.28 -
153.29 -#include <lemon/max_matching.h>
153.30 -#include <lemon/smart_graph.h>
153.31 -#include <lemon/lgf_reader.h>
153.32 -
153.33 -#include "test_tools.h"
153.34 -
153.35 -using namespace std;
153.36 -using namespace lemon;
153.37 -
153.38 -GRAPH_TYPEDEFS(SmartGraph);
153.39 -
153.40 -
153.41 -const int lgfn = 3;
153.42 -const std::string lgf[lgfn] = {
153.43 - "@nodes\n"
153.44 - "label\n"
153.45 - "0\n"
153.46 - "1\n"
153.47 - "2\n"
153.48 - "3\n"
153.49 - "4\n"
153.50 - "5\n"
153.51 - "6\n"
153.52 - "7\n"
153.53 - "@edges\n"
153.54 - " label weight\n"
153.55 - "7 4 0 984\n"
153.56 - "0 7 1 73\n"
153.57 - "7 1 2 204\n"
153.58 - "2 3 3 583\n"
153.59 - "2 7 4 565\n"
153.60 - "2 1 5 582\n"
153.61 - "0 4 6 551\n"
153.62 - "2 5 7 385\n"
153.63 - "1 5 8 561\n"
153.64 - "5 3 9 484\n"
153.65 - "7 5 10 904\n"
153.66 - "3 6 11 47\n"
153.67 - "7 6 12 888\n"
153.68 - "3 0 13 747\n"
153.69 - "6 1 14 310\n",
153.70 -
153.71 - "@nodes\n"
153.72 - "label\n"
153.73 - "0\n"
153.74 - "1\n"
153.75 - "2\n"
153.76 - "3\n"
153.77 - "4\n"
153.78 - "5\n"
153.79 - "6\n"
153.80 - "7\n"
153.81 - "@edges\n"
153.82 - " label weight\n"
153.83 - "2 5 0 710\n"
153.84 - "0 5 1 241\n"
153.85 - "2 4 2 856\n"
153.86 - "2 6 3 762\n"
153.87 - "4 1 4 747\n"
153.88 - "6 1 5 962\n"
153.89 - "4 7 6 723\n"
153.90 - "1 7 7 661\n"
153.91 - "2 3 8 376\n"
153.92 - "1 0 9 416\n"
153.93 - "6 7 10 391\n",
153.94 -
153.95 - "@nodes\n"
153.96 - "label\n"
153.97 - "0\n"
153.98 - "1\n"
153.99 - "2\n"
153.100 - "3\n"
153.101 - "4\n"
153.102 - "5\n"
153.103 - "6\n"
153.104 - "7\n"
153.105 - "@edges\n"
153.106 - " label weight\n"
153.107 - "6 2 0 553\n"
153.108 - "0 7 1 653\n"
153.109 - "6 3 2 22\n"
153.110 - "4 7 3 846\n"
153.111 - "7 2 4 981\n"
153.112 - "7 6 5 250\n"
153.113 - "5 2 6 539\n",
153.114 -};
153.115 -
153.116 -void checkMatching(const SmartGraph& graph,
153.117 - const MaxMatching<SmartGraph>& mm) {
153.118 - int num = 0;
153.119 -
153.120 - IntNodeMap comp_index(graph);
153.121 - UnionFind<IntNodeMap> comp(comp_index);
153.122 -
153.123 - int barrier_num = 0;
153.124 -
153.125 - for (NodeIt n(graph); n != INVALID; ++n) {
153.126 - check(mm.decomposition(n) == MaxMatching<SmartGraph>::EVEN ||
153.127 - mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
153.128 - if (mm.decomposition(n) == MaxMatching<SmartGraph>::ODD) {
153.129 - ++barrier_num;
153.130 - } else {
153.131 - comp.insert(n);
153.132 - }
153.133 - }
153.134 -
153.135 - for (EdgeIt e(graph); e != INVALID; ++e) {
153.136 - if (mm.matching(e)) {
153.137 - check(e == mm.matching(graph.u(e)), "Wrong matching");
153.138 - check(e == mm.matching(graph.v(e)), "Wrong matching");
153.139 - ++num;
153.140 - }
153.141 - check(mm.decomposition(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
153.142 - mm.decomposition(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
153.143 - "Wrong Gallai-Edmonds decomposition");
153.144 -
153.145 - check(mm.decomposition(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
153.146 - mm.decomposition(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
153.147 - "Wrong Gallai-Edmonds decomposition");
153.148 -
153.149 - if (mm.decomposition(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
153.150 - mm.decomposition(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
153.151 - comp.join(graph.u(e), graph.v(e));
153.152 - }
153.153 - }
153.154 -
153.155 - std::set<int> comp_root;
153.156 - int odd_comp_num = 0;
153.157 - for (NodeIt n(graph); n != INVALID; ++n) {
153.158 - if (mm.decomposition(n) != MaxMatching<SmartGraph>::ODD) {
153.159 - int root = comp.find(n);
153.160 - if (comp_root.find(root) == comp_root.end()) {
153.161 - comp_root.insert(root);
153.162 - if (comp.size(n) % 2 == 1) {
153.163 - ++odd_comp_num;
153.164 - }
153.165 - }
153.166 - }
153.167 - }
153.168 -
153.169 - check(mm.matchingSize() == num, "Wrong matching");
153.170 - check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num),
153.171 - "Wrong matching");
153.172 - return;
153.173 -}
153.174 -
153.175 -void checkWeightedMatching(const SmartGraph& graph,
153.176 - const SmartGraph::EdgeMap<int>& weight,
153.177 - const MaxWeightedMatching<SmartGraph>& mwm) {
153.178 - for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
153.179 - if (graph.u(e) == graph.v(e)) continue;
153.180 - int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e));
153.181 -
153.182 - for (int i = 0; i < mwm.blossomNum(); ++i) {
153.183 - bool s = false, t = false;
153.184 - for (MaxWeightedMatching<SmartGraph>::BlossomIt n(mwm, i);
153.185 - n != INVALID; ++n) {
153.186 - if (graph.u(e) == n) s = true;
153.187 - if (graph.v(e) == n) t = true;
153.188 - }
153.189 - if (s == true && t == true) {
153.190 - rw += mwm.blossomValue(i);
153.191 - }
153.192 - }
153.193 - rw -= weight[e] * mwm.dualScale;
153.194 -
153.195 - check(rw >= 0, "Negative reduced weight");
153.196 - check(rw == 0 || !mwm.matching(e),
153.197 - "Non-zero reduced weight on matching edge");
153.198 - }
153.199 -
153.200 - int pv = 0;
153.201 - for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
153.202 - if (mwm.matching(n) != INVALID) {
153.203 - check(mwm.nodeValue(n) >= 0, "Invalid node value");
153.204 - pv += weight[mwm.matching(n)];
153.205 - SmartGraph::Node o = graph.target(mwm.matching(n));
153.206 - check(mwm.mate(n) == o, "Invalid matching");
153.207 - check(mwm.matching(n) == graph.oppositeArc(mwm.matching(o)),
153.208 - "Invalid matching");
153.209 - } else {
153.210 - check(mwm.mate(n) == INVALID, "Invalid matching");
153.211 - check(mwm.nodeValue(n) == 0, "Invalid matching");
153.212 - }
153.213 - }
153.214 -
153.215 - int dv = 0;
153.216 - for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
153.217 - dv += mwm.nodeValue(n);
153.218 - }
153.219 -
153.220 - for (int i = 0; i < mwm.blossomNum(); ++i) {
153.221 - check(mwm.blossomValue(i) >= 0, "Invalid blossom value");
153.222 - check(mwm.blossomSize(i) % 2 == 1, "Even blossom size");
153.223 - dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2);
153.224 - }
153.225 -
153.226 - check(pv * mwm.dualScale == dv * 2, "Wrong duality");
153.227 -
153.228 - return;
153.229 -}
153.230 -
153.231 -void checkWeightedPerfectMatching(const SmartGraph& graph,
153.232 - const SmartGraph::EdgeMap<int>& weight,
153.233 - const MaxWeightedPerfectMatching<SmartGraph>& mwpm) {
153.234 - for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
153.235 - if (graph.u(e) == graph.v(e)) continue;
153.236 - int rw = mwpm.nodeValue(graph.u(e)) + mwpm.nodeValue(graph.v(e));
153.237 -
153.238 - for (int i = 0; i < mwpm.blossomNum(); ++i) {
153.239 - bool s = false, t = false;
153.240 - for (MaxWeightedPerfectMatching<SmartGraph>::BlossomIt n(mwpm, i);
153.241 - n != INVALID; ++n) {
153.242 - if (graph.u(e) == n) s = true;
153.243 - if (graph.v(e) == n) t = true;
153.244 - }
153.245 - if (s == true && t == true) {
153.246 - rw += mwpm.blossomValue(i);
153.247 - }
153.248 - }
153.249 - rw -= weight[e] * mwpm.dualScale;
153.250 -
153.251 - check(rw >= 0, "Negative reduced weight");
153.252 - check(rw == 0 || !mwpm.matching(e),
153.253 - "Non-zero reduced weight on matching edge");
153.254 - }
153.255 -
153.256 - int pv = 0;
153.257 - for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
153.258 - check(mwpm.matching(n) != INVALID, "Non perfect");
153.259 - pv += weight[mwpm.matching(n)];
153.260 - SmartGraph::Node o = graph.target(mwpm.matching(n));
153.261 - check(mwpm.mate(n) == o, "Invalid matching");
153.262 - check(mwpm.matching(n) == graph.oppositeArc(mwpm.matching(o)),
153.263 - "Invalid matching");
153.264 - }
153.265 -
153.266 - int dv = 0;
153.267 - for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
153.268 - dv += mwpm.nodeValue(n);
153.269 - }
153.270 -
153.271 - for (int i = 0; i < mwpm.blossomNum(); ++i) {
153.272 - check(mwpm.blossomValue(i) >= 0, "Invalid blossom value");
153.273 - check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size");
153.274 - dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2);
153.275 - }
153.276 -
153.277 - check(pv * mwpm.dualScale == dv * 2, "Wrong duality");
153.278 -
153.279 - return;
153.280 -}
153.281 -
153.282 -
153.283 -int main() {
153.284 -
153.285 - for (int i = 0; i < lgfn; ++i) {
153.286 - SmartGraph graph;
153.287 - SmartGraph::EdgeMap<int> weight(graph);
153.288 -
153.289 - istringstream lgfs(lgf[i]);
153.290 - graphReader(graph, lgfs).
153.291 - edgeMap("weight", weight).run();
153.292 -
153.293 - MaxMatching<SmartGraph> mm(graph);
153.294 - mm.run();
153.295 - checkMatching(graph, mm);
153.296 -
153.297 - MaxWeightedMatching<SmartGraph> mwm(graph, weight);
153.298 - mwm.run();
153.299 - checkWeightedMatching(graph, weight, mwm);
153.300 -
153.301 - MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
153.302 - bool perfect = mwpm.run();
153.303 -
153.304 - check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
153.305 - "Perfect matching found");
153.306 -
153.307 - if (perfect) {
153.308 - checkWeightedPerfectMatching(graph, weight, mwpm);
153.309 - }
153.310 - }
153.311 -
153.312 - return 0;
153.313 -}
154.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
154.2 +++ b/test/min_cost_arborescence_test.cc Thu Nov 05 15:48:01 2009 +0100
154.3 @@ -0,0 +1,206 @@
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-2008
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 <set>
154.24 +#include <vector>
154.25 +#include <iterator>
154.26 +
154.27 +#include <lemon/smart_graph.h>
154.28 +#include <lemon/min_cost_arborescence.h>
154.29 +#include <lemon/lgf_reader.h>
154.30 +#include <lemon/concepts/digraph.h>
154.31 +
154.32 +#include "test_tools.h"
154.33 +
154.34 +using namespace lemon;
154.35 +using namespace std;
154.36 +
154.37 +const char test_lgf[] =
154.38 + "@nodes\n"
154.39 + "label\n"
154.40 + "0\n"
154.41 + "1\n"
154.42 + "2\n"
154.43 + "3\n"
154.44 + "4\n"
154.45 + "5\n"
154.46 + "6\n"
154.47 + "7\n"
154.48 + "8\n"
154.49 + "9\n"
154.50 + "@arcs\n"
154.51 + " label cost\n"
154.52 + "1 8 0 107\n"
154.53 + "0 3 1 70\n"
154.54 + "2 1 2 46\n"
154.55 + "4 1 3 28\n"
154.56 + "4 4 4 91\n"
154.57 + "3 9 5 76\n"
154.58 + "9 8 6 61\n"
154.59 + "8 1 7 39\n"
154.60 + "9 8 8 74\n"
154.61 + "8 0 9 39\n"
154.62 + "4 3 10 45\n"
154.63 + "2 2 11 34\n"
154.64 + "0 1 12 100\n"
154.65 + "6 3 13 95\n"
154.66 + "4 1 14 22\n"
154.67 + "1 1 15 31\n"
154.68 + "7 2 16 51\n"
154.69 + "2 6 17 29\n"
154.70 + "8 3 18 115\n"
154.71 + "6 9 19 32\n"
154.72 + "1 1 20 60\n"
154.73 + "0 3 21 40\n"
154.74 + "@attributes\n"
154.75 + "source 0\n";
154.76 +
154.77 +
154.78 +void checkMinCostArborescenceCompile()
154.79 +{
154.80 + typedef double VType;
154.81 + typedef concepts::Digraph Digraph;
154.82 + typedef concepts::ReadMap<Digraph::Arc, VType> CostMap;
154.83 + typedef Digraph::Node Node;
154.84 + typedef Digraph::Arc Arc;
154.85 + typedef concepts::WriteMap<Digraph::Arc, bool> ArbMap;
154.86 + typedef concepts::ReadWriteMap<Digraph::Node, Digraph::Arc> PredMap;
154.87 +
154.88 + typedef MinCostArborescence<Digraph, CostMap>::
154.89 + SetArborescenceMap<ArbMap>::
154.90 + SetPredMap<PredMap>::Create MinCostArbType;
154.91 +
154.92 + Digraph g;
154.93 + Node s, n;
154.94 + Arc e;
154.95 + VType c;
154.96 + bool b;
154.97 + int i;
154.98 + CostMap cost;
154.99 + ArbMap arb;
154.100 + PredMap pred;
154.101 +
154.102 + MinCostArbType mcarb_test(g, cost);
154.103 + const MinCostArbType& const_mcarb_test = mcarb_test;
154.104 +
154.105 + mcarb_test
154.106 + .arborescenceMap(arb)
154.107 + .predMap(pred)
154.108 + .run(s);
154.109 +
154.110 + mcarb_test.init();
154.111 + mcarb_test.addSource(s);
154.112 + mcarb_test.start();
154.113 + n = mcarb_test.processNextNode();
154.114 + b = const_mcarb_test.emptyQueue();
154.115 + i = const_mcarb_test.queueSize();
154.116 +
154.117 + c = const_mcarb_test.arborescenceCost();
154.118 + b = const_mcarb_test.arborescence(e);
154.119 + e = const_mcarb_test.pred(n);
154.120 + const MinCostArbType::ArborescenceMap &am =
154.121 + const_mcarb_test.arborescenceMap();
154.122 + const MinCostArbType::PredMap &pm =
154.123 + const_mcarb_test.predMap();
154.124 + b = const_mcarb_test.reached(n);
154.125 + b = const_mcarb_test.processed(n);
154.126 +
154.127 + i = const_mcarb_test.dualNum();
154.128 + c = const_mcarb_test.dualValue();
154.129 + i = const_mcarb_test.dualSize(i);
154.130 + c = const_mcarb_test.dualValue(i);
154.131 +
154.132 + ignore_unused_variable_warning(am);
154.133 + ignore_unused_variable_warning(pm);
154.134 +}
154.135 +
154.136 +int main() {
154.137 + typedef SmartDigraph Digraph;
154.138 + DIGRAPH_TYPEDEFS(Digraph);
154.139 +
154.140 + typedef Digraph::ArcMap<double> CostMap;
154.141 +
154.142 + Digraph digraph;
154.143 + CostMap cost(digraph);
154.144 + Node source;
154.145 +
154.146 + std::istringstream is(test_lgf);
154.147 + digraphReader(digraph, is).
154.148 + arcMap("cost", cost).
154.149 + node("source", source).run();
154.150 +
154.151 + MinCostArborescence<Digraph, CostMap> mca(digraph, cost);
154.152 + mca.run(source);
154.153 +
154.154 + vector<pair<double, set<Node> > > dualSolution(mca.dualNum());
154.155 +
154.156 + for (int i = 0; i < mca.dualNum(); ++i) {
154.157 + dualSolution[i].first = mca.dualValue(i);
154.158 + for (MinCostArborescence<Digraph, CostMap>::DualIt it(mca, i);
154.159 + it != INVALID; ++it) {
154.160 + dualSolution[i].second.insert(it);
154.161 + }
154.162 + }
154.163 +
154.164 + for (ArcIt it(digraph); it != INVALID; ++it) {
154.165 + if (mca.reached(digraph.source(it))) {
154.166 + double sum = 0.0;
154.167 + for (int i = 0; i < int(dualSolution.size()); ++i) {
154.168 + if (dualSolution[i].second.find(digraph.target(it))
154.169 + != dualSolution[i].second.end() &&
154.170 + dualSolution[i].second.find(digraph.source(it))
154.171 + == dualSolution[i].second.end()) {
154.172 + sum += dualSolution[i].first;
154.173 + }
154.174 + }
154.175 + if (mca.arborescence(it)) {
154.176 + check(sum == cost[it], "Invalid dual solution");
154.177 + }
154.178 + check(sum <= cost[it], "Invalid dual solution");
154.179 + }
154.180 + }
154.181 +
154.182 +
154.183 + check(mca.dualValue() == mca.arborescenceCost(), "Invalid dual solution");
154.184 +
154.185 + check(mca.reached(source), "Invalid arborescence");
154.186 + for (ArcIt a(digraph); a != INVALID; ++a) {
154.187 + check(!mca.reached(digraph.source(a)) ||
154.188 + mca.reached(digraph.target(a)), "Invalid arborescence");
154.189 + }
154.190 +
154.191 + for (NodeIt n(digraph); n != INVALID; ++n) {
154.192 + if (!mca.reached(n)) continue;
154.193 + int cnt = 0;
154.194 + for (InArcIt a(digraph, n); a != INVALID; ++a) {
154.195 + if (mca.arborescence(a)) {
154.196 + check(mca.pred(n) == a, "Invalid arborescence");
154.197 + ++cnt;
154.198 + }
154.199 + }
154.200 + check((n == source ? cnt == 0 : cnt == 1), "Invalid arborescence");
154.201 + }
154.202 +
154.203 + Digraph::ArcMap<bool> arborescence(digraph);
154.204 + check(mca.arborescenceCost() ==
154.205 + minCostArborescence(digraph, cost, source, arborescence),
154.206 + "Wrong result of the function interface");
154.207 +
154.208 + return 0;
154.209 +}
155.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
155.2 +++ b/test/min_cost_flow_test.cc Thu Nov 05 15:48:01 2009 +0100
155.3 @@ -0,0 +1,450 @@
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 <iostream>
155.23 +#include <fstream>
155.24 +#include <limits>
155.25 +
155.26 +#include <lemon/list_graph.h>
155.27 +#include <lemon/lgf_reader.h>
155.28 +
155.29 +#include <lemon/network_simplex.h>
155.30 +
155.31 +#include <lemon/concepts/digraph.h>
155.32 +#include <lemon/concept_check.h>
155.33 +
155.34 +#include "test_tools.h"
155.35 +
155.36 +using namespace lemon;
155.37 +
155.38 +char test_lgf[] =
155.39 + "@nodes\n"
155.40 + "label sup1 sup2 sup3 sup4 sup5 sup6\n"
155.41 + " 1 20 27 0 30 20 30\n"
155.42 + " 2 -4 0 0 0 -8 -3\n"
155.43 + " 3 0 0 0 0 0 0\n"
155.44 + " 4 0 0 0 0 0 0\n"
155.45 + " 5 9 0 0 0 6 11\n"
155.46 + " 6 -6 0 0 0 -5 -6\n"
155.47 + " 7 0 0 0 0 0 0\n"
155.48 + " 8 0 0 0 0 0 3\n"
155.49 + " 9 3 0 0 0 0 0\n"
155.50 + " 10 -2 0 0 0 -7 -2\n"
155.51 + " 11 0 0 0 0 -10 0\n"
155.52 + " 12 -20 -27 0 -30 -30 -20\n"
155.53 + "\n"
155.54 + "@arcs\n"
155.55 + " cost cap low1 low2 low3\n"
155.56 + " 1 2 70 11 0 8 8\n"
155.57 + " 1 3 150 3 0 1 0\n"
155.58 + " 1 4 80 15 0 2 2\n"
155.59 + " 2 8 80 12 0 0 0\n"
155.60 + " 3 5 140 5 0 3 1\n"
155.61 + " 4 6 60 10 0 1 0\n"
155.62 + " 4 7 80 2 0 0 0\n"
155.63 + " 4 8 110 3 0 0 0\n"
155.64 + " 5 7 60 14 0 0 0\n"
155.65 + " 5 11 120 12 0 0 0\n"
155.66 + " 6 3 0 3 0 0 0\n"
155.67 + " 6 9 140 4 0 0 0\n"
155.68 + " 6 10 90 8 0 0 0\n"
155.69 + " 7 1 30 5 0 0 -5\n"
155.70 + " 8 12 60 16 0 4 3\n"
155.71 + " 9 12 50 6 0 0 0\n"
155.72 + "10 12 70 13 0 5 2\n"
155.73 + "10 2 100 7 0 0 0\n"
155.74 + "10 7 60 10 0 0 -3\n"
155.75 + "11 10 20 14 0 6 -20\n"
155.76 + "12 11 30 10 0 0 -10\n"
155.77 + "\n"
155.78 + "@attributes\n"
155.79 + "source 1\n"
155.80 + "target 12\n";
155.81 +
155.82 +
155.83 +enum SupplyType {
155.84 + EQ,
155.85 + GEQ,
155.86 + LEQ
155.87 +};
155.88 +
155.89 +// Check the interface of an MCF algorithm
155.90 +template <typename GR, typename Value, typename Cost>
155.91 +class McfClassConcept
155.92 +{
155.93 +public:
155.94 +
155.95 + template <typename MCF>
155.96 + struct Constraints {
155.97 + void constraints() {
155.98 + checkConcept<concepts::Digraph, GR>();
155.99 +
155.100 + const Constraints& me = *this;
155.101 +
155.102 + MCF mcf(me.g);
155.103 + const MCF& const_mcf = mcf;
155.104 +
155.105 + b = mcf.reset()
155.106 + .lowerMap(me.lower)
155.107 + .upperMap(me.upper)
155.108 + .costMap(me.cost)
155.109 + .supplyMap(me.sup)
155.110 + .stSupply(me.n, me.n, me.k)
155.111 + .run();
155.112 +
155.113 + c = const_mcf.totalCost();
155.114 + x = const_mcf.template totalCost<double>();
155.115 + v = const_mcf.flow(me.a);
155.116 + c = const_mcf.potential(me.n);
155.117 + const_mcf.flowMap(fm);
155.118 + const_mcf.potentialMap(pm);
155.119 + }
155.120 +
155.121 + typedef typename GR::Node Node;
155.122 + typedef typename GR::Arc Arc;
155.123 + typedef concepts::ReadMap<Node, Value> NM;
155.124 + typedef concepts::ReadMap<Arc, Value> VAM;
155.125 + typedef concepts::ReadMap<Arc, Cost> CAM;
155.126 + typedef concepts::WriteMap<Arc, Value> FlowMap;
155.127 + typedef concepts::WriteMap<Node, Cost> PotMap;
155.128 +
155.129 + GR g;
155.130 + VAM lower;
155.131 + VAM upper;
155.132 + CAM cost;
155.133 + NM sup;
155.134 + Node n;
155.135 + Arc a;
155.136 + Value k;
155.137 +
155.138 + FlowMap fm;
155.139 + PotMap pm;
155.140 + bool b;
155.141 + double x;
155.142 + typename MCF::Value v;
155.143 + typename MCF::Cost c;
155.144 + };
155.145 +
155.146 +};
155.147 +
155.148 +
155.149 +// Check the feasibility of the given flow (primal soluiton)
155.150 +template < typename GR, typename LM, typename UM,
155.151 + typename SM, typename FM >
155.152 +bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
155.153 + const SM& supply, const FM& flow,
155.154 + SupplyType type = EQ )
155.155 +{
155.156 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
155.157 +
155.158 + for (ArcIt e(gr); e != INVALID; ++e) {
155.159 + if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
155.160 + }
155.161 +
155.162 + for (NodeIt n(gr); n != INVALID; ++n) {
155.163 + typename SM::Value sum = 0;
155.164 + for (OutArcIt e(gr, n); e != INVALID; ++e)
155.165 + sum += flow[e];
155.166 + for (InArcIt e(gr, n); e != INVALID; ++e)
155.167 + sum -= flow[e];
155.168 + bool b = (type == EQ && sum == supply[n]) ||
155.169 + (type == GEQ && sum >= supply[n]) ||
155.170 + (type == LEQ && sum <= supply[n]);
155.171 + if (!b) return false;
155.172 + }
155.173 +
155.174 + return true;
155.175 +}
155.176 +
155.177 +// Check the feasibility of the given potentials (dual soluiton)
155.178 +// using the "Complementary Slackness" optimality condition
155.179 +template < typename GR, typename LM, typename UM,
155.180 + typename CM, typename SM, typename FM, typename PM >
155.181 +bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
155.182 + const CM& cost, const SM& supply, const FM& flow,
155.183 + const PM& pi, SupplyType type )
155.184 +{
155.185 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
155.186 +
155.187 + bool opt = true;
155.188 + for (ArcIt e(gr); opt && e != INVALID; ++e) {
155.189 + typename CM::Value red_cost =
155.190 + cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
155.191 + opt = red_cost == 0 ||
155.192 + (red_cost > 0 && flow[e] == lower[e]) ||
155.193 + (red_cost < 0 && flow[e] == upper[e]);
155.194 + }
155.195 +
155.196 + for (NodeIt n(gr); opt && n != INVALID; ++n) {
155.197 + typename SM::Value sum = 0;
155.198 + for (OutArcIt e(gr, n); e != INVALID; ++e)
155.199 + sum += flow[e];
155.200 + for (InArcIt e(gr, n); e != INVALID; ++e)
155.201 + sum -= flow[e];
155.202 + if (type != LEQ) {
155.203 + opt = (pi[n] <= 0) && (sum == supply[n] || pi[n] == 0);
155.204 + } else {
155.205 + opt = (pi[n] >= 0) && (sum == supply[n] || pi[n] == 0);
155.206 + }
155.207 + }
155.208 +
155.209 + return opt;
155.210 +}
155.211 +
155.212 +// Check whether the dual cost is equal to the primal cost
155.213 +template < typename GR, typename LM, typename UM,
155.214 + typename CM, typename SM, typename PM >
155.215 +bool checkDualCost( const GR& gr, const LM& lower, const UM& upper,
155.216 + const CM& cost, const SM& supply, const PM& pi,
155.217 + typename CM::Value total )
155.218 +{
155.219 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
155.220 +
155.221 + typename CM::Value dual_cost = 0;
155.222 + SM red_supply(gr);
155.223 + for (NodeIt n(gr); n != INVALID; ++n) {
155.224 + red_supply[n] = supply[n];
155.225 + }
155.226 + for (ArcIt a(gr); a != INVALID; ++a) {
155.227 + if (lower[a] != 0) {
155.228 + dual_cost += lower[a] * cost[a];
155.229 + red_supply[gr.source(a)] -= lower[a];
155.230 + red_supply[gr.target(a)] += lower[a];
155.231 + }
155.232 + }
155.233 +
155.234 + for (NodeIt n(gr); n != INVALID; ++n) {
155.235 + dual_cost -= red_supply[n] * pi[n];
155.236 + }
155.237 + for (ArcIt a(gr); a != INVALID; ++a) {
155.238 + typename CM::Value red_cost =
155.239 + cost[a] + pi[gr.source(a)] - pi[gr.target(a)];
155.240 + dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0);
155.241 + }
155.242 +
155.243 + return dual_cost == total;
155.244 +}
155.245 +
155.246 +// Run a minimum cost flow algorithm and check the results
155.247 +template < typename MCF, typename GR,
155.248 + typename LM, typename UM,
155.249 + typename CM, typename SM,
155.250 + typename PT >
155.251 +void checkMcf( const MCF& mcf, PT mcf_result,
155.252 + const GR& gr, const LM& lower, const UM& upper,
155.253 + const CM& cost, const SM& supply,
155.254 + PT result, bool optimal, typename CM::Value total,
155.255 + const std::string &test_id = "",
155.256 + SupplyType type = EQ )
155.257 +{
155.258 + check(mcf_result == result, "Wrong result " + test_id);
155.259 + if (optimal) {
155.260 + typename GR::template ArcMap<typename SM::Value> flow(gr);
155.261 + typename GR::template NodeMap<typename CM::Value> pi(gr);
155.262 + mcf.flowMap(flow);
155.263 + mcf.potentialMap(pi);
155.264 + check(checkFlow(gr, lower, upper, supply, flow, type),
155.265 + "The flow is not feasible " + test_id);
155.266 + check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
155.267 + check(checkPotential(gr, lower, upper, cost, supply, flow, pi, type),
155.268 + "Wrong potentials " + test_id);
155.269 + check(checkDualCost(gr, lower, upper, cost, supply, pi, total),
155.270 + "Wrong dual cost " + test_id);
155.271 + }
155.272 +}
155.273 +
155.274 +int main()
155.275 +{
155.276 + // Check the interfaces
155.277 + {
155.278 + typedef concepts::Digraph GR;
155.279 + checkConcept< McfClassConcept<GR, int, int>,
155.280 + NetworkSimplex<GR> >();
155.281 + checkConcept< McfClassConcept<GR, double, double>,
155.282 + NetworkSimplex<GR, double> >();
155.283 + checkConcept< McfClassConcept<GR, int, double>,
155.284 + NetworkSimplex<GR, int, double> >();
155.285 + }
155.286 +
155.287 + // Run various MCF tests
155.288 + typedef ListDigraph Digraph;
155.289 + DIGRAPH_TYPEDEFS(ListDigraph);
155.290 +
155.291 + // Read the test digraph
155.292 + Digraph gr;
155.293 + Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
155.294 + Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
155.295 + ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
155.296 + Node v, w;
155.297 +
155.298 + std::istringstream input(test_lgf);
155.299 + DigraphReader<Digraph>(gr, input)
155.300 + .arcMap("cost", c)
155.301 + .arcMap("cap", u)
155.302 + .arcMap("low1", l1)
155.303 + .arcMap("low2", l2)
155.304 + .arcMap("low3", l3)
155.305 + .nodeMap("sup1", s1)
155.306 + .nodeMap("sup2", s2)
155.307 + .nodeMap("sup3", s3)
155.308 + .nodeMap("sup4", s4)
155.309 + .nodeMap("sup5", s5)
155.310 + .nodeMap("sup6", s6)
155.311 + .node("source", v)
155.312 + .node("target", w)
155.313 + .run();
155.314 +
155.315 + // Build test digraphs with negative costs
155.316 + Digraph neg_gr;
155.317 + Node n1 = neg_gr.addNode();
155.318 + Node n2 = neg_gr.addNode();
155.319 + Node n3 = neg_gr.addNode();
155.320 + Node n4 = neg_gr.addNode();
155.321 + Node n5 = neg_gr.addNode();
155.322 + Node n6 = neg_gr.addNode();
155.323 + Node n7 = neg_gr.addNode();
155.324 +
155.325 + Arc a1 = neg_gr.addArc(n1, n2);
155.326 + Arc a2 = neg_gr.addArc(n1, n3);
155.327 + Arc a3 = neg_gr.addArc(n2, n4);
155.328 + Arc a4 = neg_gr.addArc(n3, n4);
155.329 + Arc a5 = neg_gr.addArc(n3, n2);
155.330 + Arc a6 = neg_gr.addArc(n5, n3);
155.331 + Arc a7 = neg_gr.addArc(n5, n6);
155.332 + Arc a8 = neg_gr.addArc(n6, n7);
155.333 + Arc a9 = neg_gr.addArc(n7, n5);
155.334 +
155.335 + Digraph::ArcMap<int> neg_c(neg_gr), neg_l1(neg_gr, 0), neg_l2(neg_gr, 0);
155.336 + ConstMap<Arc, int> neg_u1(std::numeric_limits<int>::max()), neg_u2(5000);
155.337 + Digraph::NodeMap<int> neg_s(neg_gr, 0);
155.338 +
155.339 + neg_l2[a7] = 1000;
155.340 + neg_l2[a8] = -1000;
155.341 +
155.342 + neg_s[n1] = 100;
155.343 + neg_s[n4] = -100;
155.344 +
155.345 + neg_c[a1] = 100;
155.346 + neg_c[a2] = 30;
155.347 + neg_c[a3] = 20;
155.348 + neg_c[a4] = 80;
155.349 + neg_c[a5] = 50;
155.350 + neg_c[a6] = 10;
155.351 + neg_c[a7] = 80;
155.352 + neg_c[a8] = 30;
155.353 + neg_c[a9] = -120;
155.354 +
155.355 + Digraph negs_gr;
155.356 + Digraph::NodeMap<int> negs_s(negs_gr);
155.357 + Digraph::ArcMap<int> negs_c(negs_gr);
155.358 + ConstMap<Arc, int> negs_l(0), negs_u(1000);
155.359 + n1 = negs_gr.addNode();
155.360 + n2 = negs_gr.addNode();
155.361 + negs_s[n1] = 100;
155.362 + negs_s[n2] = -300;
155.363 + negs_c[negs_gr.addArc(n1, n2)] = -1;
155.364 +
155.365 +
155.366 + // A. Test NetworkSimplex with the default pivot rule
155.367 + {
155.368 + NetworkSimplex<Digraph> mcf(gr);
155.369 +
155.370 + // Check the equality form
155.371 + mcf.upperMap(u).costMap(c);
155.372 + checkMcf(mcf, mcf.supplyMap(s1).run(),
155.373 + gr, l1, u, c, s1, mcf.OPTIMAL, true, 5240, "#A1");
155.374 + checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
155.375 + gr, l1, u, c, s2, mcf.OPTIMAL, true, 7620, "#A2");
155.376 + mcf.lowerMap(l2);
155.377 + checkMcf(mcf, mcf.supplyMap(s1).run(),
155.378 + gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#A3");
155.379 + checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
155.380 + gr, l2, u, c, s2, mcf.OPTIMAL, true, 8010, "#A4");
155.381 + mcf.reset();
155.382 + checkMcf(mcf, mcf.supplyMap(s1).run(),
155.383 + gr, l1, cu, cc, s1, mcf.OPTIMAL, true, 74, "#A5");
155.384 + checkMcf(mcf, mcf.lowerMap(l2).stSupply(v, w, 27).run(),
155.385 + gr, l2, cu, cc, s2, mcf.OPTIMAL, true, 94, "#A6");
155.386 + mcf.reset();
155.387 + checkMcf(mcf, mcf.run(),
155.388 + gr, l1, cu, cc, s3, mcf.OPTIMAL, true, 0, "#A7");
155.389 + checkMcf(mcf, mcf.lowerMap(l2).upperMap(u).run(),
155.390 + gr, l2, u, cc, s3, mcf.INFEASIBLE, false, 0, "#A8");
155.391 + mcf.reset().lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
155.392 + checkMcf(mcf, mcf.run(),
155.393 + gr, l3, u, c, s4, mcf.OPTIMAL, true, 6360, "#A9");
155.394 +
155.395 + // Check the GEQ form
155.396 + mcf.reset().upperMap(u).costMap(c).supplyMap(s5);
155.397 + checkMcf(mcf, mcf.run(),
155.398 + gr, l1, u, c, s5, mcf.OPTIMAL, true, 3530, "#A10", GEQ);
155.399 + mcf.supplyType(mcf.GEQ);
155.400 + checkMcf(mcf, mcf.lowerMap(l2).run(),
155.401 + gr, l2, u, c, s5, mcf.OPTIMAL, true, 4540, "#A11", GEQ);
155.402 + mcf.supplyMap(s6);
155.403 + checkMcf(mcf, mcf.run(),
155.404 + gr, l2, u, c, s6, mcf.INFEASIBLE, false, 0, "#A12", GEQ);
155.405 +
155.406 + // Check the LEQ form
155.407 + mcf.reset().supplyType(mcf.LEQ);
155.408 + mcf.upperMap(u).costMap(c).supplyMap(s6);
155.409 + checkMcf(mcf, mcf.run(),
155.410 + gr, l1, u, c, s6, mcf.OPTIMAL, true, 5080, "#A13", LEQ);
155.411 + checkMcf(mcf, mcf.lowerMap(l2).run(),
155.412 + gr, l2, u, c, s6, mcf.OPTIMAL, true, 5930, "#A14", LEQ);
155.413 + mcf.supplyMap(s5);
155.414 + checkMcf(mcf, mcf.run(),
155.415 + gr, l2, u, c, s5, mcf.INFEASIBLE, false, 0, "#A15", LEQ);
155.416 +
155.417 + // Check negative costs
155.418 + NetworkSimplex<Digraph> neg_mcf(neg_gr);
155.419 + neg_mcf.lowerMap(neg_l1).costMap(neg_c).supplyMap(neg_s);
155.420 + checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u1,
155.421 + neg_c, neg_s, neg_mcf.UNBOUNDED, false, 0, "#A16");
155.422 + neg_mcf.upperMap(neg_u2);
155.423 + checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u2,
155.424 + neg_c, neg_s, neg_mcf.OPTIMAL, true, -40000, "#A17");
155.425 + neg_mcf.reset().lowerMap(neg_l2).costMap(neg_c).supplyMap(neg_s);
155.426 + checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l2, neg_u1,
155.427 + neg_c, neg_s, neg_mcf.UNBOUNDED, false, 0, "#A18");
155.428 +
155.429 + NetworkSimplex<Digraph> negs_mcf(negs_gr);
155.430 + negs_mcf.costMap(negs_c).supplyMap(negs_s);
155.431 + checkMcf(negs_mcf, negs_mcf.run(), negs_gr, negs_l, negs_u,
155.432 + negs_c, negs_s, negs_mcf.OPTIMAL, true, -300, "#A19", GEQ);
155.433 + }
155.434 +
155.435 + // B. Test NetworkSimplex with each pivot rule
155.436 + {
155.437 + NetworkSimplex<Digraph> mcf(gr);
155.438 + mcf.supplyMap(s1).costMap(c).upperMap(u).lowerMap(l2);
155.439 +
155.440 + checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::FIRST_ELIGIBLE),
155.441 + gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B1");
155.442 + checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BEST_ELIGIBLE),
155.443 + gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B2");
155.444 + checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BLOCK_SEARCH),
155.445 + gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B3");
155.446 + checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::CANDIDATE_LIST),
155.447 + gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B4");
155.448 + checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::ALTERING_LIST),
155.449 + gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B5");
155.450 + }
155.451 +
155.452 + return 0;
155.453 +}
156.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
156.2 +++ b/test/min_mean_cycle_test.cc Thu Nov 05 15:48:01 2009 +0100
156.3 @@ -0,0 +1,216 @@
156.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
156.5 + *
156.6 + * This file is a part of LEMON, a generic C++ optimization library.
156.7 + *
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 + * Permission to use, modify and distribute this software is granted
156.13 + * provided that this copyright notice appears in all copies. For
156.14 + * precise terms see the accompanying LICENSE file.
156.15 + *
156.16 + * This software is provided "AS IS" with no warranty of any kind,
156.17 + * express or implied, and with no claim as to its suitability for any
156.18 + * purpose.
156.19 + *
156.20 + */
156.21 +
156.22 +#include <iostream>
156.23 +#include <sstream>
156.24 +
156.25 +#include <lemon/smart_graph.h>
156.26 +#include <lemon/lgf_reader.h>
156.27 +#include <lemon/path.h>
156.28 +#include <lemon/concepts/digraph.h>
156.29 +#include <lemon/concept_check.h>
156.30 +
156.31 +#include <lemon/karp.h>
156.32 +#include <lemon/hartmann_orlin.h>
156.33 +#include <lemon/howard.h>
156.34 +
156.35 +#include "test_tools.h"
156.36 +
156.37 +using namespace lemon;
156.38 +
156.39 +char test_lgf[] =
156.40 + "@nodes\n"
156.41 + "label\n"
156.42 + "1\n"
156.43 + "2\n"
156.44 + "3\n"
156.45 + "4\n"
156.46 + "5\n"
156.47 + "6\n"
156.48 + "7\n"
156.49 + "@arcs\n"
156.50 + " len1 len2 len3 len4 c1 c2 c3 c4\n"
156.51 + "1 2 1 1 1 1 0 0 0 0\n"
156.52 + "2 4 5 5 5 5 1 0 0 0\n"
156.53 + "2 3 8 8 8 8 0 0 0 0\n"
156.54 + "3 2 -2 0 0 0 1 0 0 0\n"
156.55 + "3 4 4 4 4 4 0 0 0 0\n"
156.56 + "3 7 -4 -4 -4 -4 0 0 0 0\n"
156.57 + "4 1 2 2 2 2 0 0 0 0\n"
156.58 + "4 3 3 3 3 3 1 0 0 0\n"
156.59 + "4 4 3 3 0 0 0 0 1 0\n"
156.60 + "5 2 4 4 4 4 0 0 0 0\n"
156.61 + "5 6 3 3 3 3 0 1 0 0\n"
156.62 + "6 5 2 2 2 2 0 1 0 0\n"
156.63 + "6 4 -1 -1 -1 -1 0 0 0 0\n"
156.64 + "6 7 1 1 1 1 0 0 0 0\n"
156.65 + "7 7 4 4 4 -1 0 0 0 1\n";
156.66 +
156.67 +
156.68 +// Check the interface of an MMC algorithm
156.69 +template <typename GR, typename Value>
156.70 +struct MmcClassConcept
156.71 +{
156.72 + template <typename MMC>
156.73 + struct Constraints {
156.74 + void constraints() {
156.75 + const Constraints& me = *this;
156.76 +
156.77 + typedef typename MMC
156.78 + ::template SetPath<ListPath<GR> >
156.79 + ::template SetLargeValue<Value>
156.80 + ::Create MmcAlg;
156.81 + MmcAlg mmc(me.g, me.length);
156.82 + const MmcAlg& const_mmc = mmc;
156.83 +
156.84 + typename MmcAlg::Tolerance tol = const_mmc.tolerance();
156.85 + mmc.tolerance(tol);
156.86 +
156.87 + b = mmc.cycle(p).run();
156.88 + b = mmc.findMinMean();
156.89 + b = mmc.findCycle();
156.90 +
156.91 + v = const_mmc.cycleLength();
156.92 + i = const_mmc.cycleArcNum();
156.93 + d = const_mmc.cycleMean();
156.94 + p = const_mmc.cycle();
156.95 + }
156.96 +
156.97 + typedef concepts::ReadMap<typename GR::Arc, Value> LM;
156.98 +
156.99 + GR g;
156.100 + LM length;
156.101 + ListPath<GR> p;
156.102 + Value v;
156.103 + int i;
156.104 + double d;
156.105 + bool b;
156.106 + };
156.107 +};
156.108 +
156.109 +// Perform a test with the given parameters
156.110 +template <typename MMC>
156.111 +void checkMmcAlg(const SmartDigraph& gr,
156.112 + const SmartDigraph::ArcMap<int>& lm,
156.113 + const SmartDigraph::ArcMap<int>& cm,
156.114 + int length, int size) {
156.115 + MMC alg(gr, lm);
156.116 + alg.findMinMean();
156.117 + check(alg.cycleMean() == static_cast<double>(length) / size,
156.118 + "Wrong cycle mean");
156.119 + alg.findCycle();
156.120 + check(alg.cycleLength() == length && alg.cycleArcNum() == size,
156.121 + "Wrong path");
156.122 + SmartDigraph::ArcMap<int> cycle(gr, 0);
156.123 + for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
156.124 + ++cycle[a];
156.125 + }
156.126 + for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
156.127 + check(cm[a] == cycle[a], "Wrong path");
156.128 + }
156.129 +}
156.130 +
156.131 +// Class for comparing types
156.132 +template <typename T1, typename T2>
156.133 +struct IsSameType {
156.134 + static const int result = 0;
156.135 +};
156.136 +
156.137 +template <typename T>
156.138 +struct IsSameType<T,T> {
156.139 + static const int result = 1;
156.140 +};
156.141 +
156.142 +
156.143 +int main() {
156.144 + #ifdef LEMON_HAVE_LONG_LONG
156.145 + typedef long long long_int;
156.146 + #else
156.147 + typedef long long_int;
156.148 + #endif
156.149 +
156.150 + // Check the interface
156.151 + {
156.152 + typedef concepts::Digraph GR;
156.153 +
156.154 + // Karp
156.155 + checkConcept< MmcClassConcept<GR, int>,
156.156 + Karp<GR, concepts::ReadMap<GR::Arc, int> > >();
156.157 + checkConcept< MmcClassConcept<GR, float>,
156.158 + Karp<GR, concepts::ReadMap<GR::Arc, float> > >();
156.159 +
156.160 + // HartmannOrlin
156.161 + checkConcept< MmcClassConcept<GR, int>,
156.162 + HartmannOrlin<GR, concepts::ReadMap<GR::Arc, int> > >();
156.163 + checkConcept< MmcClassConcept<GR, float>,
156.164 + HartmannOrlin<GR, concepts::ReadMap<GR::Arc, float> > >();
156.165 +
156.166 + // Howard
156.167 + checkConcept< MmcClassConcept<GR, int>,
156.168 + Howard<GR, concepts::ReadMap<GR::Arc, int> > >();
156.169 + checkConcept< MmcClassConcept<GR, float>,
156.170 + Howard<GR, concepts::ReadMap<GR::Arc, float> > >();
156.171 +
156.172 + if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,
156.173 + long_int>::result == 0) check(false, "Wrong LargeValue type");
156.174 + if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,
156.175 + double>::result == 0) check(false, "Wrong LargeValue type");
156.176 + }
156.177 +
156.178 + // Run various tests
156.179 + {
156.180 + typedef SmartDigraph GR;
156.181 + DIGRAPH_TYPEDEFS(GR);
156.182 +
156.183 + GR gr;
156.184 + IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
156.185 + IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
156.186 +
156.187 + std::istringstream input(test_lgf);
156.188 + digraphReader(gr, input).
156.189 + arcMap("len1", l1).
156.190 + arcMap("len2", l2).
156.191 + arcMap("len3", l3).
156.192 + arcMap("len4", l4).
156.193 + arcMap("c1", c1).
156.194 + arcMap("c2", c2).
156.195 + arcMap("c3", c3).
156.196 + arcMap("c4", c4).
156.197 + run();
156.198 +
156.199 + // Karp
156.200 + checkMmcAlg<Karp<GR, IntArcMap> >(gr, l1, c1, 6, 3);
156.201 + checkMmcAlg<Karp<GR, IntArcMap> >(gr, l2, c2, 5, 2);
156.202 + checkMmcAlg<Karp<GR, IntArcMap> >(gr, l3, c3, 0, 1);
156.203 + checkMmcAlg<Karp<GR, IntArcMap> >(gr, l4, c4, -1, 1);
156.204 +
156.205 + // HartmannOrlin
156.206 + checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l1, c1, 6, 3);
156.207 + checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l2, c2, 5, 2);
156.208 + checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l3, c3, 0, 1);
156.209 + checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l4, c4, -1, 1);
156.210 +
156.211 + // Howard
156.212 + checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1, 6, 3);
156.213 + checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2, 5, 2);
156.214 + checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3, 0, 1);
156.215 + checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1);
156.216 + }
156.217 +
156.218 + return 0;
156.219 +}
157.1 --- a/test/mip_test.cc Mon Jan 12 23:11:39 2009 +0100
157.2 +++ b/test/mip_test.cc Thu Nov 05 15:48:01 2009 +0100
157.3 @@ -2,7 +2,7 @@
157.4 *
157.5 * This file is a part of LEMON, a generic C++ optimization library.
157.6 *
157.7 - * Copyright (C) 2003-2008
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 @@ -18,19 +18,20 @@
157.13
157.14 #include "test_tools.h"
157.15
157.16 +#include <lemon/config.h>
157.17
157.18 -#ifdef HAVE_CONFIG_H
157.19 -#include <lemon/config.h>
157.20 -#endif
157.21 -
157.22 -#ifdef HAVE_CPLEX
157.23 +#ifdef LEMON_HAVE_CPLEX
157.24 #include <lemon/cplex.h>
157.25 #endif
157.26
157.27 -#ifdef HAVE_GLPK
157.28 +#ifdef LEMON_HAVE_GLPK
157.29 #include <lemon/glpk.h>
157.30 #endif
157.31
157.32 +#ifdef LEMON_HAVE_CBC
157.33 +#include <lemon/cbc.h>
157.34 +#endif
157.35 +
157.36
157.37 using namespace lemon;
157.38
157.39 @@ -49,7 +50,8 @@
157.40
157.41 if (stat == MipSolver::OPTIMAL) {
157.42 std::ostringstream sbuf;
157.43 - buf << "Wrong optimal value: the right optimum is " << exp_opt;
157.44 + sbuf << "Wrong optimal value ("<< mip.solValue()
157.45 + <<" instead of " << exp_opt << ")";
157.46 check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
157.47 //+ecvt(exp_opt,2)
157.48 }
157.49 @@ -57,14 +59,13 @@
157.50
157.51 void aTest(MipSolver& mip)
157.52 {
157.53 - //The following example is very simple
157.54 + //The following example is very simple
157.55
157.56
157.57 typedef MipSolver::Row Row;
157.58 typedef MipSolver::Col Col;
157.59
157.60
157.61 -
157.62 Col x1 = mip.addCol();
157.63 Col x2 = mip.addCol();
157.64
157.65 @@ -74,23 +75,24 @@
157.66
157.67 mip.max();
157.68
157.69 -
157.70 //Unconstrained optimization
157.71 mip.solve();
157.72 //Check it out!
157.73
157.74 //Constraints
157.75 - mip.addRow(2*x1+x2 <=2);
157.76 - mip.addRow(x1-2*x2 <=0);
157.77 + mip.addRow(2 * x1 + x2 <= 2);
157.78 + Row y2 = mip.addRow(x1 - 2 * x2 <= 0);
157.79
157.80 //Nonnegativity of the variable x1
157.81 mip.colLowerBound(x1, 0);
157.82
157.83 +
157.84 //Maximization of x1
157.85 //over the triangle with vertices (0,0),(4/5,2/5),(0,2)
157.86 double expected_opt=4.0/5.0;
157.87 solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
157.88
157.89 +
157.90 //Restrict x2 to integer
157.91 mip.colType(x2,MipSolver::INTEGER);
157.92 expected_opt=1.0/2.0;
157.93 @@ -102,32 +104,53 @@
157.94 expected_opt=0;
157.95 solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
157.96
157.97 -
157.98 + //Erase a variable
157.99 + mip.erase(x2);
157.100 + mip.rowUpperBound(y2, 8);
157.101 + expected_opt=1;
157.102 + solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
157.103
157.104 }
157.105
157.106
157.107 +template<class MIP>
157.108 +void cloneTest()
157.109 +{
157.110 +
157.111 + MIP* mip = new MIP();
157.112 + MIP* mipnew = mip->newSolver();
157.113 + MIP* mipclone = mip->cloneSolver();
157.114 + delete mip;
157.115 + delete mipnew;
157.116 + delete mipclone;
157.117 +}
157.118 +
157.119 int main()
157.120 {
157.121
157.122 -#ifdef HAVE_GLPK
157.123 +#ifdef LEMON_HAVE_GLPK
157.124 {
157.125 GlpkMip mip1;
157.126 aTest(mip1);
157.127 + cloneTest<GlpkMip>();
157.128 }
157.129 #endif
157.130
157.131 -#ifdef HAVE_CPLEX
157.132 +#ifdef LEMON_HAVE_CPLEX
157.133 try {
157.134 CplexMip mip2;
157.135 aTest(mip2);
157.136 + cloneTest<CplexMip>();
157.137 } catch (CplexEnv::LicenseError& error) {
157.138 -#ifdef LEMON_FORCE_CPLEX_CHECK
157.139 check(false, error.what());
157.140 -#else
157.141 - std::cerr << error.what() << std::endl;
157.142 - std::cerr << "Cplex license check failed, lp check skipped" << std::endl;
157.143 + }
157.144 #endif
157.145 +
157.146 +#ifdef LEMON_HAVE_CBC
157.147 + {
157.148 + CbcMip mip1;
157.149 + aTest(mip1);
157.150 + cloneTest<CbcMip>();
157.151 }
157.152 #endif
157.153
158.1 --- a/test/preflow_test.cc Mon Jan 12 23:11:39 2009 +0100
158.2 +++ b/test/preflow_test.cc Thu Nov 05 15:48:01 2009 +0100
158.3 @@ -84,18 +84,27 @@
158.4 CapMap cap;
158.5 FlowMap flow;
158.6 CutMap cut;
158.7 + VType v;
158.8 + bool b;
158.9
158.10 - Preflow<Digraph, CapMap>
158.11 - ::SetFlowMap<FlowMap>
158.12 - ::SetElevator<Elev>
158.13 - ::SetStandardElevator<LinkedElev>
158.14 - ::Create preflow_test(g,cap,n,n);
158.15 + typedef Preflow<Digraph, CapMap>
158.16 + ::SetFlowMap<FlowMap>
158.17 + ::SetElevator<Elev>
158.18 + ::SetStandardElevator<LinkedElev>
158.19 + ::Create PreflowType;
158.20 + PreflowType preflow_test(g, cap, n, n);
158.21 + const PreflowType& const_preflow_test = preflow_test;
158.22 +
158.23 + const PreflowType::Elevator& elev = const_preflow_test.elevator();
158.24 + preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
158.25 + PreflowType::Tolerance tol = const_preflow_test.tolerance();
158.26 + preflow_test.tolerance(tol);
158.27
158.28 - preflow_test.capacityMap(cap);
158.29 - flow = preflow_test.flowMap();
158.30 - preflow_test.flowMap(flow);
158.31 - preflow_test.source(n);
158.32 - preflow_test.target(n);
158.33 + preflow_test
158.34 + .capacityMap(cap)
158.35 + .flowMap(flow)
158.36 + .source(n)
158.37 + .target(n);
158.38
158.39 preflow_test.init();
158.40 preflow_test.init(cap);
158.41 @@ -104,11 +113,13 @@
158.42 preflow_test.run();
158.43 preflow_test.runMinCut();
158.44
158.45 - preflow_test.flowValue();
158.46 - preflow_test.minCut(n);
158.47 - preflow_test.minCutMap(cut);
158.48 - preflow_test.flow(e);
158.49 -
158.50 + v = const_preflow_test.flowValue();
158.51 + v = const_preflow_test.flow(e);
158.52 + const FlowMap& fm = const_preflow_test.flowMap();
158.53 + b = const_preflow_test.minCut(n);
158.54 + const_preflow_test.minCutMap(cut);
158.55 +
158.56 + ignore_unused_variable_warning(fm);
158.57 }
158.58
158.59 int cutValue (const SmartDigraph& g,
159.1 --- a/test/suurballe_test.cc Mon Jan 12 23:11:39 2009 +0100
159.2 +++ b/test/suurballe_test.cc Thu Nov 05 15:48:01 2009 +0100
159.3 @@ -22,6 +22,7 @@
159.4 #include <lemon/lgf_reader.h>
159.5 #include <lemon/path.h>
159.6 #include <lemon/suurballe.h>
159.7 +#include <lemon/concepts/digraph.h>
159.8
159.9 #include "test_tools.h"
159.10
159.11 @@ -29,47 +30,97 @@
159.12
159.13 char test_lgf[] =
159.14 "@nodes\n"
159.15 - "label supply1 supply2 supply3\n"
159.16 - "1 0 20 27\n"
159.17 - "2 0 -4 0\n"
159.18 - "3 0 0 0\n"
159.19 - "4 0 0 0\n"
159.20 - "5 0 9 0\n"
159.21 - "6 0 -6 0\n"
159.22 - "7 0 0 0\n"
159.23 - "8 0 0 0\n"
159.24 - "9 0 3 0\n"
159.25 - "10 0 -2 0\n"
159.26 - "11 0 0 0\n"
159.27 - "12 0 -20 -27\n"
159.28 + "label\n"
159.29 + "1\n"
159.30 + "2\n"
159.31 + "3\n"
159.32 + "4\n"
159.33 + "5\n"
159.34 + "6\n"
159.35 + "7\n"
159.36 + "8\n"
159.37 + "9\n"
159.38 + "10\n"
159.39 + "11\n"
159.40 + "12\n"
159.41 "@arcs\n"
159.42 - " cost capacity lower1 lower2\n"
159.43 - " 1 2 70 11 0 8\n"
159.44 - " 1 3 150 3 0 1\n"
159.45 - " 1 4 80 15 0 2\n"
159.46 - " 2 8 80 12 0 0\n"
159.47 - " 3 5 140 5 0 3\n"
159.48 - " 4 6 60 10 0 1\n"
159.49 - " 4 7 80 2 0 0\n"
159.50 - " 4 8 110 3 0 0\n"
159.51 - " 5 7 60 14 0 0\n"
159.52 - " 5 11 120 12 0 0\n"
159.53 - " 6 3 0 3 0 0\n"
159.54 - " 6 9 140 4 0 0\n"
159.55 - " 6 10 90 8 0 0\n"
159.56 - " 7 1 30 5 0 0\n"
159.57 - " 8 12 60 16 0 4\n"
159.58 - " 9 12 50 6 0 0\n"
159.59 - "10 12 70 13 0 5\n"
159.60 - "10 2 100 7 0 0\n"
159.61 - "10 7 60 10 0 0\n"
159.62 - "11 10 20 14 0 6\n"
159.63 - "12 11 30 10 0 0\n"
159.64 + " length\n"
159.65 + " 1 2 70\n"
159.66 + " 1 3 150\n"
159.67 + " 1 4 80\n"
159.68 + " 2 8 80\n"
159.69 + " 3 5 140\n"
159.70 + " 4 6 60\n"
159.71 + " 4 7 80\n"
159.72 + " 4 8 110\n"
159.73 + " 5 7 60\n"
159.74 + " 5 11 120\n"
159.75 + " 6 3 0\n"
159.76 + " 6 9 140\n"
159.77 + " 6 10 90\n"
159.78 + " 7 1 30\n"
159.79 + " 8 12 60\n"
159.80 + " 9 12 50\n"
159.81 + "10 12 70\n"
159.82 + "10 2 100\n"
159.83 + "10 7 60\n"
159.84 + "11 10 20\n"
159.85 + "12 11 30\n"
159.86 "@attributes\n"
159.87 "source 1\n"
159.88 "target 12\n"
159.89 "@end\n";
159.90
159.91 +// Check the interface of Suurballe
159.92 +void checkSuurballeCompile()
159.93 +{
159.94 + typedef int VType;
159.95 + typedef concepts::Digraph Digraph;
159.96 +
159.97 + typedef Digraph::Node Node;
159.98 + typedef Digraph::Arc Arc;
159.99 + typedef concepts::ReadMap<Arc, VType> LengthMap;
159.100 +
159.101 + typedef Suurballe<Digraph, LengthMap> SuurballeType;
159.102 +
159.103 + Digraph g;
159.104 + Node n;
159.105 + Arc e;
159.106 + LengthMap len;
159.107 + SuurballeType::FlowMap flow(g);
159.108 + SuurballeType::PotentialMap pi(g);
159.109 +
159.110 + SuurballeType suurb_test(g, len);
159.111 + const SuurballeType& const_suurb_test = suurb_test;
159.112 +
159.113 + suurb_test
159.114 + .flowMap(flow)
159.115 + .potentialMap(pi);
159.116 +
159.117 + int k;
159.118 + k = suurb_test.run(n, n);
159.119 + k = suurb_test.run(n, n, k);
159.120 + suurb_test.init(n);
159.121 + k = suurb_test.findFlow(n);
159.122 + k = suurb_test.findFlow(n, k);
159.123 + suurb_test.findPaths();
159.124 +
159.125 + int f;
159.126 + VType c;
159.127 + c = const_suurb_test.totalLength();
159.128 + f = const_suurb_test.flow(e);
159.129 + const SuurballeType::FlowMap& fm =
159.130 + const_suurb_test.flowMap();
159.131 + c = const_suurb_test.potential(n);
159.132 + const SuurballeType::PotentialMap& pm =
159.133 + const_suurb_test.potentialMap();
159.134 + k = const_suurb_test.pathNum();
159.135 + Path<Digraph> p = const_suurb_test.path(k);
159.136 +
159.137 + ignore_unused_variable_warning(fm);
159.138 + ignore_unused_variable_warning(pm);
159.139 +}
159.140 +
159.141 // Check the feasibility of the flow
159.142 template <typename Digraph, typename FlowMap>
159.143 bool checkFlow( const Digraph& gr, const FlowMap& flow,
159.144 @@ -118,7 +169,6 @@
159.145 bool checkPath( const Digraph& gr, const Path& path,
159.146 typename Digraph::Node s, typename Digraph::Node t)
159.147 {
159.148 - // Check the "Complementary Slackness" optimality condition
159.149 TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
159.150 Node n = s;
159.151 for (int i = 0; i < path.length(); ++i) {
159.152 @@ -136,58 +186,55 @@
159.153 // Read the test digraph
159.154 ListDigraph digraph;
159.155 ListDigraph::ArcMap<int> length(digraph);
159.156 - Node source, target;
159.157 + Node s, t;
159.158
159.159 std::istringstream input(test_lgf);
159.160 DigraphReader<ListDigraph>(digraph, input).
159.161 - arcMap("cost", length).
159.162 - node("source", source).
159.163 - node("target", target).
159.164 + arcMap("length", length).
159.165 + node("source", s).
159.166 + node("target", t).
159.167 run();
159.168
159.169 // Find 2 paths
159.170 {
159.171 - Suurballe<ListDigraph> suurballe(digraph, length, source, target);
159.172 - check(suurballe.run(2) == 2, "Wrong number of paths");
159.173 - check(checkFlow(digraph, suurballe.flowMap(), source, target, 2),
159.174 + Suurballe<ListDigraph> suurballe(digraph, length);
159.175 + check(suurballe.run(s, t) == 2, "Wrong number of paths");
159.176 + check(checkFlow(digraph, suurballe.flowMap(), s, t, 2),
159.177 "The flow is not feasible");
159.178 check(suurballe.totalLength() == 510, "The flow is not optimal");
159.179 check(checkOptimality(digraph, length, suurballe.flowMap(),
159.180 suurballe.potentialMap()),
159.181 "Wrong potentials");
159.182 for (int i = 0; i < suurballe.pathNum(); ++i)
159.183 - check(checkPath(digraph, suurballe.path(i), source, target),
159.184 - "Wrong path");
159.185 + check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
159.186 }
159.187
159.188 // Find 3 paths
159.189 {
159.190 - Suurballe<ListDigraph> suurballe(digraph, length, source, target);
159.191 - check(suurballe.run(3) == 3, "Wrong number of paths");
159.192 - check(checkFlow(digraph, suurballe.flowMap(), source, target, 3),
159.193 + Suurballe<ListDigraph> suurballe(digraph, length);
159.194 + check(suurballe.run(s, t, 3) == 3, "Wrong number of paths");
159.195 + check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
159.196 "The flow is not feasible");
159.197 check(suurballe.totalLength() == 1040, "The flow is not optimal");
159.198 check(checkOptimality(digraph, length, suurballe.flowMap(),
159.199 suurballe.potentialMap()),
159.200 "Wrong potentials");
159.201 for (int i = 0; i < suurballe.pathNum(); ++i)
159.202 - check(checkPath(digraph, suurballe.path(i), source, target),
159.203 - "Wrong path");
159.204 + check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
159.205 }
159.206
159.207 // Find 5 paths (only 3 can be found)
159.208 {
159.209 - Suurballe<ListDigraph> suurballe(digraph, length, source, target);
159.210 - check(suurballe.run(5) == 3, "Wrong number of paths");
159.211 - check(checkFlow(digraph, suurballe.flowMap(), source, target, 3),
159.212 + Suurballe<ListDigraph> suurballe(digraph, length);
159.213 + check(suurballe.run(s, t, 5) == 3, "Wrong number of paths");
159.214 + check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
159.215 "The flow is not feasible");
159.216 check(suurballe.totalLength() == 1040, "The flow is not optimal");
159.217 check(checkOptimality(digraph, length, suurballe.flowMap(),
159.218 suurballe.potentialMap()),
159.219 "Wrong potentials");
159.220 for (int i = 0; i < suurballe.pathNum(); ++i)
159.221 - check(checkPath(digraph, suurballe.path(i), source, target),
159.222 - "Wrong path");
159.223 + check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
159.224 }
159.225
159.226 return 0;
160.1 --- a/test/test_tools.h Mon Jan 12 23:11:39 2009 +0100
160.2 +++ b/test/test_tools.h Thu Nov 05 15:48:01 2009 +0100
160.3 @@ -37,10 +37,14 @@
160.4 ///\code check(0==1,"This is obviously false.");\endcode will
160.5 ///print something like this (and then exits).
160.6 ///\verbatim file_name.cc:123: error: This is obviously false. \endverbatim
160.7 -#define check(rc, msg) \
160.8 - if(!(rc)) { \
160.9 - std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
160.10 - abort(); \
160.11 - } else { } \
160.12 +#define check(rc, msg) \
160.13 + { \
160.14 + if(!(rc)) { \
160.15 + std::cerr << __FILE__ ":" << __LINE__ << ": error: " \
160.16 + << msg << std::endl; \
160.17 + abort(); \
160.18 + } else { } \
160.19 + } \
160.20 +
160.21
160.22 #endif
161.1 --- a/test/time_measure_test.cc Mon Jan 12 23:11:39 2009 +0100
161.2 +++ b/test/time_measure_test.cc Thu Nov 05 15:48:01 2009 +0100
161.3 @@ -39,18 +39,16 @@
161.4 {
161.5 Timer T;
161.6 unsigned int n;
161.7 - for(n=0;T.realTime()<1.0;n++) ;
161.8 + for(n=0;T.realTime()<0.1;n++) ;
161.9 std::cout << T << " (" << n << " time queries)\n";
161.10 - T.restart();
161.11 - while(T.realTime()<2.0) ;
161.12 - std::cout << T << '\n';
161.13 +
161.14 TimeStamp full;
161.15 TimeStamp t;
161.16 - t=runningTimeTest(f,1,&n,&full);
161.17 + t=runningTimeTest(f,0.1,&n,&full);
161.18 std::cout << t << " (" << n << " tests)\n";
161.19 std::cout << "Total: " << full << "\n";
161.20
161.21 - t=runningTimeTest(g,1,&n,&full);
161.22 + t=runningTimeTest(g,0.1,&n,&full);
161.23 std::cout << t << " (" << n << " tests)\n";
161.24 std::cout << "Total: " << full << "\n";
161.25
162.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
162.2 +++ b/tools/CMakeLists.txt Thu Nov 05 15:48:01 2009 +0100
162.3 @@ -0,0 +1,31 @@
162.4 +INCLUDE_DIRECTORIES(
162.5 + ${PROJECT_SOURCE_DIR}
162.6 + ${PROJECT_BINARY_DIR}
162.7 +)
162.8 +
162.9 +LINK_DIRECTORIES(
162.10 + ${PROJECT_BINARY_DIR}/lemon
162.11 +)
162.12 +
162.13 +ADD_EXECUTABLE(lgf-gen lgf-gen.cc)
162.14 +TARGET_LINK_LIBRARIES(lgf-gen lemon)
162.15 +
162.16 +ADD_EXECUTABLE(dimacs-to-lgf dimacs-to-lgf.cc)
162.17 +TARGET_LINK_LIBRARIES(dimacs-to-lgf lemon)
162.18 +
162.19 +ADD_EXECUTABLE(dimacs-solver dimacs-solver.cc)
162.20 +TARGET_LINK_LIBRARIES(dimacs-solver lemon)
162.21 +
162.22 +INSTALL(
162.23 + TARGETS lgf-gen dimacs-to-lgf dimacs-solver
162.24 + RUNTIME DESTINATION bin
162.25 + COMPONENT bin
162.26 +)
162.27 +
162.28 +IF(NOT WIN32)
162.29 + INSTALL(
162.30 + PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/lemon-0.x-to-1.x.sh
162.31 + DESTINATION bin
162.32 + COMPONENT bin
162.33 + )
162.34 +ENDIF()
163.1 --- a/tools/Makefile.am Mon Jan 12 23:11:39 2009 +0100
163.2 +++ b/tools/Makefile.am Thu Nov 05 15:48:01 2009 +0100
163.3 @@ -1,10 +1,17 @@
163.4 +EXTRA_DIST += \
163.5 + tools/CMakeLists.txt
163.6 +
163.7 if WANT_TOOLS
163.8
163.9 bin_PROGRAMS += \
163.10 - tools/dimacs-to-lgf
163.11 + tools/dimacs-solver \
163.12 + tools/dimacs-to-lgf \
163.13 + tools/lgf-gen
163.14
163.15 dist_bin_SCRIPTS += tools/lemon-0.x-to-1.x.sh
163.16
163.17 endif WANT_TOOLS
163.18
163.19 +tools_dimacs_solver_SOURCES = tools/dimacs-solver.cc
163.20 tools_dimacs_to_lgf_SOURCES = tools/dimacs-to-lgf.cc
163.21 +tools_lgf_gen_SOURCES = tools/lgf-gen.cc
164.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
164.2 +++ b/tools/dimacs-solver.cc Thu Nov 05 15:48:01 2009 +0100
164.3 @@ -0,0 +1,277 @@
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-2009
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 +///\ingroup tools
164.23 +///\file
164.24 +///\brief DIMACS problem solver.
164.25 +///
164.26 +/// This program solves various problems given in DIMACS format.
164.27 +///
164.28 +/// See
164.29 +/// \code
164.30 +/// dimacs-solver --help
164.31 +/// \endcode
164.32 +/// for more info on usage.
164.33 +
164.34 +#include <iostream>
164.35 +#include <fstream>
164.36 +#include <cstring>
164.37 +
164.38 +#include <lemon/smart_graph.h>
164.39 +#include <lemon/dimacs.h>
164.40 +#include <lemon/lgf_writer.h>
164.41 +#include <lemon/time_measure.h>
164.42 +
164.43 +#include <lemon/arg_parser.h>
164.44 +#include <lemon/error.h>
164.45 +
164.46 +#include <lemon/dijkstra.h>
164.47 +#include <lemon/preflow.h>
164.48 +#include <lemon/matching.h>
164.49 +#include <lemon/network_simplex.h>
164.50 +
164.51 +using namespace lemon;
164.52 +typedef SmartDigraph Digraph;
164.53 +DIGRAPH_TYPEDEFS(Digraph);
164.54 +typedef SmartGraph Graph;
164.55 +
164.56 +template<class Value>
164.57 +void solve_sp(ArgParser &ap, std::istream &is, std::ostream &,
164.58 + DimacsDescriptor &desc)
164.59 +{
164.60 + bool report = !ap.given("q");
164.61 + Digraph g;
164.62 + Node s;
164.63 + Digraph::ArcMap<Value> len(g);
164.64 + Timer t;
164.65 + t.restart();
164.66 + readDimacsSp(is, g, len, s, desc);
164.67 + if(report) std::cerr << "Read the file: " << t << '\n';
164.68 + t.restart();
164.69 + Dijkstra<Digraph, Digraph::ArcMap<Value> > dij(g,len);
164.70 + if(report) std::cerr << "Setup Dijkstra class: " << t << '\n';
164.71 + t.restart();
164.72 + dij.run(s);
164.73 + if(report) std::cerr << "Run Dijkstra: " << t << '\n';
164.74 +}
164.75 +
164.76 +template<class Value>
164.77 +void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
164.78 + Value infty, DimacsDescriptor &desc)
164.79 +{
164.80 + bool report = !ap.given("q");
164.81 + Digraph g;
164.82 + Node s,t;
164.83 + Digraph::ArcMap<Value> cap(g);
164.84 + Timer ti;
164.85 + ti.restart();
164.86 + readDimacsMax(is, g, cap, s, t, infty, desc);
164.87 + if(report) std::cerr << "Read the file: " << ti << '\n';
164.88 + ti.restart();
164.89 + Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
164.90 + if(report) std::cerr << "Setup Preflow class: " << ti << '\n';
164.91 + ti.restart();
164.92 + pre.run();
164.93 + if(report) std::cerr << "Run Preflow: " << ti << '\n';
164.94 + if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';
164.95 +}
164.96 +
164.97 +template<class Value>
164.98 +void solve_min(ArgParser &ap, std::istream &is, std::ostream &,
164.99 + Value infty, DimacsDescriptor &desc)
164.100 +{
164.101 + bool report = !ap.given("q");
164.102 + Digraph g;
164.103 + Digraph::ArcMap<Value> lower(g), cap(g), cost(g);
164.104 + Digraph::NodeMap<Value> sup(g);
164.105 + Timer ti;
164.106 +
164.107 + ti.restart();
164.108 + readDimacsMin(is, g, lower, cap, cost, sup, infty, desc);
164.109 + ti.stop();
164.110 + Value sum_sup = 0;
164.111 + for (Digraph::NodeIt n(g); n != INVALID; ++n) {
164.112 + sum_sup += sup[n];
164.113 + }
164.114 + if (report) {
164.115 + std::cerr << "Sum of supply values: " << sum_sup << "\n";
164.116 + if (sum_sup <= 0)
164.117 + std::cerr << "GEQ supply contraints are used for NetworkSimplex\n\n";
164.118 + else
164.119 + std::cerr << "LEQ supply contraints are used for NetworkSimplex\n\n";
164.120 + }
164.121 + if (report) std::cerr << "Read the file: " << ti << '\n';
164.122 +
164.123 + ti.restart();
164.124 + NetworkSimplex<Digraph, Value> ns(g);
164.125 + ns.lowerMap(lower).upperMap(cap).costMap(cost).supplyMap(sup);
164.126 + if (sum_sup > 0) ns.supplyType(ns.LEQ);
164.127 + if (report) std::cerr << "Setup NetworkSimplex class: " << ti << '\n';
164.128 + ti.restart();
164.129 + bool res = ns.run();
164.130 + if (report) {
164.131 + std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
164.132 + std::cerr << "Feasible flow: " << (res ? "found" : "not found") << '\n';
164.133 + if (res) std::cerr << "Min flow cost: " << ns.totalCost() << '\n';
164.134 + }
164.135 +}
164.136 +
164.137 +void solve_mat(ArgParser &ap, std::istream &is, std::ostream &,
164.138 + DimacsDescriptor &desc)
164.139 +{
164.140 + bool report = !ap.given("q");
164.141 + Graph g;
164.142 + Timer ti;
164.143 + ti.restart();
164.144 + readDimacsMat(is, g, desc);
164.145 + if(report) std::cerr << "Read the file: " << ti << '\n';
164.146 + ti.restart();
164.147 + MaxMatching<Graph> mat(g);
164.148 + if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n';
164.149 + ti.restart();
164.150 + mat.run();
164.151 + if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
164.152 + if(report) std::cerr << "\nCardinality of max matching: "
164.153 + << mat.matchingSize() << '\n';
164.154 +}
164.155 +
164.156 +
164.157 +template<class Value>
164.158 +void solve(ArgParser &ap, std::istream &is, std::ostream &os,
164.159 + DimacsDescriptor &desc)
164.160 +{
164.161 + std::stringstream iss(static_cast<std::string>(ap["infcap"]));
164.162 + Value infty;
164.163 + iss >> infty;
164.164 + if(iss.fail())
164.165 + {
164.166 + std::cerr << "Cannot interpret '"
164.167 + << static_cast<std::string>(ap["infcap"]) << "' as infinite"
164.168 + << std::endl;
164.169 + exit(1);
164.170 + }
164.171 +
164.172 + switch(desc.type)
164.173 + {
164.174 + case DimacsDescriptor::MIN:
164.175 + solve_min<Value>(ap,is,os,infty,desc);
164.176 + break;
164.177 + case DimacsDescriptor::MAX:
164.178 + solve_max<Value>(ap,is,os,infty,desc);
164.179 + break;
164.180 + case DimacsDescriptor::SP:
164.181 + solve_sp<Value>(ap,is,os,desc);
164.182 + break;
164.183 + case DimacsDescriptor::MAT:
164.184 + solve_mat(ap,is,os,desc);
164.185 + break;
164.186 + default:
164.187 + break;
164.188 + }
164.189 +}
164.190 +
164.191 +int main(int argc, const char *argv[]) {
164.192 + typedef SmartDigraph Digraph;
164.193 +
164.194 + typedef Digraph::Arc Arc;
164.195 +
164.196 + std::string inputName;
164.197 + std::string outputName;
164.198 +
164.199 + ArgParser ap(argc, argv);
164.200 + ap.other("[INFILE [OUTFILE]]",
164.201 + "If either the INFILE or OUTFILE file is missing the standard\n"
164.202 + " input/output will be used instead.")
164.203 + .boolOption("q", "Do not print any report")
164.204 + .boolOption("int","Use 'int' for capacities, costs etc. (default)")
164.205 + .optionGroup("datatype","int")
164.206 +#ifdef LEMON_HAVE_LONG_LONG
164.207 + .boolOption("long","Use 'long long' for capacities, costs etc.")
164.208 + .optionGroup("datatype","long")
164.209 +#endif
164.210 + .boolOption("double","Use 'double' for capacities, costs etc.")
164.211 + .optionGroup("datatype","double")
164.212 + .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
164.213 + .optionGroup("datatype","ldouble")
164.214 + .onlyOneGroup("datatype")
164.215 + .stringOption("infcap","Value used for 'very high' capacities","0")
164.216 + .run();
164.217 +
164.218 + std::ifstream input;
164.219 + std::ofstream output;
164.220 +
164.221 + switch(ap.files().size())
164.222 + {
164.223 + case 2:
164.224 + output.open(ap.files()[1].c_str());
164.225 + if (!output) {
164.226 + throw IoError("Cannot open the file for writing", ap.files()[1]);
164.227 + }
164.228 + case 1:
164.229 + input.open(ap.files()[0].c_str());
164.230 + if (!input) {
164.231 + throw IoError("File cannot be found", ap.files()[0]);
164.232 + }
164.233 + case 0:
164.234 + break;
164.235 + default:
164.236 + std::cerr << ap.commandName() << ": too many arguments\n";
164.237 + return 1;
164.238 + }
164.239 + std::istream& is = (ap.files().size()<1 ? std::cin : input);
164.240 + std::ostream& os = (ap.files().size()<2 ? std::cout : output);
164.241 +
164.242 + DimacsDescriptor desc = dimacsType(is);
164.243 +
164.244 + if(!ap.given("q"))
164.245 + {
164.246 + std::cout << "Problem type: ";
164.247 + switch(desc.type)
164.248 + {
164.249 + case DimacsDescriptor::MIN:
164.250 + std::cout << "min";
164.251 + break;
164.252 + case DimacsDescriptor::MAX:
164.253 + std::cout << "max";
164.254 + break;
164.255 + case DimacsDescriptor::SP:
164.256 + std::cout << "sp";
164.257 + case DimacsDescriptor::MAT:
164.258 + std::cout << "mat";
164.259 + break;
164.260 + default:
164.261 + exit(1);
164.262 + break;
164.263 + }
164.264 + std::cout << "\nNum of nodes: " << desc.nodeNum;
164.265 + std::cout << "\nNum of arcs: " << desc.edgeNum;
164.266 + std::cout << "\n\n";
164.267 + }
164.268 +
164.269 + if(ap.given("double"))
164.270 + solve<double>(ap,is,os,desc);
164.271 + else if(ap.given("ldouble"))
164.272 + solve<long double>(ap,is,os,desc);
164.273 +#ifdef LEMON_HAVE_LONG_LONG
164.274 + else if(ap.given("long"))
164.275 + solve<long long>(ap,is,os,desc);
164.276 +#endif
164.277 + else solve<int>(ap,is,os,desc);
164.278 +
164.279 + return 0;
164.280 +}
165.1 --- a/tools/dimacs-to-lgf.cc Mon Jan 12 23:11:39 2009 +0100
165.2 +++ b/tools/dimacs-to-lgf.cc Thu Nov 05 15:48:01 2009 +0100
165.3 @@ -24,11 +24,10 @@
165.4 /// (LGF).
165.5 ///
165.6 /// See
165.7 -/// \verbatim
165.8 -/// dimacs-to-lgf --help
165.9 -/// \endverbatim
165.10 -/// for more info on usage.
165.11 -///
165.12 +/// \code
165.13 +/// dimacs-to-lgf --help
165.14 +/// \endcode
165.15 +/// for more info on the usage.
165.16
165.17 #include <iostream>
165.18 #include <fstream>
165.19 @@ -96,7 +95,7 @@
165.20 Digraph digraph;
165.21 DoubleArcMap lower(digraph), capacity(digraph), cost(digraph);
165.22 DoubleNodeMap supply(digraph);
165.23 - readDimacsMin(is, digraph, lower, capacity, cost, supply, desc);
165.24 + readDimacsMin(is, digraph, lower, capacity, cost, supply, 0, desc);
165.25 DigraphWriter<Digraph>(digraph, os).
165.26 nodeMap("supply", supply).
165.27 arcMap("lower", lower).
165.28 @@ -111,7 +110,7 @@
165.29 Digraph digraph;
165.30 Node s, t;
165.31 DoubleArcMap capacity(digraph);
165.32 - readDimacsMax(is, digraph, capacity, s, t, desc);
165.33 + readDimacsMax(is, digraph, capacity, s, t, 0, desc);
165.34 DigraphWriter<Digraph>(digraph, os).
165.35 arcMap("capacity", capacity).
165.36 node("source", s).
166.1 --- a/tools/lemon-0.x-to-1.x.sh Mon Jan 12 23:11:39 2009 +0100
166.2 +++ b/tools/lemon-0.x-to-1.x.sh Thu Nov 05 15:48:01 2009 +0100
166.3 @@ -22,26 +22,25 @@
166.4 -e "s/\<directed edges\>/_ar_c_label_s/g"\
166.5 -e "s/UGraph/_Gr_aph_label_/g"\
166.6 -e "s/u[Gg]raph/_gr_aph_label_/g"\
166.7 - -e "s/\<Graph\>/_Digr_aph_label_/g"\
166.8 + -e "s/Graph\>/_Digr_aph_label_/g"\
166.9 -e "s/\<graph\>/_digr_aph_label_/g"\
166.10 - -e "s/\<Graphs\>/_Digr_aph_label_s/g"\
166.11 + -e "s/Graphs\>/_Digr_aph_label_s/g"\
166.12 -e "s/\<graphs\>/_digr_aph_label_s/g"\
166.13 - -e "s/_Graph/__Gr_aph_label_/g"\
166.14 - -e "s/\([Gg]\)raph\([a-z_]\)/_\1r_aph_label_\2/g"\
166.15 + -e "s/\([Gg]\)raph\([a-z]\)/_\1r_aph_label_\2/g"\
166.16 -e "s/\([a-z_]\)graph/\1_gr_aph_label_/g"\
166.17 -e "s/Graph/_Digr_aph_label_/g"\
166.18 -e "s/graph/_digr_aph_label_/g"\
166.19 -e "s/UEdge/_Ed_ge_label_/g"\
166.20 -e "s/u[Ee]dge/_ed_ge_label_/g"\
166.21 -e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
166.22 - -e "s/\<Edge\>/_Ar_c_label_/g"\
166.23 + -e "s/Edge\>/_Ar_c_label_/g"\
166.24 -e "s/\<edge\>/_ar_c_label_/g"\
166.25 - -e "s/\<Edges\>/_Ar_c_label_s/g"\
166.26 + -e "s/_edge\>/__ar_c_label_/g"\
166.27 + -e "s/Edges\>/_Ar_c_label_s/g"\
166.28 -e "s/\<edges\>/_ar_c_label_s/g"\
166.29 - -e "s/_Edge/__Ed_ge_label_/g"\
166.30 - -e "s/Edge\([a-z_]\)/_Ed_ge_label_\1/g"\
166.31 - -e "s/edge\([a-z_]\)/_ed_ge_label_\1/g"\
166.32 - -e "s/\([a-z_]\)edge/\1_ed_ge_label_/g"\
166.33 + -e "s/_edges\>/__ar_c_label_s/g"\
166.34 + -e "s/\([Ee]\)dge\([a-z]\)/_\1d_ge_label_\2/g"\
166.35 + -e "s/\([a-z]\)edge/\1_ed_ge_label_/g"\
166.36 -e "s/Edge/_Ar_c_label_/g"\
166.37 -e "s/edge/_ar_c_label_/g"\
166.38 -e "s/A[Nn]ode/_Re_d_label_/g"\
166.39 @@ -69,6 +68,11 @@
166.40 -e "s/_blu_e_label_/blue/g"\
166.41 -e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\
166.42 -e "s/_DIGR_APH_TY_PEDE_FS_label_/DIGRAPH_TYPEDEFS/g"\
166.43 + -e "s/\<digraph_adaptor\.h\>/adaptors.h/g"\
166.44 + -e "s/\<digraph_utils\.h\>/core.h/g"\
166.45 + -e "s/\<digraph_reader\.h\>/lgf_reader.h/g"\
166.46 + -e "s/\<digraph_writer\.h\>/lgf_writer.h/g"\
166.47 + -e "s/\<topology\.h\>/connectivity.h/g"\
166.48 -e "s/DigraphToEps/GraphToEps/g"\
166.49 -e "s/digraphToEps/graphToEps/g"\
166.50 -e "s/\<DefPredMap\>/SetPredMap/g"\
166.51 @@ -90,6 +94,10 @@
166.52 -e "s/\<\([Ff]\)orkWriteMap\>/\1orkMap/g"\
166.53 -e "s/\<StoreBoolMap\>/LoggerBoolMap/g"\
166.54 -e "s/\<storeBoolMap\>/loggerBoolMap/g"\
166.55 + -e "s/\<InvertableMap\>/CrossRefMap/g"\
166.56 + -e "s/\<invertableMap\>/crossRefMap/g"\
166.57 + -e "s/\<DescriptorMap\>/RangeIdMap/g"\
166.58 + -e "s/\<descriptorMap\>/rangeIdMap/g"\
166.59 -e "s/\<BoundingBox\>/Box/g"\
166.60 -e "s/\<readNauty\>/readNautyGraph/g"\
166.61 -e "s/\<RevDigraphAdaptor\>/ReverseDigraph/g"\
166.62 @@ -116,6 +124,11 @@
166.63 -e "s/\<arcSubGraphAdaptor\>/filterEdges/g"\
166.64 -e "s/\<DirGraphAdaptor\>/Orienter/g"\
166.65 -e "s/\<dirGraphAdaptor\>/orienter/g"\
166.66 + -e "s/\<LpCplex\>/CplexLp/g"\
166.67 + -e "s/\<MipCplex\>/CplexMip/g"\
166.68 + -e "s/\<LpGlpk\>/GlpkLp/g"\
166.69 + -e "s/\<MipGlpk\>/GlpkMip/g"\
166.70 + -e "s/\<LpSoplex\>/SoplexLp/g"\
166.71 <$i > $TMP
166.72 mv $TMP $i
166.73 done
167.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
167.2 +++ b/tools/lgf-gen.cc Thu Nov 05 15:48:01 2009 +0100
167.3 @@ -0,0 +1,834 @@
167.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
167.5 + *
167.6 + * This file is a part of LEMON, a generic C++ optimization library.
167.7 + *
167.8 + * Copyright (C) 2003-2009
167.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
167.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
167.11 + *
167.12 + * Permission to use, modify and distribute this software is granted
167.13 + * provided that this copyright notice appears in all copies. For
167.14 + * precise terms see the accompanying LICENSE file.
167.15 + *
167.16 + * This software is provided "AS IS" with no warranty of any kind,
167.17 + * express or implied, and with no claim as to its suitability for any
167.18 + * purpose.
167.19 + *
167.20 + */
167.21 +
167.22 +/// \ingroup tools
167.23 +/// \file
167.24 +/// \brief Special plane graph generator.
167.25 +///
167.26 +/// Graph generator application for various types of plane graphs.
167.27 +///
167.28 +/// See
167.29 +/// \code
167.30 +/// lgf-gen --help
167.31 +/// \endcode
167.32 +/// for more information on the usage.
167.33 +
167.34 +#include <algorithm>
167.35 +#include <set>
167.36 +#include <ctime>
167.37 +#include <lemon/list_graph.h>
167.38 +#include <lemon/random.h>
167.39 +#include <lemon/dim2.h>
167.40 +#include <lemon/bfs.h>
167.41 +#include <lemon/counter.h>
167.42 +#include <lemon/suurballe.h>
167.43 +#include <lemon/graph_to_eps.h>
167.44 +#include <lemon/lgf_writer.h>
167.45 +#include <lemon/arg_parser.h>
167.46 +#include <lemon/euler.h>
167.47 +#include <lemon/math.h>
167.48 +#include <lemon/kruskal.h>
167.49 +#include <lemon/time_measure.h>
167.50 +
167.51 +using namespace lemon;
167.52 +
167.53 +typedef dim2::Point<double> Point;
167.54 +
167.55 +GRAPH_TYPEDEFS(ListGraph);
167.56 +
167.57 +bool progress=true;
167.58 +
167.59 +int N;
167.60 +// int girth;
167.61 +
167.62 +ListGraph g;
167.63 +
167.64 +std::vector<Node> nodes;
167.65 +ListGraph::NodeMap<Point> coords(g);
167.66 +
167.67 +
167.68 +double totalLen(){
167.69 + double tlen=0;
167.70 + for(EdgeIt e(g);e!=INVALID;++e)
167.71 + tlen+=std::sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
167.72 + return tlen;
167.73 +}
167.74 +
167.75 +int tsp_impr_num=0;
167.76 +
167.77 +const double EPSILON=1e-8;
167.78 +bool tsp_improve(Node u, Node v)
167.79 +{
167.80 + double luv=std::sqrt((coords[v]-coords[u]).normSquare());
167.81 + Node u2=u;
167.82 + Node v2=v;
167.83 + do {
167.84 + Node n;
167.85 + for(IncEdgeIt e(g,v2);(n=g.runningNode(e))==u2;++e) { }
167.86 + u2=v2;
167.87 + v2=n;
167.88 + if(luv+std::sqrt((coords[v2]-coords[u2]).normSquare())-EPSILON>
167.89 + std::sqrt((coords[u]-coords[u2]).normSquare())+
167.90 + std::sqrt((coords[v]-coords[v2]).normSquare()))
167.91 + {
167.92 + g.erase(findEdge(g,u,v));
167.93 + g.erase(findEdge(g,u2,v2));
167.94 + g.addEdge(u2,u);
167.95 + g.addEdge(v,v2);
167.96 + tsp_impr_num++;
167.97 + return true;
167.98 + }
167.99 + } while(v2!=u);
167.100 + return false;
167.101 +}
167.102 +
167.103 +bool tsp_improve(Node u)
167.104 +{
167.105 + for(IncEdgeIt e(g,u);e!=INVALID;++e)
167.106 + if(tsp_improve(u,g.runningNode(e))) return true;
167.107 + return false;
167.108 +}
167.109 +
167.110 +void tsp_improve()
167.111 +{
167.112 + bool b;
167.113 + do {
167.114 + b=false;
167.115 + for(NodeIt n(g);n!=INVALID;++n)
167.116 + if(tsp_improve(n)) b=true;
167.117 + } while(b);
167.118 +}
167.119 +
167.120 +void tsp()
167.121 +{
167.122 + for(int i=0;i<N;i++) g.addEdge(nodes[i],nodes[(i+1)%N]);
167.123 + tsp_improve();
167.124 +}
167.125 +
167.126 +class Line
167.127 +{
167.128 +public:
167.129 + Point a;
167.130 + Point b;
167.131 + Line(Point _a,Point _b) :a(_a),b(_b) {}
167.132 + Line(Node _a,Node _b) : a(coords[_a]),b(coords[_b]) {}
167.133 + Line(const Arc &e) : a(coords[g.source(e)]),b(coords[g.target(e)]) {}
167.134 + Line(const Edge &e) : a(coords[g.u(e)]),b(coords[g.v(e)]) {}
167.135 +};
167.136 +
167.137 +inline std::ostream& operator<<(std::ostream &os, const Line &l)
167.138 +{
167.139 + os << l.a << "->" << l.b;
167.140 + return os;
167.141 +}
167.142 +
167.143 +bool cross(Line a, Line b)
167.144 +{
167.145 + Point ao=rot90(a.b-a.a);
167.146 + Point bo=rot90(b.b-b.a);
167.147 + return (ao*(b.a-a.a))*(ao*(b.b-a.a))<0 &&
167.148 + (bo*(a.a-b.a))*(bo*(a.b-b.a))<0;
167.149 +}
167.150 +
167.151 +struct Parc
167.152 +{
167.153 + Node a;
167.154 + Node b;
167.155 + double len;
167.156 +};
167.157 +
167.158 +bool pedgeLess(Parc a,Parc b)
167.159 +{
167.160 + return a.len<b.len;
167.161 +}
167.162 +
167.163 +std::vector<Edge> arcs;
167.164 +
167.165 +namespace _delaunay_bits {
167.166 +
167.167 + struct Part {
167.168 + int prev, curr, next;
167.169 +
167.170 + Part(int p, int c, int n) : prev(p), curr(c), next(n) {}
167.171 + };
167.172 +
167.173 + inline std::ostream& operator<<(std::ostream& os, const Part& part) {
167.174 + os << '(' << part.prev << ',' << part.curr << ',' << part.next << ')';
167.175 + return os;
167.176 + }
167.177 +
167.178 + inline double circle_point(const Point& p, const Point& q, const Point& r) {
167.179 + double a = p.x * (q.y - r.y) + q.x * (r.y - p.y) + r.x * (p.y - q.y);
167.180 + if (a == 0) return std::numeric_limits<double>::quiet_NaN();
167.181 +
167.182 + double d = (p.x * p.x + p.y * p.y) * (q.y - r.y) +
167.183 + (q.x * q.x + q.y * q.y) * (r.y - p.y) +
167.184 + (r.x * r.x + r.y * r.y) * (p.y - q.y);
167.185 +
167.186 + double e = (p.x * p.x + p.y * p.y) * (q.x - r.x) +
167.187 + (q.x * q.x + q.y * q.y) * (r.x - p.x) +
167.188 + (r.x * r.x + r.y * r.y) * (p.x - q.x);
167.189 +
167.190 + double f = (p.x * p.x + p.y * p.y) * (q.x * r.y - r.x * q.y) +
167.191 + (q.x * q.x + q.y * q.y) * (r.x * p.y - p.x * r.y) +
167.192 + (r.x * r.x + r.y * r.y) * (p.x * q.y - q.x * p.y);
167.193 +
167.194 + return d / (2 * a) + std::sqrt((d * d + e * e) / (4 * a * a) + f / a);
167.195 + }
167.196 +
167.197 + inline bool circle_form(const Point& p, const Point& q, const Point& r) {
167.198 + return rot90(q - p) * (r - q) < 0.0;
167.199 + }
167.200 +
167.201 + inline double intersection(const Point& p, const Point& q, double sx) {
167.202 + const double epsilon = 1e-8;
167.203 +
167.204 + if (p.x == q.x) return (p.y + q.y) / 2.0;
167.205 +
167.206 + if (sx < p.x + epsilon) return p.y;
167.207 + if (sx < q.x + epsilon) return q.y;
167.208 +
167.209 + double a = q.x - p.x;
167.210 + double b = (q.x - sx) * p.y - (p.x - sx) * q.y;
167.211 + double d = (q.x - sx) * (p.x - sx) * (p - q).normSquare();
167.212 + return (b - std::sqrt(d)) / a;
167.213 + }
167.214 +
167.215 + struct YLess {
167.216 +
167.217 +
167.218 + YLess(const std::vector<Point>& points, double& sweep)
167.219 + : _points(points), _sweep(sweep) {}
167.220 +
167.221 + bool operator()(const Part& l, const Part& r) const {
167.222 + const double epsilon = 1e-8;
167.223 +
167.224 + // std::cerr << l << " vs " << r << std::endl;
167.225 + double lbx = l.prev != -1 ?
167.226 + intersection(_points[l.prev], _points[l.curr], _sweep) :
167.227 + - std::numeric_limits<double>::infinity();
167.228 + double rbx = r.prev != -1 ?
167.229 + intersection(_points[r.prev], _points[r.curr], _sweep) :
167.230 + - std::numeric_limits<double>::infinity();
167.231 + double lex = l.next != -1 ?
167.232 + intersection(_points[l.curr], _points[l.next], _sweep) :
167.233 + std::numeric_limits<double>::infinity();
167.234 + double rex = r.next != -1 ?
167.235 + intersection(_points[r.curr], _points[r.next], _sweep) :
167.236 + std::numeric_limits<double>::infinity();
167.237 +
167.238 + if (lbx > lex) std::swap(lbx, lex);
167.239 + if (rbx > rex) std::swap(rbx, rex);
167.240 +
167.241 + if (lex < epsilon + rex && lbx + epsilon < rex) return true;
167.242 + if (rex < epsilon + lex && rbx + epsilon < lex) return false;
167.243 + return lex < rex;
167.244 + }
167.245 +
167.246 + const std::vector<Point>& _points;
167.247 + double& _sweep;
167.248 + };
167.249 +
167.250 + struct BeachIt;
167.251 +
167.252 + typedef std::multimap<double, BeachIt> SpikeHeap;
167.253 +
167.254 + typedef std::multimap<Part, SpikeHeap::iterator, YLess> Beach;
167.255 +
167.256 + struct BeachIt {
167.257 + Beach::iterator it;
167.258 +
167.259 + BeachIt(Beach::iterator iter) : it(iter) {}
167.260 + };
167.261 +
167.262 +}
167.263 +
167.264 +inline void delaunay() {
167.265 + Counter cnt("Number of arcs added: ");
167.266 +
167.267 + using namespace _delaunay_bits;
167.268 +
167.269 + typedef _delaunay_bits::Part Part;
167.270 + typedef std::vector<std::pair<double, int> > SiteHeap;
167.271 +
167.272 +
167.273 + std::vector<Point> points;
167.274 + std::vector<Node> nodes;
167.275 +
167.276 + for (NodeIt it(g); it != INVALID; ++it) {
167.277 + nodes.push_back(it);
167.278 + points.push_back(coords[it]);
167.279 + }
167.280 +
167.281 + SiteHeap siteheap(points.size());
167.282 +
167.283 + double sweep;
167.284 +
167.285 +
167.286 + for (int i = 0; i < int(siteheap.size()); ++i) {
167.287 + siteheap[i] = std::make_pair(points[i].x, i);
167.288 + }
167.289 +
167.290 + std::sort(siteheap.begin(), siteheap.end());
167.291 + sweep = siteheap.front().first;
167.292 +
167.293 + YLess yless(points, sweep);
167.294 + Beach beach(yless);
167.295 +
167.296 + SpikeHeap spikeheap;
167.297 +
167.298 + std::set<std::pair<int, int> > arcs;
167.299 +
167.300 + int siteindex = 0;
167.301 + {
167.302 + SiteHeap front;
167.303 +
167.304 + while (siteindex < int(siteheap.size()) &&
167.305 + siteheap[0].first == siteheap[siteindex].first) {
167.306 + front.push_back(std::make_pair(points[siteheap[siteindex].second].y,
167.307 + siteheap[siteindex].second));
167.308 + ++siteindex;
167.309 + }
167.310 +
167.311 + std::sort(front.begin(), front.end());
167.312 +
167.313 + for (int i = 0; i < int(front.size()); ++i) {
167.314 + int prev = (i == 0 ? -1 : front[i - 1].second);
167.315 + int curr = front[i].second;
167.316 + int next = (i + 1 == int(front.size()) ? -1 : front[i + 1].second);
167.317 +
167.318 + beach.insert(std::make_pair(Part(prev, curr, next),
167.319 + spikeheap.end()));
167.320 + }
167.321 + }
167.322 +
167.323 + while (siteindex < int(points.size()) || !spikeheap.empty()) {
167.324 +
167.325 + SpikeHeap::iterator spit = spikeheap.begin();
167.326 +
167.327 + if (siteindex < int(points.size()) &&
167.328 + (spit == spikeheap.end() || siteheap[siteindex].first < spit->first)) {
167.329 + int site = siteheap[siteindex].second;
167.330 + sweep = siteheap[siteindex].first;
167.331 +
167.332 + Beach::iterator bit = beach.upper_bound(Part(site, site, site));
167.333 +
167.334 + if (bit->second != spikeheap.end()) {
167.335 + spikeheap.erase(bit->second);
167.336 + }
167.337 +
167.338 + int prev = bit->first.prev;
167.339 + int curr = bit->first.curr;
167.340 + int next = bit->first.next;
167.341 +
167.342 + beach.erase(bit);
167.343 +
167.344 + SpikeHeap::iterator pit = spikeheap.end();
167.345 + if (prev != -1 &&
167.346 + circle_form(points[prev], points[curr], points[site])) {
167.347 + double x = circle_point(points[prev], points[curr], points[site]);
167.348 + pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
167.349 + pit->second.it =
167.350 + beach.insert(std::make_pair(Part(prev, curr, site), pit));
167.351 + } else {
167.352 + beach.insert(std::make_pair(Part(prev, curr, site), pit));
167.353 + }
167.354 +
167.355 + beach.insert(std::make_pair(Part(curr, site, curr), spikeheap.end()));
167.356 +
167.357 + SpikeHeap::iterator nit = spikeheap.end();
167.358 + if (next != -1 &&
167.359 + circle_form(points[site], points[curr],points[next])) {
167.360 + double x = circle_point(points[site], points[curr], points[next]);
167.361 + nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
167.362 + nit->second.it =
167.363 + beach.insert(std::make_pair(Part(site, curr, next), nit));
167.364 + } else {
167.365 + beach.insert(std::make_pair(Part(site, curr, next), nit));
167.366 + }
167.367 +
167.368 + ++siteindex;
167.369 + } else {
167.370 + sweep = spit->first;
167.371 +
167.372 + Beach::iterator bit = spit->second.it;
167.373 +
167.374 + int prev = bit->first.prev;
167.375 + int curr = bit->first.curr;
167.376 + int next = bit->first.next;
167.377 +
167.378 + {
167.379 + std::pair<int, int> arc;
167.380 +
167.381 + arc = prev < curr ?
167.382 + std::make_pair(prev, curr) : std::make_pair(curr, prev);
167.383 +
167.384 + if (arcs.find(arc) == arcs.end()) {
167.385 + arcs.insert(arc);
167.386 + g.addEdge(nodes[prev], nodes[curr]);
167.387 + ++cnt;
167.388 + }
167.389 +
167.390 + arc = curr < next ?
167.391 + std::make_pair(curr, next) : std::make_pair(next, curr);
167.392 +
167.393 + if (arcs.find(arc) == arcs.end()) {
167.394 + arcs.insert(arc);
167.395 + g.addEdge(nodes[curr], nodes[next]);
167.396 + ++cnt;
167.397 + }
167.398 + }
167.399 +
167.400 + Beach::iterator pbit = bit; --pbit;
167.401 + int ppv = pbit->first.prev;
167.402 + Beach::iterator nbit = bit; ++nbit;
167.403 + int nnt = nbit->first.next;
167.404 +
167.405 + if (bit->second != spikeheap.end()) spikeheap.erase(bit->second);
167.406 + if (pbit->second != spikeheap.end()) spikeheap.erase(pbit->second);
167.407 + if (nbit->second != spikeheap.end()) spikeheap.erase(nbit->second);
167.408 +
167.409 + beach.erase(nbit);
167.410 + beach.erase(bit);
167.411 + beach.erase(pbit);
167.412 +
167.413 + SpikeHeap::iterator pit = spikeheap.end();
167.414 + if (ppv != -1 && ppv != next &&
167.415 + circle_form(points[ppv], points[prev], points[next])) {
167.416 + double x = circle_point(points[ppv], points[prev], points[next]);
167.417 + if (x < sweep) x = sweep;
167.418 + pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
167.419 + pit->second.it =
167.420 + beach.insert(std::make_pair(Part(ppv, prev, next), pit));
167.421 + } else {
167.422 + beach.insert(std::make_pair(Part(ppv, prev, next), pit));
167.423 + }
167.424 +
167.425 + SpikeHeap::iterator nit = spikeheap.end();
167.426 + if (nnt != -1 && prev != nnt &&
167.427 + circle_form(points[prev], points[next], points[nnt])) {
167.428 + double x = circle_point(points[prev], points[next], points[nnt]);
167.429 + if (x < sweep) x = sweep;
167.430 + nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
167.431 + nit->second.it =
167.432 + beach.insert(std::make_pair(Part(prev, next, nnt), nit));
167.433 + } else {
167.434 + beach.insert(std::make_pair(Part(prev, next, nnt), nit));
167.435 + }
167.436 +
167.437 + }
167.438 + }
167.439 +
167.440 + for (Beach::iterator it = beach.begin(); it != beach.end(); ++it) {
167.441 + int curr = it->first.curr;
167.442 + int next = it->first.next;
167.443 +
167.444 + if (next == -1) continue;
167.445 +
167.446 + std::pair<int, int> arc;
167.447 +
167.448 + arc = curr < next ?
167.449 + std::make_pair(curr, next) : std::make_pair(next, curr);
167.450 +
167.451 + if (arcs.find(arc) == arcs.end()) {
167.452 + arcs.insert(arc);
167.453 + g.addEdge(nodes[curr], nodes[next]);
167.454 + ++cnt;
167.455 + }
167.456 + }
167.457 +}
167.458 +
167.459 +void sparse(int d)
167.460 +{
167.461 + Counter cnt("Number of arcs removed: ");
167.462 + Bfs<ListGraph> bfs(g);
167.463 + for(std::vector<Edge>::reverse_iterator ei=arcs.rbegin();
167.464 + ei!=arcs.rend();++ei)
167.465 + {
167.466 + Node a=g.u(*ei);
167.467 + Node b=g.v(*ei);
167.468 + g.erase(*ei);
167.469 + bfs.run(a,b);
167.470 + if(bfs.predArc(b)==INVALID || bfs.dist(b)>d)
167.471 + g.addEdge(a,b);
167.472 + else cnt++;
167.473 + }
167.474 +}
167.475 +
167.476 +void sparse2(int d)
167.477 +{
167.478 + Counter cnt("Number of arcs removed: ");
167.479 + for(std::vector<Edge>::reverse_iterator ei=arcs.rbegin();
167.480 + ei!=arcs.rend();++ei)
167.481 + {
167.482 + Node a=g.u(*ei);
167.483 + Node b=g.v(*ei);
167.484 + g.erase(*ei);
167.485 + ConstMap<Arc,int> cegy(1);
167.486 + Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
167.487 + int k=sur.run(a,b,2);
167.488 + if(k<2 || sur.totalLength()>d)
167.489 + g.addEdge(a,b);
167.490 + else cnt++;
167.491 +// else std::cout << "Remove arc " << g.id(a) << "-" << g.id(b) << '\n';
167.492 + }
167.493 +}
167.494 +
167.495 +void sparseTriangle(int d)
167.496 +{
167.497 + Counter cnt("Number of arcs added: ");
167.498 + std::vector<Parc> pedges;
167.499 + for(NodeIt n(g);n!=INVALID;++n)
167.500 + for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
167.501 + {
167.502 + Parc p;
167.503 + p.a=n;
167.504 + p.b=m;
167.505 + p.len=(coords[m]-coords[n]).normSquare();
167.506 + pedges.push_back(p);
167.507 + }
167.508 + std::sort(pedges.begin(),pedges.end(),pedgeLess);
167.509 + for(std::vector<Parc>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
167.510 + {
167.511 + Line li(pi->a,pi->b);
167.512 + EdgeIt e(g);
167.513 + for(;e!=INVALID && !cross(e,li);++e) ;
167.514 + Edge ne;
167.515 + if(e==INVALID) {
167.516 + ConstMap<Arc,int> cegy(1);
167.517 + Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
167.518 + int k=sur.run(pi->a,pi->b,2);
167.519 + if(k<2 || sur.totalLength()>d)
167.520 + {
167.521 + ne=g.addEdge(pi->a,pi->b);
167.522 + arcs.push_back(ne);
167.523 + cnt++;
167.524 + }
167.525 + }
167.526 + }
167.527 +}
167.528 +
167.529 +template <typename Graph, typename CoordMap>
167.530 +class LengthSquareMap {
167.531 +public:
167.532 + typedef typename Graph::Edge Key;
167.533 + typedef typename CoordMap::Value::Value Value;
167.534 +
167.535 + LengthSquareMap(const Graph& graph, const CoordMap& coords)
167.536 + : _graph(graph), _coords(coords) {}
167.537 +
167.538 + Value operator[](const Key& key) const {
167.539 + return (_coords[_graph.v(key)] -
167.540 + _coords[_graph.u(key)]).normSquare();
167.541 + }
167.542 +
167.543 +private:
167.544 +
167.545 + const Graph& _graph;
167.546 + const CoordMap& _coords;
167.547 +};
167.548 +
167.549 +void minTree() {
167.550 + std::vector<Parc> pedges;
167.551 + Timer T;
167.552 + std::cout << T.realTime() << "s: Creating delaunay triangulation...\n";
167.553 + delaunay();
167.554 + std::cout << T.realTime() << "s: Calculating spanning tree...\n";
167.555 + LengthSquareMap<ListGraph, ListGraph::NodeMap<Point> > ls(g, coords);
167.556 + ListGraph::EdgeMap<bool> tree(g);
167.557 + kruskal(g, ls, tree);
167.558 + std::cout << T.realTime() << "s: Removing non tree arcs...\n";
167.559 + std::vector<Edge> remove;
167.560 + for (EdgeIt e(g); e != INVALID; ++e) {
167.561 + if (!tree[e]) remove.push_back(e);
167.562 + }
167.563 + for(int i = 0; i < int(remove.size()); ++i) {
167.564 + g.erase(remove[i]);
167.565 + }
167.566 + std::cout << T.realTime() << "s: Done\n";
167.567 +}
167.568 +
167.569 +void tsp2()
167.570 +{
167.571 + std::cout << "Find a tree..." << std::endl;
167.572 +
167.573 + minTree();
167.574 +
167.575 + std::cout << "Total arc length (tree) : " << totalLen() << std::endl;
167.576 +
167.577 + std::cout << "Make it Euler..." << std::endl;
167.578 +
167.579 + {
167.580 + std::vector<Node> leafs;
167.581 + for(NodeIt n(g);n!=INVALID;++n)
167.582 + if(countIncEdges(g,n)%2==1) leafs.push_back(n);
167.583 +
167.584 +// for(unsigned int i=0;i<leafs.size();i+=2)
167.585 +// g.addArc(leafs[i],leafs[i+1]);
167.586 +
167.587 + std::vector<Parc> pedges;
167.588 + for(unsigned int i=0;i<leafs.size()-1;i++)
167.589 + for(unsigned int j=i+1;j<leafs.size();j++)
167.590 + {
167.591 + Node n=leafs[i];
167.592 + Node m=leafs[j];
167.593 + Parc p;
167.594 + p.a=n;
167.595 + p.b=m;
167.596 + p.len=(coords[m]-coords[n]).normSquare();
167.597 + pedges.push_back(p);
167.598 + }
167.599 + std::sort(pedges.begin(),pedges.end(),pedgeLess);
167.600 + for(unsigned int i=0;i<pedges.size();i++)
167.601 + if(countIncEdges(g,pedges[i].a)%2 &&
167.602 + countIncEdges(g,pedges[i].b)%2)
167.603 + g.addEdge(pedges[i].a,pedges[i].b);
167.604 + }
167.605 +
167.606 + for(NodeIt n(g);n!=INVALID;++n)
167.607 + if(countIncEdges(g,n)%2 || countIncEdges(g,n)==0 )
167.608 + std::cout << "GEBASZ!!!" << std::endl;
167.609 +
167.610 + for(EdgeIt e(g);e!=INVALID;++e)
167.611 + if(g.u(e)==g.v(e))
167.612 + std::cout << "LOOP GEBASZ!!!" << std::endl;
167.613 +
167.614 + std::cout << "Number of arcs : " << countEdges(g) << std::endl;
167.615 +
167.616 + std::cout << "Total arc length (euler) : " << totalLen() << std::endl;
167.617 +
167.618 + ListGraph::EdgeMap<Arc> enext(g);
167.619 + {
167.620 + EulerIt<ListGraph> e(g);
167.621 + Arc eo=e;
167.622 + Arc ef=e;
167.623 +// std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl;
167.624 + for(++e;e!=INVALID;++e)
167.625 + {
167.626 +// std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl;
167.627 + enext[eo]=e;
167.628 + eo=e;
167.629 + }
167.630 + enext[eo]=ef;
167.631 + }
167.632 +
167.633 + std::cout << "Creating a tour from that..." << std::endl;
167.634 +
167.635 + int nnum = countNodes(g);
167.636 + int ednum = countEdges(g);
167.637 +
167.638 + for(Arc p=enext[EdgeIt(g)];ednum>nnum;p=enext[p])
167.639 + {
167.640 +// std::cout << "Checking arc " << g.id(p) << std::endl;
167.641 + Arc e=enext[p];
167.642 + Arc f=enext[e];
167.643 + Node n2=g.source(f);
167.644 + Node n1=g.oppositeNode(n2,e);
167.645 + Node n3=g.oppositeNode(n2,f);
167.646 + if(countIncEdges(g,n2)>2)
167.647 + {
167.648 +// std::cout << "Remove an Arc" << std::endl;
167.649 + Arc ff=enext[f];
167.650 + g.erase(e);
167.651 + g.erase(f);
167.652 + if(n1!=n3)
167.653 + {
167.654 + Arc ne=g.direct(g.addEdge(n1,n3),n1);
167.655 + enext[p]=ne;
167.656 + enext[ne]=ff;
167.657 + ednum--;
167.658 + }
167.659 + else {
167.660 + enext[p]=ff;
167.661 + ednum-=2;
167.662 + }
167.663 + }
167.664 + }
167.665 +
167.666 + std::cout << "Total arc length (tour) : " << totalLen() << std::endl;
167.667 +
167.668 + std::cout << "2-opt the tour..." << std::endl;
167.669 +
167.670 + tsp_improve();
167.671 +
167.672 + std::cout << "Total arc length (2-opt tour) : " << totalLen() << std::endl;
167.673 +}
167.674 +
167.675 +
167.676 +int main(int argc,const char **argv)
167.677 +{
167.678 + ArgParser ap(argc,argv);
167.679 +
167.680 +// bool eps;
167.681 + bool disc_d, square_d, gauss_d;
167.682 +// bool tsp_a,two_a,tree_a;
167.683 + int num_of_cities=1;
167.684 + double area=1;
167.685 + N=100;
167.686 +// girth=10;
167.687 + std::string ndist("disc");
167.688 + ap.refOption("n", "Number of nodes (default is 100)", N)
167.689 + .intOption("g", "Girth parameter (default is 10)", 10)
167.690 + .refOption("cities", "Number of cities (default is 1)", num_of_cities)
167.691 + .refOption("area", "Full relative area of the cities (default is 1)", area)
167.692 + .refOption("disc", "Nodes are evenly distributed on a unit disc (default)",
167.693 + disc_d)
167.694 + .optionGroup("dist", "disc")
167.695 + .refOption("square", "Nodes are evenly distributed on a unit square",
167.696 + square_d)
167.697 + .optionGroup("dist", "square")
167.698 + .refOption("gauss", "Nodes are located according to a two-dim Gauss "
167.699 + "distribution", gauss_d)
167.700 + .optionGroup("dist", "gauss")
167.701 + .onlyOneGroup("dist")
167.702 + .boolOption("eps", "Also generate .eps output (<prefix>.eps)")
167.703 + .boolOption("nonodes", "Draw only the edges in the generated .eps output")
167.704 + .boolOption("dir", "Directed graph is generated (each edge is replaced by "
167.705 + "two directed arcs)")
167.706 + .boolOption("2con", "Create a two connected planar graph")
167.707 + .optionGroup("alg","2con")
167.708 + .boolOption("tree", "Create a min. cost spanning tree")
167.709 + .optionGroup("alg","tree")
167.710 + .boolOption("tsp", "Create a TSP tour")
167.711 + .optionGroup("alg","tsp")
167.712 + .boolOption("tsp2", "Create a TSP tour (tree based)")
167.713 + .optionGroup("alg","tsp2")
167.714 + .boolOption("dela", "Delaunay triangulation graph")
167.715 + .optionGroup("alg","dela")
167.716 + .onlyOneGroup("alg")
167.717 + .boolOption("rand", "Use time seed for random number generator")
167.718 + .optionGroup("rand", "rand")
167.719 + .intOption("seed", "Random seed", -1)
167.720 + .optionGroup("rand", "seed")
167.721 + .onlyOneGroup("rand")
167.722 + .other("[prefix]","Prefix of the output files. Default is 'lgf-gen-out'")
167.723 + .run();
167.724 +
167.725 + if (ap["rand"]) {
167.726 + int seed = int(time(0));
167.727 + std::cout << "Random number seed: " << seed << std::endl;
167.728 + rnd = Random(seed);
167.729 + }
167.730 + if (ap.given("seed")) {
167.731 + int seed = ap["seed"];
167.732 + std::cout << "Random number seed: " << seed << std::endl;
167.733 + rnd = Random(seed);
167.734 + }
167.735 +
167.736 + std::string prefix;
167.737 + switch(ap.files().size())
167.738 + {
167.739 + case 0:
167.740 + prefix="lgf-gen-out";
167.741 + break;
167.742 + case 1:
167.743 + prefix=ap.files()[0];
167.744 + break;
167.745 + default:
167.746 + std::cerr << "\nAt most one prefix can be given\n\n";
167.747 + exit(1);
167.748 + }
167.749 +
167.750 + double sum_sizes=0;
167.751 + std::vector<double> sizes;
167.752 + std::vector<double> cum_sizes;
167.753 + for(int s=0;s<num_of_cities;s++)
167.754 + {
167.755 + // sum_sizes+=rnd.exponential();
167.756 + double d=rnd();
167.757 + sum_sizes+=d;
167.758 + sizes.push_back(d);
167.759 + cum_sizes.push_back(sum_sizes);
167.760 + }
167.761 + int i=0;
167.762 + for(int s=0;s<num_of_cities;s++)
167.763 + {
167.764 + Point center=(num_of_cities==1?Point(0,0):rnd.disc());
167.765 + if(gauss_d)
167.766 + for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
167.767 + Node n=g.addNode();
167.768 + nodes.push_back(n);
167.769 + coords[n]=center+rnd.gauss2()*area*
167.770 + std::sqrt(sizes[s]/sum_sizes);
167.771 + }
167.772 + else if(square_d)
167.773 + for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
167.774 + Node n=g.addNode();
167.775 + nodes.push_back(n);
167.776 + coords[n]=center+Point(rnd()*2-1,rnd()*2-1)*area*
167.777 + std::sqrt(sizes[s]/sum_sizes);
167.778 + }
167.779 + else if(disc_d || true)
167.780 + for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
167.781 + Node n=g.addNode();
167.782 + nodes.push_back(n);
167.783 + coords[n]=center+rnd.disc()*area*
167.784 + std::sqrt(sizes[s]/sum_sizes);
167.785 + }
167.786 + }
167.787 +
167.788 +// for (ListGraph::NodeIt n(g); n != INVALID; ++n) {
167.789 +// std::cerr << coords[n] << std::endl;
167.790 +// }
167.791 +
167.792 + if(ap["tsp"]) {
167.793 + tsp();
167.794 + std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
167.795 + }
167.796 + if(ap["tsp2"]) {
167.797 + tsp2();
167.798 + std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
167.799 + }
167.800 + else if(ap["2con"]) {
167.801 + std::cout << "Make triangles\n";
167.802 + // triangle();
167.803 + sparseTriangle(ap["g"]);
167.804 + std::cout << "Make it sparser\n";
167.805 + sparse2(ap["g"]);
167.806 + }
167.807 + else if(ap["tree"]) {
167.808 + minTree();
167.809 + }
167.810 + else if(ap["dela"]) {
167.811 + delaunay();
167.812 + }
167.813 +
167.814 +
167.815 + std::cout << "Number of nodes : " << countNodes(g) << std::endl;
167.816 + std::cout << "Number of arcs : " << countEdges(g) << std::endl;
167.817 + double tlen=0;
167.818 + for(EdgeIt e(g);e!=INVALID;++e)
167.819 + tlen+=std::sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
167.820 + std::cout << "Total arc length : " << tlen << std::endl;
167.821 +
167.822 + if(ap["eps"])
167.823 + graphToEps(g,prefix+".eps").scaleToA4().
167.824 + scale(600).nodeScale(.005).arcWidthScale(.001).preScale(false).
167.825 + coords(coords).hideNodes(ap.given("nonodes")).run();
167.826 +
167.827 + if(ap["dir"])
167.828 + DigraphWriter<ListGraph>(g,prefix+".lgf").
167.829 + nodeMap("coordinates_x",scaleMap(xMap(coords),600)).
167.830 + nodeMap("coordinates_y",scaleMap(yMap(coords),600)).
167.831 + run();
167.832 + else GraphWriter<ListGraph>(g,prefix+".lgf").
167.833 + nodeMap("coordinates_x",scaleMap(xMap(coords),600)).
167.834 + nodeMap("coordinates_y",scaleMap(yMap(coords),600)).
167.835 + run();
167.836 +}
167.837 +