1.1 --- a/.hgignore Fri Nov 13 12:33:33 2009 +0100
1.2 +++ b/.hgignore Thu Dec 10 17:05:35 2009 +0100
1.3 @@ -22,11 +22,16 @@
1.4 lemon/libemon.la
1.5 lemon/stamp-h2
1.6 doc/Doxyfile
1.7 -cmake/cmake.version
1.8 +cmake/version.cmake
1.9 .dirstamp
1.10 .libs/*
1.11 .deps/*
1.12 demo/*.eps
1.13 +m4/libtool.m4
1.14 +m4/ltoptions.m4
1.15 +m4/ltsugar.m4
1.16 +m4/ltversion.m4
1.17 +m4/lt~obsolete.m4
1.18
1.19 syntax: regexp
1.20 (.*/)?\#[^/]*\#$
1.21 @@ -35,10 +40,11 @@
1.22 ^doc/.*\.tag
1.23 ^autom4te.cache/.*
1.24 ^build-aux/.*
1.25 -^objs.*/.*
1.26 +^.*objs.*/.*
1.27 ^test/[a-z_]*$
1.28 +^tools/[a-z-_]*$
1.29 ^demo/.*_demo$
1.30 -^build/.*
1.31 +^.*build.*/.*
1.32 ^doc/gen-images/.*
1.33 CMakeFiles
1.34 DartTestfile.txt
2.1 --- a/CMakeLists.txt Fri Nov 13 12:33:33 2009 +0100
2.2 +++ b/CMakeLists.txt Thu Dec 10 17:05:35 2009 +0100
2.3 @@ -1,37 +1,73 @@
2.4 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
2.5
2.6 -IF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
2.7 - INCLUDE(${CMAKE_SOURCE_DIR}/cmake/version.cmake)
2.8 -ELSE(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
2.9 - SET(PROJECT_NAME "LEMON")
2.10 - SET(PROJECT_VERSION "hg-tip" CACHE STRING "LEMON version string.")
2.11 -ENDIF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
2.12 -
2.13 +SET(PROJECT_NAME "LEMON")
2.14 PROJECT(${PROJECT_NAME})
2.15
2.16 -SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
2.17 +IF(EXISTS ${PROJECT_SOURCE_DIR}/cmake/version.cmake)
2.18 + INCLUDE(${PROJECT_SOURCE_DIR}/cmake/version.cmake)
2.19 +ELSEIF(DEFINED ENV{LEMON_VERSION})
2.20 + SET(LEMON_VERSION $ENV{LEMON_VERSION} CACHE STRING "LEMON version string.")
2.21 +ELSE()
2.22 + EXECUTE_PROCESS(
2.23 + COMMAND hg id -i
2.24 + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
2.25 + OUTPUT_VARIABLE HG_REVISION
2.26 + ERROR_QUIET
2.27 + OUTPUT_STRIP_TRAILING_WHITESPACE
2.28 + )
2.29 + IF(HG_REVISION STREQUAL "")
2.30 + SET(HG_REVISION "hg-tip")
2.31 + ENDIF()
2.32 + SET(LEMON_VERSION ${HG_REVISION} CACHE STRING "LEMON version string.")
2.33 +ENDIF()
2.34
2.35 -INCLUDE(FindDoxygen)
2.36 -INCLUDE(FindGhostscript)
2.37 +SET(PROJECT_VERSION ${LEMON_VERSION})
2.38
2.39 -ADD_DEFINITIONS(-DHAVE_CONFIG_H)
2.40 +SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
2.41 +
2.42 +FIND_PACKAGE(Doxygen)
2.43 +FIND_PACKAGE(Ghostscript)
2.44 +FIND_PACKAGE(GLPK 4.33)
2.45 +FIND_PACKAGE(CPLEX)
2.46 +FIND_PACKAGE(COIN)
2.47
2.48 INCLUDE(CheckTypeSize)
2.49 -CHECK_TYPE_SIZE("long long" LEMON_LONG_LONG)
2.50 +CHECK_TYPE_SIZE("long long" LONG_LONG)
2.51 +SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
2.52
2.53 ENABLE_TESTING()
2.54
2.55 ADD_SUBDIRECTORY(lemon)
2.56 -ADD_SUBDIRECTORY(demo)
2.57 -ADD_SUBDIRECTORY(doc)
2.58 -ADD_SUBDIRECTORY(test)
2.59 +IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
2.60 + ADD_SUBDIRECTORY(demo)
2.61 + ADD_SUBDIRECTORY(tools)
2.62 + ADD_SUBDIRECTORY(doc)
2.63 + ADD_SUBDIRECTORY(test)
2.64 +ENDIF()
2.65
2.66 -IF(WIN32)
2.67 +CONFIGURE_FILE(
2.68 + ${PROJECT_SOURCE_DIR}/cmake/LEMONConfig.cmake.in
2.69 + ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
2.70 + @ONLY
2.71 +)
2.72 +IF(UNIX)
2.73 + INSTALL(
2.74 + FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
2.75 + DESTINATION share/lemon/cmake
2.76 + )
2.77 +ELSEIF(WIN32)
2.78 + INSTALL(
2.79 + FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
2.80 + DESTINATION cmake
2.81 + )
2.82 +ENDIF()
2.83 +
2.84 +IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR} AND WIN32)
2.85 SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
2.86 SET(CPACK_PACKAGE_VENDOR "EGRES")
2.87 SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
2.88 - "LEMON - Library of Efficient Models and Optimization in Networks")
2.89 - SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
2.90 + "LEMON - Library for Efficient Modeling and Optimization in Networks")
2.91 + SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
2.92
2.93 SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
2.94
2.95 @@ -40,16 +76,19 @@
2.96 SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
2.97 "${PROJECT_NAME} ${PROJECT_VERSION}")
2.98
2.99 - SET(CPACK_COMPONENTS_ALL headers library html_documentation)
2.100 + SET(CPACK_COMPONENTS_ALL headers library html_documentation bin)
2.101
2.102 SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
2.103 SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
2.104 + SET(CPACK_COMPONENT_BIN_DISPLAY_NAME "Command line utilities")
2.105 SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
2.106
2.107 SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
2.108 "C++ header files")
2.109 SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
2.110 "DLL and import library")
2.111 + SET(CPACK_COMPONENT_BIN_DESCRIPTION
2.112 + "Command line utilities")
2.113 SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
2.114 "Doxygen generated documentation")
2.115
2.116 @@ -71,9 +110,9 @@
2.117 SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
2.118
2.119 SET(CPACK_GENERATOR "NSIS")
2.120 - SET(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/lemon.ico")
2.121 - SET(CPACK_NSIS_MUI_UNIICON "${CMAKE_SOURCE_DIR}/cmake/nsis/uninstall.ico")
2.122 - #SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
2.123 + SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis/lemon.ico")
2.124 + SET(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/cmake/nsis/uninstall.ico")
2.125 + #SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
2.126 SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico")
2.127 SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
2.128 SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu")
2.129 @@ -88,4 +127,4 @@
2.130 ")
2.131
2.132 INCLUDE(CPack)
2.133 -ENDIF(WIN32)
2.134 +ENDIF()
3.1 --- a/INSTALL Fri Nov 13 12:33:33 2009 +0100
3.2 +++ b/INSTALL Thu Dec 10 17:05:35 2009 +0100
3.3 @@ -27,8 +27,8 @@
3.4 3. `make'
3.5
3.6 This command compiles the non-template part of LEMON into libemon.a
3.7 - file. It also compiles the programs in the tools and demo subdirectories
3.8 - when enabled.
3.9 + file. It also compiles the programs in the tools subdirectory by
3.10 + default.
3.11
3.12 4. `make check'
3.13
3.14 @@ -75,14 +75,6 @@
3.15
3.16 Set the installation prefix to PREFIX. By default it is /usr/local.
3.17
3.18 ---enable-demo
3.19 -
3.20 - Build the examples in the demo subdirectory.
3.21 -
3.22 ---disable-demo
3.23 -
3.24 - Do not build the examples in the demo subdirectory (default).
3.25 -
3.26 --enable-tools
3.27
3.28 Build the programs in the tools subdirectory (default).
3.29 @@ -158,3 +150,26 @@
3.30 --without-soplex
3.31
3.32 Disable SoPlex support.
3.33 +
3.34 +--with-coin[=PREFIX]
3.35 +
3.36 + Enable support for COIN-OR solvers (CLP and CBC). You should
3.37 + specify the prefix too. (by default, COIN-OR tools install
3.38 + themselves to the source code directory). This command enables the
3.39 + solvers that are actually found.
3.40 +
3.41 +--with-coin-includedir=DIR
3.42 +
3.43 + The directory where the COIN-OR header files are located. This is
3.44 + only useful when the COIN-OR headers and libraries are not under
3.45 + the same prefix (which is unlikely).
3.46 +
3.47 +--with-coin-libdir=DIR
3.48 +
3.49 + The directory where the COIN-OR libraries are located. This is only
3.50 + useful when the COIN-OR headers and libraries are not under the
3.51 + same prefix (which is unlikely).
3.52 +
3.53 +--without-coin
3.54 +
3.55 + Disable COIN-OR support.
4.1 --- a/LICENSE Fri Nov 13 12:33:33 2009 +0100
4.2 +++ b/LICENSE Thu Dec 10 17:05:35 2009 +0100
4.3 @@ -1,7 +1,7 @@
4.4 LEMON code without an explicit copyright notice is covered by the following
4.5 copyright/license.
4.6
4.7 -Copyright (C) 2003-2008 Egervary Jeno Kombinatorikus Optimalizalasi
4.8 +Copyright (C) 2003-2009 Egervary Jeno Kombinatorikus Optimalizalasi
4.9 Kutatocsoport (Egervary Combinatorial Optimization Research Group,
4.10 EGRES).
4.11
5.1 --- a/Makefile.am Fri Nov 13 12:33:33 2009 +0100
5.2 +++ b/Makefile.am Thu Dec 10 17:05:35 2009 +0100
5.3 @@ -1,5 +1,7 @@
5.4 ACLOCAL_AMFLAGS = -I m4
5.5
5.6 +AM_CXXFLAGS = $(WARNINGCXXFLAGS)
5.7 +
5.8 AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
5.9 LDADD = $(top_builddir)/lemon/libemon.la
5.10
5.11 @@ -9,8 +11,12 @@
5.12 m4/lx_check_cplex.m4 \
5.13 m4/lx_check_glpk.m4 \
5.14 m4/lx_check_soplex.m4 \
5.15 + m4/lx_check_coin.m4 \
5.16 CMakeLists.txt \
5.17 cmake/FindGhostscript.cmake \
5.18 + cmake/FindCPLEX.cmake \
5.19 + cmake/FindGLPK.cmake \
5.20 + cmake/FindCOIN.cmake \
5.21 cmake/version.cmake.in \
5.22 cmake/version.cmake \
5.23 cmake/nsis/lemon.ico \
5.24 @@ -36,9 +42,13 @@
5.25 include lemon/Makefile.am
5.26 include test/Makefile.am
5.27 include doc/Makefile.am
5.28 -include demo/Makefile.am
5.29 include tools/Makefile.am
5.30
5.31 +DIST_SUBDIRS = demo
5.32 +
5.33 +demo:
5.34 + $(MAKE) $(AM_MAKEFLAGS) -C demo
5.35 +
5.36 MRPROPERFILES = \
5.37 aclocal.m4 \
5.38 config.h.in \
5.39 @@ -65,4 +75,4 @@
5.40 zcat $(PACKAGE)-$(VERSION).tar.gz | \
5.41 bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
5.42
5.43 -.PHONY: mrproper dist-bz2 distcheck-bz2
5.44 +.PHONY: demo mrproper dist-bz2 distcheck-bz2
6.1 --- a/NEWS Fri Nov 13 12:33:33 2009 +0100
6.2 +++ b/NEWS Thu Dec 10 17:05:35 2009 +0100
6.3 @@ -1,3 +1,90 @@
6.4 +2009-05-13 Version 1.1 released
6.5 +
6.6 + This is the second stable release of the 1.x series. It
6.7 + features a better coverage of the tools available in the 0.x
6.8 + series, a thoroughly reworked LP/MIP interface plus various
6.9 + improvements in the existing tools.
6.10 +
6.11 + * Much improved M$ Windows support
6.12 + * Various improvements in the CMAKE build system
6.13 + * Compilation warnings are fixed/suppressed
6.14 + * Support IBM xlC compiler
6.15 + * New algorithms
6.16 + * Connectivity related algorithms (#61)
6.17 + * Euler walks (#65)
6.18 + * Preflow push-relabel max. flow algorithm (#176)
6.19 + * Circulation algorithm (push-relabel based) (#175)
6.20 + * Suurballe algorithm (#47)
6.21 + * Gomory-Hu algorithm (#66)
6.22 + * Hao-Orlin algorithm (#58)
6.23 + * Edmond's maximum cardinality and weighted matching algorithms
6.24 + in general graphs (#48,#265)
6.25 + * Minimum cost arborescence/branching (#60)
6.26 + * Network Simplex min. cost flow algorithm (#234)
6.27 + * New data structures
6.28 + * Full graph structure (#57)
6.29 + * Grid graph structure (#57)
6.30 + * Hypercube graph structure (#57)
6.31 + * Graph adaptors (#67)
6.32 + * ArcSet and EdgeSet classes (#67)
6.33 + * Elevator class (#174)
6.34 + * Other new tools
6.35 + * LP/MIP interface (#44)
6.36 + * Support for GLPK, CPLEX, Soplex, COIN-OR CLP and CBC
6.37 + * Reader for the Nauty file format (#55)
6.38 + * DIMACS readers (#167)
6.39 + * Radix sort algorithms (#72)
6.40 + * RangeIdMap and CrossRefMap (#160)
6.41 + * New command line tools
6.42 + * DIMACS to LGF converter (#182)
6.43 + * lgf-gen - a graph generator (#45)
6.44 + * DIMACS solver utility (#226)
6.45 + * Other code improvements
6.46 + * Lognormal distribution added to Random (#102)
6.47 + * Better (i.e. O(1) time) item counting in SmartGraph (#3)
6.48 + * The standard maps of graphs are guaranteed to be
6.49 + reference maps (#190)
6.50 + * Miscellaneous
6.51 + * Various doc improvements
6.52 + * Improved 0.x -> 1.x converter script
6.53 +
6.54 + * Several bugfixes (compared to release 1.0):
6.55 + #170: Bugfix SmartDigraph::split()
6.56 + #171: Bugfix in SmartGraph::restoreSnapshot()
6.57 + #172: Extended test cases for graphs and digraphs
6.58 + #173: Bugfix in Random
6.59 + * operator()s always return a double now
6.60 + * the faulty real<Num>(Num) and real<Num>(Num,Num)
6.61 + have been removed
6.62 + #187: Remove DijkstraWidestPathOperationTraits
6.63 + #61: Bugfix in DfsVisit
6.64 + #193: Bugfix in GraphReader::skipSection()
6.65 + #195: Bugfix in ConEdgeIt()
6.66 + #197: Bugfix in heap unionfind
6.67 + * This bug affects Edmond's general matching algorithms
6.68 + #207: Fix 'make install' without 'make html' using CMAKE
6.69 + #208: Suppress or fix VS2008 compilation warnings
6.70 + ----: Update the LEMON icon
6.71 + ----: Enable the component-based installer
6.72 + (in installers made by CPACK)
6.73 + ----: Set the proper version for CMAKE in the tarballs
6.74 + (made by autotools)
6.75 + ----: Minor clarification in the LICENSE file
6.76 + ----: Add missing unistd.h include to time_measure.h
6.77 + #204: Compilation bug fixed in graph_to_eps.h with VS2005
6.78 + #214,#215: windows.h should never be included by lemon headers
6.79 + #230: Build systems check the availability of 'long long' type
6.80 + #229: Default implementation of Tolerance<> is used for integer types
6.81 + #211,#212: Various fixes for compiling on AIX
6.82 + ----: Improvements in CMAKE config
6.83 + - docs is installed in share/doc/
6.84 + - detects newer versions of Ghostscript
6.85 + #239: Fix missing 'inline' specifier in time_measure.h
6.86 + #274,#280: Install lemon/config.h
6.87 + #275: Prefix macro names with LEMON_ in lemon/config.h
6.88 + ----: Small script for making the release tarballs added
6.89 + ----: Minor improvement in unify-sources.sh (a76f55d7d397)
6.90 +
6.91 2009-03-27 LEMON joins to the COIN-OR initiative
6.92
6.93 COIN-OR (Computational Infrastructure for Operations Research,
7.1 --- a/README Fri Nov 13 12:33:33 2009 +0100
7.2 +++ b/README Thu Dec 10 17:05:35 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 Dec 10 17:05:35 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 Dec 10 17:05:35 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 Dec 10 17:05:35 2009 +0100
10.3 @@ -0,0 +1,61 @@
10.4 +SET(GLPK_ROOT_DIR "" CACHE PATH "GLPK root directory")
10.5 +
10.6 +SET(GLPK_REGKEY "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Glpk;InstallPath]")
10.7 +GET_FILENAME_COMPONENT(GLPK_ROOT_PATH ${GLPK_REGKEY} ABSOLUTE)
10.8 +
10.9 +FIND_PATH(GLPK_INCLUDE_DIR
10.10 + glpk.h
10.11 + PATHS ${GLPK_REGKEY}/include
10.12 + HINTS ${GLPK_ROOT_DIR}/include
10.13 +)
10.14 +FIND_LIBRARY(GLPK_LIBRARY
10.15 + glpk
10.16 + PATHS ${GLPK_REGKEY}/lib
10.17 + HINTS ${GLPK_ROOT_DIR}/lib
10.18 +)
10.19 +
10.20 +IF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY)
10.21 + FILE(READ ${GLPK_INCLUDE_DIR}/glpk.h GLPK_GLPK_H)
10.22 +
10.23 + STRING(REGEX MATCH "define[ ]+GLP_MAJOR_VERSION[ ]+[0-9]+" GLPK_MAJOR_VERSION_LINE "${GLPK_GLPK_H}")
10.24 + STRING(REGEX REPLACE "define[ ]+GLP_MAJOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MAJOR "${GLPK_MAJOR_VERSION_LINE}")
10.25 +
10.26 + STRING(REGEX MATCH "define[ ]+GLP_MINOR_VERSION[ ]+[0-9]+" GLPK_MINOR_VERSION_LINE "${GLPK_GLPK_H}")
10.27 + STRING(REGEX REPLACE "define[ ]+GLP_MINOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MINOR "${GLPK_MINOR_VERSION_LINE}")
10.28 +
10.29 + SET(GLPK_VERSION_STRING "${GLPK_VERSION_MAJOR}.${GLPK_VERSION_MINOR}")
10.30 +
10.31 + IF(GLPK_FIND_VERSION)
10.32 + IF(GLPK_FIND_VERSION_COUNT GREATER 2)
10.33 + MESSAGE(SEND_ERROR "unexpected version string")
10.34 + ENDIF(GLPK_FIND_VERSION_COUNT GREATER 2)
10.35 +
10.36 + MATH(EXPR GLPK_REQUESTED_VERSION "${GLPK_FIND_VERSION_MAJOR}*100 + ${GLPK_FIND_VERSION_MINOR}")
10.37 + MATH(EXPR GLPK_FOUND_VERSION "${GLPK_VERSION_MAJOR}*100 + ${GLPK_VERSION_MINOR}")
10.38 +
10.39 + IF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
10.40 + SET(GLPK_PROPER_VERSION_FOUND FALSE)
10.41 + ELSE(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
10.42 + SET(GLPK_PROPER_VERSION_FOUND TRUE)
10.43 + ENDIF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
10.44 + ELSE(GLPK_FIND_VERSION)
10.45 + SET(GLPK_PROPER_VERSION_FOUND TRUE)
10.46 + ENDIF(GLPK_FIND_VERSION)
10.47 +ENDIF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY)
10.48 +
10.49 +INCLUDE(FindPackageHandleStandardArgs)
10.50 +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLPK DEFAULT_MSG GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_PROPER_VERSION_FOUND)
10.51 +
10.52 +IF(GLPK_FOUND)
10.53 + SET(GLPK_INCLUDE_DIRS ${GLPK_INCLUDE_DIR})
10.54 + SET(GLPK_LIBRARIES ${GLPK_LIBRARY})
10.55 + SET(GLPK_BIN_DIR ${GLPK_ROOT_PATH}/bin)
10.56 +ENDIF(GLPK_FOUND)
10.57 +
10.58 +MARK_AS_ADVANCED(GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_BIN_DIR)
10.59 +
10.60 +IF(GLPK_FOUND)
10.61 + SET(LEMON_HAVE_LP TRUE)
10.62 + SET(LEMON_HAVE_MIP TRUE)
10.63 + SET(LEMON_HAVE_GLPK TRUE)
10.64 +ENDIF(GLPK_FOUND)
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/cmake/LEMONConfig.cmake.in Thu Dec 10 17:05:35 2009 +0100
11.3 @@ -0,0 +1,13 @@
11.4 +SET(LEMON_INCLUDE_DIR "@CMAKE_INSTALL_PREFIX@/include" CACHE PATH "LEMON include directory")
11.5 +SET(LEMON_INCLUDE_DIRS "${LEMON_INCLUDE_DIR}")
11.6 +
11.7 +IF(UNIX)
11.8 + SET(LEMON_LIB_NAME "libemon.a")
11.9 +ELSEIF(WIN32)
11.10 + SET(LEMON_LIB_NAME "lemon.lib")
11.11 +ENDIF(UNIX)
11.12 +
11.13 +SET(LEMON_LIBRARY "@CMAKE_INSTALL_PREFIX@/lib/${LEMON_LIB_NAME}" CACHE FILEPATH "LEMON library")
11.14 +SET(LEMON_LIBRARIES "${LEMON_LIBRARY}")
11.15 +
11.16 +MARK_AS_ADVANCED(LEMON_LIBRARY LEMON_INCLUDE_DIR)
12.1 --- a/cmake/version.cmake.in Fri Nov 13 12:33:33 2009 +0100
12.2 +++ b/cmake/version.cmake.in Thu Dec 10 17:05:35 2009 +0100
12.3 @@ -1,2 +1,1 @@
12.4 -SET(PROJECT_NAME "@PACKAGE_NAME@")
12.5 -SET(PROJECT_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.")
12.6 +SET(LEMON_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.")
13.1 --- a/configure.ac Fri Nov 13 12:33:33 2009 +0100
13.2 +++ b/configure.ac Thu Dec 10 17:05:35 2009 +0100
13.3 @@ -2,14 +2,17 @@
13.4
13.5 dnl Version information.
13.6 m4_define([lemon_version_number],
13.7 - [m4_normalize(esyscmd([echo ${LEMON_VERSION}]))])
13.8 + [m4_normalize(esyscmd([echo ${LEMON_VERSION}]))])
13.9 dnl m4_define([lemon_version_number], [])
13.10 m4_define([lemon_hg_path], [m4_normalize(esyscmd([./scripts/chg-len.py]))])
13.11 -m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i]))])
13.12 +m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i 2> /dev/null]))])
13.13 m4_define([lemon_version], [ifelse(lemon_version_number(),
13.14 - [],
13.15 - [lemon_hg_path().lemon_hg_revision()],
13.16 - [lemon_version_number()])])
13.17 + [],
13.18 + [ifelse(lemon_hg_revision(),
13.19 + [],
13.20 + [hg-tip],
13.21 + [lemon_hg_path().lemon_hg_revision()])],
13.22 + [lemon_version_number()])])
13.23
13.24 AC_PREREQ([2.59])
13.25 AC_INIT([LEMON], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon])
13.26 @@ -19,7 +22,7 @@
13.27 AC_CONFIG_SRCDIR([lemon/list_graph.h])
13.28 AC_CONFIG_HEADERS([config.h lemon/config.h])
13.29
13.30 -lx_cmdline_cxxflags_set=${CXXFLAGS+set}
13.31 +AC_DEFINE([LEMON_VERSION], [lemon_version()], [The version string])
13.32
13.33 dnl Do compilation tests using the C++ compiler.
13.34 AC_LANG([C++])
13.35 @@ -52,27 +55,19 @@
13.36 fi
13.37
13.38 dnl Set custom compiler flags when using g++.
13.39 -if test x"$lx_cmdline_cxxflags_set" != x"set" -a "$GXX" = yes -a "$ICC" = no; then
13.40 - CXXFLAGS="$CXXFLAGS -Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
13.41 +if test "$GXX" = yes -a "$ICC" = no; then
13.42 + WARNINGCXXFLAGS="-Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
13.43 fi
13.44 +AC_SUBST([WARNINGCXXFLAGS])
13.45
13.46 dnl Checks for libraries.
13.47 -#LX_CHECK_GLPK
13.48 -#LX_CHECK_CPLEX
13.49 -#LX_CHECK_SOPLEX
13.50 +LX_CHECK_GLPK
13.51 +LX_CHECK_CPLEX
13.52 +LX_CHECK_SOPLEX
13.53 +LX_CHECK_COIN
13.54
13.55 -dnl Disable/enable building the demo programs.
13.56 -AC_ARG_ENABLE([demo],
13.57 -AS_HELP_STRING([--enable-demo], [build the demo programs])
13.58 -AS_HELP_STRING([--disable-demo], [do not build the demo programs @<:@default@:>@]),
13.59 - [], [enable_demo=no])
13.60 -AC_MSG_CHECKING([whether to build the demo programs])
13.61 -if test x"$enable_demo" != x"no"; then
13.62 - AC_MSG_RESULT([yes])
13.63 -else
13.64 - AC_MSG_RESULT([no])
13.65 -fi
13.66 -AM_CONDITIONAL([WANT_DEMO], [test x"$enable_demo" != x"no"])
13.67 +AM_CONDITIONAL([HAVE_LP], [test x"$lx_lp_found" = x"yes"])
13.68 +AM_CONDITIONAL([HAVE_MIP], [test x"$lx_mip_found" = x"yes"])
13.69
13.70 dnl Disable/enable building the binary tools.
13.71 AC_ARG_ENABLE([tools],
13.72 @@ -107,6 +102,7 @@
13.73
13.74 AC_CONFIG_FILES([
13.75 Makefile
13.76 +demo/Makefile
13.77 cmake/version.cmake
13.78 doc/Doxyfile
13.79 lemon/lemon.pc
13.80 @@ -120,15 +116,16 @@
13.81 echo Package version............... : $PACKAGE-$VERSION
13.82 echo
13.83 echo C++ compiler.................. : $CXX
13.84 -echo C++ compiles flags............ : $CXXFLAGS
13.85 +echo C++ compiles flags............ : $WARNINGCXXFLAGS $CXXFLAGS
13.86 echo
13.87 echo Compiler supports long long... : $long_long_found
13.88 echo
13.89 -#echo GLPK support.................. : $lx_glpk_found
13.90 -#echo CPLEX support................. : $lx_cplex_found
13.91 -#echo SOPLEX support................ : $lx_soplex_found
13.92 -#echo
13.93 -echo Build demo programs........... : $enable_demo
13.94 +echo GLPK support.................. : $lx_glpk_found
13.95 +echo CPLEX support................. : $lx_cplex_found
13.96 +echo SOPLEX support................ : $lx_soplex_found
13.97 +echo CLP support................... : $lx_clp_found
13.98 +echo CBC support................... : $lx_cbc_found
13.99 +echo
13.100 echo Build additional tools........ : $enable_tools
13.101 echo
13.102 echo The packace will be installed in
14.1 --- a/demo/CMakeLists.txt Fri Nov 13 12:33:33 2009 +0100
14.2 +++ b/demo/CMakeLists.txt Thu Dec 10 17:05:35 2009 +0100
14.3 @@ -1,16 +1,19 @@
14.4 INCLUDE_DIRECTORIES(
14.5 - ${CMAKE_SOURCE_DIR}
14.6 + ${PROJECT_SOURCE_DIR}
14.7 ${PROJECT_BINARY_DIR}
14.8 )
14.9
14.10 -LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
14.11 +LINK_DIRECTORIES(
14.12 + ${PROJECT_BINARY_DIR}/lemon
14.13 +)
14.14
14.15 SET(DEMOS
14.16 arg_parser_demo
14.17 graph_to_eps_demo
14.18 - lgf_demo)
14.19 + lgf_demo
14.20 +)
14.21
14.22 FOREACH(DEMO_NAME ${DEMOS})
14.23 ADD_EXECUTABLE(${DEMO_NAME} ${DEMO_NAME}.cc)
14.24 TARGET_LINK_LIBRARIES(${DEMO_NAME} lemon)
14.25 -ENDFOREACH(DEMO_NAME)
14.26 +ENDFOREACH()
15.1 --- a/demo/Makefile.am Fri Nov 13 12:33:33 2009 +0100
15.2 +++ b/demo/Makefile.am Thu Dec 10 17:05:35 2009 +0100
15.3 @@ -1,16 +1,17 @@
15.4 -EXTRA_DIST += \
15.5 - demo/CMakeLists.txt \
15.6 - demo/digraph.lgf
15.7 +AM_CXXFLAGS = $(WARNINGCXXFLAGS)
15.8
15.9 -if WANT_DEMO
15.10 +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
15.11 +LDADD = $(top_builddir)/lemon/libemon.la
15.12
15.13 -noinst_PROGRAMS += \
15.14 - demo/arg_parser_demo \
15.15 - demo/graph_to_eps_demo \
15.16 - demo/lgf_demo
15.17 +EXTRA_DIST = \
15.18 + CMakeLists.txt \
15.19 + digraph.lgf
15.20
15.21 -endif WANT_DEMO
15.22 +noinst_PROGRAMS = \
15.23 + arg_parser_demo \
15.24 + graph_to_eps_demo \
15.25 + lgf_demo
15.26
15.27 -demo_arg_parser_demo_SOURCES = demo/arg_parser_demo.cc
15.28 -demo_graph_to_eps_demo_SOURCES = demo/graph_to_eps_demo.cc
15.29 -demo_lgf_demo_SOURCES = demo/lgf_demo.cc
15.30 +arg_parser_demo_SOURCES = arg_parser_demo.cc
15.31 +graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc
15.32 +lgf_demo_SOURCES = lgf_demo.cc
16.1 --- a/demo/arg_parser_demo.cc Fri Nov 13 12:33:33 2009 +0100
16.2 +++ b/demo/arg_parser_demo.cc Thu Dec 10 17:05:35 2009 +0100
16.3 @@ -2,7 +2,7 @@
16.4 *
16.5 * This file is a part of LEMON, a generic C++ optimization library.
16.6 *
16.7 - * Copyright (C) 2003-2008
16.8 + * Copyright (C) 2003-2009
16.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
16.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
16.11 *
17.1 --- a/demo/graph_to_eps_demo.cc Fri Nov 13 12:33:33 2009 +0100
17.2 +++ b/demo/graph_to_eps_demo.cc Thu Dec 10 17:05:35 2009 +0100
17.3 @@ -2,7 +2,7 @@
17.4 *
17.5 * This file is a part of LEMON, a generic C++ optimization library.
17.6 *
17.7 - * Copyright (C) 2003-2008
17.8 + * Copyright (C) 2003-2009
17.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
17.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
17.11 *
17.12 @@ -85,14 +85,14 @@
17.13 graphToEps(g,"graph_to_eps_demo_out_1_pure.eps").
17.14 coords(coords).
17.15 title("Sample .eps figure").
17.16 - copyright("(C) 2003-2008 LEMON Project").
17.17 + copyright("(C) 2003-2009 LEMON Project").
17.18 run();
17.19
17.20 cout << "Create 'graph_to_eps_demo_out_2.eps'" << endl;
17.21 graphToEps(g,"graph_to_eps_demo_out_2.eps").
17.22 coords(coords).
17.23 title("Sample .eps figure").
17.24 - copyright("(C) 2003-2008 LEMON Project").
17.25 + copyright("(C) 2003-2009 LEMON Project").
17.26 absoluteNodeSizes().absoluteArcWidths().
17.27 nodeScale(2).nodeSizes(sizes).
17.28 nodeShapes(shapes).
17.29 @@ -105,7 +105,7 @@
17.30 cout << "Create 'graph_to_eps_demo_out_3_arr.eps'" << endl;
17.31 graphToEps(g,"graph_to_eps_demo_out_3_arr.eps").
17.32 title("Sample .eps figure (with arrowheads)").
17.33 - copyright("(C) 2003-2008 LEMON Project").
17.34 + copyright("(C) 2003-2009 LEMON Project").
17.35 absoluteNodeSizes().absoluteArcWidths().
17.36 nodeColors(composeMap(palette,colors)).
17.37 coords(coords).
17.38 @@ -132,7 +132,7 @@
17.39 cout << "Create 'graph_to_eps_demo_out_4_par.eps'" << endl;
17.40 graphToEps(g,"graph_to_eps_demo_out_4_par.eps").
17.41 title("Sample .eps figure (parallel arcs)").
17.42 - copyright("(C) 2003-2008 LEMON Project").
17.43 + copyright("(C) 2003-2009 LEMON Project").
17.44 absoluteNodeSizes().absoluteArcWidths().
17.45 nodeShapes(shapes).
17.46 coords(coords).
17.47 @@ -147,7 +147,7 @@
17.48 cout << "Create 'graph_to_eps_demo_out_5_par_arr.eps'" << endl;
17.49 graphToEps(g,"graph_to_eps_demo_out_5_par_arr.eps").
17.50 title("Sample .eps figure (parallel arcs and arrowheads)").
17.51 - copyright("(C) 2003-2008 LEMON Project").
17.52 + copyright("(C) 2003-2009 LEMON Project").
17.53 absoluteNodeSizes().absoluteArcWidths().
17.54 nodeScale(2).nodeSizes(sizes).
17.55 coords(coords).
17.56 @@ -163,7 +163,7 @@
17.57 cout << "Create 'graph_to_eps_demo_out_6_par_arr_a4.eps'" << endl;
17.58 graphToEps(g,"graph_to_eps_demo_out_6_par_arr_a4.eps").
17.59 title("Sample .eps figure (fits to A4)").
17.60 - copyright("(C) 2003-2008 LEMON Project").
17.61 + copyright("(C) 2003-2009 LEMON Project").
17.62 scaleToA4().
17.63 absoluteNodeSizes().absoluteArcWidths().
17.64 nodeScale(2).nodeSizes(sizes).
17.65 @@ -182,7 +182,7 @@
17.66 ListDigraph::NodeMap<int> hcolors(h);
17.67 ListDigraph::NodeMap<Point> hcoords(h);
17.68
17.69 - int cols=int(sqrt(double(palette.size())));
17.70 + int cols=int(std::sqrt(double(palette.size())));
17.71 for(int i=0;i<int(paletteW.size());i++) {
17.72 Node n=h.addNode();
17.73 hcoords[n]=Point(1+i%cols,1+i/cols);
17.74 @@ -193,7 +193,7 @@
17.75 graphToEps(h,"graph_to_eps_demo_out_7_colors.eps").
17.76 scale(60).
17.77 title("Sample .eps figure (Palette demo)").
17.78 - copyright("(C) 2003-2008 LEMON Project").
17.79 + copyright("(C) 2003-2009 LEMON Project").
17.80 coords(hcoords).
17.81 absoluteNodeSizes().absoluteArcWidths().
17.82 nodeScale(.45).
18.1 --- a/demo/lgf_demo.cc Fri Nov 13 12:33:33 2009 +0100
18.2 +++ b/demo/lgf_demo.cc Thu Dec 10 17:05:35 2009 +0100
18.3 @@ -2,7 +2,7 @@
18.4 *
18.5 * This file is a part of LEMON, a generic C++ optimization library.
18.6 *
18.7 - * Copyright (C) 2003-2008
18.8 + * Copyright (C) 2003-2009
18.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
18.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
18.11 *
19.1 --- a/doc/CMakeLists.txt Fri Nov 13 12:33:33 2009 +0100
19.2 +++ b/doc/CMakeLists.txt Thu Dec 10 17:05:35 2009 +0100
19.3 @@ -1,42 +1,51 @@
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 FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
19.22 + SET(GHOSTSCRIPT_OPTIONS -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha)
19.23 + ADD_CUSTOM_TARGET(html
19.24 + COMMAND ${CMAKE_COMMAND} -E remove_directory gen-images
19.25 + COMMAND ${CMAKE_COMMAND} -E make_directory gen-images
19.26 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps
19.27 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps
19.28 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps
19.29 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
19.30 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
19.31 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
19.32 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
19.33 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
19.34 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
19.35 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
19.36 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
19.37 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
19.38 + COMMAND ${CMAKE_COMMAND} -E remove_directory html
19.39 + COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
19.40 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
19.41 + )
19.42 +
19.43 + SET_TARGET_PROPERTIES(html PROPERTIES PROJECT_LABEL BUILD_DOC)
19.44 +
19.45 IF(UNIX)
19.46 - ADD_CUSTOM_TARGET(html
19.47 - COMMAND rm -rf gen-images
19.48 - COMMAND mkdir gen-images
19.49 - 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.50 - 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.51 - 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.52 - 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.53 - 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.54 - COMMAND rm -rf html
19.55 - COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
19.56 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
19.57 + INSTALL(
19.58 + DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
19.59 + DESTINATION share/doc/lemon/html
19.60 + COMPONENT html_documentation
19.61 + )
19.62 ELSEIF(WIN32)
19.63 - ADD_CUSTOM_TARGET(html
19.64 - COMMAND if exist gen-images rmdir /s /q gen-images
19.65 - COMMAND mkdir gen-images
19.66 - 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.67 - 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.68 - 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.69 - 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.70 - 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.71 - COMMAND if exist html rmdir /s /q html
19.72 - COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
19.73 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
19.74 - ENDIF(UNIX)
19.75 - INSTALL(
19.76 - DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
19.77 - DESTINATION share/doc
19.78 - COMPONENT html_documentation)
19.79 -ENDIF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
19.80 + INSTALL(
19.81 + DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
19.82 + DESTINATION doc
19.83 + COMPONENT html_documentation
19.84 + )
19.85 + ENDIF()
19.86 +
19.87 +ENDIF()
20.1 --- a/doc/Doxyfile.in Fri Nov 13 12:33:33 2009 +0100
20.2 +++ b/doc/Doxyfile.in Thu Dec 10 17:05:35 2009 +0100
20.3 @@ -66,7 +66,7 @@
20.4 GENERATE_DEPRECATEDLIST= YES
20.5 ENABLED_SECTIONS =
20.6 MAX_INITIALIZER_LINES = 5
20.7 -SHOW_USED_FILES = YES
20.8 +SHOW_USED_FILES = NO
20.9 SHOW_DIRECTORIES = YES
20.10 SHOW_FILES = YES
20.11 SHOW_NAMESPACES = YES
21.1 --- a/doc/Makefile.am Fri Nov 13 12:33:33 2009 +0100
21.2 +++ b/doc/Makefile.am Thu Dec 10 17:05:35 2009 +0100
21.3 @@ -8,20 +8,31 @@
21.4 doc/license.dox \
21.5 doc/mainpage.dox \
21.6 doc/migration.dox \
21.7 + doc/min_cost_flow.dox \
21.8 doc/named-param.dox \
21.9 doc/namespaces.dox \
21.10 doc/html \
21.11 doc/CMakeLists.txt
21.12
21.13 DOC_EPS_IMAGES18 = \
21.14 + grid_graph.eps \
21.15 nodeshape_0.eps \
21.16 nodeshape_1.eps \
21.17 nodeshape_2.eps \
21.18 nodeshape_3.eps \
21.19 nodeshape_4.eps
21.20
21.21 +DOC_EPS_IMAGES27 = \
21.22 + bipartite_matching.eps \
21.23 + bipartite_partitions.eps \
21.24 + connected_components.eps \
21.25 + edge_biconnected_components.eps \
21.26 + node_biconnected_components.eps \
21.27 + strongly_connected_components.eps
21.28 +
21.29 DOC_EPS_IMAGES = \
21.30 - $(DOC_EPS_IMAGES18)
21.31 + $(DOC_EPS_IMAGES18) \
21.32 + $(DOC_EPS_IMAGES27)
21.33
21.34 DOC_PNG_IMAGES = \
21.35 $(DOC_EPS_IMAGES:%.eps=doc/gen-images/%.png)
21.36 @@ -44,6 +55,17 @@
21.37 exit 1; \
21.38 fi
21.39
21.40 +$(DOC_EPS_IMAGES27:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
21.41 + -mkdir doc/gen-images
21.42 + if test ${gs_found} = yes; then \
21.43 + $(GS_COMMAND) -sDEVICE=pngalpha -r27 -sOutputFile=$@ $<; \
21.44 + else \
21.45 + echo; \
21.46 + echo "Ghostscript not found."; \
21.47 + echo; \
21.48 + exit 1; \
21.49 + fi
21.50 +
21.51 html-local: $(DOC_PNG_IMAGES)
21.52 if test ${doxygen_found} = yes; then \
21.53 cd doc; \
21.54 @@ -69,19 +91,19 @@
21.55
21.56 install-html-local: doc/html
21.57 @$(NORMAL_INSTALL)
21.58 - $(mkinstalldirs) $(DESTDIR)$(htmldir)/docs
21.59 + $(mkinstalldirs) $(DESTDIR)$(htmldir)/html
21.60 for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
21.61 f="`echo $$p | sed -e 's|^.*/||'`"; \
21.62 - echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/docs/$$f"; \
21.63 - $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/docs/$$f; \
21.64 + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f"; \
21.65 + $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f; \
21.66 done
21.67
21.68 uninstall-local:
21.69 @$(NORMAL_UNINSTALL)
21.70 for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
21.71 f="`echo $$p | sed -e 's|^.*/||'`"; \
21.72 - echo " rm -f $(DESTDIR)$(htmldir)/docs/$$f"; \
21.73 - rm -f $(DESTDIR)$(htmldir)/docs/$$f; \
21.74 + echo " rm -f $(DESTDIR)$(htmldir)/html/$$f"; \
21.75 + rm -f $(DESTDIR)$(htmldir)/html/$$f; \
21.76 done
21.77
21.78 .PHONY: update-external-tags
22.1 --- a/doc/coding_style.dox Fri Nov 13 12:33:33 2009 +0100
22.2 +++ b/doc/coding_style.dox Thu Dec 10 17:05:35 2009 +0100
22.3 @@ -2,7 +2,7 @@
22.4 *
22.5 * This file is a part of LEMON, a generic C++ optimization library.
22.6 *
22.7 - * Copyright (C) 2003-2008
22.8 + * Copyright (C) 2003-2009
22.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
22.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
22.11 *
23.1 --- a/doc/dirs.dox Fri Nov 13 12:33:33 2009 +0100
23.2 +++ b/doc/dirs.dox Thu Dec 10 17:05:35 2009 +0100
23.3 @@ -2,7 +2,7 @@
23.4 *
23.5 * This file is a part of LEMON, a generic C++ optimization library.
23.6 *
23.7 - * Copyright (C) 2003-2008
23.8 + * Copyright (C) 2003-2009
23.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
23.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
23.11 *
23.12 @@ -71,7 +71,7 @@
23.13 \dir bits
23.14 \brief Auxiliary tools for implementation.
23.15
23.16 -This directory contains some auxiliary classes for implementing graphs,
23.17 +This directory contains some auxiliary classes for implementing graphs,
23.18 maps and some other classes.
23.19 As a user you typically don't have to deal with these files.
23.20 */
24.1 --- a/doc/groups.dox Fri Nov 13 12:33:33 2009 +0100
24.2 +++ b/doc/groups.dox Thu Dec 10 17:05:35 2009 +0100
24.3 @@ -2,7 +2,7 @@
24.4 *
24.5 * This file is a part of LEMON, a generic C++ optimization library.
24.6 *
24.7 - * Copyright (C) 2003-2008
24.8 + * Copyright (C) 2003-2009
24.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
24.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
24.11 *
24.12 @@ -16,9 +16,11 @@
24.13 *
24.14 */
24.15
24.16 +namespace lemon {
24.17 +
24.18 /**
24.19 @defgroup datas Data Structures
24.20 -This group describes the several data structures implemented in LEMON.
24.21 +This group contains the several data structures implemented in LEMON.
24.22 */
24.23
24.24 /**
24.25 @@ -60,13 +62,79 @@
24.26 */
24.27
24.28 /**
24.29 -@defgroup semi_adaptors Semi-Adaptor Classes for Graphs
24.30 +@defgroup graph_adaptors Adaptor Classes for Graphs
24.31 @ingroup graphs
24.32 -\brief Graph types between real graphs and graph adaptors.
24.33 +\brief Adaptor classes for digraphs and graphs
24.34
24.35 -This group describes some graph types between real graphs and graph adaptors.
24.36 -These classes wrap graphs to give new functionality as the adaptors do it.
24.37 -On the other hand they are not light-weight structures as the adaptors.
24.38 +This group contains several useful adaptor classes for digraphs and graphs.
24.39 +
24.40 +The main parts of LEMON are the different graph structures, generic
24.41 +graph algorithms, graph concepts, which couple them, and graph
24.42 +adaptors. While the previous notions are more or less clear, the
24.43 +latter one needs further explanation. Graph adaptors are graph classes
24.44 +which serve for considering graph structures in different ways.
24.45 +
24.46 +A short example makes this much clearer. Suppose that we have an
24.47 +instance \c g of a directed graph type, say ListDigraph and an algorithm
24.48 +\code
24.49 +template <typename Digraph>
24.50 +int algorithm(const Digraph&);
24.51 +\endcode
24.52 +is needed to run on the reverse oriented graph. It may be expensive
24.53 +(in time or in memory usage) to copy \c g with the reversed
24.54 +arcs. In this case, an adaptor class is used, which (according
24.55 +to LEMON \ref concepts::Digraph "digraph concepts") works as a digraph.
24.56 +The adaptor uses the original digraph structure and digraph operations when
24.57 +methods of the reversed oriented graph are called. This means that the adaptor
24.58 +have minor memory usage, and do not perform sophisticated algorithmic
24.59 +actions. The purpose of it is to give a tool for the cases when a
24.60 +graph have to be used in a specific alteration. If this alteration is
24.61 +obtained by a usual construction like filtering the node or the arc set or
24.62 +considering a new orientation, then an adaptor is worthwhile to use.
24.63 +To come back to the reverse oriented graph, in this situation
24.64 +\code
24.65 +template<typename Digraph> class ReverseDigraph;
24.66 +\endcode
24.67 +template class can be used. The code looks as follows
24.68 +\code
24.69 +ListDigraph g;
24.70 +ReverseDigraph<ListDigraph> rg(g);
24.71 +int result = algorithm(rg);
24.72 +\endcode
24.73 +During running the algorithm, the original digraph \c g is untouched.
24.74 +This techniques give rise to an elegant code, and based on stable
24.75 +graph adaptors, complex algorithms can be implemented easily.
24.76 +
24.77 +In flow, circulation and matching problems, the residual
24.78 +graph is of particular importance. Combining an adaptor implementing
24.79 +this with shortest path algorithms or minimum mean cycle algorithms,
24.80 +a range of weighted and cardinality optimization algorithms can be
24.81 +obtained. For other examples, the interested user is referred to the
24.82 +detailed documentation of particular adaptors.
24.83 +
24.84 +The behavior of graph adaptors can be very different. Some of them keep
24.85 +capabilities of the original graph while in other cases this would be
24.86 +meaningless. This means that the concepts that they meet depend
24.87 +on the graph adaptor, and the wrapped graph.
24.88 +For example, if an arc of a reversed digraph is deleted, this is carried
24.89 +out by deleting the corresponding arc of the original digraph, thus the
24.90 +adaptor modifies the original digraph.
24.91 +However in case of a residual digraph, this operation has no sense.
24.92 +
24.93 +Let us stand one more example here to simplify your work.
24.94 +ReverseDigraph has constructor
24.95 +\code
24.96 +ReverseDigraph(Digraph& digraph);
24.97 +\endcode
24.98 +This means that in a situation, when a <tt>const %ListDigraph&</tt>
24.99 +reference to a graph is given, then it have to be instantiated with
24.100 +<tt>Digraph=const %ListDigraph</tt>.
24.101 +\code
24.102 +int algorithm1(const ListDigraph& g) {
24.103 + ReverseDigraph<const ListDigraph> rg(g);
24.104 + return algorithm2(rg);
24.105 +}
24.106 +\endcode
24.107 */
24.108
24.109 /**
24.110 @@ -74,7 +142,7 @@
24.111 @ingroup datas
24.112 \brief Map structures implemented in LEMON.
24.113
24.114 -This group describes the map structures implemented in LEMON.
24.115 +This group contains the map structures implemented in LEMON.
24.116
24.117 LEMON provides several special purpose maps and map adaptors that e.g. combine
24.118 new maps from existing ones.
24.119 @@ -87,8 +155,11 @@
24.120 @ingroup maps
24.121 \brief Special graph-related maps.
24.122
24.123 -This group describes maps that are specifically designed to assign
24.124 -values to the nodes and arcs of graphs.
24.125 +This group contains maps that are specifically designed to assign
24.126 +values to the nodes and arcs/edges of graphs.
24.127 +
24.128 +If you are looking for the standard graph maps (\c NodeMap, \c ArcMap,
24.129 +\c EdgeMap), see the \ref graph_concepts "Graph Structure Concepts".
24.130 */
24.131
24.132 /**
24.133 @@ -96,10 +167,10 @@
24.134 \ingroup maps
24.135 \brief Tools to create new maps from existing ones
24.136
24.137 -This group describes map adaptors that are used to create "implicit"
24.138 +This group contains map adaptors that are used to create "implicit"
24.139 maps from other maps.
24.140
24.141 -Most of them are \ref lemon::concepts::ReadMap "read-only maps".
24.142 +Most of them are \ref concepts::ReadMap "read-only maps".
24.143 They can make arithmetic and logical operations between one or two maps
24.144 (negation, shifting, addition, multiplication, logical 'and', 'or',
24.145 'not' etc.) or e.g. convert a map to another one of different Value type.
24.146 @@ -159,7 +230,7 @@
24.147 @ingroup datas
24.148 \brief Two dimensional data storages implemented in LEMON.
24.149
24.150 -This group describes two dimensional data storages implemented in LEMON.
24.151 +This group contains two dimensional data storages implemented in LEMON.
24.152 */
24.153
24.154 /**
24.155 @@ -167,7 +238,7 @@
24.156 @ingroup datas
24.157 \brief %Path structures implemented in LEMON.
24.158
24.159 -This group describes the path structures implemented in LEMON.
24.160 +This group contains the path structures implemented in LEMON.
24.161
24.162 LEMON provides flexible data structures to work with paths.
24.163 All of them have similar interfaces and they can be copied easily with
24.164 @@ -183,16 +254,16 @@
24.165 @ingroup datas
24.166 \brief Auxiliary data structures implemented in LEMON.
24.167
24.168 -This group describes some data structures implemented in LEMON in
24.169 +This group contains some data structures implemented in LEMON in
24.170 order to make it easier to implement combinatorial algorithms.
24.171 */
24.172
24.173 /**
24.174 @defgroup algs Algorithms
24.175 -\brief This group describes the several algorithms
24.176 +\brief This group contains the several algorithms
24.177 implemented in LEMON.
24.178
24.179 -This group describes the several algorithms
24.180 +This group contains the several algorithms
24.181 implemented in LEMON.
24.182 */
24.183
24.184 @@ -201,8 +272,8 @@
24.185 @ingroup algs
24.186 \brief Common graph search algorithms.
24.187
24.188 -This group describes the common graph search algorithms like
24.189 -Breadth-First Search (BFS) and Depth-First Search (DFS).
24.190 +This group contains the common graph search algorithms, namely
24.191 +\e breadth-first \e search (BFS) and \e depth-first \e search (DFS).
24.192 */
24.193
24.194 /**
24.195 @@ -210,7 +281,20 @@
24.196 @ingroup algs
24.197 \brief Algorithms for finding shortest paths.
24.198
24.199 -This group describes the algorithms for finding shortest paths in graphs.
24.200 +This group contains the algorithms for finding shortest paths in digraphs.
24.201 +
24.202 + - \ref Dijkstra algorithm for finding shortest paths from a source node
24.203 + when all arc lengths are non-negative.
24.204 + - \ref BellmanFord "Bellman-Ford" algorithm for finding shortest paths
24.205 + from a source node when arc lenghts can be either positive or negative,
24.206 + but the digraph should not contain directed cycles with negative total
24.207 + length.
24.208 + - \ref FloydWarshall "Floyd-Warshall" and \ref Johnson "Johnson" algorithms
24.209 + for solving the \e all-pairs \e shortest \e paths \e problem when arc
24.210 + lenghts can be either positive or negative, but the digraph should
24.211 + not contain directed cycles with negative total length.
24.212 + - \ref Suurballe A successive shortest path algorithm for finding
24.213 + arc-disjoint paths between two nodes having minimum total length.
24.214 */
24.215
24.216 /**
24.217 @@ -218,40 +302,62 @@
24.218 @ingroup algs
24.219 \brief Algorithms for finding maximum flows.
24.220
24.221 -This group describes the algorithms for finding maximum flows and
24.222 +This group contains the algorithms for finding maximum flows and
24.223 feasible circulations.
24.224
24.225 -The maximum flow problem is to find a flow between a single source and
24.226 -a single target that is maximum. Formally, there is a \f$G=(V,A)\f$
24.227 -directed graph, an \f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity
24.228 -function and given \f$s, t \in V\f$ source and target node. The
24.229 -maximum flow is the \f$f_a\f$ solution of the next optimization problem:
24.230 +The \e maximum \e flow \e problem is to find a flow of maximum value between
24.231 +a single source and a single target. Formally, there is a \f$G=(V,A)\f$
24.232 +digraph, a \f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function and
24.233 +\f$s, t \in V\f$ source and target nodes.
24.234 +A maximum flow is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ solution of the
24.235 +following optimization problem.
24.236
24.237 -\f[ 0 \le f_a \le c_a \f]
24.238 -\f[ \sum_{v\in\delta^{-}(u)}f_{vu}=\sum_{v\in\delta^{+}(u)}f_{uv}
24.239 -\qquad \forall u \in V \setminus \{s,t\}\f]
24.240 -\f[ \max \sum_{v\in\delta^{+}(s)}f_{uv} - \sum_{v\in\delta^{-}(s)}f_{vu}\f]
24.241 +\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f]
24.242 +\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu)
24.243 + \quad \forall u\in V\setminus\{s,t\} \f]
24.244 +\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
24.245
24.246 LEMON contains several algorithms for solving maximum flow problems:
24.247 -- \ref lemon::EdmondsKarp "Edmonds-Karp"
24.248 -- \ref lemon::Preflow "Goldberg's Preflow algorithm"
24.249 -- \ref lemon::DinitzSleatorTarjan "Dinitz's blocking flow algorithm with dynamic trees"
24.250 -- \ref lemon::GoldbergTarjan "Preflow algorithm with dynamic trees"
24.251 +- \ref EdmondsKarp Edmonds-Karp algorithm.
24.252 +- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm.
24.253 +- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees.
24.254 +- \ref GoldbergTarjan Preflow push-relabel algorithm with dynamic trees.
24.255
24.256 -In most cases the \ref lemon::Preflow "Preflow" algorithm provides the
24.257 -fastest method to compute the maximum flow. All impelementations
24.258 -provides functions to query the minimum cut, which is the dual linear
24.259 -programming problem of the maximum flow.
24.260 +In most cases the \ref Preflow "Preflow" algorithm provides the
24.261 +fastest method for computing a maximum flow. All implementations
24.262 +also provide functions to query the minimum cut, which is the dual
24.263 +problem of maximum flow.
24.264 +
24.265 +\ref Circulation is a preflow push-relabel algorithm implemented directly
24.266 +for finding feasible circulations, which is a somewhat different problem,
24.267 +but it is strongly related to maximum flow.
24.268 +For more information, see \ref Circulation.
24.269 */
24.270
24.271 /**
24.272 -@defgroup min_cost_flow Minimum Cost Flow Algorithms
24.273 +@defgroup min_cost_flow_algs Minimum Cost Flow Algorithms
24.274 @ingroup algs
24.275
24.276 \brief Algorithms for finding minimum cost flows and circulations.
24.277
24.278 -This group describes the algorithms for finding minimum cost flows and
24.279 -circulations.
24.280 +This group contains the algorithms for finding minimum cost flows and
24.281 +circulations. For more information about this problem and its dual
24.282 +solution see \ref min_cost_flow "Minimum Cost Flow Problem".
24.283 +
24.284 +LEMON contains several algorithms for this problem.
24.285 + - \ref NetworkSimplex Primal Network Simplex algorithm with various
24.286 + pivot strategies.
24.287 + - \ref CostScaling Push-Relabel and Augment-Relabel algorithms based on
24.288 + cost scaling.
24.289 + - \ref CapacityScaling Successive Shortest %Path algorithm with optional
24.290 + capacity scaling.
24.291 + - \ref CancelAndTighten The Cancel and Tighten algorithm.
24.292 + - \ref CycleCanceling Cycle-Canceling algorithms.
24.293 +
24.294 +In general NetworkSimplex is the most efficient implementation,
24.295 +but in special cases other algorithms could be faster.
24.296 +For example, if the total supply and/or capacities are rather small,
24.297 +CapacityScaling is usually the fastest algorithm (without effective scaling).
24.298 */
24.299
24.300 /**
24.301 @@ -260,36 +366,36 @@
24.302
24.303 \brief Algorithms for finding minimum cut in graphs.
24.304
24.305 -This group describes the algorithms for finding minimum cut in graphs.
24.306 +This group contains the algorithms for finding minimum cut in graphs.
24.307
24.308 -The minimum cut problem is to find a non-empty and non-complete
24.309 -\f$X\f$ subset of the vertices with minimum overall capacity on
24.310 -outgoing arcs. Formally, there is \f$G=(V,A)\f$ directed graph, an
24.311 -\f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
24.312 +The \e minimum \e cut \e problem is to find a non-empty and non-complete
24.313 +\f$X\f$ subset of the nodes with minimum overall capacity on
24.314 +outgoing arcs. Formally, there is a \f$G=(V,A)\f$ digraph, a
24.315 +\f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
24.316 cut is the \f$X\f$ solution of the next optimization problem:
24.317
24.318 \f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
24.319 -\sum_{uv\in A, u\in X, v\not\in X}c_{uv}\f]
24.320 + \sum_{uv\in A, u\in X, v\not\in X}cap(uv) \f]
24.321
24.322 LEMON contains several algorithms related to minimum cut problems:
24.323
24.324 -- \ref lemon::HaoOrlin "Hao-Orlin algorithm" to calculate minimum cut
24.325 - in directed graphs
24.326 -- \ref lemon::NagamochiIbaraki "Nagamochi-Ibaraki algorithm" to
24.327 - calculate minimum cut in undirected graphs
24.328 -- \ref lemon::GomoryHuTree "Gomory-Hu tree computation" to calculate all
24.329 - pairs minimum cut in undirected graphs
24.330 +- \ref HaoOrlin "Hao-Orlin algorithm" for calculating minimum cut
24.331 + in directed graphs.
24.332 +- \ref NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
24.333 + calculating minimum cut in undirected graphs.
24.334 +- \ref GomoryHu "Gomory-Hu tree computation" for calculating
24.335 + all-pairs minimum cut in undirected graphs.
24.336
24.337 If you want to find minimum cut just between two distinict nodes,
24.338 -please see the \ref max_flow "Maximum Flow page".
24.339 +see the \ref max_flow "maximum flow problem".
24.340 */
24.341
24.342 /**
24.343 -@defgroup graph_prop Connectivity and Other Graph Properties
24.344 +@defgroup graph_properties Connectivity and Other Graph Properties
24.345 @ingroup algs
24.346 \brief Algorithms for discovering the graph properties
24.347
24.348 -This group describes the algorithms for discovering the graph properties
24.349 +This group contains the algorithms for discovering the graph properties
24.350 like connectivity, bipartiteness, euler property, simplicity etc.
24.351
24.352 \image html edge_biconnected_components.png
24.353 @@ -301,7 +407,7 @@
24.354 @ingroup algs
24.355 \brief Algorithms for planarity checking, embedding and drawing
24.356
24.357 -This group describes the algorithms for planarity checking,
24.358 +This group contains the algorithms for planarity checking,
24.359 embedding and drawing.
24.360
24.361 \image html planar.png
24.362 @@ -313,37 +419,36 @@
24.363 @ingroup algs
24.364 \brief Algorithms for finding matchings in graphs and bipartite graphs.
24.365
24.366 -This group contains algorithm objects and functions to calculate
24.367 +This group contains the algorithms for calculating
24.368 matchings in graphs and bipartite graphs. The general matching problem is
24.369 -finding a subset of the arcs which does not shares common endpoints.
24.370 +finding a subset of the edges for which each node has at most one incident
24.371 +edge.
24.372
24.373 There are several different algorithms for calculate matchings in
24.374 graphs. The matching problems in bipartite graphs are generally
24.375 easier than in general graphs. The goal of the matching optimization
24.376 -can be the finding maximum cardinality, maximum weight or minimum cost
24.377 +can be finding maximum cardinality, maximum weight or minimum cost
24.378 matching. The search can be constrained to find perfect or
24.379 maximum cardinality matching.
24.380
24.381 -LEMON contains the next algorithms:
24.382 -- \ref lemon::MaxBipartiteMatching "MaxBipartiteMatching" Hopcroft-Karp
24.383 - augmenting path algorithm for calculate maximum cardinality matching in
24.384 - bipartite graphs
24.385 -- \ref lemon::PrBipartiteMatching "PrBipartiteMatching" Push-Relabel
24.386 - algorithm for calculate maximum cardinality matching in bipartite graphs
24.387 -- \ref lemon::MaxWeightedBipartiteMatching "MaxWeightedBipartiteMatching"
24.388 - Successive shortest path algorithm for calculate maximum weighted matching
24.389 - and maximum weighted bipartite matching in bipartite graph
24.390 -- \ref lemon::MinCostMaxBipartiteMatching "MinCostMaxBipartiteMatching"
24.391 - Successive shortest path algorithm for calculate minimum cost maximum
24.392 - matching in bipartite graph
24.393 -- \ref lemon::MaxMatching "MaxMatching" Edmond's blossom shrinking algorithm
24.394 - for calculate maximum cardinality matching in general graph
24.395 -- \ref lemon::MaxWeightedMatching "MaxWeightedMatching" Edmond's blossom
24.396 - shrinking algorithm for calculate maximum weighted matching in general
24.397 - graph
24.398 -- \ref lemon::MaxWeightedPerfectMatching "MaxWeightedPerfectMatching"
24.399 - Edmond's blossom shrinking algorithm for calculate maximum weighted
24.400 - perfect matching in general graph
24.401 +The matching algorithms implemented in LEMON:
24.402 +- \ref MaxBipartiteMatching Hopcroft-Karp augmenting path algorithm
24.403 + for calculating maximum cardinality matching in bipartite graphs.
24.404 +- \ref PrBipartiteMatching Push-relabel algorithm
24.405 + for calculating maximum cardinality matching in bipartite graphs.
24.406 +- \ref MaxWeightedBipartiteMatching
24.407 + Successive shortest path algorithm for calculating maximum weighted
24.408 + matching and maximum weighted bipartite matching in bipartite graphs.
24.409 +- \ref MinCostMaxBipartiteMatching
24.410 + Successive shortest path algorithm for calculating minimum cost maximum
24.411 + matching in bipartite graphs.
24.412 +- \ref MaxMatching Edmond's blossom shrinking algorithm for calculating
24.413 + maximum cardinality matching in general graphs.
24.414 +- \ref MaxWeightedMatching Edmond's blossom shrinking algorithm for calculating
24.415 + maximum weighted matching in general graphs.
24.416 +- \ref MaxWeightedPerfectMatching
24.417 + Edmond's blossom shrinking algorithm for calculating maximum weighted
24.418 + perfect matching in general graphs.
24.419
24.420 \image html bipartite_matching.png
24.421 \image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
24.422 @@ -352,10 +457,10 @@
24.423 /**
24.424 @defgroup spantree Minimum Spanning Tree Algorithms
24.425 @ingroup algs
24.426 -\brief Algorithms for finding a minimum cost spanning tree in a graph.
24.427 +\brief Algorithms for finding minimum cost spanning trees and arborescences.
24.428
24.429 -This group describes the algorithms for finding a minimum cost spanning
24.430 -tree in a graph
24.431 +This group contains the algorithms for finding minimum cost spanning
24.432 +trees and arborescences.
24.433 */
24.434
24.435 /**
24.436 @@ -363,7 +468,7 @@
24.437 @ingroup algs
24.438 \brief Auxiliary algorithms implemented in LEMON.
24.439
24.440 -This group describes some algorithms implemented in LEMON
24.441 +This group contains some algorithms implemented in LEMON
24.442 in order to make it easier to implement complex algorithms.
24.443 */
24.444
24.445 @@ -372,16 +477,16 @@
24.446 @ingroup algs
24.447 \brief Approximation algorithms.
24.448
24.449 -This group describes the approximation and heuristic algorithms
24.450 +This group contains the approximation and heuristic algorithms
24.451 implemented in LEMON.
24.452 */
24.453
24.454 /**
24.455 @defgroup gen_opt_group General Optimization Tools
24.456 -\brief This group describes some general optimization frameworks
24.457 +\brief This group contains some general optimization frameworks
24.458 implemented in LEMON.
24.459
24.460 -This group describes some general optimization frameworks
24.461 +This group contains some general optimization frameworks
24.462 implemented in LEMON.
24.463 */
24.464
24.465 @@ -390,7 +495,7 @@
24.466 @ingroup gen_opt_group
24.467 \brief Lp and Mip solver interfaces for LEMON.
24.468
24.469 -This group describes Lp and Mip solver interfaces for LEMON. The
24.470 +This group contains Lp and Mip solver interfaces for LEMON. The
24.471 various LP solvers could be used in the same manner with this
24.472 interface.
24.473 */
24.474 @@ -409,7 +514,7 @@
24.475 @ingroup gen_opt_group
24.476 \brief Metaheuristics for LEMON library.
24.477
24.478 -This group describes some metaheuristic optimization tools.
24.479 +This group contains some metaheuristic optimization tools.
24.480 */
24.481
24.482 /**
24.483 @@ -424,7 +529,7 @@
24.484 @ingroup utils
24.485 \brief Simple basic graph utilities.
24.486
24.487 -This group describes some simple basic graph utilities.
24.488 +This group contains some simple basic graph utilities.
24.489 */
24.490
24.491 /**
24.492 @@ -432,7 +537,7 @@
24.493 @ingroup utils
24.494 \brief Tools for development, debugging and testing.
24.495
24.496 -This group describes several useful tools for development,
24.497 +This group contains several useful tools for development,
24.498 debugging and testing.
24.499 */
24.500
24.501 @@ -441,7 +546,7 @@
24.502 @ingroup misc
24.503 \brief Simple tools for measuring the performance of algorithms.
24.504
24.505 -This group describes simple tools for measuring the performance
24.506 +This group contains simple tools for measuring the performance
24.507 of algorithms.
24.508 */
24.509
24.510 @@ -450,25 +555,25 @@
24.511 @ingroup utils
24.512 \brief Exceptions defined in LEMON.
24.513
24.514 -This group describes the exceptions defined in LEMON.
24.515 +This group contains the exceptions defined in LEMON.
24.516 */
24.517
24.518 /**
24.519 @defgroup io_group Input-Output
24.520 \brief Graph Input-Output methods
24.521
24.522 -This group describes the tools for importing and exporting graphs
24.523 +This group contains the tools for importing and exporting graphs
24.524 and graph related data. Now it supports the \ref lgf-format
24.525 "LEMON Graph Format", the \c DIMACS format and the encapsulated
24.526 postscript (EPS) format.
24.527 */
24.528
24.529 /**
24.530 -@defgroup lemon_io LEMON Input-Output
24.531 +@defgroup lemon_io LEMON Graph Format
24.532 @ingroup io_group
24.533 \brief Reading and writing LEMON Graph Format.
24.534
24.535 -This group describes methods for reading and writing
24.536 +This group contains methods for reading and writing
24.537 \ref lgf-format "LEMON Graph Format".
24.538 */
24.539
24.540 @@ -477,15 +582,31 @@
24.541 @ingroup io_group
24.542 \brief General \c EPS drawer and graph exporter
24.543
24.544 -This group describes general \c EPS drawing methods and special
24.545 +This group contains general \c EPS drawing methods and special
24.546 graph exporting tools.
24.547 */
24.548
24.549 /**
24.550 +@defgroup dimacs_group DIMACS format
24.551 +@ingroup io_group
24.552 +\brief Read and write files in DIMACS format
24.553 +
24.554 +Tools to read a digraph from or write it to a file in DIMACS format data.
24.555 +*/
24.556 +
24.557 +/**
24.558 +@defgroup nauty_group NAUTY Format
24.559 +@ingroup io_group
24.560 +\brief Read \e Nauty format
24.561 +
24.562 +Tool to read graphs from \e Nauty format data.
24.563 +*/
24.564 +
24.565 +/**
24.566 @defgroup concept Concepts
24.567 \brief Skeleton classes and concept checking classes
24.568
24.569 -This group describes the data/algorithm skeletons and concept checking
24.570 +This group contains the data/algorithm skeletons and concept checking
24.571 classes implemented in LEMON.
24.572
24.573 The purpose of the classes in this group is fourfold.
24.574 @@ -515,7 +636,7 @@
24.575 @ingroup concept
24.576 \brief Skeleton and concept checking classes for graph structures
24.577
24.578 -This group describes the skeletons and concept checking classes of LEMON's
24.579 +This group contains the skeletons and concept checking classes of LEMON's
24.580 graph structures and helper classes used to implement these.
24.581 */
24.582
24.583 @@ -524,23 +645,23 @@
24.584 @ingroup concept
24.585 \brief Skeleton and concept checking classes for maps
24.586
24.587 -This group describes the skeletons and concept checking classes of maps.
24.588 +This group contains the skeletons and concept checking classes of maps.
24.589 */
24.590
24.591 /**
24.592 \anchor demoprograms
24.593
24.594 -@defgroup demos Demo programs
24.595 +@defgroup demos Demo Programs
24.596
24.597 Some demo programs are listed here. Their full source codes can be found in
24.598 the \c demo subdirectory of the source tree.
24.599
24.600 -It order to compile them, use <tt>--enable-demo</tt> configure option when
24.601 -build the library.
24.602 +In order to compile them, use the <tt>make demo</tt> or the
24.603 +<tt>make check</tt> commands.
24.604 */
24.605
24.606 /**
24.607 -@defgroup tools Standalone utility applications
24.608 +@defgroup tools Standalone Utility Applications
24.609
24.610 Some utility applications are listed here.
24.611
24.612 @@ -548,3 +669,4 @@
24.613 them, as well.
24.614 */
24.615
24.616 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/doc/images/bipartite_matching.eps Thu Dec 10 17:05:35 2009 +0100
25.3 @@ -0,0 +1,586 @@
25.4 +%!PS-Adobe-3.0 EPSF-3.0
25.5 +%%BoundingBox: 15 18 829 570
25.6 +%%HiResBoundingBox: 15.1913 18.4493 828.078 569.438
25.7 +%%Creator: Karbon14 EPS Exportfilter 0.5
25.8 +%%CreationDate: (04/15/06 15:20:26)
25.9 +%%For: (Balazs Dezso) ()
25.10 +%%Title: ()
25.11 +
25.12 +/N {newpath} def
25.13 +/C {closepath} def
25.14 +/m {moveto} def
25.15 +/c {curveto} def
25.16 +/l {lineto} def
25.17 +/s {stroke} def
25.18 +/f {fill} def
25.19 +/w {setlinewidth} def
25.20 +/d {setdash} def
25.21 +/r {setrgbcolor} def
25.22 +/S {gsave} def
25.23 +/R {grestore} def
25.24 +
25.25 +N
25.26 +251.402 32.047 m
25.27 +532.945 293.946 814.484 555.844 814.484 555.844 c
25.28 +[] 0 d 1 0 0 r 3.92814 w s
25.29 +
25.30 +N
25.31 +749.012 32.047 m
25.32 +742.465 293.946 735.918 555.844 735.918 555.844 c
25.33 +[] 0 d 0 0 0 r 1.96407 w s
25.34 +
25.35 +N
25.36 +539.492 32.047 m
25.37 +637.703 293.946 735.918 555.844 735.918 555.844 c
25.38 +[] 0 d 0 0 0 r 1.96407 w s
25.39 +
25.40 +N
25.41 +172.832 32.047 m
25.42 +454.375 293.946 735.918 555.844 735.918 555.844 c
25.43 +[] 0 d 0 0 0 r 1.96407 w s
25.44 +
25.45 +N
25.46 +107.355 32.047 m
25.47 +421.637 293.946 735.918 555.844 735.918 555.844 c
25.48 +[] 0 d 1 0 0 r 3.92814 w s
25.49 +
25.50 +N
25.51 +644.25 555.844 m
25.52 +696.633 293.946 749.012 32.047 749.012 32.047 c
25.53 +[] 0 d 0 0 0 r 1.96407 w s
25.54 +
25.55 +N
25.56 +474.016 555.844 m
25.57 +611.516 293.946 749.012 32.047 749.012 32.047 c
25.58 +[] 0 d 1 0 0 r 3.92814 w s
25.59 +
25.60 +N
25.61 +683.535 32.047 m
25.62 +663.894 293.946 644.25 555.844 644.25 555.844 c
25.63 +[] 0 d 0 0 0 r 1.96407 w s
25.64 +
25.65 +N
25.66 +120.453 555.844 m
25.67 +401.992 293.946 683.535 32.047 683.535 32.047 c
25.68 +[] 0 d 0 0 0 r 1.96407 w s
25.69 +
25.70 +N
25.71 +28.7853 555.844 m
25.72 +356.16 293.946 683.535 32.047 683.535 32.047 c
25.73 +[] 0 d 1 0 0 r 3.92814 w s
25.74 +
25.75 +N
25.76 +539.492 32.047 m
25.77 +546.039 293.946 552.586 555.844 552.586 555.844 c
25.78 +[] 0 d 1 0 0 r 3.92814 w s
25.79 +
25.80 +N
25.81 +316.875 32.047 m
25.82 +349.613 293.946 382.351 555.844 382.351 555.844 c
25.83 +[] 0 d 1 0 0 r 3.92814 w s
25.84 +
25.85 +N
25.86 +107.355 32.047 m
25.87 +244.855 293.946 382.351 555.844 382.351 555.844 c
25.88 +[] 0 d 0 0 0 r 1.96407 w s
25.89 +
25.90 +N
25.91 +290.687 555.844 m
25.92 +375.805 293.946 460.922 32.047 460.922 32.047 c
25.93 +[] 0 d 1 0 0 r 3.92814 w s
25.94 +
25.95 +N
25.96 +120.453 555.844 m
25.97 +290.687 293.946 460.922 32.047 460.922 32.047 c
25.98 +[] 0 d 0 0 0 r 1.96407 w s
25.99 +
25.100 +N
25.101 +172.832 32.047 m
25.102 +146.64 293.946 120.453 555.844 120.453 555.844 c
25.103 +[] 0 d 1 0 0 r 3.92814 w s
25.104 +
25.105 +N
25.106 +15.6913 555.844 m
25.107 +15.6913 555.844 l
25.108 +15.6913 548.614 21.5553 542.75 28.7853 542.75 c
25.109 +36.0163 542.75 41.8833 548.614 41.8833 555.844 c
25.110 +41.8833 563.075 36.0163 568.938 28.7853 568.938 c
25.111 +21.5553 568.938 15.6913 563.075 15.6913 555.844 c
25.112 +15.6913 555.844 l
25.113 +C
25.114 +S 0 0 0 r f R
25.115 +
25.116 +N
25.117 +16.8833 555.844 m
25.118 +16.8833 555.844 l
25.119 +16.8833 549.27 22.2113 543.942 28.7853 543.942 c
25.120 +35.3593 543.942 40.6913 549.27 40.6913 555.844 c
25.121 +40.6913 562.418 35.3593 567.747 28.7853 567.747 c
25.122 +22.2113 567.747 16.8833 562.418 16.8833 555.844 c
25.123 +16.8833 555.844 l
25.124 +C
25.125 +S 1 0.5 1 r f R
25.126 +
25.127 +N
25.128 +107.355 555.844 m
25.129 +107.355 555.844 l
25.130 +107.355 548.614 113.223 542.75 120.453 542.75 c
25.131 +127.683 542.75 133.547 548.614 133.547 555.844 c
25.132 +133.547 563.075 127.683 568.938 120.453 568.938 c
25.133 +113.223 568.938 107.355 563.075 107.355 555.844 c
25.134 +107.355 555.844 l
25.135 +C
25.136 +S 0 0 0 r f R
25.137 +
25.138 +N
25.139 +108.547 555.844 m
25.140 +108.547 555.844 l
25.141 +108.547 549.27 113.879 543.942 120.453 543.942 c
25.142 +127.027 543.942 132.355 549.27 132.355 555.844 c
25.143 +132.355 562.418 127.027 567.747 120.453 567.747 c
25.144 +113.879 567.747 108.547 562.418 108.547 555.844 c
25.145 +108.547 555.844 l
25.146 +C
25.147 +S 1 0 1 r f R
25.148 +
25.149 +N
25.150 +199.019 555.844 m
25.151 +199.019 555.844 l
25.152 +199.019 548.614 204.887 542.75 212.117 542.75 c
25.153 +219.348 542.75 225.211 548.614 225.211 555.844 c
25.154 +225.211 563.075 219.348 568.938 212.117 568.938 c
25.155 +204.887 568.938 199.019 563.075 199.019 555.844 c
25.156 +199.019 555.844 l
25.157 +C
25.158 +S 0 0 0 r f R
25.159 +
25.160 +N
25.161 +200.211 555.844 m
25.162 +200.211 555.844 l
25.163 +200.211 549.27 205.543 543.942 212.117 543.942 c
25.164 +218.691 543.942 224.019 549.27 224.019 555.844 c
25.165 +224.019 562.418 218.691 567.747 212.117 567.747 c
25.166 +205.543 567.747 200.211 562.418 200.211 555.844 c
25.167 +200.211 555.844 l
25.168 +C
25.169 +S 1 0.5 1 r f R
25.170 +
25.171 +N
25.172 +277.59 555.844 m
25.173 +277.59 555.844 l
25.174 +277.59 548.614 283.457 542.75 290.687 542.75 c
25.175 +297.918 542.75 303.781 548.614 303.781 555.844 c
25.176 +303.781 563.075 297.918 568.938 290.687 568.938 c
25.177 +283.457 568.938 277.59 563.075 277.59 555.844 c
25.178 +277.59 555.844 l
25.179 +C
25.180 +S 0 0 0 r f R
25.181 +
25.182 +N
25.183 +278.781 555.844 m
25.184 +278.781 555.844 l
25.185 +278.781 549.27 284.113 543.942 290.687 543.942 c
25.186 +297.262 543.942 302.59 549.27 302.59 555.844 c
25.187 +302.59 562.418 297.262 567.747 290.687 567.747 c
25.188 +284.113 567.747 278.781 562.418 278.781 555.844 c
25.189 +278.781 555.844 l
25.190 +C
25.191 +S 1 0 1 r f R
25.192 +
25.193 +N
25.194 +369.258 555.844 m
25.195 +369.258 555.844 l
25.196 +369.258 548.614 375.121 542.75 382.351 542.75 c
25.197 +389.582 542.75 395.445 548.614 395.445 555.844 c
25.198 +395.445 563.075 389.582 568.938 382.351 568.938 c
25.199 +375.121 568.938 369.258 563.075 369.258 555.844 c
25.200 +369.258 555.844 l
25.201 +C
25.202 +S 0 0 0 r f R
25.203 +
25.204 +N
25.205 +370.445 555.844 m
25.206 +370.445 555.844 l
25.207 +370.445 549.27 375.777 543.942 382.351 543.942 c
25.208 +388.926 543.942 394.258 549.27 394.258 555.844 c
25.209 +394.258 562.418 388.926 567.747 382.351 567.747 c
25.210 +375.777 567.747 370.445 562.418 370.445 555.844 c
25.211 +370.445 555.844 l
25.212 +C
25.213 +S 1 0 1 r f R
25.214 +
25.215 +N
25.216 +460.922 555.844 m
25.217 +460.922 555.844 l
25.218 +460.922 548.614 466.785 542.75 474.016 542.75 c
25.219 +481.246 542.75 487.109 548.614 487.109 555.844 c
25.220 +487.109 563.075 481.246 568.938 474.016 568.938 c
25.221 +466.785 568.938 460.922 563.075 460.922 555.844 c
25.222 +460.922 555.844 l
25.223 +C
25.224 +S 0 0 0 r f R
25.225 +
25.226 +N
25.227 +462.113 555.844 m
25.228 +462.113 555.844 l
25.229 +462.113 549.27 467.441 543.942 474.016 543.942 c
25.230 +480.59 543.942 485.922 549.27 485.922 555.844 c
25.231 +485.922 562.418 480.59 567.747 474.016 567.747 c
25.232 +467.441 567.747 462.113 562.418 462.113 555.844 c
25.233 +462.113 555.844 l
25.234 +C
25.235 +S 1 0.5 1 r f R
25.236 +
25.237 +N
25.238 +539.492 555.844 m
25.239 +539.492 555.844 l
25.240 +539.492 548.614 545.355 542.75 552.586 542.75 c
25.241 +559.816 542.75 565.68 548.614 565.68 555.844 c
25.242 +565.68 563.075 559.816 568.938 552.586 568.938 c
25.243 +545.355 568.938 539.492 563.075 539.492 555.844 c
25.244 +539.492 555.844 l
25.245 +C
25.246 +S 0 0 0 r f R
25.247 +
25.248 +N
25.249 +540.683 555.844 m
25.250 +540.683 555.844 l
25.251 +540.683 549.27 546.012 543.942 552.586 543.942 c
25.252 +559.16 543.942 564.492 549.27 564.492 555.844 c
25.253 +564.492 562.418 559.16 567.747 552.586 567.747 c
25.254 +546.012 567.747 540.683 562.418 540.683 555.844 c
25.255 +540.683 555.844 l
25.256 +C
25.257 +S 1 0 1 r f R
25.258 +
25.259 +N
25.260 +631.156 555.844 m
25.261 +631.156 555.844 l
25.262 +631.156 548.614 637.019 542.75 644.25 542.75 c
25.263 +651.48 542.75 657.348 548.614 657.348 555.844 c
25.264 +657.348 563.075 651.48 568.938 644.25 568.938 c
25.265 +637.019 568.938 631.156 563.075 631.156 555.844 c
25.266 +631.156 555.844 l
25.267 +C
25.268 +S 0 0 0 r f R
25.269 +
25.270 +N
25.271 +632.348 555.844 m
25.272 +632.348 555.844 l
25.273 +632.348 549.27 637.676 543.942 644.25 543.942 c
25.274 +650.824 543.942 656.156 549.27 656.156 555.844 c
25.275 +656.156 562.418 650.824 567.747 644.25 567.747 c
25.276 +637.676 567.747 632.348 562.418 632.348 555.844 c
25.277 +632.348 555.844 l
25.278 +C
25.279 +S 1 0.5 1 r f R
25.280 +
25.281 +N
25.282 +722.82 555.844 m
25.283 +722.82 555.844 l
25.284 +722.82 548.614 728.687 542.75 735.918 542.75 c
25.285 +743.149 542.75 749.012 548.614 749.012 555.844 c
25.286 +749.012 563.075 743.149 568.938 735.918 568.938 c
25.287 +728.687 568.938 722.82 563.075 722.82 555.844 c
25.288 +722.82 555.844 l
25.289 +C
25.290 +S 0 0 0 r f R
25.291 +
25.292 +N
25.293 +724.012 555.844 m
25.294 +724.012 555.844 l
25.295 +724.012 549.27 729.344 543.942 735.918 543.942 c
25.296 +742.492 543.942 747.82 549.27 747.82 555.844 c
25.297 +747.82 562.418 742.492 567.747 735.918 567.747 c
25.298 +729.344 567.747 724.012 562.418 724.012 555.844 c
25.299 +724.012 555.844 l
25.300 +C
25.301 +S 1 0 1 r f R
25.302 +
25.303 +N
25.304 +801.391 555.844 m
25.305 +801.391 555.844 l
25.306 +801.391 548.614 807.254 542.75 814.484 542.75 c
25.307 +821.715 542.75 827.578 548.614 827.578 555.844 c
25.308 +827.578 563.075 821.715 568.938 814.484 568.938 c
25.309 +807.254 568.938 801.391 563.075 801.391 555.844 c
25.310 +801.391 555.844 l
25.311 +C
25.312 +S 0 0 0 r f R
25.313 +
25.314 +N
25.315 +802.582 555.844 m
25.316 +802.582 555.844 l
25.317 +802.582 549.27 807.91 543.942 814.484 543.942 c
25.318 +821.059 543.942 826.387 549.27 826.387 555.844 c
25.319 +826.387 562.418 821.059 567.747 814.484 567.747 c
25.320 +807.91 567.747 802.582 562.418 802.582 555.844 c
25.321 +802.582 555.844 l
25.322 +C
25.323 +S 1 0 1 r f R
25.324 +
25.325 +N
25.326 +15.6913 32.047 m
25.327 +15.6913 32.047 l
25.328 +15.6913 24.8165 21.5553 18.9493 28.7853 18.9493 c
25.329 +36.0163 18.9493 41.8833 24.8165 41.8833 32.047 c
25.330 +41.8833 39.2775 36.0163 45.1407 28.7853 45.1407 c
25.331 +21.5553 45.1407 15.6913 39.2775 15.6913 32.047 c
25.332 +15.6913 32.047 l
25.333 +C
25.334 +S 0 0 0 r f R
25.335 +
25.336 +N
25.337 +16.8833 32.047 m
25.338 +16.8833 32.047 l
25.339 +16.8833 25.4728 22.2113 20.1407 28.7853 20.1407 c
25.340 +35.3593 20.1407 40.6913 25.4728 40.6913 32.047 c
25.341 +40.6913 38.6212 35.3593 43.9493 28.7853 43.9493 c
25.342 +22.2113 43.9493 16.8833 38.6212 16.8833 32.047 c
25.343 +16.8833 32.047 l
25.344 +C
25.345 +S 0.5 0.5 1 r f R
25.346 +
25.347 +N
25.348 +94.2623 32.047 m
25.349 +94.2623 32.047 l
25.350 +94.2623 24.8165 100.125 18.9493 107.355 18.9493 c
25.351 +114.586 18.9493 120.453 24.8165 120.453 32.047 c
25.352 +120.453 39.2775 114.586 45.1407 107.355 45.1407 c
25.353 +100.125 45.1407 94.2623 39.2775 94.2623 32.047 c
25.354 +94.2623 32.047 l
25.355 +C
25.356 +S 0 0 0 r f R
25.357 +
25.358 +N
25.359 +95.4533 32.047 m
25.360 +95.4533 32.047 l
25.361 +95.4533 25.4728 100.781 20.1407 107.355 20.1407 c
25.362 +113.93 20.1407 119.262 25.4728 119.262 32.047 c
25.363 +119.262 38.6212 113.93 43.9493 107.355 43.9493 c
25.364 +100.781 43.9493 95.4533 38.6212 95.4533 32.047 c
25.365 +95.4533 32.047 l
25.366 +C
25.367 +S 0.5 0.5 1 r f R
25.368 +
25.369 +N
25.370 +159.734 32.047 m
25.371 +159.734 32.047 l
25.372 +159.734 24.8165 165.601 18.9493 172.832 18.9493 c
25.373 +180.062 18.9493 185.926 24.8165 185.926 32.047 c
25.374 +185.926 39.2775 180.062 45.1407 172.832 45.1407 c
25.375 +165.601 45.1407 159.734 39.2775 159.734 32.047 c
25.376 +159.734 32.047 l
25.377 +C
25.378 +S 0 0 0 r f R
25.379 +
25.380 +N
25.381 +160.926 32.047 m
25.382 +160.926 32.047 l
25.383 +160.926 25.4728 166.258 20.1407 172.832 20.1407 c
25.384 +179.406 20.1407 184.734 25.4728 184.734 32.047 c
25.385 +184.734 38.6212 179.406 43.9493 172.832 43.9493 c
25.386 +166.258 43.9493 160.926 38.6212 160.926 32.047 c
25.387 +160.926 32.047 l
25.388 +C
25.389 +S 0.5 0.5 1 r f R
25.390 +
25.391 +N
25.392 +238.305 32.047 m
25.393 +238.305 32.047 l
25.394 +238.305 24.8165 244.172 18.9493 251.402 18.9493 c
25.395 +258.633 18.9493 264.496 24.8165 264.496 32.047 c
25.396 +264.496 39.2775 258.633 45.1407 251.402 45.1407 c
25.397 +244.172 45.1407 238.305 39.2775 238.305 32.047 c
25.398 +238.305 32.047 l
25.399 +C
25.400 +S 0 0 0 r f R
25.401 +
25.402 +N
25.403 +239.496 32.047 m
25.404 +239.496 32.047 l
25.405 +239.496 25.4728 244.828 20.1407 251.402 20.1407 c
25.406 +257.976 20.1407 263.305 25.4728 263.305 32.047 c
25.407 +263.305 38.6212 257.976 43.9493 251.402 43.9493 c
25.408 +244.828 43.9493 239.496 38.6212 239.496 32.047 c
25.409 +239.496 32.047 l
25.410 +C
25.411 +S 0.5 0.5 1 r f R
25.412 +
25.413 +N
25.414 +303.781 32.047 m
25.415 +303.781 32.047 l
25.416 +303.781 24.8165 309.644 18.9493 316.875 18.9493 c
25.417 +324.105 18.9493 329.973 24.8165 329.973 32.047 c
25.418 +329.973 39.2775 324.105 45.1407 316.875 45.1407 c
25.419 +309.644 45.1407 303.781 39.2775 303.781 32.047 c
25.420 +303.781 32.047 l
25.421 +C
25.422 +S 0 0 0 r f R
25.423 +
25.424 +N
25.425 +304.973 32.047 m
25.426 +304.973 32.047 l
25.427 +304.973 25.4728 310.301 20.1407 316.875 20.1407 c
25.428 +323.449 20.1407 328.781 25.4728 328.781 32.047 c
25.429 +328.781 38.6212 323.449 43.9493 316.875 43.9493 c
25.430 +310.301 43.9493 304.973 38.6212 304.973 32.047 c
25.431 +304.973 32.047 l
25.432 +C
25.433 +S 0.5 0.5 1 r f R
25.434 +
25.435 +N
25.436 +382.351 32.047 m
25.437 +382.351 32.047 l
25.438 +382.351 24.8165 388.215 18.9493 395.445 18.9493 c
25.439 +402.676 18.9493 408.543 24.8165 408.543 32.047 c
25.440 +408.543 39.2775 402.676 45.1407 395.445 45.1407 c
25.441 +388.215 45.1407 382.351 39.2775 382.351 32.047 c
25.442 +382.351 32.047 l
25.443 +C
25.444 +S 0 0 0 r f R
25.445 +
25.446 +N
25.447 +383.543 32.047 m
25.448 +383.543 32.047 l
25.449 +383.543 25.4728 388.871 20.1407 395.445 20.1407 c
25.450 +402.019 20.1407 407.351 25.4728 407.351 32.047 c
25.451 +407.351 38.6212 402.019 43.9493 395.445 43.9493 c
25.452 +388.871 43.9493 383.543 38.6212 383.543 32.047 c
25.453 +383.543 32.047 l
25.454 +C
25.455 +S 0.5 0.5 1 r f R
25.456 +
25.457 +N
25.458 +447.828 32.047 m
25.459 +447.828 32.047 l
25.460 +447.828 24.8165 453.691 18.9493 460.922 18.9493 c
25.461 +468.152 18.9493 474.016 24.8165 474.016 32.047 c
25.462 +474.016 39.2775 468.152 45.1407 460.922 45.1407 c
25.463 +453.691 45.1407 447.828 39.2775 447.828 32.047 c
25.464 +447.828 32.047 l
25.465 +C
25.466 +S 0 0 0 r f R
25.467 +
25.468 +N
25.469 +449.016 32.047 m
25.470 +449.016 32.047 l
25.471 +449.016 25.4728 454.348 20.1407 460.922 20.1407 c
25.472 +467.496 20.1407 472.824 25.4728 472.824 32.047 c
25.473 +472.824 38.6212 467.496 43.9493 460.922 43.9493 c
25.474 +454.348 43.9493 449.016 38.6212 449.016 32.047 c
25.475 +449.016 32.047 l
25.476 +C
25.477 +S 0.5 0.5 1 r f R
25.478 +
25.479 +N
25.480 +526.394 32.047 m
25.481 +526.394 32.047 l
25.482 +526.394 24.8165 532.262 18.9493 539.492 18.9493 c
25.483 +546.723 18.9493 552.586 24.8165 552.586 32.047 c
25.484 +552.586 39.2775 546.723 45.1407 539.492 45.1407 c
25.485 +532.262 45.1407 526.394 39.2775 526.394 32.047 c
25.486 +526.394 32.047 l
25.487 +C
25.488 +S 0 0 0 r f R
25.489 +
25.490 +N
25.491 +527.586 32.047 m
25.492 +527.586 32.047 l
25.493 +527.586 25.4728 532.918 20.1407 539.492 20.1407 c
25.494 +546.066 20.1407 551.394 25.4728 551.394 32.047 c
25.495 +551.394 38.6212 546.066 43.9493 539.492 43.9493 c
25.496 +532.918 43.9493 527.586 38.6212 527.586 32.047 c
25.497 +527.586 32.047 l
25.498 +C
25.499 +S 0.5 0.5 1 r f R
25.500 +
25.501 +N
25.502 +591.871 32.047 m
25.503 +591.871 32.047 l
25.504 +591.871 24.8165 597.734 18.9493 604.965 18.9493 c
25.505 +612.195 18.9493 618.062 24.8165 618.062 32.047 c
25.506 +618.062 39.2775 612.195 45.1407 604.965 45.1407 c
25.507 +597.734 45.1407 591.871 39.2775 591.871 32.047 c
25.508 +591.871 32.047 l
25.509 +C
25.510 +S 0 0 0 r f R
25.511 +
25.512 +N
25.513 +593.062 32.047 m
25.514 +593.062 32.047 l
25.515 +593.062 25.4728 598.39 20.1407 604.965 20.1407 c
25.516 +611.539 20.1407 616.871 25.4728 616.871 32.047 c
25.517 +616.871 38.6212 611.539 43.9493 604.965 43.9493 c
25.518 +598.39 43.9493 593.062 38.6212 593.062 32.047 c
25.519 +593.062 32.047 l
25.520 +C
25.521 +S 0.5 0.5 1 r f R
25.522 +
25.523 +N
25.524 +670.441 32.047 m
25.525 +670.441 32.047 l
25.526 +670.441 24.8165 676.305 18.9493 683.535 18.9493 c
25.527 +690.766 18.9493 696.633 24.8165 696.633 32.047 c
25.528 +696.633 39.2775 690.766 45.1407 683.535 45.1407 c
25.529 +676.305 45.1407 670.441 39.2775 670.441 32.047 c
25.530 +670.441 32.047 l
25.531 +C
25.532 +S 0 0 0 r f R
25.533 +
25.534 +N
25.535 +671.633 32.047 m
25.536 +671.633 32.047 l
25.537 +671.633 25.4728 676.961 20.1407 683.535 20.1407 c
25.538 +690.109 20.1407 695.441 25.4728 695.441 32.047 c
25.539 +695.441 38.6212 690.109 43.9493 683.535 43.9493 c
25.540 +676.961 43.9493 671.633 38.6212 671.633 32.047 c
25.541 +671.633 32.047 l
25.542 +C
25.543 +S 0 0 1 r f R
25.544 +
25.545 +N
25.546 +735.918 32.047 m
25.547 +735.918 32.047 l
25.548 +735.918 24.8165 741.781 18.9493 749.012 18.9493 c
25.549 +756.242 18.9493 762.106 24.8165 762.106 32.047 c
25.550 +762.106 39.2775 756.242 45.1407 749.012 45.1407 c
25.551 +741.781 45.1407 735.918 39.2775 735.918 32.047 c
25.552 +735.918 32.047 l
25.553 +C
25.554 +S 0 0 0 r f R
25.555 +
25.556 +N
25.557 +737.105 32.047 m
25.558 +737.105 32.047 l
25.559 +737.105 25.4728 742.437 20.1407 749.012 20.1407 c
25.560 +755.586 20.1407 760.914 25.4728 760.914 32.047 c
25.561 +760.914 38.6212 755.586 43.9493 749.012 43.9493 c
25.562 +742.437 43.9493 737.105 38.6212 737.105 32.047 c
25.563 +737.105 32.047 l
25.564 +C
25.565 +S 0 0 1 r f R
25.566 +
25.567 +N
25.568 +801.391 32.047 m
25.569 +801.391 32.047 l
25.570 +801.391 24.8165 807.254 18.9493 814.484 18.9493 c
25.571 +821.715 18.9493 827.578 24.8165 827.578 32.047 c
25.572 +827.578 39.2775 821.715 45.1407 814.484 45.1407 c
25.573 +807.254 45.1407 801.391 39.2775 801.391 32.047 c
25.574 +801.391 32.047 l
25.575 +C
25.576 +S 0 0 0 r f R
25.577 +
25.578 +N
25.579 +802.582 32.047 m
25.580 +802.582 32.047 l
25.581 +802.582 25.4728 807.91 20.1407 814.484 20.1407 c
25.582 +821.059 20.1407 826.387 25.4728 826.387 32.047 c
25.583 +826.387 38.6212 821.059 43.9493 814.484 43.9493 c
25.584 +807.91 43.9493 802.582 38.6212 802.582 32.047 c
25.585 +802.582 32.047 l
25.586 +C
25.587 +S 0.5 0.5 1 r f R
25.588 +
25.589 +%%EOF
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/doc/images/bipartite_partitions.eps Thu Dec 10 17:05:35 2009 +0100
26.3 @@ -0,0 +1,114 @@
26.4 +%!PS-Adobe-2.0 EPSF-2.0
26.5 +%%Creator: LEMON, graphToEps()
26.6 +%%CreationDate: Tue Nov 15 16:51:43 2005
26.7 +%%BoundingBox: 0 0 842 596
26.8 +%%EndComments
26.9 +/lb { setlinewidth setrgbcolor newpath moveto
26.10 + 4 2 roll 1 index 1 index curveto stroke } bind def
26.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
26.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
26.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
26.14 + 2 index 1 index sub 2 index 2 index add lineto
26.15 + 2 index 1 index sub 2 index 2 index sub lineto
26.16 + 2 index 1 index add 2 index 2 index sub lineto
26.17 + closepath pop pop pop} bind def
26.18 +/di { newpath 2 index 1 index add 2 index moveto
26.19 + 2 index 2 index 2 index add lineto
26.20 + 2 index 1 index sub 2 index lineto
26.21 + 2 index 2 index 2 index sub lineto
26.22 + closepath pop pop pop} bind def
26.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
26.24 + setrgbcolor 1.1 div c fill
26.25 + } bind def
26.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
26.27 + setrgbcolor 1.1 div sq fill
26.28 + } bind def
26.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
26.30 + setrgbcolor 1.1 div di fill
26.31 + } bind def
26.32 +/arrl 1 def
26.33 +/arrw 0.3 def
26.34 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
26.35 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
26.36 + /w exch def /len exch def
26.37 + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
26.38 + len w sub arrl sub dx dy lrl
26.39 + arrw dy dx neg lrl
26.40 + dx arrl w add mul dy w 2 div arrw add mul sub
26.41 + dy arrl w add mul dx w 2 div arrw add mul add rlineto
26.42 + dx arrl w add mul neg dy w 2 div arrw add mul sub
26.43 + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
26.44 + arrw dy dx neg lrl
26.45 + len w sub arrl sub neg dx dy lrl
26.46 + closepath fill } bind def
26.47 +/cshow { 2 index 2 index moveto dup stringwidth pop
26.48 + neg 2 div fosi .35 mul neg rmoveto show pop pop} def
26.49 +
26.50 +gsave
26.51 +90 rotate
26.52 +0 -842 translate
26.53 +71.6378 15 translate
26.54 +0.389093 dup scale
26.55 +90 rotate
26.56 +1197.47 -613.138 translate
26.57 +%Edges:
26.58 +gsave
26.59 +513.857 -446.322 296.569 -487.43 79.2808 -528.539 0 0 0 2 lb
26.60 +513.857 -446.322 575.52 -315.655 637.183 -184.989 0 0 0 2 lb
26.61 +393.468 566.711 494.771 434.577 596.074 302.442 0 0 0 2 lb
26.62 +393.468 566.711 155.625 579.925 -82.2171 593.138 0 0 0 2 lb
26.63 +393.468 566.711 251.056 450.726 108.644 334.741 0 0 0 2 lb
26.64 +869.153 52.8539 732.613 177.648 596.074 302.442 0 0 0 2 lb
26.65 +869.153 52.8539 753.168 -66.0676 637.183 -184.989 0 0 0 2 lb
26.66 +-82.2171 593.138 -91.0261 346.487 -99.8351 99.8351 0 0 0 2 lb
26.67 +-663.61 546.157 -753.168 394.936 -842.726 243.715 0 0 0 2 lb
26.68 +-663.61 546.157 -574.052 437.513 -484.494 328.869 0 0 0 2 lb
26.69 +-1077.63 161.498 -960.178 202.606 -842.726 243.715 0 0 0 2 lb
26.70 +-1077.63 161.498 -968.987 66.0674 -860.344 -29.3633 0 0 0 2 lb
26.71 +-1177.47 -234.906 -1029.18 -381.722 -880.898 -528.539 0 0 0 2 lb
26.72 +-1177.47 -234.906 -1018.91 -132.135 -860.344 -29.3633 0 0 0 2 lb
26.73 +-880.898 -528.539 -744.359 -387.595 -607.82 -246.651 0 0 0 2 lb
26.74 +-499.175 -499.175 -355.295 -475.685 -211.415 -452.194 0 0 0 2 lb
26.75 +-499.175 -499.175 -553.498 -372.913 -607.82 -246.651 0 0 0 2 lb
26.76 +-499.175 -499.175 -386.587 -315.087 -274 -131 0 0 0 2 lb
26.77 +79.2808 -528.539 -66.0671 -490.366 -211.415 -452.194 0 0 0 2 lb
26.78 +637.183 -184.989 421.363 -253.993 205.543 -322.996 0 0 0 2 lb
26.79 +205.543 -322.996 162.966 -226.097 120.389 -129.198 0 0 0 2 lb
26.80 +399.34 88.0898 259.865 -20.5541 120.389 -129.198 0 0 0 2 lb
26.81 +399.34 88.0898 253.992 211.415 108.644 334.741 0 0 0 2 lb
26.82 +-842.726 243.715 -471.281 171.775 -99.8351 99.8351 0 0 0 2 lb
26.83 +-842.726 243.715 -558.363 56.3575 -274 -131 0 0 0 2 lb
26.84 +-860.344 -29.3633 -734.082 -138.007 -607.82 -246.651 0 0 0 2 lb
26.85 +-211.415 -452.194 -45.513 -290.696 120.389 -129.198 0 0 0 2 lb
26.86 +-99.8351 99.8351 4.40445 217.288 108.644 334.741 0 0 0 2 lb
26.87 +-99.8351 99.8351 -292.165 214.352 -484.494 328.869 0 0 0 2 lb
26.88 +120.389 -129.198 -76.8055 -130.099 -274 -131 0 0 0 2 lb
26.89 +grestore
26.90 +%Nodes:
26.91 +gsave
26.92 +-274 -131 20 1 0 0 nc
26.93 +-607.82 -246.651 20 1 0 0 nc
26.94 +-484.494 328.869 20 0 0 1 nc
26.95 +108.644 334.741 20 0 0 1 nc
26.96 +120.389 -129.198 20 0 0 1 nc
26.97 +-99.8351 99.8351 20 1 0 0 nc
26.98 +-211.415 -452.194 20 1 0 0 nc
26.99 +-860.344 -29.3633 20 0 0 1 nc
26.100 +-842.726 243.715 20 0 0 1 nc
26.101 +399.34 88.0898 20 1 0 0 nc
26.102 +205.543 -322.996 20 1 0 0 nc
26.103 +637.183 -184.989 20 0 0 1 nc
26.104 +79.2808 -528.539 20 0 0 1 nc
26.105 +-499.175 -499.175 20 0 0 1 nc
26.106 +-880.898 -528.539 20 0 0 1 nc
26.107 +-1177.47 -234.906 20 1 0 0 nc
26.108 +-1077.63 161.498 20 1 0 0 nc
26.109 +-663.61 546.157 20 1 0 0 nc
26.110 +-82.2171 593.138 20 0 0 1 nc
26.111 +596.074 302.442 20 0 0 1 nc
26.112 +869.153 52.8539 20 1 0 0 nc
26.113 +393.468 566.711 20 1 0 0 nc
26.114 +513.857 -446.322 20 1 0 0 nc
26.115 +grestore
26.116 +grestore
26.117 +showpage
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/doc/images/connected_components.eps Thu Dec 10 17:05:35 2009 +0100
27.3 @@ -0,0 +1,159 @@
27.4 +%!PS-Adobe-2.0 EPSF-2.0
27.5 +%%Creator: LEMON, graphToEps()
27.6 +%%CreationDate: Fri Nov 4 13:47:12 2005
27.7 +%%BoundingBox: 0 0 842 596
27.8 +%%EndComments
27.9 +/lb { setlinewidth setrgbcolor newpath moveto
27.10 + 4 2 roll 1 index 1 index curveto stroke } bind def
27.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
27.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
27.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
27.14 + 2 index 1 index sub 2 index 2 index add lineto
27.15 + 2 index 1 index sub 2 index 2 index sub lineto
27.16 + 2 index 1 index add 2 index 2 index sub lineto
27.17 + closepath pop pop pop} bind def
27.18 +/di { newpath 2 index 1 index add 2 index moveto
27.19 + 2 index 2 index 2 index add lineto
27.20 + 2 index 1 index sub 2 index lineto
27.21 + 2 index 2 index 2 index sub lineto
27.22 + closepath pop pop pop} bind def
27.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
27.24 + setrgbcolor 1.1 div c fill
27.25 + } bind def
27.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
27.27 + setrgbcolor 1.1 div sq fill
27.28 + } bind def
27.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
27.30 + setrgbcolor 1.1 div di fill
27.31 + } bind def
27.32 +/arrl 1 def
27.33 +/arrw 0.3 def
27.34 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
27.35 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
27.36 + /w exch def /len exch def
27.37 + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
27.38 + len w sub arrl sub dx dy lrl
27.39 + arrw dy dx neg lrl
27.40 + dx arrl w add mul dy w 2 div arrw add mul sub
27.41 + dy arrl w add mul dx w 2 div arrw add mul add rlineto
27.42 + dx arrl w add mul neg dy w 2 div arrw add mul sub
27.43 + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
27.44 + arrw dy dx neg lrl
27.45 + len w sub arrl sub neg dx dy lrl
27.46 + closepath fill } bind def
27.47 +/cshow { 2 index 2 index moveto dup stringwidth pop
27.48 + neg 2 div fosi .35 mul neg rmoveto show pop pop} def
27.49 +
27.50 +gsave
27.51 +90 rotate
27.52 +0 -842 translate
27.53 +71.0944 15 translate
27.54 +0.434694 dup scale
27.55 +90 rotate
27.56 +860.856 -588.349 translate
27.57 +%Edges:
27.58 +gsave
27.59 +574.035 177.301 622.149 225.748 670.264 274.195 0 0 0 2 lb
27.60 +694.579 115.483 682.421 194.839 670.264 274.195 0 0 0 2 lb
27.61 +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 0 2 lb
27.62 +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 0 2 lb
27.63 +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 0 2 lb
27.64 +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 0 2 lb
27.65 +286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 0 2 lb
27.66 +438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 0 2 lb
27.67 +438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 0 2 lb
27.68 +397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 0 2 lb
27.69 +366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 0 2 lb
27.70 +271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 0 2 lb
27.71 +271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 0 2 lb
27.72 +277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 0 2 lb
27.73 +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0 0 2 lb
27.74 +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0 2 lb
27.75 +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0 2 lb
27.76 +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0 2 lb
27.77 +906.312 201.403 946.592 42.798 986.873 -115.807 0 0 0 2 lb
27.78 +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 0 2 lb
27.79 +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 0 2 lb
27.80 +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0 0 0 2 lb
27.81 +422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 0 2 lb
27.82 +422.945 521.129 376.371 417.911 329.797 314.692 0 0 0 2 lb
27.83 +422.945 521.129 474.554 276.928 526.164 32.7279 0 0 0 2 lb
27.84 +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 0 2 lb
27.85 +329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 0 2 lb
27.86 +-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 0 2 lb
27.87 +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 0 2 lb
27.88 +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 0 2 lb
27.89 +526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 0 2 lb
27.90 +730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 0 2 lb
27.91 +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 0 0 0 2 lb
27.92 +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 0 2 lb
27.93 +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 0 2 lb
27.94 +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 0 2 lb
27.95 +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 0 2 lb
27.96 +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 0 2 lb
27.97 +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 0 2 lb
27.98 +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 0 2 lb
27.99 +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 0 2 lb
27.100 +116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 0 2 lb
27.101 +-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 0 2 lb
27.102 +-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 0 2 lb
27.103 +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 0 2 lb
27.104 +-180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 0 2 lb
27.105 +-180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 0 2 lb
27.106 +-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 0 2 lb
27.107 +-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 0 2 lb
27.108 +-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 0 2 lb
27.109 +670.264 274.195 629.188 409.347 588.113 544.499 0 0 0 2 lb
27.110 +670.264 274.195 797.466 341.771 924.667 409.347 0 0 0 2 lb
27.111 +588.113 544.499 756.39 476.923 924.667 409.347 0 0 0 2 lb
27.112 +-689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 0 2 lb
27.113 +-689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 0 2 lb
27.114 +grestore
27.115 +%Nodes:
27.116 +gsave
27.117 +-567.302 43.6423 20 0 0 0 nc
27.118 +-689.204 -237.261 20 0 0 0 nc
27.119 +924.667 409.347 20 1 0 0 nc
27.120 +588.113 544.499 20 1 0 0 nc
27.121 +670.264 274.195 20 1 0 0 nc
27.122 +-371.2 568.349 20 0 1 0 nc
27.123 +-132.697 451.748 20 0 1 0 nc
27.124 +-416.25 345.746 20 0 1 0 nc
27.125 +-180.397 245.045 20 0 1 0 nc
27.126 +-13.4452 133.743 20 0 1 0 nc
27.127 +-262.548 107.243 20 0 1 0 nc
27.128 +201.208 38.3422 20 0 1 0 nc
27.129 +116.407 -173.66 20 0 1 0 nc
27.130 +-26.6953 -19.9585 20 0 1 0 nc
27.131 +-539.894 -262.64 20 0 0 1 nc
27.132 +-323.543 -433.964 20 0 0 1 nc
27.133 +-309.657 -57.9033 20 0 0 1 nc
27.134 +-67.9734 -347.42 20 0 0 1 nc
27.135 +415.393 -289.516 20 0 0 1 nc
27.136 +730.084 -307.139 20 0 0 1 nc
27.137 +526.164 32.7279 20 0 0 1 nc
27.138 +762.812 -17.6227 20 0 0 1 nc
27.139 +-67.9734 319.727 20 0 0 1 nc
27.140 +329.797 314.692 20 0 0 1 nc
27.141 +-5.03507 561.41 20 0 0 1 nc
27.142 +422.945 521.129 20 0 0 1 nc
27.143 +-470.779 158.605 20 0 0 1 nc
27.144 +986.873 -115.807 20 0 0 1 nc
27.145 +906.312 201.403 20 0 0 1 nc
27.146 +-767.847 113.289 20 0 0 1 nc
27.147 +-579.033 445.603 20 0 0 1 nc
27.148 +-840.856 -246.718 20 0 0 1 nc
27.149 +206.221 -205.967 20 1 1 0 nc
27.150 +277.311 -252.33 20 1 1 0 nc
27.151 +271.13 -175.058 20 1 1 0 nc
27.152 +366.947 -110.15 20 1 1 0 nc
27.153 +397.855 -196.694 20 1 1 0 nc
27.154 +438.037 -88.514 20 1 1 0 nc
27.155 +286.584 -48.3327 20 1 1 0 nc
27.156 +212.403 -23.6057 20 1 1 0 nc
27.157 +280.402 10.3938 20 1 1 0 nc
27.158 +694.579 115.483 20 1 0 0 nc
27.159 +574.035 177.301 20 1 0 0 nc
27.160 +grestore
27.161 +grestore
27.162 +showpage
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/doc/images/edge_biconnected_components.eps Thu Dec 10 17:05:35 2009 +0100
28.3 @@ -0,0 +1,159 @@
28.4 +%!PS-Adobe-2.0 EPSF-2.0
28.5 +%%Creator: LEMON, graphToEps()
28.6 +%%CreationDate: Fri Nov 4 13:47:12 2005
28.7 +%%BoundingBox: 0 0 842 596
28.8 +%%EndComments
28.9 +/lb { setlinewidth setrgbcolor newpath moveto
28.10 + 4 2 roll 1 index 1 index curveto stroke } bind def
28.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
28.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
28.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
28.14 + 2 index 1 index sub 2 index 2 index add lineto
28.15 + 2 index 1 index sub 2 index 2 index sub lineto
28.16 + 2 index 1 index add 2 index 2 index sub lineto
28.17 + closepath pop pop pop} bind def
28.18 +/di { newpath 2 index 1 index add 2 index moveto
28.19 + 2 index 2 index 2 index add lineto
28.20 + 2 index 1 index sub 2 index lineto
28.21 + 2 index 2 index 2 index sub lineto
28.22 + closepath pop pop pop} bind def
28.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
28.24 + setrgbcolor 1.1 div c fill
28.25 + } bind def
28.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
28.27 + setrgbcolor 1.1 div sq fill
28.28 + } bind def
28.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
28.30 + setrgbcolor 1.1 div di fill
28.31 + } bind def
28.32 +/arrl 1 def
28.33 +/arrw 0.3 def
28.34 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
28.35 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
28.36 + /w exch def /len exch def
28.37 + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
28.38 + len w sub arrl sub dx dy lrl
28.39 + arrw dy dx neg lrl
28.40 + dx arrl w add mul dy w 2 div arrw add mul sub
28.41 + dy arrl w add mul dx w 2 div arrw add mul add rlineto
28.42 + dx arrl w add mul neg dy w 2 div arrw add mul sub
28.43 + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
28.44 + arrw dy dx neg lrl
28.45 + len w sub arrl sub neg dx dy lrl
28.46 + closepath fill } bind def
28.47 +/cshow { 2 index 2 index moveto dup stringwidth pop
28.48 + neg 2 div fosi .35 mul neg rmoveto show pop pop} def
28.49 +
28.50 +gsave
28.51 +90 rotate
28.52 +0 -842 translate
28.53 +71.0944 15 translate
28.54 +0.434694 dup scale
28.55 +90 rotate
28.56 +860.856 -588.349 translate
28.57 +%Edges:
28.58 +gsave
28.59 +574.035 177.301 622.149 225.748 670.264 274.195 1 0 0 2 lb
28.60 +694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 2 lb
28.61 +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 1 2 lb
28.62 +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 1 2 lb
28.63 +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 1 2 lb
28.64 +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 1 2 lb
28.65 +286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 1 2 lb
28.66 +438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 1 2 lb
28.67 +438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 1 2 lb
28.68 +397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 1 2 lb
28.69 +366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 1 2 lb
28.70 +271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 1 2 lb
28.71 +271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 1 2 lb
28.72 +277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 1 2 lb
28.73 +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 1 0 0 2 lb
28.74 +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 1 2 lb
28.75 +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 1 2 lb
28.76 +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 1 2 lb
28.77 +906.312 201.403 946.592 42.798 986.873 -115.807 0 0 1 2 lb
28.78 +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 1 2 lb
28.79 +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 1 2 lb
28.80 +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 1 0 0 2 lb
28.81 +422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 1 2 lb
28.82 +422.945 521.129 376.371 417.911 329.797 314.692 0 0 1 2 lb
28.83 +422.945 521.129 474.554 276.928 526.164 32.7279 0 0 1 2 lb
28.84 +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 1 2 lb
28.85 +329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 1 2 lb
28.86 +-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 1 2 lb
28.87 +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 1 2 lb
28.88 +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 1 2 lb
28.89 +526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 1 2 lb
28.90 +730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 1 2 lb
28.91 +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0 0 2 lb
28.92 +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 1 2 lb
28.93 +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 1 2 lb
28.94 +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 1 2 lb
28.95 +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 1 2 lb
28.96 +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 1 2 lb
28.97 +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 1 2 lb
28.98 +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 1 2 lb
28.99 +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 1 2 lb
28.100 +116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 1 2 lb
28.101 +-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 1 2 lb
28.102 +-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 1 2 lb
28.103 +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 1 2 lb
28.104 +-180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 1 2 lb
28.105 +-180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 1 2 lb
28.106 +-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 1 2 lb
28.107 +-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 1 2 lb
28.108 +-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 1 2 lb
28.109 +670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 2 lb
28.110 +670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 2 lb
28.111 +588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 2 lb
28.112 +-689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 1 2 lb
28.113 +-689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 1 2 lb
28.114 +grestore
28.115 +%Nodes:
28.116 +gsave
28.117 +-567.302 43.6423 20 0 0 0 nc
28.118 +-689.204 -237.261 20 0 0 0 nc
28.119 +924.667 409.347 20 0 0 1 nc
28.120 +588.113 544.499 20 0 0 1 nc
28.121 +670.264 274.195 20 0 0 1 nc
28.122 +-371.2 568.349 20 1 1 0 nc
28.123 +-132.697 451.748 20 1 1 0 nc
28.124 +-416.25 345.746 20 1 1 0 nc
28.125 +-180.397 245.045 20 1 1 0 nc
28.126 +-13.4452 133.743 20 1 1 0 nc
28.127 +-262.548 107.243 20 1 1 0 nc
28.128 +201.208 38.3422 20 1 1 0 nc
28.129 +116.407 -173.66 20 1 1 0 nc
28.130 +-26.6953 -19.9585 20 1 1 0 nc
28.131 +-539.894 -262.64 20 0 0.5 0 nc
28.132 +-323.543 -433.964 20 0 0.5 0 nc
28.133 +-309.657 -57.9033 20 0 0.5 0 nc
28.134 +-67.9734 -347.42 20 0 0.5 0 nc
28.135 +415.393 -289.516 20 0.5 0 0 nc
28.136 +730.084 -307.139 20 0.5 0 0 nc
28.137 +526.164 32.7279 20 0.5 0 0 nc
28.138 +762.812 -17.6227 20 0.5 0 0 nc
28.139 +-67.9734 319.727 20 0.5 0 0 nc
28.140 +329.797 314.692 20 0.5 0 0 nc
28.141 +-5.03507 561.41 20 0.5 0 0 nc
28.142 +422.945 521.129 20 0.5 0 0 nc
28.143 +-470.779 158.605 20 0 1 1 nc
28.144 +986.873 -115.807 20 0.5 0 0 nc
28.145 +906.312 201.403 20 0.5 0 0 nc
28.146 +-767.847 113.289 20 0 1 1 nc
28.147 +-579.033 445.603 20 0 1 1 nc
28.148 +-840.856 -246.718 20 1 0 1 nc
28.149 +206.221 -205.967 20 0 0 0.5 nc
28.150 +277.311 -252.33 20 0 0 0.5 nc
28.151 +271.13 -175.058 20 0 0 0.5 nc
28.152 +366.947 -110.15 20 0 0 0.5 nc
28.153 +397.855 -196.694 20 0 0 0.5 nc
28.154 +438.037 -88.514 20 0 0 0.5 nc
28.155 +286.584 -48.3327 20 0 0 0.5 nc
28.156 +212.403 -23.6057 20 0 0 0.5 nc
28.157 +280.402 10.3938 20 0 0 0.5 nc
28.158 +694.579 115.483 20 1 0 0 nc
28.159 +574.035 177.301 20 0 1 0 nc
28.160 +grestore
28.161 +grestore
28.162 +showpage
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/doc/images/grid_graph.eps Thu Dec 10 17:05:35 2009 +0100
29.3 @@ -0,0 +1,286 @@
29.4 +%!PS-Adobe-2.0 EPSF-2.0
29.5 +%%Title: Grid undirected graph
29.6 +%%Copyright: (C) 2006 LEMON Project
29.7 +%%Creator: LEMON, graphToEps()
29.8 +%%CreationDate: Fri Sep 29 11:55:56 2006
29.9 +%%BoundingBox: 0 0 985 1144
29.10 +%%EndComments
29.11 +/lb { setlinewidth setrgbcolor newpath moveto
29.12 + 4 2 roll 1 index 1 index curveto stroke } bind def
29.13 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
29.14 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
29.15 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
29.16 + 2 index 1 index sub 2 index 2 index add lineto
29.17 + 2 index 1 index sub 2 index 2 index sub lineto
29.18 + 2 index 1 index add 2 index 2 index sub lineto
29.19 + closepath pop pop pop} bind def
29.20 +/di { newpath 2 index 1 index add 2 index moveto
29.21 + 2 index 2 index 2 index add lineto
29.22 + 2 index 1 index sub 2 index lineto
29.23 + 2 index 2 index 2 index sub lineto
29.24 + closepath pop pop pop} bind def
29.25 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
29.26 + setrgbcolor 1.1 div c fill
29.27 + } bind def
29.28 +/arrl 1 def
29.29 +/arrw 0.3 def
29.30 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
29.31 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
29.32 + /w exch def /len exch def
29.33 + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
29.34 + len w sub arrl sub dx dy lrl
29.35 + arrw dy dx neg lrl
29.36 + dx arrl w add mul dy w 2 div arrw add mul sub
29.37 + dy arrl w add mul dx w 2 div arrw add mul add rlineto
29.38 + dx arrl w add mul neg dy w 2 div arrw add mul sub
29.39 + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
29.40 + arrw dy dx neg lrl
29.41 + len w sub arrl sub neg dx dy lrl
29.42 + closepath fill } bind def
29.43 +/cshow { 2 index 2 index moveto dup stringwidth pop
29.44 + neg 2 div fosi .35 mul neg rmoveto show pop pop} def
29.45 +
29.46 +gsave
29.47 +2 2 scale
29.48 +50 40 translate
29.49 +5.5000 5.5000 scale
29.50 +% 1.14018 1.14018 translate
29.51 +%Edges:
29.52 +gsave
29.53 +70 80 70 90 0 0 0 0.5000 l
29.54 +70 70 70 80 0 0 0 0.5000 l
29.55 +70 60 70 70 0 0 0 0.5000 l
29.56 +70 50 70 60 0 0 0 0.5000 l
29.57 +70 40 70 50 0 0 0 0.5000 l
29.58 +70 30 70 40 0 0 0 0.5000 l
29.59 +70 20 70 30 0 0 0 0.5000 l
29.60 +70 10 70 20 0 0 0 0.5000 l
29.61 +70 0 70 10 0 0 0 0.5000 l
29.62 +60 80 60 90 0 0 0 0.5000 l
29.63 +60 70 60 80 0 0 0 0.5000 l
29.64 +60 60 60 70 0 0 0 0.5000 l
29.65 +60 50 60 60 0 0 0 0.5000 l
29.66 +60 40 60 50 0 0 0 0.5000 l
29.67 +60 30 60 40 0 0 0 0.5000 l
29.68 +60 20 60 30 0 0 0 0.5000 l
29.69 +60 10 60 20 0 0 0 0.5000 l
29.70 +60 0 60 10 0 0 0 0.5000 l
29.71 +50 80 50 90 0 0 0 0.5000 l
29.72 +50 70 50 80 0 0 0 0.5000 l
29.73 +50 60 50 70 0 0 0 0.5000 l
29.74 +50 50 50 60 0 0 0 0.5000 l
29.75 +50 40 50 50 0 0 0 0.5000 l
29.76 +50 30 50 40 0 0 0 0.5000 l
29.77 +50 20 50 30 0 0 0 0.5000 l
29.78 +50 10 50 20 0 0 0 0.5000 l
29.79 +50 0 50 10 0 0 0 0.5000 l
29.80 +40 80 40 90 0 0 0 0.5000 l
29.81 +40 70 40 80 0 0 0 0.5000 l
29.82 +40 60 40 70 0 0 0 0.5000 l
29.83 +40 50 40 60 0 0 0 0.5000 l
29.84 +40 40 40 50 0 0 0 0.5000 l
29.85 +40 30 40 40 0 0 0 0.5000 l
29.86 +40 20 40 30 0 0 0 0.5000 l
29.87 +40 10 40 20 0 0 0 0.5000 l
29.88 +40 0 40 10 0 0 0 0.5000 l
29.89 +30 80 30 90 0 0 0 0.5000 l
29.90 +30 70 30 80 0 0 0 0.5000 l
29.91 +30 60 30 70 0 0 0 0.5000 l
29.92 +30 50 30 60 0 0 0 0.5000 l
29.93 +30 40 30 50 0 0 0 0.5000 l
29.94 +30 30 30 40 0 0 0 0.5000 l
29.95 +30 20 30 30 0 0 0 0.5000 l
29.96 +30 10 30 20 0 0 0 0.5000 l
29.97 +30 0 30 10 0 0 0 0.5000 l
29.98 +20 80 20 90 0 0 0 0.5000 l
29.99 +20 70 20 80 0 0 0 0.5000 l
29.100 +20 60 20 70 0 0 0 0.5000 l
29.101 +20 50 20 60 0 0 0 0.5000 l
29.102 +20 40 20 50 0 0 0 0.5000 l
29.103 +20 30 20 40 0 0 0 0.5000 l
29.104 +20 20 20 30 0 0 0 0.5000 l
29.105 +20 10 20 20 0 0 0 0.5000 l
29.106 +20 0 20 10 0 0 0 0.5000 l
29.107 +10 80 10 90 0 0 0 0.5000 l
29.108 +10 70 10 80 0 0 0 0.5000 l
29.109 +10 60 10 70 0 0 0 0.5000 l
29.110 +10 50 10 60 0 0 0 0.5000 l
29.111 +10 40 10 50 0 0 0 0.5000 l
29.112 +10 30 10 40 0 0 0 0.5000 l
29.113 +10 20 10 30 0 0 0 0.5000 l
29.114 +10 10 10 20 0 0 0 0.5000 l
29.115 +10 0 10 10 0 0 0 0.5000 l
29.116 +0 80 0 90 0 0 0 0.5000 l
29.117 +0 70 0 80 0 0 0 0.5000 l
29.118 +0 60 0 70 0 0 0 0.5000 l
29.119 +0 50 0 60 0 0 0 0.5000 l
29.120 +0 40 0 50 0 0 0 0.5000 l
29.121 +0 30 0 40 0 0 0 0.5000 l
29.122 +0 20 0 30 0 0 0 0.5000 l
29.123 +0 10 0 20 0 0 0 0.5000 l
29.124 +0 0 0 10 0 0 0 0.5000 l
29.125 +60 90 70 90 0 0 0 0.5000 l
29.126 +60 80 70 80 0 0 0 0.5000 l
29.127 +60 70 70 70 0 0 0 0.5000 l
29.128 +60 60 70 60 0 0 0 0.5000 l
29.129 +60 50 70 50 0 0 0 0.5000 l
29.130 +60 40 70 40 0 0 0 0.5000 l
29.131 +60 30 70 30 0 0 0 0.5000 l
29.132 +60 20 70 20 0 0 0 0.5000 l
29.133 +60 10 70 10 0 0 0 0.5000 l
29.134 +60 0 70 0 0 0 0 0.5000 l
29.135 +50 90 60 90 0 0 0 0.5000 l
29.136 +50 80 60 80 0 0 0 0.5000 l
29.137 +50 70 60 70 0 0 0 0.5000 l
29.138 +50 60 60 60 0 0 0 0.5000 l
29.139 +50 50 60 50 0 0 0 0.5000 l
29.140 +50 40 60 40 0 0 0 0.5000 l
29.141 +50 30 60 30 0 0 0 0.5000 l
29.142 +50 20 60 20 0 0 0 0.5000 l
29.143 +50 10 60 10 0 0 0 0.5000 l
29.144 +50 0 60 0 0 0 0 0.5000 l
29.145 +40 90 50 90 0 0 0 0.5000 l
29.146 +40 80 50 80 0 0 0 0.5000 l
29.147 +40 70 50 70 0 0 0 0.5000 l
29.148 +40 60 50 60 0 0 0 0.5000 l
29.149 +40 50 50 50 0 0 0 0.5000 l
29.150 +40 40 50 40 0 0 0 0.5000 l
29.151 +40 30 50 30 0 0 0 0.5000 l
29.152 +40 20 50 20 0 0 0 0.5000 l
29.153 +40 10 50 10 0 0 0 0.5000 l
29.154 +40 0 50 0 0 0 0 0.5000 l
29.155 +30 90 40 90 0 0 0 0.5000 l
29.156 +30 80 40 80 0 0 0 0.5000 l
29.157 +30 70 40 70 0 0 0 0.5000 l
29.158 +30 60 40 60 0 0 0 0.5000 l
29.159 +30 50 40 50 0 0 0 0.5000 l
29.160 +30 40 40 40 0 0 0 0.5000 l
29.161 +30 30 40 30 0 0 0 0.5000 l
29.162 +30 20 40 20 0 0 0 0.5000 l
29.163 +30 10 40 10 0 0 0 0.5000 l
29.164 +30 0 40 0 0 0 0 0.5000 l
29.165 +20 90 30 90 0 0 0 0.5000 l
29.166 +20 80 30 80 0 0 0 0.5000 l
29.167 +20 70 30 70 0 0 0 0.5000 l
29.168 +20 60 30 60 0 0 0 0.5000 l
29.169 +20 50 30 50 0 0 0 0.5000 l
29.170 +20 40 30 40 0 0 0 0.5000 l
29.171 +20 30 30 30 0 0 0 0.5000 l
29.172 +20 20 30 20 0 0 0 0.5000 l
29.173 +20 10 30 10 0 0 0 0.5000 l
29.174 +20 0 30 0 0 0 0 0.5000 l
29.175 +10 90 20 90 0 0 0 0.5000 l
29.176 +10 80 20 80 0 0 0 0.5000 l
29.177 +10 70 20 70 0 0 0 0.5000 l
29.178 +10 60 20 60 0 0 0 0.5000 l
29.179 +10 50 20 50 0 0 0 0.5000 l
29.180 +10 40 20 40 0 0 0 0.5000 l
29.181 +10 30 20 30 0 0 0 0.5000 l
29.182 +10 20 20 20 0 0 0 0.5000 l
29.183 +10 10 20 10 0 0 0 0.5000 l
29.184 +10 0 20 0 0 0 0 0.5000 l
29.185 +0 90 10 90 0 0 0 0.5000 l
29.186 +0 80 10 80 0 0 0 0.5000 l
29.187 +0 70 10 70 0 0 0 0.5000 l
29.188 +0 60 10 60 0 0 0 0.5000 l
29.189 +0 50 10 50 0 0 0 0.5000 l
29.190 +0 40 10 40 0 0 0 0.5000 l
29.191 +0 30 10 30 0 0 0 0.5000 l
29.192 +0 20 10 20 0 0 0 0.5000 l
29.193 +0 10 10 10 0 0 0 0.5000 l
29.194 +0 0 10 0 0 0 0 0.5000 l
29.195 +grestore
29.196 +%Nodes:
29.197 +gsave
29.198 +70 90 1.4000 0 0 0 nc
29.199 +70 80 1.4000 1 1 1 nc
29.200 +70 70 1.4000 1 1 1 nc
29.201 +70 60 1.4000 1 1 1 nc
29.202 +70 50 1.4000 1 1 1 nc
29.203 +70 40 1.4000 1 1 1 nc
29.204 +70 30 1.4000 1 1 1 nc
29.205 +70 20 1.4000 1 1 1 nc
29.206 +70 10 1.4000 1 1 1 nc
29.207 +70 0 1.4000 0 0 0 nc
29.208 +60 90 1.4000 1 1 1 nc
29.209 +60 80 1.4000 1 1 1 nc
29.210 +60 70 1.4000 1 1 1 nc
29.211 +60 60 1.4000 1 1 1 nc
29.212 +60 50 1.4000 1 1 1 nc
29.213 +60 40 1.4000 1 1 1 nc
29.214 +60 30 1.4000 1 1 1 nc
29.215 +60 20 1.4000 1 1 1 nc
29.216 +60 10 1.4000 1 1 1 nc
29.217 +60 0 1.4000 1 1 1 nc
29.218 +50 90 1.4000 1 1 1 nc
29.219 +50 80 1.4000 1 1 1 nc
29.220 +50 70 1.4000 1 1 1 nc
29.221 +50 60 1.4000 1 1 1 nc
29.222 +50 50 1.4000 1 1 1 nc
29.223 +50 40 1.4000 1 1 1 nc
29.224 +50 30 1.4000 1 1 1 nc
29.225 +50 20 1.4000 1 1 1 nc
29.226 +50 10 1.4000 1 1 1 nc
29.227 +50 0 1.4000 1 1 1 nc
29.228 +40 90 1.4000 1 1 1 nc
29.229 +40 80 1.4000 1 1 1 nc
29.230 +40 70 1.4000 1 1 1 nc
29.231 +40 60 1.4000 1 1 1 nc
29.232 +40 50 1.4000 1 1 1 nc
29.233 +40 40 1.4000 1 1 1 nc
29.234 +40 30 1.4000 1 1 1 nc
29.235 +40 20 1.4000 1 1 1 nc
29.236 +40 10 1.4000 1 1 1 nc
29.237 +40 0 1.4000 1 1 1 nc
29.238 +30 90 1.4000 1 1 1 nc
29.239 +30 80 1.4000 1 1 1 nc
29.240 +30 70 1.4000 1 1 1 nc
29.241 +30 60 1.4000 1 1 1 nc
29.242 +30 50 1.4000 1 1 1 nc
29.243 +30 40 1.4000 1 1 1 nc
29.244 +30 30 1.4000 1 1 1 nc
29.245 +30 20 1.4000 1 1 1 nc
29.246 +30 10 1.4000 1 1 1 nc
29.247 +30 0 1.4000 1 1 1 nc
29.248 +20 90 1.4000 1 1 1 nc
29.249 +20 80 1.4000 1 1 1 nc
29.250 +20 70 1.4000 1 1 1 nc
29.251 +20 60 1.4000 1 1 1 nc
29.252 +20 50 1.4000 1 1 1 nc
29.253 +20 40 1.4000 1 1 1 nc
29.254 +20 30 1.4000 1 1 1 nc
29.255 +20 20 1.4000 1 1 1 nc
29.256 +20 10 1.4000 1 1 1 nc
29.257 +20 0 1.4000 1 1 1 nc
29.258 +10 90 1.4000 1 1 1 nc
29.259 +10 80 1.4000 1 1 1 nc
29.260 +10 70 1.4000 1 1 1 nc
29.261 +10 60 1.4000 1 1 1 nc
29.262 +10 50 1.4000 1 1 1 nc
29.263 +10 40 1.4000 1 1 1 nc
29.264 +10 30 1.4000 1 1 1 nc
29.265 +10 20 1.4000 1 1 1 nc
29.266 +10 10 1.4000 1 1 1 nc
29.267 +10 0 1.4000 1 1 1 nc
29.268 +0 90 1.4000 0 0 0 nc
29.269 +0 80 1.4000 1 1 1 nc
29.270 +0 70 1.4000 1 1 1 nc
29.271 +0 60 1.4000 1 1 1 nc
29.272 +0 50 1.4000 1 1 1 nc
29.273 +0 40 1.4000 1 1 1 nc
29.274 +0 30 1.4000 1 1 1 nc
29.275 +0 20 1.4000 1 1 1 nc
29.276 +0 10 1.4000 1 1 1 nc
29.277 +0 0 1.4000 0 0 0 nc
29.278 +grestore
29.279 +gsave
29.280 +/fosi 3.5 def
29.281 +(Helvetica) findfont fosi scalefont setfont
29.282 +0 0 0 setrgbcolor
29.283 +0 95 ((0,height-1)) cshow
29.284 +67 95 ((width-1,height-1)) cshow
29.285 +0 -5 ((0,0)) cshow
29.286 +70 -5 ((width-1,0)) cshow
29.287 +grestore
29.288 +grestore
29.289 +showpage
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/doc/images/node_biconnected_components.eps Thu Dec 10 17:05:35 2009 +0100
30.3 @@ -0,0 +1,159 @@
30.4 +%!PS-Adobe-2.0 EPSF-2.0
30.5 +%%Creator: LEMON, graphToEps()
30.6 +%%CreationDate: Fri Nov 4 13:47:12 2005
30.7 +%%BoundingBox: 0 0 842 596
30.8 +%%EndComments
30.9 +/lb { setlinewidth setrgbcolor newpath moveto
30.10 + 4 2 roll 1 index 1 index curveto stroke } bind def
30.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
30.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
30.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
30.14 + 2 index 1 index sub 2 index 2 index add lineto
30.15 + 2 index 1 index sub 2 index 2 index sub lineto
30.16 + 2 index 1 index add 2 index 2 index sub lineto
30.17 + closepath pop pop pop} bind def
30.18 +/di { newpath 2 index 1 index add 2 index moveto
30.19 + 2 index 2 index 2 index add lineto
30.20 + 2 index 1 index sub 2 index lineto
30.21 + 2 index 2 index 2 index sub lineto
30.22 + closepath pop pop pop} bind def
30.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
30.24 + setrgbcolor 1.1 div c fill
30.25 + } bind def
30.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
30.27 + setrgbcolor 1.1 div sq fill
30.28 + } bind def
30.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
30.30 + setrgbcolor 1.1 div di fill
30.31 + } bind def
30.32 +/arrl 1 def
30.33 +/arrw 0.3 def
30.34 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
30.35 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
30.36 + /w exch def /len exch def
30.37 + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
30.38 + len w sub arrl sub dx dy lrl
30.39 + arrw dy dx neg lrl
30.40 + dx arrl w add mul dy w 2 div arrw add mul sub
30.41 + dy arrl w add mul dx w 2 div arrw add mul add rlineto
30.42 + dx arrl w add mul neg dy w 2 div arrw add mul sub
30.43 + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
30.44 + arrw dy dx neg lrl
30.45 + len w sub arrl sub neg dx dy lrl
30.46 + closepath fill } bind def
30.47 +/cshow { 2 index 2 index moveto dup stringwidth pop
30.48 + neg 2 div fosi .35 mul neg rmoveto show pop pop} def
30.49 +
30.50 +gsave
30.51 +90 rotate
30.52 +0 -842 translate
30.53 +71.0944 15 translate
30.54 +0.434694 dup scale
30.55 +90 rotate
30.56 +860.856 -588.349 translate
30.57 +%Edges:
30.58 +gsave
30.59 +574.035 177.301 622.149 225.748 670.264 274.195 0 1 0 5 lb
30.60 +694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 5 lb
30.61 +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 1 1 0.5 5 lb
30.62 +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 1 1 0.5 5 lb
30.63 +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 1 1 0.5 5 lb
30.64 +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 1 0.5 1 5 lb
30.65 +286.584 -48.3327 278.857 -111.695 271.13 -175.058 1 0.5 1 5 lb
30.66 +438.037 -88.514 417.946 -142.604 397.855 -196.694 0.5 0.5 1 5 lb
30.67 +438.037 -88.514 402.492 -99.332 366.947 -110.15 0.5 0.5 1 5 lb
30.68 +397.855 -196.694 382.401 -153.422 366.947 -110.15 0.5 0.5 1 5 lb
30.69 +366.947 -110.15 319.038 -142.604 271.13 -175.058 1 0.5 1 5 lb
30.70 +271.13 -175.058 274.221 -213.694 277.311 -252.33 0.5 1 1 5 lb
30.71 +271.13 -175.058 238.675 -190.512 206.221 -205.967 0.5 1 1 5 lb
30.72 +277.311 -252.33 241.766 -229.149 206.221 -205.967 0.5 1 1 5 lb
30.73 +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0.5 0 5 lb
30.74 +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0.5 5 lb
30.75 +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0.5 5 lb
30.76 +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0.5 5 lb
30.77 +906.312 201.403 946.592 42.798 986.873 -115.807 0 0.5 0.5 5 lb
30.78 +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0.5 0.5 5 lb
30.79 +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0.5 0.5 5 lb
30.80 +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0.5 0.5 0 5 lb
30.81 +422.945 521.129 208.955 541.269 -5.03507 561.41 0.5 0 0.5 5 lb
30.82 +422.945 521.129 376.371 417.911 329.797 314.692 0.5 0 0.5 5 lb
30.83 +422.945 521.129 474.554 276.928 526.164 32.7279 0.5 0 0.5 5 lb
30.84 +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0.5 0 0.5 5 lb
30.85 +329.797 314.692 130.912 317.209 -67.9734 319.727 0.5 0 0.5 5 lb
30.86 +-67.9734 319.727 229.095 176.227 526.164 32.7279 0.5 0 0.5 5 lb
30.87 +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0.5 0.5 0.5 5 lb
30.88 +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0.5 0.5 0.5 5 lb
30.89 +526.164 32.7279 470.779 -128.394 415.393 -289.516 0.5 0.5 0.5 5 lb
30.90 +730.084 -307.139 572.738 -298.327 415.393 -289.516 0.5 0.5 0.5 5 lb
30.91 +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0.5 0.5 5 lb
30.92 +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0.5 1 0.5 5 lb
30.93 +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0.5 1 0.5 5 lb
30.94 +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0.5 1 0.5 5 lb
30.95 +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0.5 1 0.5 5 lb
30.96 +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 1 1 0 5 lb
30.97 +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 1 1 0 5 lb
30.98 +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 1 0 1 5 lb
30.99 +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 1 0 1 5 lb
30.100 +116.407 -173.66 158.808 -67.6589 201.208 38.3422 1 1 0 5 lb
30.101 +-262.548 107.243 -137.997 120.493 -13.4452 133.743 1 0 1 5 lb
30.102 +-262.548 107.243 -221.472 176.144 -180.397 245.045 1 0 1 5 lb
30.103 +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 1 0 1 5 lb
30.104 +-180.397 245.045 -140.307 344.649 -132.697 451.748 0 1 1 5 lb
30.105 +-180.397 245.045 -172.787 352.144 -132.697 451.748 0 1 1 5 lb
30.106 +-416.25 345.746 -274.474 398.747 -132.697 451.748 0.5 0 0 5 lb
30.107 +-416.25 345.746 -393.725 457.048 -371.2 568.349 0.5 0 0 5 lb
30.108 +-132.697 451.748 -251.948 510.048 -371.2 568.349 0.5 0 0 5 lb
30.109 +670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 5 lb
30.110 +670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 5 lb
30.111 +588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 5 lb
30.112 +-689.204 -237.261 -612.964 -103.444 -567.302 43.6423 0 0 0 5 lb
30.113 +-689.204 -237.261 -643.542 -90.1744 -567.302 43.6423 0 0 0 5 lb
30.114 +grestore
30.115 +%Nodes:
30.116 +gsave
30.117 +-567.302 43.6423 20 0 0 1 nc
30.118 +-689.204 -237.261 20 0 0 1 nc
30.119 +924.667 409.347 20 0 0 1 nc
30.120 +588.113 544.499 20 0 0 1 nc
30.121 +670.264 274.195 20 1 0 0 nc
30.122 +-371.2 568.349 20 0 0 1 nc
30.123 +-132.697 451.748 20 1 0 0 nc
30.124 +-416.25 345.746 20 0 0 1 nc
30.125 +-180.397 245.045 20 1 0 0 nc
30.126 +-13.4452 133.743 20 0 0 1 nc
30.127 +-262.548 107.243 20 0 0 1 nc
30.128 +201.208 38.3422 20 0 0 1 nc
30.129 +116.407 -173.66 20 0 0 1 nc
30.130 +-26.6953 -19.9585 20 1 0 0 nc
30.131 +-539.894 -262.64 20 0 0 1 nc
30.132 +-323.543 -433.964 20 0 0 1 nc
30.133 +-309.657 -57.9033 20 1 0 0 nc
30.134 +-67.9734 -347.42 20 1 0 0 nc
30.135 +415.393 -289.516 20 1 0 0 nc
30.136 +730.084 -307.139 20 0 0 1 nc
30.137 +526.164 32.7279 20 1 0 0 nc
30.138 +762.812 -17.6227 20 1 0 0 nc
30.139 +-67.9734 319.727 20 0 0 1 nc
30.140 +329.797 314.692 20 0 0 1 nc
30.141 +-5.03507 561.41 20 0 0 1 nc
30.142 +422.945 521.129 20 0 0 1 nc
30.143 +-470.779 158.605 20 1 0 0 nc
30.144 +986.873 -115.807 20 0 0 1 nc
30.145 +906.312 201.403 20 0 0 1 nc
30.146 +-767.847 113.289 20 1 0 0 nc
30.147 +-579.033 445.603 20 0 0 1 nc
30.148 +-840.856 -246.718 20 0 0 1 nc
30.149 +206.221 -205.967 20 0 0 1 nc
30.150 +277.311 -252.33 20 0 0 1 nc
30.151 +271.13 -175.058 20 1 0 0 nc
30.152 +366.947 -110.15 20 1 0 0 nc
30.153 +397.855 -196.694 20 0 0 1 nc
30.154 +438.037 -88.514 20 0 0 1 nc
30.155 +286.584 -48.3327 20 1 0 0 nc
30.156 +212.403 -23.6057 20 0 0 1 nc
30.157 +280.402 10.3938 20 0 0 1 nc
30.158 +694.579 115.483 20 0 0 1 nc
30.159 +574.035 177.301 20 0 0 1 nc
30.160 +grestore
30.161 +grestore
30.162 +showpage
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/doc/images/strongly_connected_components.eps Thu Dec 10 17:05:35 2009 +0100
31.3 @@ -0,0 +1,180 @@
31.4 +%!PS-Adobe-2.0 EPSF-2.0
31.5 +%%Creator: LEMON, graphToEps()
31.6 +%%CreationDate: Fri Nov 4 13:47:12 2005
31.7 +%%BoundingBox: 0 0 842 596
31.8 +%%EndComments
31.9 +/lb { setlinewidth setrgbcolor newpath moveto
31.10 + 4 2 roll 1 index 1 index curveto stroke } bind def
31.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
31.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
31.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
31.14 + 2 index 1 index sub 2 index 2 index add lineto
31.15 + 2 index 1 index sub 2 index 2 index sub lineto
31.16 + 2 index 1 index add 2 index 2 index sub lineto
31.17 + closepath pop pop pop} bind def
31.18 +/di { newpath 2 index 1 index add 2 index moveto
31.19 + 2 index 2 index 2 index add lineto
31.20 + 2 index 1 index sub 2 index lineto
31.21 + 2 index 2 index 2 index sub lineto
31.22 + closepath pop pop pop} bind def
31.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
31.24 + setrgbcolor 1.1 div c fill
31.25 + } bind def
31.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
31.27 + setrgbcolor 1.1 div sq fill
31.28 + } bind def
31.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
31.30 + setrgbcolor 1.1 div di fill
31.31 + } bind def
31.32 +/arrl 10 def
31.33 +/arrw 3 def
31.34 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
31.35 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
31.36 + /w exch def /len exch def
31.37 + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
31.38 + len w sub arrl sub dx dy lrl
31.39 + arrw dy dx neg lrl
31.40 + dx arrl w add mul dy w 2 div arrw add mul sub
31.41 + dy arrl w add mul dx w 2 div arrw add mul add rlineto
31.42 + dx arrl w add mul neg dy w 2 div arrw add mul sub
31.43 + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
31.44 + arrw dy dx neg lrl
31.45 + len w sub arrl sub neg dx dy lrl
31.46 + closepath fill } bind def
31.47 +/cshow { 2 index 2 index moveto dup stringwidth pop
31.48 + neg 2 div fosi .35 mul neg rmoveto show pop pop} def
31.49 +
31.50 +gsave
31.51 +90 rotate
31.52 +0 -842 translate
31.53 +77.1122 15 translate
31.54 +0.585745 dup scale
31.55 +90 rotate
31.56 +695.963 -397.916 translate
31.57 +%Edges:
31.58 +gsave
31.59 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.60 +218.178 27.2723 moveto
31.61 +192.373 -40.1551 188.622 -49.9556 169.228 -100.631 curveto stroke
31.62 +newpath 164.939 -111.838 moveto 165.492 -99.2013 lineto 172.964 -102.061 lineto closepath fill
31.63 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.64 +44.8044 15.5841 moveto
31.65 +119.293 20.6059 129.775 21.3125 186.25 25.1199 curveto stroke
31.66 +newpath 198.223 25.927 moveto 186.519 21.1289 lineto 185.981 29.1108 lineto closepath fill
31.67 +2 setlinewidth 1 0 0 setrgbcolor newpath
31.68 +218.178 27.2723 moveto
31.69 +285.395 -87.4449 290.763 -96.6058 348.102 -194.464 curveto stroke
31.70 +newpath 354.169 -204.818 moveto 344.651 -196.487 lineto 351.554 -192.442 lineto closepath fill
31.71 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.72 +157.79 -130.517 moveto
31.73 +108.71 -67.0521 102.27 -58.7243 64.3804 -9.72954 curveto stroke
31.74 +newpath 57.0394 -0.236898 moveto 67.5446 -7.28254 lineto 61.2162 -12.1765 lineto closepath fill
31.75 +2 setlinewidth 1 0 0 setrgbcolor newpath
31.76 +-105.193 -261.035 moveto
31.77 +-35.6576 -132.801 -30.5923 -123.459 29.5506 -12.5464 curveto stroke
31.78 +newpath 35.2708 -1.99743 moveto 33.0669 -14.4531 lineto 26.0343 -10.6397 lineto closepath fill
31.79 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.80 +-465.576 -42.8564 moveto
31.81 +-559.078 -25.5413 -569.47 -23.6169 -644.498 -9.72286 curveto stroke
31.82 +newpath -656.297 -7.5378 moveto -643.77 -5.78973 lineto -645.226 -13.656 lineto closepath fill
31.83 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.84 +-574.666 -153.893 moveto
31.85 +-528.842 -107.252 -521.515 -99.794 -488.002 -65.683 curveto stroke
31.86 +newpath -479.592 -57.123 moveto -485.149 -68.4863 lineto -490.856 -62.8797 lineto closepath fill
31.87 +2 setlinewidth 1 0 0 setrgbcolor newpath
31.88 +-490.901 120.777 moveto
31.89 +-480.122 51.1328 -478.519 40.7713 -470.47 -11.2329 curveto stroke
31.90 +newpath -468.635 -23.0917 moveto -474.423 -11.8447 lineto -466.517 -10.6212 lineto closepath fill
31.91 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.92 +-675.963 -3.89604 moveto
31.93 +-632.116 -68.8235 -626.228 -77.5422 -592.575 -127.374 curveto stroke
31.94 +newpath -585.859 -137.319 moveto -595.89 -129.612 lineto -589.26 -125.135 lineto closepath fill
31.95 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.96 +-490.901 120.777 moveto
31.97 +-435.445 215.844 -430.107 224.995 -384.3 303.522 curveto stroke
31.98 +newpath -378.253 313.887 moveto -380.845 301.507 lineto -387.755 305.537 lineto closepath fill
31.99 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.100 +-266.879 114.933 moveto
31.101 +-367.067 117.547 -377.642 117.822 -458.912 119.943 curveto stroke
31.102 +newpath -470.908 120.255 moveto -458.807 123.941 lineto -459.016 115.944 lineto closepath fill
31.103 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.104 +-368.176 331.163 moveto
31.105 +-322.511 233.685 -318.018 224.095 -280.454 143.911 curveto stroke
31.106 +newpath -275.364 133.044 moveto -284.076 142.214 lineto -276.832 145.608 lineto closepath fill
31.107 +2 setlinewidth 1 0 0 setrgbcolor newpath
31.108 +-266.879 114.933 moveto
31.109 +-224.004 235.52 -220.448 245.52 -184.094 347.765 curveto stroke
31.110 +newpath -180.074 359.072 moveto -180.325 346.425 lineto -187.863 349.105 lineto closepath fill
31.111 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.112 +-251.294 -335.059 moveto
31.113 +-189.25 -303.624 -179.902 -298.887 -133.738 -275.498 curveto stroke
31.114 +newpath -123.034 -270.074 moveto -131.93 -279.066 lineto -135.546 -271.93 lineto closepath fill
31.115 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.116 +-389.604 -136.361 moveto
31.117 +-327.15 -226.083 -321.098 -234.777 -269.576 -308.795 curveto stroke
31.118 +newpath -262.72 -318.644 moveto -272.859 -311.081 lineto -266.293 -306.51 lineto closepath fill
31.119 +2 setlinewidth 1 0 0 setrgbcolor newpath
31.120 +5.84406 175.322 moveto
31.121 +-76.0754 267.926 -83.1051 275.873 -152.172 353.948 curveto stroke
31.122 +newpath -160.122 362.936 moveto -149.176 356.598 lineto -155.168 351.298 lineto closepath fill
31.123 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.124 +169.478 311.683 moveto
31.125 +96.8003 251.119 88.6819 244.353 30.4273 195.808 curveto stroke
31.126 +newpath 21.2086 188.126 moveto 27.8666 198.881 lineto 32.988 192.735 lineto closepath fill
31.127 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.128 +342.851 111.037 moveto
31.129 +263.766 202.563 256.831 210.589 190.4 287.47 curveto stroke
31.130 +newpath 182.554 296.55 moveto 193.427 290.085 lineto 187.373 284.855 lineto closepath fill
31.131 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.132 +5.84406 175.322 moveto
31.133 +163.16 145.314 173.605 143.321 311.418 117.033 curveto stroke
31.134 +newpath 323.205 114.784 moveto 310.668 113.104 lineto 312.167 120.962 lineto closepath fill
31.135 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.136 +342.851 111.037 moveto
31.137 +497.255 2.58683 505.964 -3.53033 643.932 -100.436 curveto stroke
31.138 +newpath 653.752 -107.334 moveto 641.633 -103.71 lineto 646.231 -97.163 lineto closepath fill
31.139 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.140 +364.28 -222.074 moveto
31.141 +354.298 -66.9063 353.616 -56.2971 344.905 79.1029 curveto stroke
31.142 +newpath 344.135 91.0781 moveto 348.897 79.3597 lineto 340.914 78.8461 lineto closepath fill
31.143 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.144 +670.118 -118.829 moveto
31.145 +528.037 -166.793 517.967 -170.192 394.599 -211.839 curveto stroke
31.146 +newpath 383.229 -215.677 moveto 393.32 -208.049 lineto 395.878 -215.629 lineto closepath fill
31.147 +2 setlinewidth 1 0 0 setrgbcolor newpath
31.148 +-105.193 -261.035 moveto
31.149 +118.401 -242.479 129.015 -241.598 332.39 -224.721 curveto stroke
31.150 +newpath 344.348 -223.728 moveto 332.72 -228.707 lineto 332.059 -220.734 lineto closepath fill
31.151 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.152 +-105.193 -261.035 moveto
31.153 +-160.867 -161.176 -166.028 -151.918 -212.336 -68.858 curveto stroke
31.154 +newpath -218.179 -58.3769 moveto -208.842 -66.9102 lineto -215.829 -70.8058 lineto closepath fill
31.155 +2 setlinewidth 0 0 1 setrgbcolor newpath
31.156 +-227.918 -40.9084 moveto
31.157 +-298.35 -82.4884 -307.42 -87.8432 -362.048 -120.093 curveto stroke
31.158 +newpath -372.381 -126.193 moveto -364.081 -116.648 lineto -360.014 -123.537 lineto closepath fill
31.159 +grestore
31.160 +%Nodes:
31.161 +gsave
31.162 +-389.604 -136.361 20 0 1 0 nc
31.163 +-227.918 -40.9084 20 0 1 0 nc
31.164 +-105.193 -261.035 20 0 1 0 nc
31.165 +364.28 -222.074 20 1 1 0 nc
31.166 +670.118 -118.829 20 1 1 0 nc
31.167 +342.851 111.037 20 1 1 0 nc
31.168 +5.84406 175.322 20 1 1 0 nc
31.169 +169.478 311.683 20 1 1 0 nc
31.170 +-173.374 377.916 20 1 0 1 nc
31.171 +-251.294 -335.059 20 0 1 0 nc
31.172 +-266.879 114.933 20 0 0 0 nc
31.173 +-368.176 331.163 20 0 0 0 nc
31.174 +-490.901 120.777 20 0 0 0 nc
31.175 +-574.666 -153.893 20 1 0 0 nc
31.176 +-675.963 -3.89604 20 1 0 0 nc
31.177 +-465.576 -42.8564 20 1 0 0 nc
31.178 +44.8044 15.5841 20 0 0 1 nc
31.179 +157.79 -130.517 20 0 0 1 nc
31.180 +218.178 27.2723 20 0 0 1 nc
31.181 +grestore
31.182 +grestore
31.183 +showpage
32.1 --- a/doc/lgf.dox Fri Nov 13 12:33:33 2009 +0100
32.2 +++ b/doc/lgf.dox Thu Dec 10 17:05:35 2009 +0100
32.3 @@ -2,7 +2,7 @@
32.4 *
32.5 * This file is a part of LEMON, a generic C++ optimization library.
32.6 *
32.7 - * Copyright (C) 2003-2008
32.8 + * Copyright (C) 2003-2009
32.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
32.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
32.11 *
33.1 --- a/doc/license.dox Fri Nov 13 12:33:33 2009 +0100
33.2 +++ b/doc/license.dox Thu Dec 10 17:05:35 2009 +0100
33.3 @@ -2,7 +2,7 @@
33.4 *
33.5 * This file is a part of LEMON, a generic C++ optimization library.
33.6 *
33.7 - * Copyright (C) 2003-2008
33.8 + * Copyright (C) 2003-2009
33.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
33.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
33.11 *
34.1 --- a/doc/mainpage.dox Fri Nov 13 12:33:33 2009 +0100
34.2 +++ b/doc/mainpage.dox Thu Dec 10 17:05:35 2009 +0100
34.3 @@ -2,7 +2,7 @@
34.4 *
34.5 * This file is a part of LEMON, a generic C++ optimization library.
34.6 *
34.7 - * Copyright (C) 2003-2008
34.8 + * Copyright (C) 2003-2009
34.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
34.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
34.11 *
34.12 @@ -23,8 +23,7 @@
34.13
34.14 \subsection whatis What is LEMON
34.15
34.16 -LEMON stands for
34.17 -<b>L</b>ibrary of <b>E</b>fficient <b>M</b>odels
34.18 +LEMON stands for <b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
34.19 and <b>O</b>ptimization in <b>N</b>etworks.
34.20 It is a C++ template
34.21 library aimed at combinatorial optimization tasks which
34.22 @@ -41,20 +40,11 @@
34.23
34.24 \subsection howtoread How to read the documentation
34.25
34.26 -If you want to get a quick start and see the most important features then
34.27 -take a look at our \ref quicktour
34.28 -"Quick Tour to LEMON" which will guide you along.
34.29 +If you would like to get to know the library, see
34.30 +<a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
34.31
34.32 -If you already feel like using our library, see the page that tells you
34.33 -\ref getstart "How to start using LEMON".
34.34 -
34.35 -If you
34.36 -want to see how LEMON works, see
34.37 -some \ref demoprograms "demo programs".
34.38 -
34.39 -If you know what you are looking for then try to find it under the
34.40 -<a class="el" href="modules.html">Modules</a>
34.41 -section.
34.42 +If you know what you are looking for, then try to find it under the
34.43 +<a class="el" href="modules.html">Modules</a> section.
34.44
34.45 If you are a user of the old (0.x) series of LEMON, please check out the
34.46 \ref migration "Migration Guide" for the backward incompatibilities.
35.1 --- a/doc/migration.dox Fri Nov 13 12:33:33 2009 +0100
35.2 +++ b/doc/migration.dox Thu Dec 10 17:05:35 2009 +0100
35.3 @@ -2,7 +2,7 @@
35.4 *
35.5 * This file is a part of LEMON, a generic C++ optimization library.
35.6 *
35.7 - * Copyright (C) 2003-2008
35.8 + * Copyright (C) 2003-2009
35.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
35.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
35.11 *
35.12 @@ -25,7 +25,7 @@
35.13 to the 0.x release series.
35.14
35.15 Many of these changes adjusted automatically by the
35.16 -<tt>script/lemon-0.x-to-1.x.sh</tt> tool. Those requiring manual
35.17 +<tt>lemon-0.x-to-1.x.sh</tt> tool. Those requiring manual
35.18 update are typeset <b>boldface</b>.
35.19
35.20 \section migration-graph Graph Related Name Changes
35.21 @@ -53,9 +53,11 @@
35.22 for <tt>Arc</tt>s (directed edges).
35.23
35.24 \warning
35.25 -<b>The <tt>script/lemon-0.x-to-1.x.sh</tt> tool replaces all instances of
35.26 -the words \c graph, \c digraph, \c edge and \c arc, so it replaces them
35.27 -in strings, comments etc. as well as in all identifiers.</b>
35.28 +<b>The <tt>lemon-0.x-to-1.x.sh</tt> script replaces the words \c graph,
35.29 +\c ugraph, \c edge and \c uedge in your own identifiers and in
35.30 +strings, comments etc. as well as in all LEMON specific identifiers.
35.31 +So use the script carefully and make a backup copy of your source files
35.32 +before applying the script to them.</b>
35.33
35.34 \section migration-lgf LGF tools
35.35 - The \ref lgf-format "LGF file format" has changed,
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/doc/min_cost_flow.dox Thu Dec 10 17:05:35 2009 +0100
36.3 @@ -0,0 +1,153 @@
36.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
36.5 + *
36.6 + * This file is a part of LEMON, a generic C++ optimization library.
36.7 + *
36.8 + * Copyright (C) 2003-2009
36.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
36.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
36.11 + *
36.12 + * Permission to use, modify and distribute this software is granted
36.13 + * provided that this copyright notice appears in all copies. For
36.14 + * precise terms see the accompanying LICENSE file.
36.15 + *
36.16 + * This software is provided "AS IS" with no warranty of any kind,
36.17 + * express or implied, and with no claim as to its suitability for any
36.18 + * purpose.
36.19 + *
36.20 + */
36.21 +
36.22 +namespace lemon {
36.23 +
36.24 +/**
36.25 +\page min_cost_flow Minimum Cost Flow Problem
36.26 +
36.27 +\section mcf_def Definition (GEQ form)
36.28 +
36.29 +The \e minimum \e cost \e flow \e problem is to find a feasible flow of
36.30 +minimum total cost from a set of supply nodes to a set of demand nodes
36.31 +in a network with capacity constraints (lower and upper bounds)
36.32 +and arc costs.
36.33 +
36.34 +Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
36.35 +\f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
36.36 +upper bounds for the flow values on the arcs, for which
36.37 +\f$lower(uv) \leq upper(uv)\f$ must hold for all \f$uv\in A\f$,
36.38 +\f$cost: A\rightarrow\mathbf{R}\f$ denotes the cost per unit flow
36.39 +on the arcs and \f$sup: V\rightarrow\mathbf{R}\f$ denotes the
36.40 +signed supply values of the nodes.
36.41 +If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
36.42 +supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
36.43 +\f$-sup(u)\f$ demand.
36.44 +A minimum cost flow is an \f$f: A\rightarrow\mathbf{R}\f$ solution
36.45 +of the following optimization problem.
36.46 +
36.47 +\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
36.48 +\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \geq
36.49 + sup(u) \quad \forall u\in V \f]
36.50 +\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
36.51 +
36.52 +The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
36.53 +zero or negative in order to have a feasible solution (since the sum
36.54 +of the expressions on the left-hand side of the inequalities is zero).
36.55 +It means that the total demand must be greater or equal to the total
36.56 +supply and all the supplies have to be carried out from the supply nodes,
36.57 +but there could be demands that are not satisfied.
36.58 +If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
36.59 +constraints have to be satisfied with equality, i.e. all demands
36.60 +have to be satisfied and all supplies have to be used.
36.61 +
36.62 +
36.63 +\section mcf_algs Algorithms
36.64 +
36.65 +LEMON contains several algorithms for solving this problem, for more
36.66 +information see \ref min_cost_flow_algs "Minimum Cost Flow Algorithms".
36.67 +
36.68 +A feasible solution for this problem can be found using \ref Circulation.
36.69 +
36.70 +
36.71 +\section mcf_dual Dual Solution
36.72 +
36.73 +The dual solution of the minimum cost flow problem is represented by
36.74 +node potentials \f$\pi: V\rightarrow\mathbf{R}\f$.
36.75 +An \f$f: A\rightarrow\mathbf{R}\f$ primal feasible solution is optimal
36.76 +if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$ node potentials
36.77 +the following \e complementary \e slackness optimality conditions hold.
36.78 +
36.79 + - For all \f$uv\in A\f$ arcs:
36.80 + - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
36.81 + - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
36.82 + - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
36.83 + - For all \f$u\in V\f$ nodes:
36.84 + - \f$\pi(u)<=0\f$;
36.85 + - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
36.86 + then \f$\pi(u)=0\f$.
36.87 +
36.88 +Here \f$cost^\pi(uv)\f$ denotes the \e reduced \e cost of the arc
36.89 +\f$uv\in A\f$ with respect to the potential function \f$\pi\f$, i.e.
36.90 +\f[ cost^\pi(uv) = cost(uv) + \pi(u) - \pi(v).\f]
36.91 +
36.92 +All algorithms provide dual solution (node potentials), as well,
36.93 +if an optimal flow is found.
36.94 +
36.95 +
36.96 +\section mcf_eq Equality Form
36.97 +
36.98 +The above \ref mcf_def "definition" is actually more general than the
36.99 +usual formulation of the minimum cost flow problem, in which strict
36.100 +equalities are required in the supply/demand contraints.
36.101 +
36.102 +\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
36.103 +\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) =
36.104 + sup(u) \quad \forall u\in V \f]
36.105 +\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
36.106 +
36.107 +However if the sum of the supply values is zero, then these two problems
36.108 +are equivalent.
36.109 +The \ref min_cost_flow_algs "algorithms" in LEMON support the general
36.110 +form, so if you need the equality form, you have to ensure this additional
36.111 +contraint manually.
36.112 +
36.113 +
36.114 +\section mcf_leq Opposite Inequalites (LEQ Form)
36.115 +
36.116 +Another possible definition of the minimum cost flow problem is
36.117 +when there are <em>"less or equal"</em> (LEQ) supply/demand constraints,
36.118 +instead of the <em>"greater or equal"</em> (GEQ) constraints.
36.119 +
36.120 +\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
36.121 +\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \leq
36.122 + sup(u) \quad \forall u\in V \f]
36.123 +\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
36.124 +
36.125 +It means that the total demand must be less or equal to the
36.126 +total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
36.127 +positive) and all the demands have to be satisfied, but there
36.128 +could be supplies that are not carried out from the supply
36.129 +nodes.
36.130 +The equality form is also a special case of this form, of course.
36.131 +
36.132 +You could easily transform this case to the \ref mcf_def "GEQ form"
36.133 +of the problem by reversing the direction of the arcs and taking the
36.134 +negative of the supply values (e.g. using \ref ReverseDigraph and
36.135 +\ref NegMap adaptors).
36.136 +However \ref NetworkSimplex algorithm also supports this form directly
36.137 +for the sake of convenience.
36.138 +
36.139 +Note that the optimality conditions for this supply constraint type are
36.140 +slightly differ from the conditions that are discussed for the GEQ form,
36.141 +namely the potentials have to be non-negative instead of non-positive.
36.142 +An \f$f: A\rightarrow\mathbf{R}\f$ feasible solution of this problem
36.143 +is optimal if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$
36.144 +node potentials the following conditions hold.
36.145 +
36.146 + - For all \f$uv\in A\f$ arcs:
36.147 + - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
36.148 + - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
36.149 + - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
36.150 + - For all \f$u\in V\f$ nodes:
36.151 + - \f$\pi(u)>=0\f$;
36.152 + - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
36.153 + then \f$\pi(u)=0\f$.
36.154 +
36.155 +*/
36.156 +}
37.1 --- a/doc/named-param.dox Fri Nov 13 12:33:33 2009 +0100
37.2 +++ b/doc/named-param.dox Thu Dec 10 17:05:35 2009 +0100
37.3 @@ -2,7 +2,7 @@
37.4 *
37.5 * This file is a part of LEMON, a generic C++ optimization library.
37.6 *
37.7 - * Copyright (C) 2003-2008
37.8 + * Copyright (C) 2003-2009
37.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
37.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
37.11 *
38.1 --- a/doc/namespaces.dox Fri Nov 13 12:33:33 2009 +0100
38.2 +++ b/doc/namespaces.dox Thu Dec 10 17:05:35 2009 +0100
38.3 @@ -2,7 +2,7 @@
38.4 *
38.5 * This file is a part of LEMON, a generic C++ optimization library.
38.6 *
38.7 - * Copyright (C) 2003-2008
38.8 + * Copyright (C) 2003-2009
38.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
38.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
38.11 *
39.1 --- a/doc/template.h Fri Nov 13 12:33:33 2009 +0100
39.2 +++ b/doc/template.h Thu Dec 10 17:05:35 2009 +0100
39.3 @@ -2,7 +2,7 @@
39.4 *
39.5 * This file is a part of LEMON, a generic C++ optimization library.
39.6 *
39.7 - * Copyright (C) 2003-2008
39.8 + * Copyright (C) 2003-2009
39.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
39.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
39.11 *
40.1 --- a/lemon/CMakeLists.txt Fri Nov 13 12:33:33 2009 +0100
40.2 +++ b/lemon/CMakeLists.txt Thu Dec 10 17:05:35 2009 +0100
40.3 @@ -1,5 +1,5 @@
40.4 INCLUDE_DIRECTORIES(
40.5 - ${CMAKE_SOURCE_DIR}
40.6 + ${PROJECT_SOURCE_DIR}
40.7 ${PROJECT_BINARY_DIR}
40.8 )
40.9
40.10 @@ -8,26 +8,61 @@
40.11 ${CMAKE_CURRENT_BINARY_DIR}/config.h
40.12 )
40.13
40.14 -ADD_LIBRARY(lemon
40.15 +SET(LEMON_SOURCES
40.16 arg_parser.cc
40.17 base.cc
40.18 color.cc
40.19 + lp_base.cc
40.20 + lp_skeleton.cc
40.21 random.cc
40.22 bits/windows.cc
40.23 )
40.24
40.25 +IF(LEMON_HAVE_GLPK)
40.26 + SET(LEMON_SOURCES ${LEMON_SOURCES} glpk.cc)
40.27 + INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIRS})
40.28 + IF(WIN32)
40.29 + INSTALL(FILES ${GLPK_BIN_DIR}/glpk.dll DESTINATION bin)
40.30 + INSTALL(FILES ${GLPK_BIN_DIR}/libltdl3.dll DESTINATION bin)
40.31 + INSTALL(FILES ${GLPK_BIN_DIR}/zlib1.dll DESTINATION bin)
40.32 + ENDIF()
40.33 +ENDIF()
40.34 +
40.35 +IF(LEMON_HAVE_CPLEX)
40.36 + SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc)
40.37 + INCLUDE_DIRECTORIES(${CPLEX_INCLUDE_DIRS})
40.38 +ENDIF()
40.39 +
40.40 +IF(LEMON_HAVE_CLP)
40.41 + SET(LEMON_SOURCES ${LEMON_SOURCES} clp.cc)
40.42 + INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
40.43 +ENDIF()
40.44 +
40.45 +IF(LEMON_HAVE_CBC)
40.46 + SET(LEMON_SOURCES ${LEMON_SOURCES} cbc.cc)
40.47 + INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
40.48 +ENDIF()
40.49 +
40.50 +ADD_LIBRARY(lemon ${LEMON_SOURCES})
40.51 +IF(UNIX)
40.52 + SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon)
40.53 +ENDIF()
40.54 +
40.55 INSTALL(
40.56 TARGETS lemon
40.57 ARCHIVE DESTINATION lib
40.58 - COMPONENT library)
40.59 + COMPONENT library
40.60 +)
40.61
40.62 INSTALL(
40.63 DIRECTORY . bits concepts
40.64 DESTINATION include/lemon
40.65 COMPONENT headers
40.66 - FILES_MATCHING PATTERN "*.h")
40.67 + FILES_MATCHING PATTERN "*.h"
40.68 +)
40.69
40.70 INSTALL(
40.71 FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h
40.72 DESTINATION include/lemon
40.73 - COMPONENT headers)
40.74 + COMPONENT headers
40.75 +)
41.1 --- a/lemon/Makefile.am Fri Nov 13 12:33:33 2009 +0100
41.2 +++ b/lemon/Makefile.am Thu Dec 10 17:05:35 2009 +0100
41.3 @@ -1,62 +1,131 @@
41.4 EXTRA_DIST += \
41.5 lemon/lemon.pc.in \
41.6 - lemon/CMakeLists.txt
41.7 + lemon/CMakeLists.txt \
41.8 + lemon/config.h.cmake
41.9
41.10 pkgconfig_DATA += lemon/lemon.pc
41.11
41.12 lib_LTLIBRARIES += lemon/libemon.la
41.13
41.14 lemon_libemon_la_SOURCES = \
41.15 - lemon/arg_parser.cc \
41.16 - lemon/base.cc \
41.17 - lemon/color.cc \
41.18 - lemon/random.cc \
41.19 + lemon/arg_parser.cc \
41.20 + lemon/base.cc \
41.21 + lemon/color.cc \
41.22 + lemon/lp_base.cc \
41.23 + lemon/lp_skeleton.cc \
41.24 + lemon/random.cc \
41.25 lemon/bits/windows.cc
41.26
41.27 -#lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS)
41.28 -#lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS)
41.29 +nodist_lemon_HEADERS = lemon/config.h
41.30
41.31 -nodist_lemon_HEADERS = lemon/config.h
41.32 +lemon_libemon_la_CXXFLAGS = \
41.33 + $(AM_CXXFLAGS) \
41.34 + $(GLPK_CFLAGS) \
41.35 + $(CPLEX_CFLAGS) \
41.36 + $(SOPLEX_CXXFLAGS) \
41.37 + $(CLP_CXXFLAGS) \
41.38 + $(CBC_CXXFLAGS)
41.39 +
41.40 +lemon_libemon_la_LDFLAGS = \
41.41 + $(GLPK_LIBS) \
41.42 + $(CPLEX_LIBS) \
41.43 + $(SOPLEX_LIBS) \
41.44 + $(CLP_LIBS) \
41.45 + $(CBC_LIBS)
41.46 +
41.47 +if HAVE_GLPK
41.48 +lemon_libemon_la_SOURCES += lemon/glpk.cc
41.49 +endif
41.50 +
41.51 +if HAVE_CPLEX
41.52 +lemon_libemon_la_SOURCES += lemon/cplex.cc
41.53 +endif
41.54 +
41.55 +if HAVE_SOPLEX
41.56 +lemon_libemon_la_SOURCES += lemon/soplex.cc
41.57 +endif
41.58 +
41.59 +if HAVE_CLP
41.60 +lemon_libemon_la_SOURCES += lemon/clp.cc
41.61 +endif
41.62 +
41.63 +if HAVE_CBC
41.64 +lemon_libemon_la_SOURCES += lemon/cbc.cc
41.65 +endif
41.66
41.67 lemon_HEADERS += \
41.68 - lemon/arg_parser.h \
41.69 + lemon/adaptors.h \
41.70 + lemon/arg_parser.h \
41.71 lemon/assert.h \
41.72 - lemon/bfs.h \
41.73 - lemon/bin_heap.h \
41.74 - lemon/color.h \
41.75 + lemon/bfs.h \
41.76 + lemon/bin_heap.h \
41.77 + lemon/bucket_heap.h \
41.78 + lemon/cbc.h \
41.79 + lemon/circulation.h \
41.80 + lemon/clp.h \
41.81 + lemon/color.h \
41.82 lemon/concept_check.h \
41.83 - lemon/counter.h \
41.84 + lemon/connectivity.h \
41.85 + lemon/counter.h \
41.86 lemon/core.h \
41.87 - lemon/dfs.h \
41.88 - lemon/dijkstra.h \
41.89 - lemon/dim2.h \
41.90 + lemon/cplex.h \
41.91 + lemon/dfs.h \
41.92 + lemon/dijkstra.h \
41.93 + lemon/dim2.h \
41.94 + lemon/dimacs.h \
41.95 + lemon/edge_set.h \
41.96 + lemon/elevator.h \
41.97 lemon/error.h \
41.98 - lemon/graph_to_eps.h \
41.99 + lemon/euler.h \
41.100 + lemon/fib_heap.h \
41.101 + lemon/full_graph.h \
41.102 + lemon/glpk.h \
41.103 + lemon/gomory_hu.h \
41.104 + lemon/graph_to_eps.h \
41.105 + lemon/grid_graph.h \
41.106 + lemon/hypercube_graph.h \
41.107 lemon/kruskal.h \
41.108 + lemon/hao_orlin.h \
41.109 lemon/lgf_reader.h \
41.110 lemon/lgf_writer.h \
41.111 lemon/list_graph.h \
41.112 + lemon/lp.h \
41.113 + lemon/lp_base.h \
41.114 + lemon/lp_skeleton.h \
41.115 + lemon/list_graph.h \
41.116 lemon/maps.h \
41.117 + lemon/matching.h \
41.118 lemon/math.h \
41.119 + lemon/min_cost_arborescence.h \
41.120 + lemon/nauty_reader.h \
41.121 + lemon/network_simplex.h \
41.122 lemon/path.h \
41.123 - lemon/random.h \
41.124 + lemon/preflow.h \
41.125 + lemon/radix_heap.h \
41.126 + lemon/radix_sort.h \
41.127 + lemon/random.h \
41.128 lemon/smart_graph.h \
41.129 - lemon/time_measure.h \
41.130 - lemon/tolerance.h \
41.131 + lemon/soplex.h \
41.132 + lemon/suurballe.h \
41.133 + lemon/time_measure.h \
41.134 + lemon/tolerance.h \
41.135 lemon/unionfind.h \
41.136 lemon/bits/windows.h
41.137
41.138 bits_HEADERS += \
41.139 lemon/bits/alteration_notifier.h \
41.140 lemon/bits/array_map.h \
41.141 - lemon/bits/base_extender.h \
41.142 - lemon/bits/bezier.h \
41.143 + lemon/bits/bezier.h \
41.144 lemon/bits/default_map.h \
41.145 - lemon/bits/enable_if.h \
41.146 + lemon/bits/edge_set_extender.h \
41.147 + lemon/bits/enable_if.h \
41.148 + lemon/bits/graph_adaptor_extender.h \
41.149 lemon/bits/graph_extender.h \
41.150 lemon/bits/map_extender.h \
41.151 lemon/bits/path_dump.h \
41.152 + lemon/bits/solver_bits.h \
41.153 lemon/bits/traits.h \
41.154 + lemon/bits/variant.h \
41.155 lemon/bits/vector_map.h
41.156
41.157 concept_HEADERS += \
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/lemon/adaptors.h Thu Dec 10 17:05:35 2009 +0100
42.3 @@ -0,0 +1,3614 @@
42.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
42.5 + *
42.6 + * This file is a part of LEMON, a generic C++ optimization library.
42.7 + *
42.8 + * Copyright (C) 2003-2009
42.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
42.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
42.11 + *
42.12 + * Permission to use, modify and distribute this software is granted
42.13 + * provided that this copyright notice appears in all copies. For
42.14 + * precise terms see the accompanying LICENSE file.
42.15 + *
42.16 + * This software is provided "AS IS" with no warranty of any kind,
42.17 + * express or implied, and with no claim as to its suitability for any
42.18 + * purpose.
42.19 + *
42.20 + */
42.21 +
42.22 +#ifndef LEMON_ADAPTORS_H
42.23 +#define LEMON_ADAPTORS_H
42.24 +
42.25 +/// \ingroup graph_adaptors
42.26 +/// \file
42.27 +/// \brief Adaptor classes for digraphs and graphs
42.28 +///
42.29 +/// This file contains several useful adaptors for digraphs and graphs.
42.30 +
42.31 +#include <lemon/core.h>
42.32 +#include <lemon/maps.h>
42.33 +#include <lemon/bits/variant.h>
42.34 +
42.35 +#include <lemon/bits/graph_adaptor_extender.h>
42.36 +#include <lemon/bits/map_extender.h>
42.37 +#include <lemon/tolerance.h>
42.38 +
42.39 +#include <algorithm>
42.40 +
42.41 +namespace lemon {
42.42 +
42.43 +#ifdef _MSC_VER
42.44 +#define LEMON_SCOPE_FIX(OUTER, NESTED) OUTER::NESTED
42.45 +#else
42.46 +#define LEMON_SCOPE_FIX(OUTER, NESTED) typename OUTER::template NESTED
42.47 +#endif
42.48 +
42.49 + template<typename DGR>
42.50 + class DigraphAdaptorBase {
42.51 + public:
42.52 + typedef DGR Digraph;
42.53 + typedef DigraphAdaptorBase Adaptor;
42.54 +
42.55 + protected:
42.56 + DGR* _digraph;
42.57 + DigraphAdaptorBase() : _digraph(0) { }
42.58 + void initialize(DGR& digraph) { _digraph = &digraph; }
42.59 +
42.60 + public:
42.61 + DigraphAdaptorBase(DGR& digraph) : _digraph(&digraph) { }
42.62 +
42.63 + typedef typename DGR::Node Node;
42.64 + typedef typename DGR::Arc Arc;
42.65 +
42.66 + void first(Node& i) const { _digraph->first(i); }
42.67 + void first(Arc& i) const { _digraph->first(i); }
42.68 + void firstIn(Arc& i, const Node& n) const { _digraph->firstIn(i, n); }
42.69 + void firstOut(Arc& i, const Node& n ) const { _digraph->firstOut(i, n); }
42.70 +
42.71 + void next(Node& i) const { _digraph->next(i); }
42.72 + void next(Arc& i) const { _digraph->next(i); }
42.73 + void nextIn(Arc& i) const { _digraph->nextIn(i); }
42.74 + void nextOut(Arc& i) const { _digraph->nextOut(i); }
42.75 +
42.76 + Node source(const Arc& a) const { return _digraph->source(a); }
42.77 + Node target(const Arc& a) const { return _digraph->target(a); }
42.78 +
42.79 + typedef NodeNumTagIndicator<DGR> NodeNumTag;
42.80 + int nodeNum() const { return _digraph->nodeNum(); }
42.81 +
42.82 + typedef ArcNumTagIndicator<DGR> ArcNumTag;
42.83 + int arcNum() const { return _digraph->arcNum(); }
42.84 +
42.85 + typedef FindArcTagIndicator<DGR> FindArcTag;
42.86 + Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) const {
42.87 + return _digraph->findArc(u, v, prev);
42.88 + }
42.89 +
42.90 + Node addNode() { return _digraph->addNode(); }
42.91 + Arc addArc(const Node& u, const Node& v) { return _digraph->addArc(u, v); }
42.92 +
42.93 + void erase(const Node& n) { _digraph->erase(n); }
42.94 + void erase(const Arc& a) { _digraph->erase(a); }
42.95 +
42.96 + void clear() { _digraph->clear(); }
42.97 +
42.98 + int id(const Node& n) const { return _digraph->id(n); }
42.99 + int id(const Arc& a) const { return _digraph->id(a); }
42.100 +
42.101 + Node nodeFromId(int ix) const { return _digraph->nodeFromId(ix); }
42.102 + Arc arcFromId(int ix) const { return _digraph->arcFromId(ix); }
42.103 +
42.104 + int maxNodeId() const { return _digraph->maxNodeId(); }
42.105 + int maxArcId() const { return _digraph->maxArcId(); }
42.106 +
42.107 + typedef typename ItemSetTraits<DGR, Node>::ItemNotifier NodeNotifier;
42.108 + NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
42.109 +
42.110 + typedef typename ItemSetTraits<DGR, Arc>::ItemNotifier ArcNotifier;
42.111 + ArcNotifier& notifier(Arc) const { return _digraph->notifier(Arc()); }
42.112 +
42.113 + template <typename V>
42.114 + class NodeMap : public DGR::template NodeMap<V> {
42.115 + typedef typename DGR::template NodeMap<V> Parent;
42.116 +
42.117 + public:
42.118 + explicit NodeMap(const Adaptor& adaptor)
42.119 + : Parent(*adaptor._digraph) {}
42.120 + NodeMap(const Adaptor& adaptor, const V& value)
42.121 + : Parent(*adaptor._digraph, value) { }
42.122 +
42.123 + private:
42.124 + NodeMap& operator=(const NodeMap& cmap) {
42.125 + return operator=<NodeMap>(cmap);
42.126 + }
42.127 +
42.128 + template <typename CMap>
42.129 + NodeMap& operator=(const CMap& cmap) {
42.130 + Parent::operator=(cmap);
42.131 + return *this;
42.132 + }
42.133 +
42.134 + };
42.135 +
42.136 + template <typename V>
42.137 + class ArcMap : public DGR::template ArcMap<V> {
42.138 + typedef typename DGR::template ArcMap<V> Parent;
42.139 +
42.140 + public:
42.141 + explicit ArcMap(const DigraphAdaptorBase<DGR>& adaptor)
42.142 + : Parent(*adaptor._digraph) {}
42.143 + ArcMap(const DigraphAdaptorBase<DGR>& adaptor, const V& value)
42.144 + : Parent(*adaptor._digraph, value) {}
42.145 +
42.146 + private:
42.147 + ArcMap& operator=(const ArcMap& cmap) {
42.148 + return operator=<ArcMap>(cmap);
42.149 + }
42.150 +
42.151 + template <typename CMap>
42.152 + ArcMap& operator=(const CMap& cmap) {
42.153 + Parent::operator=(cmap);
42.154 + return *this;
42.155 + }
42.156 +
42.157 + };
42.158 +
42.159 + };
42.160 +
42.161 + template<typename GR>
42.162 + class GraphAdaptorBase {
42.163 + public:
42.164 + typedef GR Graph;
42.165 +
42.166 + protected:
42.167 + GR* _graph;
42.168 +
42.169 + GraphAdaptorBase() : _graph(0) {}
42.170 +
42.171 + void initialize(GR& graph) { _graph = &graph; }
42.172 +
42.173 + public:
42.174 + GraphAdaptorBase(GR& graph) : _graph(&graph) {}
42.175 +
42.176 + typedef typename GR::Node Node;
42.177 + typedef typename GR::Arc Arc;
42.178 + typedef typename GR::Edge Edge;
42.179 +
42.180 + void first(Node& i) const { _graph->first(i); }
42.181 + void first(Arc& i) const { _graph->first(i); }
42.182 + void first(Edge& i) const { _graph->first(i); }
42.183 + void firstIn(Arc& i, const Node& n) const { _graph->firstIn(i, n); }
42.184 + void firstOut(Arc& i, const Node& n ) const { _graph->firstOut(i, n); }
42.185 + void firstInc(Edge &i, bool &d, const Node &n) const {
42.186 + _graph->firstInc(i, d, n);
42.187 + }
42.188 +
42.189 + void next(Node& i) const { _graph->next(i); }
42.190 + void next(Arc& i) const { _graph->next(i); }
42.191 + void next(Edge& i) const { _graph->next(i); }
42.192 + void nextIn(Arc& i) const { _graph->nextIn(i); }
42.193 + void nextOut(Arc& i) const { _graph->nextOut(i); }
42.194 + void nextInc(Edge &i, bool &d) const { _graph->nextInc(i, d); }
42.195 +
42.196 + Node u(const Edge& e) const { return _graph->u(e); }
42.197 + Node v(const Edge& e) const { return _graph->v(e); }
42.198 +
42.199 + Node source(const Arc& a) const { return _graph->source(a); }
42.200 + Node target(const Arc& a) const { return _graph->target(a); }
42.201 +
42.202 + typedef NodeNumTagIndicator<Graph> NodeNumTag;
42.203 + int nodeNum() const { return _graph->nodeNum(); }
42.204 +
42.205 + typedef ArcNumTagIndicator<Graph> ArcNumTag;
42.206 + int arcNum() const { return _graph->arcNum(); }
42.207 +
42.208 + typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
42.209 + int edgeNum() const { return _graph->edgeNum(); }
42.210 +
42.211 + typedef FindArcTagIndicator<Graph> FindArcTag;
42.212 + Arc findArc(const Node& u, const Node& v,
42.213 + const Arc& prev = INVALID) const {
42.214 + return _graph->findArc(u, v, prev);
42.215 + }
42.216 +
42.217 + typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
42.218 + Edge findEdge(const Node& u, const Node& v,
42.219 + const Edge& prev = INVALID) const {
42.220 + return _graph->findEdge(u, v, prev);
42.221 + }
42.222 +
42.223 + Node addNode() { return _graph->addNode(); }
42.224 + Edge addEdge(const Node& u, const Node& v) { return _graph->addEdge(u, v); }
42.225 +
42.226 + void erase(const Node& i) { _graph->erase(i); }
42.227 + void erase(const Edge& i) { _graph->erase(i); }
42.228 +
42.229 + void clear() { _graph->clear(); }
42.230 +
42.231 + bool direction(const Arc& a) const { return _graph->direction(a); }
42.232 + Arc direct(const Edge& e, bool d) const { return _graph->direct(e, d); }
42.233 +
42.234 + int id(const Node& v) const { return _graph->id(v); }
42.235 + int id(const Arc& a) const { return _graph->id(a); }
42.236 + int id(const Edge& e) const { return _graph->id(e); }
42.237 +
42.238 + Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
42.239 + Arc arcFromId(int ix) const { return _graph->arcFromId(ix); }
42.240 + Edge edgeFromId(int ix) const { return _graph->edgeFromId(ix); }
42.241 +
42.242 + int maxNodeId() const { return _graph->maxNodeId(); }
42.243 + int maxArcId() const { return _graph->maxArcId(); }
42.244 + int maxEdgeId() const { return _graph->maxEdgeId(); }
42.245 +
42.246 + typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
42.247 + NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
42.248 +
42.249 + typedef typename ItemSetTraits<GR, Arc>::ItemNotifier ArcNotifier;
42.250 + ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
42.251 +
42.252 + typedef typename ItemSetTraits<GR, Edge>::ItemNotifier EdgeNotifier;
42.253 + EdgeNotifier& notifier(Edge) const { return _graph->notifier(Edge()); }
42.254 +
42.255 + template <typename V>
42.256 + class NodeMap : public GR::template NodeMap<V> {
42.257 + typedef typename GR::template NodeMap<V> Parent;
42.258 +
42.259 + public:
42.260 + explicit NodeMap(const GraphAdaptorBase<GR>& adapter)
42.261 + : Parent(*adapter._graph) {}
42.262 + NodeMap(const GraphAdaptorBase<GR>& adapter, const V& value)
42.263 + : Parent(*adapter._graph, value) {}
42.264 +
42.265 + private:
42.266 + NodeMap& operator=(const NodeMap& cmap) {
42.267 + return operator=<NodeMap>(cmap);
42.268 + }
42.269 +
42.270 + template <typename CMap>
42.271 + NodeMap& operator=(const CMap& cmap) {
42.272 + Parent::operator=(cmap);
42.273 + return *this;
42.274 + }
42.275 +
42.276 + };
42.277 +
42.278 + template <typename V>
42.279 + class ArcMap : public GR::template ArcMap<V> {
42.280 + typedef typename GR::template ArcMap<V> Parent;
42.281 +
42.282 + public:
42.283 + explicit ArcMap(const GraphAdaptorBase<GR>& adapter)
42.284 + : Parent(*adapter._graph) {}
42.285 + ArcMap(const GraphAdaptorBase<GR>& adapter, const V& value)
42.286 + : Parent(*adapter._graph, value) {}
42.287 +
42.288 + private:
42.289 + ArcMap& operator=(const ArcMap& cmap) {
42.290 + return operator=<ArcMap>(cmap);
42.291 + }
42.292 +
42.293 + template <typename CMap>
42.294 + ArcMap& operator=(const CMap& cmap) {
42.295 + Parent::operator=(cmap);
42.296 + return *this;
42.297 + }
42.298 + };
42.299 +
42.300 + template <typename V>
42.301 + class EdgeMap : public GR::template EdgeMap<V> {
42.302 + typedef typename GR::template EdgeMap<V> Parent;
42.303 +
42.304 + public:
42.305 + explicit EdgeMap(const GraphAdaptorBase<GR>& adapter)
42.306 + : Parent(*adapter._graph) {}
42.307 + EdgeMap(const GraphAdaptorBase<GR>& adapter, const V& value)
42.308 + : Parent(*adapter._graph, value) {}
42.309 +
42.310 + private:
42.311 + EdgeMap& operator=(const EdgeMap& cmap) {
42.312 + return operator=<EdgeMap>(cmap);
42.313 + }
42.314 +
42.315 + template <typename CMap>
42.316 + EdgeMap& operator=(const CMap& cmap) {
42.317 + Parent::operator=(cmap);
42.318 + return *this;
42.319 + }
42.320 + };
42.321 +
42.322 + };
42.323 +
42.324 + template <typename DGR>
42.325 + class ReverseDigraphBase : public DigraphAdaptorBase<DGR> {
42.326 + typedef DigraphAdaptorBase<DGR> Parent;
42.327 + public:
42.328 + typedef DGR Digraph;
42.329 + protected:
42.330 + ReverseDigraphBase() : Parent() { }
42.331 + public:
42.332 + typedef typename Parent::Node Node;
42.333 + typedef typename Parent::Arc Arc;
42.334 +
42.335 + void firstIn(Arc& a, const Node& n) const { Parent::firstOut(a, n); }
42.336 + void firstOut(Arc& a, const Node& n ) const { Parent::firstIn(a, n); }
42.337 +
42.338 + void nextIn(Arc& a) const { Parent::nextOut(a); }
42.339 + void nextOut(Arc& a) const { Parent::nextIn(a); }
42.340 +
42.341 + Node source(const Arc& a) const { return Parent::target(a); }
42.342 + Node target(const Arc& a) const { return Parent::source(a); }
42.343 +
42.344 + Arc addArc(const Node& u, const Node& v) { return Parent::addArc(v, u); }
42.345 +
42.346 + typedef FindArcTagIndicator<DGR> FindArcTag;
42.347 + Arc findArc(const Node& u, const Node& v,
42.348 + const Arc& prev = INVALID) const {
42.349 + return Parent::findArc(v, u, prev);
42.350 + }
42.351 +
42.352 + };
42.353 +
42.354 + /// \ingroup graph_adaptors
42.355 + ///
42.356 + /// \brief Adaptor class for reversing the orientation of the arcs in
42.357 + /// a digraph.
42.358 + ///
42.359 + /// ReverseDigraph can be used for reversing the arcs in a digraph.
42.360 + /// It conforms to the \ref concepts::Digraph "Digraph" concept.
42.361 + ///
42.362 + /// The adapted digraph can also be modified through this adaptor
42.363 + /// by adding or removing nodes or arcs, unless the \c GR template
42.364 + /// parameter is set to be \c const.
42.365 + ///
42.366 + /// \tparam DGR The type of the adapted digraph.
42.367 + /// It must conform to the \ref concepts::Digraph "Digraph" concept.
42.368 + /// It can also be specified to be \c const.
42.369 + ///
42.370 + /// \note The \c Node and \c Arc types of this adaptor and the adapted
42.371 + /// digraph are convertible to each other.
42.372 + template<typename DGR>
42.373 +#ifdef DOXYGEN
42.374 + class ReverseDigraph {
42.375 +#else
42.376 + class ReverseDigraph :
42.377 + public DigraphAdaptorExtender<ReverseDigraphBase<DGR> > {
42.378 +#endif
42.379 + typedef DigraphAdaptorExtender<ReverseDigraphBase<DGR> > Parent;
42.380 + public:
42.381 + /// The type of the adapted digraph.
42.382 + typedef DGR Digraph;
42.383 + protected:
42.384 + ReverseDigraph() { }
42.385 + public:
42.386 +
42.387 + /// \brief Constructor
42.388 + ///
42.389 + /// Creates a reverse digraph adaptor for the given digraph.
42.390 + explicit ReverseDigraph(DGR& digraph) {
42.391 + Parent::initialize(digraph);
42.392 + }
42.393 + };
42.394 +
42.395 + /// \brief Returns a read-only ReverseDigraph adaptor
42.396 + ///
42.397 + /// This function just returns a read-only \ref ReverseDigraph adaptor.
42.398 + /// \ingroup graph_adaptors
42.399 + /// \relates ReverseDigraph
42.400 + template<typename DGR>
42.401 + ReverseDigraph<const DGR> reverseDigraph(const DGR& digraph) {
42.402 + return ReverseDigraph<const DGR>(digraph);
42.403 + }
42.404 +
42.405 +
42.406 + template <typename DGR, typename NF, typename AF, bool ch = true>
42.407 + class SubDigraphBase : public DigraphAdaptorBase<DGR> {
42.408 + typedef DigraphAdaptorBase<DGR> Parent;
42.409 + public:
42.410 + typedef DGR Digraph;
42.411 + typedef NF NodeFilterMap;
42.412 + typedef AF ArcFilterMap;
42.413 +
42.414 + typedef SubDigraphBase Adaptor;
42.415 + protected:
42.416 + NF* _node_filter;
42.417 + AF* _arc_filter;
42.418 + SubDigraphBase()
42.419 + : Parent(), _node_filter(0), _arc_filter(0) { }
42.420 +
42.421 + void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
42.422 + Parent::initialize(digraph);
42.423 + _node_filter = &node_filter;
42.424 + _arc_filter = &arc_filter;
42.425 + }
42.426 +
42.427 + public:
42.428 +
42.429 + typedef typename Parent::Node Node;
42.430 + typedef typename Parent::Arc Arc;
42.431 +
42.432 + void first(Node& i) const {
42.433 + Parent::first(i);
42.434 + while (i != INVALID && !(*_node_filter)[i]) Parent::next(i);
42.435 + }
42.436 +
42.437 + void first(Arc& i) const {
42.438 + Parent::first(i);
42.439 + while (i != INVALID && (!(*_arc_filter)[i]
42.440 + || !(*_node_filter)[Parent::source(i)]
42.441 + || !(*_node_filter)[Parent::target(i)]))
42.442 + Parent::next(i);
42.443 + }
42.444 +
42.445 + void firstIn(Arc& i, const Node& n) const {
42.446 + Parent::firstIn(i, n);
42.447 + while (i != INVALID && (!(*_arc_filter)[i]
42.448 + || !(*_node_filter)[Parent::source(i)]))
42.449 + Parent::nextIn(i);
42.450 + }
42.451 +
42.452 + void firstOut(Arc& i, const Node& n) const {
42.453 + Parent::firstOut(i, n);
42.454 + while (i != INVALID && (!(*_arc_filter)[i]
42.455 + || !(*_node_filter)[Parent::target(i)]))
42.456 + Parent::nextOut(i);
42.457 + }
42.458 +
42.459 + void next(Node& i) const {
42.460 + Parent::next(i);
42.461 + while (i != INVALID && !(*_node_filter)[i]) Parent::next(i);
42.462 + }
42.463 +
42.464 + void next(Arc& i) const {
42.465 + Parent::next(i);
42.466 + while (i != INVALID && (!(*_arc_filter)[i]
42.467 + || !(*_node_filter)[Parent::source(i)]
42.468 + || !(*_node_filter)[Parent::target(i)]))
42.469 + Parent::next(i);
42.470 + }
42.471 +
42.472 + void nextIn(Arc& i) const {
42.473 + Parent::nextIn(i);
42.474 + while (i != INVALID && (!(*_arc_filter)[i]
42.475 + || !(*_node_filter)[Parent::source(i)]))
42.476 + Parent::nextIn(i);
42.477 + }
42.478 +
42.479 + void nextOut(Arc& i) const {
42.480 + Parent::nextOut(i);
42.481 + while (i != INVALID && (!(*_arc_filter)[i]
42.482 + || !(*_node_filter)[Parent::target(i)]))
42.483 + Parent::nextOut(i);
42.484 + }
42.485 +
42.486 + void status(const Node& n, bool v) const { _node_filter->set(n, v); }
42.487 + void status(const Arc& a, bool v) const { _arc_filter->set(a, v); }
42.488 +
42.489 + bool status(const Node& n) const { return (*_node_filter)[n]; }
42.490 + bool status(const Arc& a) const { return (*_arc_filter)[a]; }
42.491 +
42.492 + typedef False NodeNumTag;
42.493 + typedef False ArcNumTag;
42.494 +
42.495 + typedef FindArcTagIndicator<DGR> FindArcTag;
42.496 + Arc findArc(const Node& source, const Node& target,
42.497 + const Arc& prev = INVALID) const {
42.498 + if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
42.499 + return INVALID;
42.500 + }
42.501 + Arc arc = Parent::findArc(source, target, prev);
42.502 + while (arc != INVALID && !(*_arc_filter)[arc]) {
42.503 + arc = Parent::findArc(source, target, arc);
42.504 + }
42.505 + return arc;
42.506 + }
42.507 +
42.508 + public:
42.509 +
42.510 + template <typename V>
42.511 + class NodeMap
42.512 + : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
42.513 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
42.514 + typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
42.515 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
42.516 +
42.517 + public:
42.518 + typedef V Value;
42.519 +
42.520 + NodeMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
42.521 + : Parent(adaptor) {}
42.522 + NodeMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor, const V& value)
42.523 + : Parent(adaptor, value) {}
42.524 +
42.525 + private:
42.526 + NodeMap& operator=(const NodeMap& cmap) {
42.527 + return operator=<NodeMap>(cmap);
42.528 + }
42.529 +
42.530 + template <typename CMap>
42.531 + NodeMap& operator=(const CMap& cmap) {
42.532 + Parent::operator=(cmap);
42.533 + return *this;
42.534 + }
42.535 + };
42.536 +
42.537 + template <typename V>
42.538 + class ArcMap
42.539 + : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
42.540 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
42.541 + typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
42.542 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
42.543 +
42.544 + public:
42.545 + typedef V Value;
42.546 +
42.547 + ArcMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
42.548 + : Parent(adaptor) {}
42.549 + ArcMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor, const V& value)
42.550 + : Parent(adaptor, value) {}
42.551 +
42.552 + private:
42.553 + ArcMap& operator=(const ArcMap& cmap) {
42.554 + return operator=<ArcMap>(cmap);
42.555 + }
42.556 +
42.557 + template <typename CMap>
42.558 + ArcMap& operator=(const CMap& cmap) {
42.559 + Parent::operator=(cmap);
42.560 + return *this;
42.561 + }
42.562 + };
42.563 +
42.564 + };
42.565 +
42.566 + template <typename DGR, typename NF, typename AF>
42.567 + class SubDigraphBase<DGR, NF, AF, false>
42.568 + : public DigraphAdaptorBase<DGR> {
42.569 + typedef DigraphAdaptorBase<DGR> Parent;
42.570 + public:
42.571 + typedef DGR Digraph;
42.572 + typedef NF NodeFilterMap;
42.573 + typedef AF ArcFilterMap;
42.574 +
42.575 + typedef SubDigraphBase Adaptor;
42.576 + protected:
42.577 + NF* _node_filter;
42.578 + AF* _arc_filter;
42.579 + SubDigraphBase()
42.580 + : Parent(), _node_filter(0), _arc_filter(0) { }
42.581 +
42.582 + void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
42.583 + Parent::initialize(digraph);
42.584 + _node_filter = &node_filter;
42.585 + _arc_filter = &arc_filter;
42.586 + }
42.587 +
42.588 + public:
42.589 +
42.590 + typedef typename Parent::Node Node;
42.591 + typedef typename Parent::Arc Arc;
42.592 +
42.593 + void first(Node& i) const {
42.594 + Parent::first(i);
42.595 + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
42.596 + }
42.597 +
42.598 + void first(Arc& i) const {
42.599 + Parent::first(i);
42.600 + while (i!=INVALID && !(*_arc_filter)[i]) Parent::next(i);
42.601 + }
42.602 +
42.603 + void firstIn(Arc& i, const Node& n) const {
42.604 + Parent::firstIn(i, n);
42.605 + while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextIn(i);
42.606 + }
42.607 +
42.608 + void firstOut(Arc& i, const Node& n) const {
42.609 + Parent::firstOut(i, n);
42.610 + while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextOut(i);
42.611 + }
42.612 +
42.613 + void next(Node& i) const {
42.614 + Parent::next(i);
42.615 + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
42.616 + }
42.617 + void next(Arc& i) const {
42.618 + Parent::next(i);
42.619 + while (i!=INVALID && !(*_arc_filter)[i]) Parent::next(i);
42.620 + }
42.621 + void nextIn(Arc& i) const {
42.622 + Parent::nextIn(i);
42.623 + while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextIn(i);
42.624 + }
42.625 +
42.626 + void nextOut(Arc& i) const {
42.627 + Parent::nextOut(i);
42.628 + while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextOut(i);
42.629 + }
42.630 +
42.631 + void status(const Node& n, bool v) const { _node_filter->set(n, v); }
42.632 + void status(const Arc& a, bool v) const { _arc_filter->set(a, v); }
42.633 +
42.634 + bool status(const Node& n) const { return (*_node_filter)[n]; }
42.635 + bool status(const Arc& a) const { return (*_arc_filter)[a]; }
42.636 +
42.637 + typedef False NodeNumTag;
42.638 + typedef False ArcNumTag;
42.639 +
42.640 + typedef FindArcTagIndicator<DGR> FindArcTag;
42.641 + Arc findArc(const Node& source, const Node& target,
42.642 + const Arc& prev = INVALID) const {
42.643 + if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
42.644 + return INVALID;
42.645 + }
42.646 + Arc arc = Parent::findArc(source, target, prev);
42.647 + while (arc != INVALID && !(*_arc_filter)[arc]) {
42.648 + arc = Parent::findArc(source, target, arc);
42.649 + }
42.650 + return arc;
42.651 + }
42.652 +
42.653 + template <typename V>
42.654 + class NodeMap
42.655 + : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
42.656 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
42.657 + typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
42.658 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
42.659 +
42.660 + public:
42.661 + typedef V Value;
42.662 +
42.663 + NodeMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
42.664 + : Parent(adaptor) {}
42.665 + NodeMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor, const V& value)
42.666 + : Parent(adaptor, value) {}
42.667 +
42.668 + private:
42.669 + NodeMap& operator=(const NodeMap& cmap) {
42.670 + return operator=<NodeMap>(cmap);
42.671 + }
42.672 +
42.673 + template <typename CMap>
42.674 + NodeMap& operator=(const CMap& cmap) {
42.675 + Parent::operator=(cmap);
42.676 + return *this;
42.677 + }
42.678 + };
42.679 +
42.680 + template <typename V>
42.681 + class ArcMap
42.682 + : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
42.683 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
42.684 + typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
42.685 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
42.686 +
42.687 + public:
42.688 + typedef V Value;
42.689 +
42.690 + ArcMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
42.691 + : Parent(adaptor) {}
42.692 + ArcMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor, const V& value)
42.693 + : Parent(adaptor, value) {}
42.694 +
42.695 + private:
42.696 + ArcMap& operator=(const ArcMap& cmap) {
42.697 + return operator=<ArcMap>(cmap);
42.698 + }
42.699 +
42.700 + template <typename CMap>
42.701 + ArcMap& operator=(const CMap& cmap) {
42.702 + Parent::operator=(cmap);
42.703 + return *this;
42.704 + }
42.705 + };
42.706 +
42.707 + };
42.708 +
42.709 + /// \ingroup graph_adaptors
42.710 + ///
42.711 + /// \brief Adaptor class for hiding nodes and arcs in a digraph
42.712 + ///
42.713 + /// SubDigraph can be used for hiding nodes and arcs in a digraph.
42.714 + /// A \c bool node map and a \c bool arc map must be specified, which
42.715 + /// define the filters for nodes and arcs.
42.716 + /// Only the nodes and arcs with \c true filter value are
42.717 + /// shown in the subdigraph. The arcs that are incident to hidden
42.718 + /// nodes are also filtered out.
42.719 + /// This adaptor conforms to the \ref concepts::Digraph "Digraph" concept.
42.720 + ///
42.721 + /// The adapted digraph can also be modified through this adaptor
42.722 + /// by adding or removing nodes or arcs, unless the \c GR template
42.723 + /// parameter is set to be \c const.
42.724 + ///
42.725 + /// \tparam DGR The type of the adapted digraph.
42.726 + /// It must conform to the \ref concepts::Digraph "Digraph" concept.
42.727 + /// It can also be specified to be \c const.
42.728 + /// \tparam NF The type of the node filter map.
42.729 + /// It must be a \c bool (or convertible) node map of the
42.730 + /// adapted digraph. The default type is
42.731 + /// \ref concepts::Digraph::NodeMap "DGR::NodeMap<bool>".
42.732 + /// \tparam AF The type of the arc filter map.
42.733 + /// It must be \c bool (or convertible) arc map of the
42.734 + /// adapted digraph. The default type is
42.735 + /// \ref concepts::Digraph::ArcMap "DGR::ArcMap<bool>".
42.736 + ///
42.737 + /// \note The \c Node and \c Arc types of this adaptor and the adapted
42.738 + /// digraph are convertible to each other.
42.739 + ///
42.740 + /// \see FilterNodes
42.741 + /// \see FilterArcs
42.742 +#ifdef DOXYGEN
42.743 + template<typename DGR, typename NF, typename AF>
42.744 + class SubDigraph {
42.745 +#else
42.746 + template<typename DGR,
42.747 + typename NF = typename DGR::template NodeMap<bool>,
42.748 + typename AF = typename DGR::template ArcMap<bool> >
42.749 + class SubDigraph :
42.750 + public DigraphAdaptorExtender<SubDigraphBase<DGR, NF, AF, true> > {
42.751 +#endif
42.752 + public:
42.753 + /// The type of the adapted digraph.
42.754 + typedef DGR Digraph;
42.755 + /// The type of the node filter map.
42.756 + typedef NF NodeFilterMap;
42.757 + /// The type of the arc filter map.
42.758 + typedef AF ArcFilterMap;
42.759 +
42.760 + typedef DigraphAdaptorExtender<SubDigraphBase<DGR, NF, AF, true> >
42.761 + Parent;
42.762 +
42.763 + typedef typename Parent::Node Node;
42.764 + typedef typename Parent::Arc Arc;
42.765 +
42.766 + protected:
42.767 + SubDigraph() { }
42.768 + public:
42.769 +
42.770 + /// \brief Constructor
42.771 + ///
42.772 + /// Creates a subdigraph for the given digraph with the
42.773 + /// given node and arc filter maps.
42.774 + SubDigraph(DGR& digraph, NF& node_filter, AF& arc_filter) {
42.775 + Parent::initialize(digraph, node_filter, arc_filter);
42.776 + }
42.777 +
42.778 + /// \brief Sets the status of the given node
42.779 + ///
42.780 + /// This function sets the status of the given node.
42.781 + /// It is done by simply setting the assigned value of \c n
42.782 + /// to \c v in the node filter map.
42.783 + void status(const Node& n, bool v) const { Parent::status(n, v); }
42.784 +
42.785 + /// \brief Sets the status of the given arc
42.786 + ///
42.787 + /// This function sets the status of the given arc.
42.788 + /// It is done by simply setting the assigned value of \c a
42.789 + /// to \c v in the arc filter map.
42.790 + void status(const Arc& a, bool v) const { Parent::status(a, v); }
42.791 +
42.792 + /// \brief Returns the status of the given node
42.793 + ///
42.794 + /// This function returns the status of the given node.
42.795 + /// It is \c true if the given node is enabled (i.e. not hidden).
42.796 + bool status(const Node& n) const { return Parent::status(n); }
42.797 +
42.798 + /// \brief Returns the status of the given arc
42.799 + ///
42.800 + /// This function returns the status of the given arc.
42.801 + /// It is \c true if the given arc is enabled (i.e. not hidden).
42.802 + bool status(const Arc& a) const { return Parent::status(a); }
42.803 +
42.804 + /// \brief Disables the given node
42.805 + ///
42.806 + /// This function disables the given node in the subdigraph,
42.807 + /// so the iteration jumps over it.
42.808 + /// It is the same as \ref status() "status(n, false)".
42.809 + void disable(const Node& n) const { Parent::status(n, false); }
42.810 +
42.811 + /// \brief Disables the given arc
42.812 + ///
42.813 + /// This function disables the given arc in the subdigraph,
42.814 + /// so the iteration jumps over it.
42.815 + /// It is the same as \ref status() "status(a, false)".
42.816 + void disable(const Arc& a) const { Parent::status(a, false); }
42.817 +
42.818 + /// \brief Enables the given node
42.819 + ///
42.820 + /// This function enables the given node in the subdigraph.
42.821 + /// It is the same as \ref status() "status(n, true)".
42.822 + void enable(const Node& n) const { Parent::status(n, true); }
42.823 +
42.824 + /// \brief Enables the given arc
42.825 + ///
42.826 + /// This function enables the given arc in the subdigraph.
42.827 + /// It is the same as \ref status() "status(a, true)".
42.828 + void enable(const Arc& a) const { Parent::status(a, true); }
42.829 +
42.830 + };
42.831 +
42.832 + /// \brief Returns a read-only SubDigraph adaptor
42.833 + ///
42.834 + /// This function just returns a read-only \ref SubDigraph adaptor.
42.835 + /// \ingroup graph_adaptors
42.836 + /// \relates SubDigraph
42.837 + template<typename DGR, typename NF, typename AF>
42.838 + SubDigraph<const DGR, NF, AF>
42.839 + subDigraph(const DGR& digraph,
42.840 + NF& node_filter, AF& arc_filter) {
42.841 + return SubDigraph<const DGR, NF, AF>
42.842 + (digraph, node_filter, arc_filter);
42.843 + }
42.844 +
42.845 + template<typename DGR, typename NF, typename AF>
42.846 + SubDigraph<const DGR, const NF, AF>
42.847 + subDigraph(const DGR& digraph,
42.848 + const NF& node_filter, AF& arc_filter) {
42.849 + return SubDigraph<const DGR, const NF, AF>
42.850 + (digraph, node_filter, arc_filter);
42.851 + }
42.852 +
42.853 + template<typename DGR, typename NF, typename AF>
42.854 + SubDigraph<const DGR, NF, const AF>
42.855 + subDigraph(const DGR& digraph,
42.856 + NF& node_filter, const AF& arc_filter) {
42.857 + return SubDigraph<const DGR, NF, const AF>
42.858 + (digraph, node_filter, arc_filter);
42.859 + }
42.860 +
42.861 + template<typename DGR, typename NF, typename AF>
42.862 + SubDigraph<const DGR, const NF, const AF>
42.863 + subDigraph(const DGR& digraph,
42.864 + const NF& node_filter, const AF& arc_filter) {
42.865 + return SubDigraph<const DGR, const NF, const AF>
42.866 + (digraph, node_filter, arc_filter);
42.867 + }
42.868 +
42.869 +
42.870 + template <typename GR, typename NF, typename EF, bool ch = true>
42.871 + class SubGraphBase : public GraphAdaptorBase<GR> {
42.872 + typedef GraphAdaptorBase<GR> Parent;
42.873 + public:
42.874 + typedef GR Graph;
42.875 + typedef NF NodeFilterMap;
42.876 + typedef EF EdgeFilterMap;
42.877 +
42.878 + typedef SubGraphBase Adaptor;
42.879 + protected:
42.880 +
42.881 + NF* _node_filter;
42.882 + EF* _edge_filter;
42.883 +
42.884 + SubGraphBase()
42.885 + : Parent(), _node_filter(0), _edge_filter(0) { }
42.886 +
42.887 + void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
42.888 + Parent::initialize(graph);
42.889 + _node_filter = &node_filter;
42.890 + _edge_filter = &edge_filter;
42.891 + }
42.892 +
42.893 + public:
42.894 +
42.895 + typedef typename Parent::Node Node;
42.896 + typedef typename Parent::Arc Arc;
42.897 + typedef typename Parent::Edge Edge;
42.898 +
42.899 + void first(Node& i) const {
42.900 + Parent::first(i);
42.901 + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
42.902 + }
42.903 +
42.904 + void first(Arc& i) const {
42.905 + Parent::first(i);
42.906 + while (i!=INVALID && (!(*_edge_filter)[i]
42.907 + || !(*_node_filter)[Parent::source(i)]
42.908 + || !(*_node_filter)[Parent::target(i)]))
42.909 + Parent::next(i);
42.910 + }
42.911 +
42.912 + void first(Edge& i) const {
42.913 + Parent::first(i);
42.914 + while (i!=INVALID && (!(*_edge_filter)[i]
42.915 + || !(*_node_filter)[Parent::u(i)]
42.916 + || !(*_node_filter)[Parent::v(i)]))
42.917 + Parent::next(i);
42.918 + }
42.919 +
42.920 + void firstIn(Arc& i, const Node& n) const {
42.921 + Parent::firstIn(i, n);
42.922 + while (i!=INVALID && (!(*_edge_filter)[i]
42.923 + || !(*_node_filter)[Parent::source(i)]))
42.924 + Parent::nextIn(i);
42.925 + }
42.926 +
42.927 + void firstOut(Arc& i, const Node& n) const {
42.928 + Parent::firstOut(i, n);
42.929 + while (i!=INVALID && (!(*_edge_filter)[i]
42.930 + || !(*_node_filter)[Parent::target(i)]))
42.931 + Parent::nextOut(i);
42.932 + }
42.933 +
42.934 + void firstInc(Edge& i, bool& d, const Node& n) const {
42.935 + Parent::firstInc(i, d, n);
42.936 + while (i!=INVALID && (!(*_edge_filter)[i]
42.937 + || !(*_node_filter)[Parent::u(i)]
42.938 + || !(*_node_filter)[Parent::v(i)]))
42.939 + Parent::nextInc(i, d);
42.940 + }
42.941 +
42.942 + void next(Node& i) const {
42.943 + Parent::next(i);
42.944 + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
42.945 + }
42.946 +
42.947 + void next(Arc& i) const {
42.948 + Parent::next(i);
42.949 + while (i!=INVALID && (!(*_edge_filter)[i]
42.950 + || !(*_node_filter)[Parent::source(i)]
42.951 + || !(*_node_filter)[Parent::target(i)]))
42.952 + Parent::next(i);
42.953 + }
42.954 +
42.955 + void next(Edge& i) const {
42.956 + Parent::next(i);
42.957 + while (i!=INVALID && (!(*_edge_filter)[i]
42.958 + || !(*_node_filter)[Parent::u(i)]
42.959 + || !(*_node_filter)[Parent::v(i)]))
42.960 + Parent::next(i);
42.961 + }
42.962 +
42.963 + void nextIn(Arc& i) const {
42.964 + Parent::nextIn(i);
42.965 + while (i!=INVALID && (!(*_edge_filter)[i]
42.966 + || !(*_node_filter)[Parent::source(i)]))
42.967 + Parent::nextIn(i);
42.968 + }
42.969 +
42.970 + void nextOut(Arc& i) const {
42.971 + Parent::nextOut(i);
42.972 + while (i!=INVALID && (!(*_edge_filter)[i]
42.973 + || !(*_node_filter)[Parent::target(i)]))
42.974 + Parent::nextOut(i);
42.975 + }
42.976 +
42.977 + void nextInc(Edge& i, bool& d) const {
42.978 + Parent::nextInc(i, d);
42.979 + while (i!=INVALID && (!(*_edge_filter)[i]
42.980 + || !(*_node_filter)[Parent::u(i)]
42.981 + || !(*_node_filter)[Parent::v(i)]))
42.982 + Parent::nextInc(i, d);
42.983 + }
42.984 +
42.985 + void status(const Node& n, bool v) const { _node_filter->set(n, v); }
42.986 + void status(const Edge& e, bool v) const { _edge_filter->set(e, v); }
42.987 +
42.988 + bool status(const Node& n) const { return (*_node_filter)[n]; }
42.989 + bool status(const Edge& e) const { return (*_edge_filter)[e]; }
42.990 +
42.991 + typedef False NodeNumTag;
42.992 + typedef False ArcNumTag;
42.993 + typedef False EdgeNumTag;
42.994 +
42.995 + typedef FindArcTagIndicator<Graph> FindArcTag;
42.996 + Arc findArc(const Node& u, const Node& v,
42.997 + const Arc& prev = INVALID) const {
42.998 + if (!(*_node_filter)[u] || !(*_node_filter)[v]) {
42.999 + return INVALID;
42.1000 + }
42.1001 + Arc arc = Parent::findArc(u, v, prev);
42.1002 + while (arc != INVALID && !(*_edge_filter)[arc]) {
42.1003 + arc = Parent::findArc(u, v, arc);
42.1004 + }
42.1005 + return arc;
42.1006 + }
42.1007 +
42.1008 + typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
42.1009 + Edge findEdge(const Node& u, const Node& v,
42.1010 + const Edge& prev = INVALID) const {
42.1011 + if (!(*_node_filter)[u] || !(*_node_filter)[v]) {
42.1012 + return INVALID;
42.1013 + }
42.1014 + Edge edge = Parent::findEdge(u, v, prev);
42.1015 + while (edge != INVALID && !(*_edge_filter)[edge]) {
42.1016 + edge = Parent::findEdge(u, v, edge);
42.1017 + }
42.1018 + return edge;
42.1019 + }
42.1020 +
42.1021 + template <typename V>
42.1022 + class NodeMap
42.1023 + : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
42.1024 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
42.1025 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
42.1026 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
42.1027 +
42.1028 + public:
42.1029 + typedef V Value;
42.1030 +
42.1031 + NodeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
42.1032 + : Parent(adaptor) {}
42.1033 + NodeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
42.1034 + : Parent(adaptor, value) {}
42.1035 +
42.1036 + private:
42.1037 + NodeMap& operator=(const NodeMap& cmap) {
42.1038 + return operator=<NodeMap>(cmap);
42.1039 + }
42.1040 +
42.1041 + template <typename CMap>
42.1042 + NodeMap& operator=(const CMap& cmap) {
42.1043 + Parent::operator=(cmap);
42.1044 + return *this;
42.1045 + }
42.1046 + };
42.1047 +
42.1048 + template <typename V>
42.1049 + class ArcMap
42.1050 + : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
42.1051 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
42.1052 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
42.1053 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
42.1054 +
42.1055 + public:
42.1056 + typedef V Value;
42.1057 +
42.1058 + ArcMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
42.1059 + : Parent(adaptor) {}
42.1060 + ArcMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
42.1061 + : Parent(adaptor, value) {}
42.1062 +
42.1063 + private:
42.1064 + ArcMap& operator=(const ArcMap& cmap) {
42.1065 + return operator=<ArcMap>(cmap);
42.1066 + }
42.1067 +
42.1068 + template <typename CMap>
42.1069 + ArcMap& operator=(const CMap& cmap) {
42.1070 + Parent::operator=(cmap);
42.1071 + return *this;
42.1072 + }
42.1073 + };
42.1074 +
42.1075 + template <typename V>
42.1076 + class EdgeMap
42.1077 + : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
42.1078 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
42.1079 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
42.1080 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
42.1081 +
42.1082 + public:
42.1083 + typedef V Value;
42.1084 +
42.1085 + EdgeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
42.1086 + : Parent(adaptor) {}
42.1087 +
42.1088 + EdgeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
42.1089 + : Parent(adaptor, value) {}
42.1090 +
42.1091 + private:
42.1092 + EdgeMap& operator=(const EdgeMap& cmap) {
42.1093 + return operator=<EdgeMap>(cmap);
42.1094 + }
42.1095 +
42.1096 + template <typename CMap>
42.1097 + EdgeMap& operator=(const CMap& cmap) {
42.1098 + Parent::operator=(cmap);
42.1099 + return *this;
42.1100 + }
42.1101 + };
42.1102 +
42.1103 + };
42.1104 +
42.1105 + template <typename GR, typename NF, typename EF>
42.1106 + class SubGraphBase<GR, NF, EF, false>
42.1107 + : public GraphAdaptorBase<GR> {
42.1108 + typedef GraphAdaptorBase<GR> Parent;
42.1109 + public:
42.1110 + typedef GR Graph;
42.1111 + typedef NF NodeFilterMap;
42.1112 + typedef EF EdgeFilterMap;
42.1113 +
42.1114 + typedef SubGraphBase Adaptor;
42.1115 + protected:
42.1116 + NF* _node_filter;
42.1117 + EF* _edge_filter;
42.1118 + SubGraphBase()
42.1119 + : Parent(), _node_filter(0), _edge_filter(0) { }
42.1120 +
42.1121 + void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
42.1122 + Parent::initialize(graph);
42.1123 + _node_filter = &node_filter;
42.1124 + _edge_filter = &edge_filter;
42.1125 + }
42.1126 +
42.1127 + public:
42.1128 +
42.1129 + typedef typename Parent::Node Node;
42.1130 + typedef typename Parent::Arc Arc;
42.1131 + typedef typename Parent::Edge Edge;
42.1132 +
42.1133 + void first(Node& i) const {
42.1134 + Parent::first(i);
42.1135 + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
42.1136 + }
42.1137 +
42.1138 + void first(Arc& i) const {
42.1139 + Parent::first(i);
42.1140 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
42.1141 + }
42.1142 +
42.1143 + void first(Edge& i) const {
42.1144 + Parent::first(i);
42.1145 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
42.1146 + }
42.1147 +
42.1148 + void firstIn(Arc& i, const Node& n) const {
42.1149 + Parent::firstIn(i, n);
42.1150 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextIn(i);
42.1151 + }
42.1152 +
42.1153 + void firstOut(Arc& i, const Node& n) const {
42.1154 + Parent::firstOut(i, n);
42.1155 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextOut(i);
42.1156 + }
42.1157 +
42.1158 + void firstInc(Edge& i, bool& d, const Node& n) const {
42.1159 + Parent::firstInc(i, d, n);
42.1160 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextInc(i, d);
42.1161 + }
42.1162 +
42.1163 + void next(Node& i) const {
42.1164 + Parent::next(i);
42.1165 + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
42.1166 + }
42.1167 + void next(Arc& i) const {
42.1168 + Parent::next(i);
42.1169 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
42.1170 + }
42.1171 + void next(Edge& i) const {
42.1172 + Parent::next(i);
42.1173 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
42.1174 + }
42.1175 + void nextIn(Arc& i) const {
42.1176 + Parent::nextIn(i);
42.1177 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextIn(i);
42.1178 + }
42.1179 +
42.1180 + void nextOut(Arc& i) const {
42.1181 + Parent::nextOut(i);
42.1182 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextOut(i);
42.1183 + }
42.1184 + void nextInc(Edge& i, bool& d) const {
42.1185 + Parent::nextInc(i, d);
42.1186 + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextInc(i, d);
42.1187 + }
42.1188 +
42.1189 + void status(const Node& n, bool v) const { _node_filter->set(n, v); }
42.1190 + void status(const Edge& e, bool v) const { _edge_filter->set(e, v); }
42.1191 +
42.1192 + bool status(const Node& n) const { return (*_node_filter)[n]; }
42.1193 + bool status(const Edge& e) const { return (*_edge_filter)[e]; }
42.1194 +
42.1195 + typedef False NodeNumTag;
42.1196 + typedef False ArcNumTag;
42.1197 + typedef False EdgeNumTag;
42.1198 +
42.1199 + typedef FindArcTagIndicator<Graph> FindArcTag;
42.1200 + Arc findArc(const Node& u, const Node& v,
42.1201 + const Arc& prev = INVALID) const {
42.1202 + Arc arc = Parent::findArc(u, v, prev);
42.1203 + while (arc != INVALID && !(*_edge_filter)[arc]) {
42.1204 + arc = Parent::findArc(u, v, arc);
42.1205 + }
42.1206 + return arc;
42.1207 + }
42.1208 +
42.1209 + typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
42.1210 + Edge findEdge(const Node& u, const Node& v,
42.1211 + const Edge& prev = INVALID) const {
42.1212 + Edge edge = Parent::findEdge(u, v, prev);
42.1213 + while (edge != INVALID && !(*_edge_filter)[edge]) {
42.1214 + edge = Parent::findEdge(u, v, edge);
42.1215 + }
42.1216 + return edge;
42.1217 + }
42.1218 +
42.1219 + template <typename V>
42.1220 + class NodeMap
42.1221 + : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
42.1222 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
42.1223 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
42.1224 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
42.1225 +
42.1226 + public:
42.1227 + typedef V Value;
42.1228 +
42.1229 + NodeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
42.1230 + : Parent(adaptor) {}
42.1231 + NodeMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
42.1232 + : Parent(adaptor, value) {}
42.1233 +
42.1234 + private:
42.1235 + NodeMap& operator=(const NodeMap& cmap) {
42.1236 + return operator=<NodeMap>(cmap);
42.1237 + }
42.1238 +
42.1239 + template <typename CMap>
42.1240 + NodeMap& operator=(const CMap& cmap) {
42.1241 + Parent::operator=(cmap);
42.1242 + return *this;
42.1243 + }
42.1244 + };
42.1245 +
42.1246 + template <typename V>
42.1247 + class ArcMap
42.1248 + : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
42.1249 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
42.1250 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
42.1251 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
42.1252 +
42.1253 + public:
42.1254 + typedef V Value;
42.1255 +
42.1256 + ArcMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
42.1257 + : Parent(adaptor) {}
42.1258 + ArcMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
42.1259 + : Parent(adaptor, value) {}
42.1260 +
42.1261 + private:
42.1262 + ArcMap& operator=(const ArcMap& cmap) {
42.1263 + return operator=<ArcMap>(cmap);
42.1264 + }
42.1265 +
42.1266 + template <typename CMap>
42.1267 + ArcMap& operator=(const CMap& cmap) {
42.1268 + Parent::operator=(cmap);
42.1269 + return *this;
42.1270 + }
42.1271 + };
42.1272 +
42.1273 + template <typename V>
42.1274 + class EdgeMap
42.1275 + : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
42.1276 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
42.1277 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
42.1278 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
42.1279 +
42.1280 + public:
42.1281 + typedef V Value;
42.1282 +
42.1283 + EdgeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
42.1284 + : Parent(adaptor) {}
42.1285 +
42.1286 + EdgeMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
42.1287 + : Parent(adaptor, value) {}
42.1288 +
42.1289 + private:
42.1290 + EdgeMap& operator=(const EdgeMap& cmap) {
42.1291 + return operator=<EdgeMap>(cmap);
42.1292 + }
42.1293 +
42.1294 + template <typename CMap>
42.1295 + EdgeMap& operator=(const CMap& cmap) {
42.1296 + Parent::operator=(cmap);
42.1297 + return *this;
42.1298 + }
42.1299 + };
42.1300 +
42.1301 + };
42.1302 +
42.1303 + /// \ingroup graph_adaptors
42.1304 + ///
42.1305 + /// \brief Adaptor class for hiding nodes and edges in an undirected
42.1306 + /// graph.
42.1307 + ///
42.1308 + /// SubGraph can be used for hiding nodes and edges in a graph.
42.1309 + /// A \c bool node map and a \c bool edge map must be specified, which
42.1310 + /// define the filters for nodes and edges.
42.1311 + /// Only the nodes and edges with \c true filter value are
42.1312 + /// shown in the subgraph. The edges that are incident to hidden
42.1313 + /// nodes are also filtered out.
42.1314 + /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
42.1315 + ///
42.1316 + /// The adapted graph can also be modified through this adaptor
42.1317 + /// by adding or removing nodes or edges, unless the \c GR template
42.1318 + /// parameter is set to be \c const.
42.1319 + ///
42.1320 + /// \tparam GR The type of the adapted graph.
42.1321 + /// It must conform to the \ref concepts::Graph "Graph" concept.
42.1322 + /// It can also be specified to be \c const.
42.1323 + /// \tparam NF The type of the node filter map.
42.1324 + /// It must be a \c bool (or convertible) node map of the
42.1325 + /// adapted graph. The default type is
42.1326 + /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
42.1327 + /// \tparam EF The type of the edge filter map.
42.1328 + /// It must be a \c bool (or convertible) edge map of the
42.1329 + /// adapted graph. The default type is
42.1330 + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
42.1331 + ///
42.1332 + /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
42.1333 + /// adapted graph are convertible to each other.
42.1334 + ///
42.1335 + /// \see FilterNodes
42.1336 + /// \see FilterEdges
42.1337 +#ifdef DOXYGEN
42.1338 + template<typename GR, typename NF, typename EF>
42.1339 + class SubGraph {
42.1340 +#else
42.1341 + template<typename GR,
42.1342 + typename NF = typename GR::template NodeMap<bool>,
42.1343 + typename EF = typename GR::template EdgeMap<bool> >
42.1344 + class SubGraph :
42.1345 + public GraphAdaptorExtender<SubGraphBase<GR, NF, EF, true> > {
42.1346 +#endif
42.1347 + public:
42.1348 + /// The type of the adapted graph.
42.1349 + typedef GR Graph;
42.1350 + /// The type of the node filter map.
42.1351 + typedef NF NodeFilterMap;
42.1352 + /// The type of the edge filter map.
42.1353 + typedef EF EdgeFilterMap;
42.1354 +
42.1355 + typedef GraphAdaptorExtender<SubGraphBase<GR, NF, EF, true> >
42.1356 + Parent;
42.1357 +
42.1358 + typedef typename Parent::Node Node;
42.1359 + typedef typename Parent::Edge Edge;
42.1360 +
42.1361 + protected:
42.1362 + SubGraph() { }
42.1363 + public:
42.1364 +
42.1365 + /// \brief Constructor
42.1366 + ///
42.1367 + /// Creates a subgraph for the given graph with the given node
42.1368 + /// and edge filter maps.
42.1369 + SubGraph(GR& graph, NF& node_filter, EF& edge_filter) {
42.1370 + initialize(graph, node_filter, edge_filter);
42.1371 + }
42.1372 +
42.1373 + /// \brief Sets the status of the given node
42.1374 + ///
42.1375 + /// This function sets the status of the given node.
42.1376 + /// It is done by simply setting the assigned value of \c n
42.1377 + /// to \c v in the node filter map.
42.1378 + void status(const Node& n, bool v) const { Parent::status(n, v); }
42.1379 +
42.1380 + /// \brief Sets the status of the given edge
42.1381 + ///
42.1382 + /// This function sets the status of the given edge.
42.1383 + /// It is done by simply setting the assigned value of \c e
42.1384 + /// to \c v in the edge filter map.
42.1385 + void status(const Edge& e, bool v) const { Parent::status(e, v); }
42.1386 +
42.1387 + /// \brief Returns the status of the given node
42.1388 + ///
42.1389 + /// This function returns the status of the given node.
42.1390 + /// It is \c true if the given node is enabled (i.e. not hidden).
42.1391 + bool status(const Node& n) const { return Parent::status(n); }
42.1392 +
42.1393 + /// \brief Returns the status of the given edge
42.1394 + ///
42.1395 + /// This function returns the status of the given edge.
42.1396 + /// It is \c true if the given edge is enabled (i.e. not hidden).
42.1397 + bool status(const Edge& e) const { return Parent::status(e); }
42.1398 +
42.1399 + /// \brief Disables the given node
42.1400 + ///
42.1401 + /// This function disables the given node in the subdigraph,
42.1402 + /// so the iteration jumps over it.
42.1403 + /// It is the same as \ref status() "status(n, false)".
42.1404 + void disable(const Node& n) const { Parent::status(n, false); }
42.1405 +
42.1406 + /// \brief Disables the given edge
42.1407 + ///
42.1408 + /// This function disables the given edge in the subgraph,
42.1409 + /// so the iteration jumps over it.
42.1410 + /// It is the same as \ref status() "status(e, false)".
42.1411 + void disable(const Edge& e) const { Parent::status(e, false); }
42.1412 +
42.1413 + /// \brief Enables the given node
42.1414 + ///
42.1415 + /// This function enables the given node in the subdigraph.
42.1416 + /// It is the same as \ref status() "status(n, true)".
42.1417 + void enable(const Node& n) const { Parent::status(n, true); }
42.1418 +
42.1419 + /// \brief Enables the given edge
42.1420 + ///
42.1421 + /// This function enables the given edge in the subgraph.
42.1422 + /// It is the same as \ref status() "status(e, true)".
42.1423 + void enable(const Edge& e) const { Parent::status(e, true); }
42.1424 +
42.1425 + };
42.1426 +
42.1427 + /// \brief Returns a read-only SubGraph adaptor
42.1428 + ///
42.1429 + /// This function just returns a read-only \ref SubGraph adaptor.
42.1430 + /// \ingroup graph_adaptors
42.1431 + /// \relates SubGraph
42.1432 + template<typename GR, typename NF, typename EF>
42.1433 + SubGraph<const GR, NF, EF>
42.1434 + subGraph(const GR& graph, NF& node_filter, EF& edge_filter) {
42.1435 + return SubGraph<const GR, NF, EF>
42.1436 + (graph, node_filter, edge_filter);
42.1437 + }
42.1438 +
42.1439 + template<typename GR, typename NF, typename EF>
42.1440 + SubGraph<const GR, const NF, EF>
42.1441 + subGraph(const GR& graph, const NF& node_filter, EF& edge_filter) {
42.1442 + return SubGraph<const GR, const NF, EF>
42.1443 + (graph, node_filter, edge_filter);
42.1444 + }
42.1445 +
42.1446 + template<typename GR, typename NF, typename EF>
42.1447 + SubGraph<const GR, NF, const EF>
42.1448 + subGraph(const GR& graph, NF& node_filter, const EF& edge_filter) {
42.1449 + return SubGraph<const GR, NF, const EF>
42.1450 + (graph, node_filter, edge_filter);
42.1451 + }
42.1452 +
42.1453 + template<typename GR, typename NF, typename EF>
42.1454 + SubGraph<const GR, const NF, const EF>
42.1455 + subGraph(const GR& graph, const NF& node_filter, const EF& edge_filter) {
42.1456 + return SubGraph<const GR, const NF, const EF>
42.1457 + (graph, node_filter, edge_filter);
42.1458 + }
42.1459 +
42.1460 +
42.1461 + /// \ingroup graph_adaptors
42.1462 + ///
42.1463 + /// \brief Adaptor class for hiding nodes in a digraph or a graph.
42.1464 + ///
42.1465 + /// FilterNodes adaptor can be used for hiding nodes in a digraph or a
42.1466 + /// graph. A \c bool node map must be specified, which defines the filter
42.1467 + /// for the nodes. Only the nodes with \c true filter value and the
42.1468 + /// arcs/edges incident to nodes both with \c true filter value are shown
42.1469 + /// in the subgraph. This adaptor conforms to the \ref concepts::Digraph
42.1470 + /// "Digraph" concept or the \ref concepts::Graph "Graph" concept
42.1471 + /// depending on the \c GR template parameter.
42.1472 + ///
42.1473 + /// The adapted (di)graph can also be modified through this adaptor
42.1474 + /// by adding or removing nodes or arcs/edges, unless the \c GR template
42.1475 + /// parameter is set to be \c const.
42.1476 + ///
42.1477 + /// \tparam GR The type of the adapted digraph or graph.
42.1478 + /// It must conform to the \ref concepts::Digraph "Digraph" concept
42.1479 + /// or the \ref concepts::Graph "Graph" concept.
42.1480 + /// It can also be specified to be \c const.
42.1481 + /// \tparam NF The type of the node filter map.
42.1482 + /// It must be a \c bool (or convertible) node map of the
42.1483 + /// adapted (di)graph. The default type is
42.1484 + /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
42.1485 + ///
42.1486 + /// \note The \c Node and <tt>Arc/Edge</tt> types of this adaptor and the
42.1487 + /// adapted (di)graph are convertible to each other.
42.1488 +#ifdef DOXYGEN
42.1489 + template<typename GR, typename NF>
42.1490 + class FilterNodes {
42.1491 +#else
42.1492 + template<typename GR,
42.1493 + typename NF = typename GR::template NodeMap<bool>,
42.1494 + typename Enable = void>
42.1495 + class FilterNodes :
42.1496 + public DigraphAdaptorExtender<
42.1497 + SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >,
42.1498 + true> > {
42.1499 +#endif
42.1500 + typedef DigraphAdaptorExtender<
42.1501 + SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >,
42.1502 + true> > Parent;
42.1503 +
42.1504 + public:
42.1505 +
42.1506 + typedef GR Digraph;
42.1507 + typedef NF NodeFilterMap;
42.1508 +
42.1509 + typedef typename Parent::Node Node;
42.1510 +
42.1511 + protected:
42.1512 + ConstMap<typename Digraph::Arc, Const<bool, true> > const_true_map;
42.1513 +
42.1514 + FilterNodes() : const_true_map() {}
42.1515 +
42.1516 + public:
42.1517 +
42.1518 + /// \brief Constructor
42.1519 + ///
42.1520 + /// Creates a subgraph for the given digraph or graph with the
42.1521 + /// given node filter map.
42.1522 + FilterNodes(GR& graph, NF& node_filter)
42.1523 + : Parent(), const_true_map()
42.1524 + {
42.1525 + Parent::initialize(graph, node_filter, const_true_map);
42.1526 + }
42.1527 +
42.1528 + /// \brief Sets the status of the given node
42.1529 + ///
42.1530 + /// This function sets the status of the given node.
42.1531 + /// It is done by simply setting the assigned value of \c n
42.1532 + /// to \c v in the node filter map.
42.1533 + void status(const Node& n, bool v) const { Parent::status(n, v); }
42.1534 +
42.1535 + /// \brief Returns the status of the given node
42.1536 + ///
42.1537 + /// This function returns the status of the given node.
42.1538 + /// It is \c true if the given node is enabled (i.e. not hidden).
42.1539 + bool status(const Node& n) const { return Parent::status(n); }
42.1540 +
42.1541 + /// \brief Disables the given node
42.1542 + ///
42.1543 + /// This function disables the given node, so the iteration
42.1544 + /// jumps over it.
42.1545 + /// It is the same as \ref status() "status(n, false)".
42.1546 + void disable(const Node& n) const { Parent::status(n, false); }
42.1547 +
42.1548 + /// \brief Enables the given node
42.1549 + ///
42.1550 + /// This function enables the given node.
42.1551 + /// It is the same as \ref status() "status(n, true)".
42.1552 + void enable(const Node& n) const { Parent::status(n, true); }
42.1553 +
42.1554 + };
42.1555 +
42.1556 + template<typename GR, typename NF>
42.1557 + class FilterNodes<GR, NF,
42.1558 + typename enable_if<UndirectedTagIndicator<GR> >::type> :
42.1559 + public GraphAdaptorExtender<
42.1560 + SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
42.1561 + true> > {
42.1562 +
42.1563 + typedef GraphAdaptorExtender<
42.1564 + SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
42.1565 + true> > Parent;
42.1566 +
42.1567 + public:
42.1568 +
42.1569 + typedef GR Graph;
42.1570 + typedef NF NodeFilterMap;
42.1571 +
42.1572 + typedef typename Parent::Node Node;
42.1573 +
42.1574 + protected:
42.1575 + ConstMap<typename GR::Edge, Const<bool, true> > const_true_map;
42.1576 +
42.1577 + FilterNodes() : const_true_map() {}
42.1578 +
42.1579 + public:
42.1580 +
42.1581 + FilterNodes(GR& graph, NodeFilterMap& node_filter) :
42.1582 + Parent(), const_true_map() {
42.1583 + Parent::initialize(graph, node_filter, const_true_map);
42.1584 + }
42.1585 +
42.1586 + void status(const Node& n, bool v) const { Parent::status(n, v); }
42.1587 + bool status(const Node& n) const { return Parent::status(n); }
42.1588 + void disable(const Node& n) const { Parent::status(n, false); }
42.1589 + void enable(const Node& n) const { Parent::status(n, true); }
42.1590 +
42.1591 + };
42.1592 +
42.1593 +
42.1594 + /// \brief Returns a read-only FilterNodes adaptor
42.1595 + ///
42.1596 + /// This function just returns a read-only \ref FilterNodes adaptor.
42.1597 + /// \ingroup graph_adaptors
42.1598 + /// \relates FilterNodes
42.1599 + template<typename GR, typename NF>
42.1600 + FilterNodes<const GR, NF>
42.1601 + filterNodes(const GR& graph, NF& node_filter) {
42.1602 + return FilterNodes<const GR, NF>(graph, node_filter);
42.1603 + }
42.1604 +
42.1605 + template<typename GR, typename NF>
42.1606 + FilterNodes<const GR, const NF>
42.1607 + filterNodes(const GR& graph, const NF& node_filter) {
42.1608 + return FilterNodes<const GR, const NF>(graph, node_filter);
42.1609 + }
42.1610 +
42.1611 + /// \ingroup graph_adaptors
42.1612 + ///
42.1613 + /// \brief Adaptor class for hiding arcs in a digraph.
42.1614 + ///
42.1615 + /// FilterArcs adaptor can be used for hiding arcs in a digraph.
42.1616 + /// A \c bool arc map must be specified, which defines the filter for
42.1617 + /// the arcs. Only the arcs with \c true filter value are shown in the
42.1618 + /// subdigraph. This adaptor conforms to the \ref concepts::Digraph
42.1619 + /// "Digraph" concept.
42.1620 + ///
42.1621 + /// The adapted digraph can also be modified through this adaptor
42.1622 + /// by adding or removing nodes or arcs, unless the \c GR template
42.1623 + /// parameter is set to be \c const.
42.1624 + ///
42.1625 + /// \tparam DGR The type of the adapted digraph.
42.1626 + /// It must conform to the \ref concepts::Digraph "Digraph" concept.
42.1627 + /// It can also be specified to be \c const.
42.1628 + /// \tparam AF The type of the arc filter map.
42.1629 + /// It must be a \c bool (or convertible) arc map of the
42.1630 + /// adapted digraph. The default type is
42.1631 + /// \ref concepts::Digraph::ArcMap "DGR::ArcMap<bool>".
42.1632 + ///
42.1633 + /// \note The \c Node and \c Arc types of this adaptor and the adapted
42.1634 + /// digraph are convertible to each other.
42.1635 +#ifdef DOXYGEN
42.1636 + template<typename DGR,
42.1637 + typename AF>
42.1638 + class FilterArcs {
42.1639 +#else
42.1640 + template<typename DGR,
42.1641 + typename AF = typename DGR::template ArcMap<bool> >
42.1642 + class FilterArcs :
42.1643 + public DigraphAdaptorExtender<
42.1644 + SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
42.1645 + AF, false> > {
42.1646 +#endif
42.1647 + typedef DigraphAdaptorExtender<
42.1648 + SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
42.1649 + AF, false> > Parent;
42.1650 +
42.1651 + public:
42.1652 +
42.1653 + /// The type of the adapted digraph.
42.1654 + typedef DGR Digraph;
42.1655 + /// The type of the arc filter map.
42.1656 + typedef AF ArcFilterMap;
42.1657 +
42.1658 + typedef typename Parent::Arc Arc;
42.1659 +
42.1660 + protected:
42.1661 + ConstMap<typename DGR::Node, Const<bool, true> > const_true_map;
42.1662 +
42.1663 + FilterArcs() : const_true_map() {}
42.1664 +
42.1665 + public:
42.1666 +
42.1667 + /// \brief Constructor
42.1668 + ///
42.1669 + /// Creates a subdigraph for the given digraph with the given arc
42.1670 + /// filter map.
42.1671 + FilterArcs(DGR& digraph, ArcFilterMap& arc_filter)
42.1672 + : Parent(), const_true_map() {
42.1673 + Parent::initialize(digraph, const_true_map, arc_filter);
42.1674 + }
42.1675 +
42.1676 + /// \brief Sets the status of the given arc
42.1677 + ///
42.1678 + /// This function sets the status of the given arc.
42.1679 + /// It is done by simply setting the assigned value of \c a
42.1680 + /// to \c v in the arc filter map.
42.1681 + void status(const Arc& a, bool v) const { Parent::status(a, v); }
42.1682 +
42.1683 + /// \brief Returns the status of the given arc
42.1684 + ///
42.1685 + /// This function returns the status of the given arc.
42.1686 + /// It is \c true if the given arc is enabled (i.e. not hidden).
42.1687 + bool status(const Arc& a) const { return Parent::status(a); }
42.1688 +
42.1689 + /// \brief Disables the given arc
42.1690 + ///
42.1691 + /// This function disables the given arc in the subdigraph,
42.1692 + /// so the iteration jumps over it.
42.1693 + /// It is the same as \ref status() "status(a, false)".
42.1694 + void disable(const Arc& a) const { Parent::status(a, false); }
42.1695 +
42.1696 + /// \brief Enables the given arc
42.1697 + ///
42.1698 + /// This function enables the given arc in the subdigraph.
42.1699 + /// It is the same as \ref status() "status(a, true)".
42.1700 + void enable(const Arc& a) const { Parent::status(a, true); }
42.1701 +
42.1702 + };
42.1703 +
42.1704 + /// \brief Returns a read-only FilterArcs adaptor
42.1705 + ///
42.1706 + /// This function just returns a read-only \ref FilterArcs adaptor.
42.1707 + /// \ingroup graph_adaptors
42.1708 + /// \relates FilterArcs
42.1709 + template<typename DGR, typename AF>
42.1710 + FilterArcs<const DGR, AF>
42.1711 + filterArcs(const DGR& digraph, AF& arc_filter) {
42.1712 + return FilterArcs<const DGR, AF>(digraph, arc_filter);
42.1713 + }
42.1714 +
42.1715 + template<typename DGR, typename AF>
42.1716 + FilterArcs<const DGR, const AF>
42.1717 + filterArcs(const DGR& digraph, const AF& arc_filter) {
42.1718 + return FilterArcs<const DGR, const AF>(digraph, arc_filter);
42.1719 + }
42.1720 +
42.1721 + /// \ingroup graph_adaptors
42.1722 + ///
42.1723 + /// \brief Adaptor class for hiding edges in a graph.
42.1724 + ///
42.1725 + /// FilterEdges adaptor can be used for hiding edges in a graph.
42.1726 + /// A \c bool edge map must be specified, which defines the filter for
42.1727 + /// the edges. Only the edges with \c true filter value are shown in the
42.1728 + /// subgraph. This adaptor conforms to the \ref concepts::Graph
42.1729 + /// "Graph" concept.
42.1730 + ///
42.1731 + /// The adapted graph can also be modified through this adaptor
42.1732 + /// by adding or removing nodes or edges, unless the \c GR template
42.1733 + /// parameter is set to be \c const.
42.1734 + ///
42.1735 + /// \tparam GR The type of the adapted graph.
42.1736 + /// It must conform to the \ref concepts::Graph "Graph" concept.
42.1737 + /// It can also be specified to be \c const.
42.1738 + /// \tparam EF The type of the edge filter map.
42.1739 + /// It must be a \c bool (or convertible) edge map of the
42.1740 + /// adapted graph. The default type is
42.1741 + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
42.1742 + ///
42.1743 + /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
42.1744 + /// adapted graph are convertible to each other.
42.1745 +#ifdef DOXYGEN
42.1746 + template<typename GR,
42.1747 + typename EF>
42.1748 + class FilterEdges {
42.1749 +#else
42.1750 + template<typename GR,
42.1751 + typename EF = typename GR::template EdgeMap<bool> >
42.1752 + class FilterEdges :
42.1753 + public GraphAdaptorExtender<
42.1754 + SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >,
42.1755 + EF, false> > {
42.1756 +#endif
42.1757 + typedef GraphAdaptorExtender<
42.1758 + SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >,
42.1759 + EF, false> > Parent;
42.1760 +
42.1761 + public:
42.1762 +
42.1763 + /// The type of the adapted graph.
42.1764 + typedef GR Graph;
42.1765 + /// The type of the edge filter map.
42.1766 + typedef EF EdgeFilterMap;
42.1767 +
42.1768 + typedef typename Parent::Edge Edge;
42.1769 +
42.1770 + protected:
42.1771 + ConstMap<typename GR::Node, Const<bool, true> > const_true_map;
42.1772 +
42.1773 + FilterEdges() : const_true_map(true) {
42.1774 + Parent::setNodeFilterMap(const_true_map);
42.1775 + }
42.1776 +
42.1777 + public:
42.1778 +
42.1779 + /// \brief Constructor
42.1780 + ///
42.1781 + /// Creates a subgraph for the given graph with the given edge
42.1782 + /// filter map.
42.1783 + FilterEdges(GR& graph, EF& edge_filter)
42.1784 + : Parent(), const_true_map() {
42.1785 + Parent::initialize(graph, const_true_map, edge_filter);
42.1786 + }
42.1787 +
42.1788 + /// \brief Sets the status of the given edge
42.1789 + ///
42.1790 + /// This function sets the status of the given edge.
42.1791 + /// It is done by simply setting the assigned value of \c e
42.1792 + /// to \c v in the edge filter map.
42.1793 + void status(const Edge& e, bool v) const { Parent::status(e, v); }
42.1794 +
42.1795 + /// \brief Returns the status of the given edge
42.1796 + ///
42.1797 + /// This function returns the status of the given edge.
42.1798 + /// It is \c true if the given edge is enabled (i.e. not hidden).
42.1799 + bool status(const Edge& e) const { return Parent::status(e); }
42.1800 +
42.1801 + /// \brief Disables the given edge
42.1802 + ///
42.1803 + /// This function disables the given edge in the subgraph,
42.1804 + /// so the iteration jumps over it.
42.1805 + /// It is the same as \ref status() "status(e, false)".
42.1806 + void disable(const Edge& e) const { Parent::status(e, false); }
42.1807 +
42.1808 + /// \brief Enables the given edge
42.1809 + ///
42.1810 + /// This function enables the given edge in the subgraph.
42.1811 + /// It is the same as \ref status() "status(e, true)".
42.1812 + void enable(const Edge& e) const { Parent::status(e, true); }
42.1813 +
42.1814 + };
42.1815 +
42.1816 + /// \brief Returns a read-only FilterEdges adaptor
42.1817 + ///
42.1818 + /// This function just returns a read-only \ref FilterEdges adaptor.
42.1819 + /// \ingroup graph_adaptors
42.1820 + /// \relates FilterEdges
42.1821 + template<typename GR, typename EF>
42.1822 + FilterEdges<const GR, EF>
42.1823 + filterEdges(const GR& graph, EF& edge_filter) {
42.1824 + return FilterEdges<const GR, EF>(graph, edge_filter);
42.1825 + }
42.1826 +
42.1827 + template<typename GR, typename EF>
42.1828 + FilterEdges<const GR, const EF>
42.1829 + filterEdges(const GR& graph, const EF& edge_filter) {
42.1830 + return FilterEdges<const GR, const EF>(graph, edge_filter);
42.1831 + }
42.1832 +
42.1833 +
42.1834 + template <typename DGR>
42.1835 + class UndirectorBase {
42.1836 + public:
42.1837 + typedef DGR Digraph;
42.1838 + typedef UndirectorBase Adaptor;
42.1839 +
42.1840 + typedef True UndirectedTag;
42.1841 +
42.1842 + typedef typename Digraph::Arc Edge;
42.1843 + typedef typename Digraph::Node Node;
42.1844 +
42.1845 + class Arc {
42.1846 + friend class UndirectorBase;
42.1847 + protected:
42.1848 + Edge _edge;
42.1849 + bool _forward;
42.1850 +
42.1851 + Arc(const Edge& edge, bool forward)
42.1852 + : _edge(edge), _forward(forward) {}
42.1853 +
42.1854 + public:
42.1855 + Arc() {}
42.1856 +
42.1857 + Arc(Invalid) : _edge(INVALID), _forward(true) {}
42.1858 +
42.1859 + operator const Edge&() const { return _edge; }
42.1860 +
42.1861 + bool operator==(const Arc &other) const {
42.1862 + return _forward == other._forward && _edge == other._edge;
42.1863 + }
42.1864 + bool operator!=(const Arc &other) const {
42.1865 + return _forward != other._forward || _edge != other._edge;
42.1866 + }
42.1867 + bool operator<(const Arc &other) const {
42.1868 + return _forward < other._forward ||
42.1869 + (_forward == other._forward && _edge < other._edge);
42.1870 + }
42.1871 + };
42.1872 +
42.1873 + void first(Node& n) const {
42.1874 + _digraph->first(n);
42.1875 + }
42.1876 +
42.1877 + void next(Node& n) const {
42.1878 + _digraph->next(n);
42.1879 + }
42.1880 +
42.1881 + void first(Arc& a) const {
42.1882 + _digraph->first(a._edge);
42.1883 + a._forward = true;
42.1884 + }
42.1885 +
42.1886 + void next(Arc& a) const {
42.1887 + if (a._forward) {
42.1888 + a._forward = false;
42.1889 + } else {
42.1890 + _digraph->next(a._edge);
42.1891 + a._forward = true;
42.1892 + }
42.1893 + }
42.1894 +
42.1895 + void first(Edge& e) const {
42.1896 + _digraph->first(e);
42.1897 + }
42.1898 +
42.1899 + void next(Edge& e) const {
42.1900 + _digraph->next(e);
42.1901 + }
42.1902 +
42.1903 + void firstOut(Arc& a, const Node& n) const {
42.1904 + _digraph->firstIn(a._edge, n);
42.1905 + if (a._edge != INVALID ) {
42.1906 + a._forward = false;
42.1907 + } else {
42.1908 + _digraph->firstOut(a._edge, n);
42.1909 + a._forward = true;
42.1910 + }
42.1911 + }
42.1912 + void nextOut(Arc &a) const {
42.1913 + if (!a._forward) {
42.1914 + Node n = _digraph->target(a._edge);
42.1915 + _digraph->nextIn(a._edge);
42.1916 + if (a._edge == INVALID) {
42.1917 + _digraph->firstOut(a._edge, n);
42.1918 + a._forward = true;
42.1919 + }
42.1920 + }
42.1921 + else {
42.1922 + _digraph->nextOut(a._edge);
42.1923 + }
42.1924 + }
42.1925 +
42.1926 + void firstIn(Arc &a, const Node &n) const {
42.1927 + _digraph->firstOut(a._edge, n);
42.1928 + if (a._edge != INVALID ) {
42.1929 + a._forward = false;
42.1930 + } else {
42.1931 + _digraph->firstIn(a._edge, n);
42.1932 + a._forward = true;
42.1933 + }
42.1934 + }
42.1935 + void nextIn(Arc &a) const {
42.1936 + if (!a._forward) {
42.1937 + Node n = _digraph->source(a._edge);
42.1938 + _digraph->nextOut(a._edge);
42.1939 + if (a._edge == INVALID ) {
42.1940 + _digraph->firstIn(a._edge, n);
42.1941 + a._forward = true;
42.1942 + }
42.1943 + }
42.1944 + else {
42.1945 + _digraph->nextIn(a._edge);
42.1946 + }
42.1947 + }
42.1948 +
42.1949 + void firstInc(Edge &e, bool &d, const Node &n) const {
42.1950 + d = true;
42.1951 + _digraph->firstOut(e, n);
42.1952 + if (e != INVALID) return;
42.1953 + d = false;
42.1954 + _digraph->firstIn(e, n);
42.1955 + }
42.1956 +
42.1957 + void nextInc(Edge &e, bool &d) const {
42.1958 + if (d) {
42.1959 + Node s = _digraph->source(e);
42.1960 + _digraph->nextOut(e);
42.1961 + if (e != INVALID) return;
42.1962 + d = false;
42.1963 + _digraph->firstIn(e, s);
42.1964 + } else {
42.1965 + _digraph->nextIn(e);
42.1966 + }
42.1967 + }
42.1968 +
42.1969 + Node u(const Edge& e) const {
42.1970 + return _digraph->source(e);
42.1971 + }
42.1972 +
42.1973 + Node v(const Edge& e) const {
42.1974 + return _digraph->target(e);
42.1975 + }
42.1976 +
42.1977 + Node source(const Arc &a) const {
42.1978 + return a._forward ? _digraph->source(a._edge) : _digraph->target(a._edge);
42.1979 + }
42.1980 +
42.1981 + Node target(const Arc &a) const {
42.1982 + return a._forward ? _digraph->target(a._edge) : _digraph->source(a._edge);
42.1983 + }
42.1984 +
42.1985 + static Arc direct(const Edge &e, bool d) {
42.1986 + return Arc(e, d);
42.1987 + }
42.1988 +
42.1989 + static bool direction(const Arc &a) { return a._forward; }
42.1990 +
42.1991 + Node nodeFromId(int ix) const { return _digraph->nodeFromId(ix); }
42.1992 + Arc arcFromId(int ix) const {
42.1993 + return direct(_digraph->arcFromId(ix >> 1), bool(ix & 1));
42.1994 + }
42.1995 + Edge edgeFromId(int ix) const { return _digraph->arcFromId(ix); }
42.1996 +
42.1997 + int id(const Node &n) const { return _digraph->id(n); }
42.1998 + int id(const Arc &a) const {
42.1999 + return (_digraph->id(a) << 1) | (a._forward ? 1 : 0);
42.2000 + }
42.2001 + int id(const Edge &e) const { return _digraph->id(e); }
42.2002 +
42.2003 + int maxNodeId() const { return _digraph->maxNodeId(); }
42.2004 + int maxArcId() const { return (_digraph->maxArcId() << 1) | 1; }
42.2005 + int maxEdgeId() const { return _digraph->maxArcId(); }
42.2006 +
42.2007 + Node addNode() { return _digraph->addNode(); }
42.2008 + Edge addEdge(const Node& u, const Node& v) {
42.2009 + return _digraph->addArc(u, v);
42.2010 + }
42.2011 +
42.2012 + void erase(const Node& i) { _digraph->erase(i); }
42.2013 + void erase(const Edge& i) { _digraph->erase(i); }
42.2014 +
42.2015 + void clear() { _digraph->clear(); }
42.2016 +
42.2017 + typedef NodeNumTagIndicator<Digraph> NodeNumTag;
42.2018 + int nodeNum() const { return _digraph->nodeNum(); }
42.2019 +
42.2020 + typedef ArcNumTagIndicator<Digraph> ArcNumTag;
42.2021 + int arcNum() const { return 2 * _digraph->arcNum(); }
42.2022 +
42.2023 + typedef ArcNumTag EdgeNumTag;
42.2024 + int edgeNum() const { return _digraph->arcNum(); }
42.2025 +
42.2026 + typedef FindArcTagIndicator<Digraph> FindArcTag;
42.2027 + Arc findArc(Node s, Node t, Arc p = INVALID) const {
42.2028 + if (p == INVALID) {
42.2029 + Edge arc = _digraph->findArc(s, t);
42.2030 + if (arc != INVALID) return direct(arc, true);
42.2031 + arc = _digraph->findArc(t, s);
42.2032 + if (arc != INVALID) return direct(arc, false);
42.2033 + } else if (direction(p)) {
42.2034 + Edge arc = _digraph->findArc(s, t, p);
42.2035 + if (arc != INVALID) return direct(arc, true);
42.2036 + arc = _digraph->findArc(t, s);
42.2037 + if (arc != INVALID) return direct(arc, false);
42.2038 + } else {
42.2039 + Edge arc = _digraph->findArc(t, s, p);
42.2040 + if (arc != INVALID) return direct(arc, false);
42.2041 + }
42.2042 + return INVALID;
42.2043 + }
42.2044 +
42.2045 + typedef FindArcTag FindEdgeTag;
42.2046 + Edge findEdge(Node s, Node t, Edge p = INVALID) const {
42.2047 + if (s != t) {
42.2048 + if (p == INVALID) {
42.2049 + Edge arc = _digraph->findArc(s, t);
42.2050 + if (arc != INVALID) return arc;
42.2051 + arc = _digraph->findArc(t, s);
42.2052 + if (arc != INVALID) return arc;
42.2053 + } else if (_digraph->source(p) == s) {
42.2054 + Edge arc = _digraph->findArc(s, t, p);
42.2055 + if (arc != INVALID) return arc;
42.2056 + arc = _digraph->findArc(t, s);
42.2057 + if (arc != INVALID) return arc;
42.2058 + } else {
42.2059 + Edge arc = _digraph->findArc(t, s, p);
42.2060 + if (arc != INVALID) return arc;
42.2061 + }
42.2062 + } else {
42.2063 + return _digraph->findArc(s, t, p);
42.2064 + }
42.2065 + return INVALID;
42.2066 + }
42.2067 +
42.2068 + private:
42.2069 +
42.2070 + template <typename V>
42.2071 + class ArcMapBase {
42.2072 + private:
42.2073 +
42.2074 + typedef typename DGR::template ArcMap<V> MapImpl;
42.2075 +
42.2076 + public:
42.2077 +
42.2078 + typedef typename MapTraits<MapImpl>::ReferenceMapTag ReferenceMapTag;
42.2079 +
42.2080 + typedef V Value;
42.2081 + typedef Arc Key;
42.2082 + typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReturnValue;
42.2083 + typedef typename MapTraits<MapImpl>::ReturnValue ReturnValue;
42.2084 + typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReference;
42.2085 + typedef typename MapTraits<MapImpl>::ReturnValue Reference;
42.2086 +
42.2087 + ArcMapBase(const UndirectorBase<DGR>& adaptor) :
42.2088 + _forward(*adaptor._digraph), _backward(*adaptor._digraph) {}
42.2089 +
42.2090 + ArcMapBase(const UndirectorBase<DGR>& adaptor, const V& value)
42.2091 + : _forward(*adaptor._digraph, value),
42.2092 + _backward(*adaptor._digraph, value) {}
42.2093 +
42.2094 + void set(const Arc& a, const V& value) {
42.2095 + if (direction(a)) {
42.2096 + _forward.set(a, value);
42.2097 + } else {
42.2098 + _backward.set(a, value);
42.2099 + }
42.2100 + }
42.2101 +
42.2102 + ConstReturnValue operator[](const Arc& a) const {
42.2103 + if (direction(a)) {
42.2104 + return _forward[a];
42.2105 + } else {
42.2106 + return _backward[a];
42.2107 + }
42.2108 + }
42.2109 +
42.2110 + ReturnValue operator[](const Arc& a) {
42.2111 + if (direction(a)) {
42.2112 + return _forward[a];
42.2113 + } else {
42.2114 + return _backward[a];
42.2115 + }
42.2116 + }
42.2117 +
42.2118 + protected:
42.2119 +
42.2120 + MapImpl _forward, _backward;
42.2121 +
42.2122 + };
42.2123 +
42.2124 + public:
42.2125 +
42.2126 + template <typename V>
42.2127 + class NodeMap : public DGR::template NodeMap<V> {
42.2128 + typedef typename DGR::template NodeMap<V> Parent;
42.2129 +
42.2130 + public:
42.2131 + typedef V Value;
42.2132 +
42.2133 + explicit NodeMap(const UndirectorBase<DGR>& adaptor)
42.2134 + : Parent(*adaptor._digraph) {}
42.2135 +
42.2136 + NodeMap(const UndirectorBase<DGR>& adaptor, const V& value)
42.2137 + : Parent(*adaptor._digraph, value) { }
42.2138 +
42.2139 + private:
42.2140 + NodeMap& operator=(const NodeMap& cmap) {
42.2141 + return operator=<NodeMap>(cmap);
42.2142 + }
42.2143 +
42.2144 + template <typename CMap>
42.2145 + NodeMap& operator=(const CMap& cmap) {
42.2146 + Parent::operator=(cmap);
42.2147 + return *this;
42.2148 + }
42.2149 +
42.2150 + };
42.2151 +
42.2152 + template <typename V>
42.2153 + class ArcMap
42.2154 + : public SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> > {
42.2155 + typedef SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> > Parent;
42.2156 +
42.2157 + public:
42.2158 + typedef V Value;
42.2159 +
42.2160 + explicit ArcMap(const UndirectorBase<DGR>& adaptor)
42.2161 + : Parent(adaptor) {}
42.2162 +
42.2163 + ArcMap(const UndirectorBase<DGR>& adaptor, const V& value)
42.2164 + : Parent(adaptor, value) {}
42.2165 +
42.2166 + private:
42.2167 + ArcMap& operator=(const ArcMap& cmap) {
42.2168 + return operator=<ArcMap>(cmap);
42.2169 + }
42.2170 +
42.2171 + template <typename CMap>
42.2172 + ArcMap& operator=(const CMap& cmap) {
42.2173 + Parent::operator=(cmap);
42.2174 + return *this;
42.2175 + }
42.2176 + };
42.2177 +
42.2178 + template <typename V>
42.2179 + class EdgeMap : public Digraph::template ArcMap<V> {
42.2180 + typedef typename Digraph::template ArcMap<V> Parent;
42.2181 +
42.2182 + public:
42.2183 + typedef V Value;
42.2184 +
42.2185 + explicit EdgeMap(const UndirectorBase<DGR>& adaptor)
42.2186 + : Parent(*adaptor._digraph) {}
42.2187 +
42.2188 + EdgeMap(const UndirectorBase<DGR>& adaptor, const V& value)
42.2189 + : Parent(*adaptor._digraph, value) {}
42.2190 +
42.2191 + private:
42.2192 + EdgeMap& operator=(const EdgeMap& cmap) {
42.2193 + return operator=<EdgeMap>(cmap);
42.2194 + }
42.2195 +
42.2196 + template <typename CMap>
42.2197 + EdgeMap& operator=(const CMap& cmap) {
42.2198 + Parent::operator=(cmap);
42.2199 + return *this;
42.2200 + }
42.2201 +
42.2202 + };
42.2203 +
42.2204 + typedef typename ItemSetTraits<DGR, Node>::ItemNotifier NodeNotifier;
42.2205 + NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
42.2206 +
42.2207 + typedef typename ItemSetTraits<DGR, Edge>::ItemNotifier EdgeNotifier;
42.2208 + EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); }
42.2209 +
42.2210 + typedef EdgeNotifier ArcNotifier;
42.2211 + ArcNotifier& notifier(Arc) const { return _digraph->notifier(Edge()); }
42.2212 +
42.2213 + protected:
42.2214 +
42.2215 + UndirectorBase() : _digraph(0) {}
42.2216 +
42.2217 + DGR* _digraph;
42.2218 +
42.2219 + void initialize(DGR& digraph) {
42.2220 + _digraph = &digraph;
42.2221 + }
42.2222 +
42.2223 + };
42.2224 +
42.2225 + /// \ingroup graph_adaptors
42.2226 + ///
42.2227 + /// \brief Adaptor class for viewing a digraph as an undirected graph.
42.2228 + ///
42.2229 + /// Undirector adaptor can be used for viewing a digraph as an undirected
42.2230 + /// graph. All arcs of the underlying digraph are showed in the
42.2231 + /// adaptor as an edge (and also as a pair of arcs, of course).
42.2232 + /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
42.2233 + ///
42.2234 + /// The adapted digraph can also be modified through this adaptor
42.2235 + /// by adding or removing nodes or edges, unless the \c GR template
42.2236 + /// parameter is set to be \c const.
42.2237 + ///
42.2238 + /// \tparam DGR The type of the adapted digraph.
42.2239 + /// It must conform to the \ref concepts::Digraph "Digraph" concept.
42.2240 + /// It can also be specified to be \c const.
42.2241 + ///
42.2242 + /// \note The \c Node type of this adaptor and the adapted digraph are
42.2243 + /// convertible to each other, moreover the \c Edge type of the adaptor
42.2244 + /// and the \c Arc type of the adapted digraph are also convertible to
42.2245 + /// each other.
42.2246 + /// (Thus the \c Arc type of the adaptor is convertible to the \c Arc type
42.2247 + /// of the adapted digraph.)
42.2248 + template<typename DGR>
42.2249 +#ifdef DOXYGEN
42.2250 + class Undirector {
42.2251 +#else
42.2252 + class Undirector :
42.2253 + public GraphAdaptorExtender<UndirectorBase<DGR> > {
42.2254 +#endif
42.2255 + typedef GraphAdaptorExtender<UndirectorBase<DGR> > Parent;
42.2256 + public:
42.2257 + /// The type of the adapted digraph.
42.2258 + typedef DGR Digraph;
42.2259 + protected:
42.2260 + Undirector() { }
42.2261 + public:
42.2262 +
42.2263 + /// \brief Constructor
42.2264 + ///
42.2265 + /// Creates an undirected graph from the given digraph.
42.2266 + Undirector(DGR& digraph) {
42.2267 + initialize(digraph);
42.2268 + }
42.2269 +
42.2270 + /// \brief Arc map combined from two original arc maps
42.2271 + ///
42.2272 + /// This map adaptor class adapts two arc maps of the underlying
42.2273 + /// digraph to get an arc map of the undirected graph.
42.2274 + /// Its value type is inherited from the first arc map type (\c FW).
42.2275 + /// \tparam FW The type of the "foward" arc map.
42.2276 + /// \tparam BK The type of the "backward" arc map.
42.2277 + template <typename FW, typename BK>
42.2278 + class CombinedArcMap {
42.2279 + public:
42.2280 +
42.2281 + /// The key type of the map
42.2282 + typedef typename Parent::Arc Key;
42.2283 + /// The value type of the map
42.2284 + typedef typename FW::Value Value;
42.2285 +
42.2286 + typedef typename MapTraits<FW>::ReferenceMapTag ReferenceMapTag;
42.2287 +
42.2288 + typedef typename MapTraits<FW>::ReturnValue ReturnValue;
42.2289 + typedef typename MapTraits<FW>::ConstReturnValue ConstReturnValue;
42.2290 + typedef typename MapTraits<FW>::ReturnValue Reference;
42.2291 + typedef typename MapTraits<FW>::ConstReturnValue ConstReference;
42.2292 +
42.2293 + /// Constructor
42.2294 + CombinedArcMap(FW& forward, BK& backward)
42.2295 + : _forward(&forward), _backward(&backward) {}
42.2296 +
42.2297 + /// Sets the value associated with the given key.
42.2298 + void set(const Key& e, const Value& a) {
42.2299 + if (Parent::direction(e)) {
42.2300 + _forward->set(e, a);
42.2301 + } else {
42.2302 + _backward->set(e, a);
42.2303 + }
42.2304 + }
42.2305 +
42.2306 + /// Returns the value associated with the given key.
42.2307 + ConstReturnValue operator[](const Key& e) const {
42.2308 + if (Parent::direction(e)) {
42.2309 + return (*_forward)[e];
42.2310 + } else {
42.2311 + return (*_backward)[e];
42.2312 + }
42.2313 + }
42.2314 +
42.2315 + /// Returns a reference to the value associated with the given key.
42.2316 + ReturnValue operator[](const Key& e) {
42.2317 + if (Parent::direction(e)) {
42.2318 + return (*_forward)[e];
42.2319 + } else {
42.2320 + return (*_backward)[e];
42.2321 + }
42.2322 + }
42.2323 +
42.2324 + protected:
42.2325 +
42.2326 + FW* _forward;
42.2327 + BK* _backward;
42.2328 +
42.2329 + };
42.2330 +
42.2331 + /// \brief Returns a combined arc map
42.2332 + ///
42.2333 + /// This function just returns a combined arc map.
42.2334 + template <typename FW, typename BK>
42.2335 + static CombinedArcMap<FW, BK>
42.2336 + combinedArcMap(FW& forward, BK& backward) {
42.2337 + return CombinedArcMap<FW, BK>(forward, backward);
42.2338 + }
42.2339 +
42.2340 + template <typename FW, typename BK>
42.2341 + static CombinedArcMap<const FW, BK>
42.2342 + combinedArcMap(const FW& forward, BK& backward) {
42.2343 + return CombinedArcMap<const FW, BK>(forward, backward);
42.2344 + }
42.2345 +
42.2346 + template <typename FW, typename BK>
42.2347 + static CombinedArcMap<FW, const BK>
42.2348 + combinedArcMap(FW& forward, const BK& backward) {
42.2349 + return CombinedArcMap<FW, const BK>(forward, backward);
42.2350 + }
42.2351 +
42.2352 + template <typename FW, typename BK>
42.2353 + static CombinedArcMap<const FW, const BK>
42.2354 + combinedArcMap(const FW& forward, const BK& backward) {
42.2355 + return CombinedArcMap<const FW, const BK>(forward, backward);
42.2356 + }
42.2357 +
42.2358 + };
42.2359 +
42.2360 + /// \brief Returns a read-only Undirector adaptor
42.2361 + ///
42.2362 + /// This function just returns a read-only \ref Undirector adaptor.
42.2363 + /// \ingroup graph_adaptors
42.2364 + /// \relates Undirector
42.2365 + template<typename DGR>
42.2366 + Undirector<const DGR> undirector(const DGR& digraph) {
42.2367 + return Undirector<const DGR>(digraph);
42.2368 + }
42.2369 +
42.2370 +
42.2371 + template <typename GR, typename DM>
42.2372 + class OrienterBase {
42.2373 + public:
42.2374 +
42.2375 + typedef GR Graph;
42.2376 + typedef DM DirectionMap;
42.2377 +
42.2378 + typedef typename GR::Node Node;
42.2379 + typedef typename GR::Edge Arc;
42.2380 +
42.2381 + void reverseArc(const Arc& arc) {
42.2382 + _direction->set(arc, !(*_direction)[arc]);
42.2383 + }
42.2384 +
42.2385 + void first(Node& i) const { _graph->first(i); }
42.2386 + void first(Arc& i) const { _graph->first(i); }
42.2387 + void firstIn(Arc& i, const Node& n) const {
42.2388 + bool d = true;
42.2389 + _graph->firstInc(i, d, n);
42.2390 + while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d);
42.2391 + }
42.2392 + void firstOut(Arc& i, const Node& n ) const {
42.2393 + bool d = true;
42.2394 + _graph->firstInc(i, d, n);
42.2395 + while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
42.2396 + }
42.2397 +
42.2398 + void next(Node& i) const { _graph->next(i); }
42.2399 + void next(Arc& i) const { _graph->next(i); }
42.2400 + void nextIn(Arc& i) const {
42.2401 + bool d = !(*_direction)[i];
42.2402 + _graph->nextInc(i, d);
42.2403 + while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d);
42.2404 + }
42.2405 + void nextOut(Arc& i) const {
42.2406 + bool d = (*_direction)[i];
42.2407 + _graph->nextInc(i, d);
42.2408 + while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
42.2409 + }
42.2410 +
42.2411 + Node source(const Arc& e) const {
42.2412 + return (*_direction)[e] ? _graph->u(e) : _graph->v(e);
42.2413 + }
42.2414 + Node target(const Arc& e) const {
42.2415 + return (*_direction)[e] ? _graph->v(e) : _graph->u(e);
42.2416 + }
42.2417 +
42.2418 + typedef NodeNumTagIndicator<Graph> NodeNumTag;
42.2419 + int nodeNum() const { return _graph->nodeNum(); }
42.2420 +
42.2421 + typedef EdgeNumTagIndicator<Graph> ArcNumTag;
42.2422 + int arcNum() const { return _graph->edgeNum(); }
42.2423 +
42.2424 + typedef FindEdgeTagIndicator<Graph> FindArcTag;
42.2425 + Arc findArc(const Node& u, const Node& v,
42.2426 + const Arc& prev = INVALID) const {
42.2427 + Arc arc = _graph->findEdge(u, v, prev);
42.2428 + while (arc != INVALID && source(arc) != u) {
42.2429 + arc = _graph->findEdge(u, v, arc);
42.2430 + }
42.2431 + return arc;
42.2432 + }
42.2433 +
42.2434 + Node addNode() {
42.2435 + return Node(_graph->addNode());
42.2436 + }
42.2437 +
42.2438 + Arc addArc(const Node& u, const Node& v) {
42.2439 + Arc arc = _graph->addEdge(u, v);
42.2440 + _direction->set(arc, _graph->u(arc) == u);
42.2441 + return arc;
42.2442 + }
42.2443 +
42.2444 + void erase(const Node& i) { _graph->erase(i); }
42.2445 + void erase(const Arc& i) { _graph->erase(i); }
42.2446 +
42.2447 + void clear() { _graph->clear(); }
42.2448 +
42.2449 + int id(const Node& v) const { return _graph->id(v); }
42.2450 + int id(const Arc& e) const { return _graph->id(e); }
42.2451 +
42.2452 + Node nodeFromId(int idx) const { return _graph->nodeFromId(idx); }
42.2453 + Arc arcFromId(int idx) const { return _graph->edgeFromId(idx); }
42.2454 +
42.2455 + int maxNodeId() const { return _graph->maxNodeId(); }
42.2456 + int maxArcId() const { return _graph->maxEdgeId(); }
42.2457 +
42.2458 + typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
42.2459 + NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
42.2460 +
42.2461 + typedef typename ItemSetTraits<GR, Arc>::ItemNotifier ArcNotifier;
42.2462 + ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
42.2463 +
42.2464 + template <typename V>
42.2465 + class NodeMap : public GR::template NodeMap<V> {
42.2466 + typedef typename GR::template NodeMap<V> Parent;
42.2467 +
42.2468 + public:
42.2469 +
42.2470 + explicit NodeMap(const OrienterBase<GR, DM>& adapter)
42.2471 + : Parent(*adapter._graph) {}
42.2472 +
42.2473 + NodeMap(const OrienterBase<GR, DM>& adapter, const V& value)
42.2474 + : Parent(*adapter._graph, value) {}
42.2475 +
42.2476 + private:
42.2477 + NodeMap& operator=(const NodeMap& cmap) {
42.2478 + return operator=<NodeMap>(cmap);
42.2479 + }
42.2480 +
42.2481 + template <typename CMap>
42.2482 + NodeMap& operator=(const CMap& cmap) {
42.2483 + Parent::operator=(cmap);
42.2484 + return *this;
42.2485 + }
42.2486 +
42.2487 + };
42.2488 +
42.2489 + template <typename V>
42.2490 + class ArcMap : public GR::template EdgeMap<V> {
42.2491 + typedef typename Graph::template EdgeMap<V> Parent;
42.2492 +
42.2493 + public:
42.2494 +
42.2495 + explicit ArcMap(const OrienterBase<GR, DM>& adapter)
42.2496 + : Parent(*adapter._graph) { }
42.2497 +
42.2498 + ArcMap(const OrienterBase<GR, DM>& adapter, const V& value)
42.2499 + : Parent(*adapter._graph, value) { }
42.2500 +
42.2501 + private:
42.2502 + ArcMap& operator=(const ArcMap& cmap) {
42.2503 + return operator=<ArcMap>(cmap);
42.2504 + }
42.2505 +
42.2506 + template <typename CMap>
42.2507 + ArcMap& operator=(const CMap& cmap) {
42.2508 + Parent::operator=(cmap);
42.2509 + return *this;
42.2510 + }
42.2511 + };
42.2512 +
42.2513 +
42.2514 +
42.2515 + protected:
42.2516 + Graph* _graph;
42.2517 + DM* _direction;
42.2518 +
42.2519 + void initialize(GR& graph, DM& direction) {
42.2520 + _graph = &graph;
42.2521 + _direction = &direction;
42.2522 + }
42.2523 +
42.2524 + };
42.2525 +
42.2526 + /// \ingroup graph_adaptors
42.2527 + ///
42.2528 + /// \brief Adaptor class for orienting the edges of a graph to get a digraph
42.2529 + ///
42.2530 + /// Orienter adaptor can be used for orienting the edges of a graph to
42.2531 + /// get a digraph. A \c bool edge map of the underlying graph must be
42.2532 + /// specified, which define the direction of the arcs in the adaptor.
42.2533 + /// The arcs can be easily reversed by the \c reverseArc() member function
42.2534 + /// of the adaptor.
42.2535 + /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
42.2536 + ///
42.2537 + /// The adapted graph can also be modified through this adaptor
42.2538 + /// by adding or removing nodes or arcs, unless the \c GR template
42.2539 + /// parameter is set to be \c const.
42.2540 + ///
42.2541 + /// \tparam GR The type of the adapted graph.
42.2542 + /// It must conform to the \ref concepts::Graph "Graph" concept.
42.2543 + /// It can also be specified to be \c const.
42.2544 + /// \tparam DM The type of the direction map.
42.2545 + /// It must be a \c bool (or convertible) edge map of the
42.2546 + /// adapted graph. The default type is
42.2547 + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
42.2548 + ///
42.2549 + /// \note The \c Node type of this adaptor and the adapted graph are
42.2550 + /// convertible to each other, moreover the \c Arc type of the adaptor
42.2551 + /// and the \c Edge type of the adapted graph are also convertible to
42.2552 + /// each other.
42.2553 +#ifdef DOXYGEN
42.2554 + template<typename GR,
42.2555 + typename DM>
42.2556 + class Orienter {
42.2557 +#else
42.2558 + template<typename GR,
42.2559 + typename DM = typename GR::template EdgeMap<bool> >
42.2560 + class Orienter :
42.2561 + public DigraphAdaptorExtender<OrienterBase<GR, DM> > {
42.2562 +#endif
42.2563 + typedef DigraphAdaptorExtender<OrienterBase<GR, DM> > Parent;
42.2564 + public:
42.2565 +
42.2566 + /// The type of the adapted graph.
42.2567 + typedef GR Graph;
42.2568 + /// The type of the direction edge map.
42.2569 + typedef DM DirectionMap;
42.2570 +
42.2571 + typedef typename Parent::Arc Arc;
42.2572 +
42.2573 + protected:
42.2574 + Orienter() { }
42.2575 +
42.2576 + public:
42.2577 +
42.2578 + /// \brief Constructor
42.2579 + ///
42.2580 + /// Constructor of the adaptor.
42.2581 + Orienter(GR& graph, DM& direction) {
42.2582 + Parent::initialize(graph, direction);
42.2583 + }
42.2584 +
42.2585 + /// \brief Reverses the given arc
42.2586 + ///
42.2587 + /// This function reverses the given arc.
42.2588 + /// It is done by simply negate the assigned value of \c a
42.2589 + /// in the direction map.
42.2590 + void reverseArc(const Arc& a) {
42.2591 + Parent::reverseArc(a);
42.2592 + }
42.2593 + };
42.2594 +
42.2595 + /// \brief Returns a read-only Orienter adaptor
42.2596 + ///
42.2597 + /// This function just returns a read-only \ref Orienter adaptor.
42.2598 + /// \ingroup graph_adaptors
42.2599 + /// \relates Orienter
42.2600 + template<typename GR, typename DM>
42.2601 + Orienter<const GR, DM>
42.2602 + orienter(const GR& graph, DM& direction) {
42.2603 + return Orienter<const GR, DM>(graph, direction);
42.2604 + }
42.2605 +
42.2606 + template<typename GR, typename DM>
42.2607 + Orienter<const GR, const DM>
42.2608 + orienter(const GR& graph, const DM& direction) {
42.2609 + return Orienter<const GR, const DM>(graph, direction);
42.2610 + }
42.2611 +
42.2612 + namespace _adaptor_bits {
42.2613 +
42.2614 + template <typename DGR, typename CM, typename FM, typename TL>
42.2615 + class ResForwardFilter {
42.2616 + public:
42.2617 +
42.2618 + typedef typename DGR::Arc Key;
42.2619 + typedef bool Value;
42.2620 +
42.2621 + private:
42.2622 +
42.2623 + const CM* _capacity;
42.2624 + const FM* _flow;
42.2625 + TL _tolerance;
42.2626 +
42.2627 + public:
42.2628 +
42.2629 + ResForwardFilter(const CM& capacity, const FM& flow,
42.2630 + const TL& tolerance = TL())
42.2631 + : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
42.2632 +
42.2633 + bool operator[](const typename DGR::Arc& a) const {
42.2634 + return _tolerance.positive((*_capacity)[a] - (*_flow)[a]);
42.2635 + }
42.2636 + };
42.2637 +
42.2638 + template<typename DGR,typename CM, typename FM, typename TL>
42.2639 + class ResBackwardFilter {
42.2640 + public:
42.2641 +
42.2642 + typedef typename DGR::Arc Key;
42.2643 + typedef bool Value;
42.2644 +
42.2645 + private:
42.2646 +
42.2647 + const CM* _capacity;
42.2648 + const FM* _flow;
42.2649 + TL _tolerance;
42.2650 +
42.2651 + public:
42.2652 +
42.2653 + ResBackwardFilter(const CM& capacity, const FM& flow,
42.2654 + const TL& tolerance = TL())
42.2655 + : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
42.2656 +
42.2657 + bool operator[](const typename DGR::Arc& a) const {
42.2658 + return _tolerance.positive((*_flow)[a]);
42.2659 + }
42.2660 + };
42.2661 +
42.2662 + }
42.2663 +
42.2664 + /// \ingroup graph_adaptors
42.2665 + ///
42.2666 + /// \brief Adaptor class for composing the residual digraph for directed
42.2667 + /// flow and circulation problems.
42.2668 + ///
42.2669 + /// ResidualDigraph can be used for composing the \e residual digraph
42.2670 + /// for directed flow and circulation problems. Let \f$ G=(V, A) \f$
42.2671 + /// be a directed graph and let \f$ F \f$ be a number type.
42.2672 + /// Let \f$ flow, cap: A\to F \f$ be functions on the arcs.
42.2673 + /// This adaptor implements a digraph structure with node set \f$ V \f$
42.2674 + /// and arc set \f$ A_{forward}\cup A_{backward} \f$,
42.2675 + /// where \f$ A_{forward}=\{uv : uv\in A, flow(uv)<cap(uv)\} \f$ and
42.2676 + /// \f$ A_{backward}=\{vu : uv\in A, flow(uv)>0\} \f$, i.e. the so
42.2677 + /// called residual digraph.
42.2678 + /// When the union \f$ A_{forward}\cup A_{backward} \f$ is taken,
42.2679 + /// multiplicities are counted, i.e. the adaptor has exactly
42.2680 + /// \f$ |A_{forward}| + |A_{backward}|\f$ arcs (it may have parallel
42.2681 + /// arcs).
42.2682 + /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
42.2683 + ///
42.2684 + /// \tparam DGR The type of the adapted digraph.
42.2685 + /// It must conform to the \ref concepts::Digraph "Digraph" concept.
42.2686 + /// It is implicitly \c const.
42.2687 + /// \tparam CM The type of the capacity map.
42.2688 + /// It must be an arc map of some numerical type, which defines
42.2689 + /// the capacities in the flow problem. It is implicitly \c const.
42.2690 + /// The default type is
42.2691 + /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
42.2692 + /// \tparam FM The type of the flow map.
42.2693 + /// It must be an arc map of some numerical type, which defines
42.2694 + /// the flow values in the flow problem. The default type is \c CM.
42.2695 + /// \tparam TL The tolerance type for handling inexact computation.
42.2696 + /// The default tolerance type depends on the value type of the
42.2697 + /// capacity map.
42.2698 + ///
42.2699 + /// \note This adaptor is implemented using Undirector and FilterArcs
42.2700 + /// adaptors.
42.2701 + ///
42.2702 + /// \note The \c Node type of this adaptor and the adapted digraph are
42.2703 + /// convertible to each other, moreover the \c Arc type of the adaptor
42.2704 + /// is convertible to the \c Arc type of the adapted digraph.
42.2705 +#ifdef DOXYGEN
42.2706 + template<typename DGR, typename CM, typename FM, typename TL>
42.2707 + class ResidualDigraph
42.2708 +#else
42.2709 + template<typename DGR,
42.2710 + typename CM = typename DGR::template ArcMap<int>,
42.2711 + typename FM = CM,
42.2712 + typename TL = Tolerance<typename CM::Value> >
42.2713 + class ResidualDigraph
42.2714 + : public SubDigraph<
42.2715 + Undirector<const DGR>,
42.2716 + ConstMap<typename DGR::Node, Const<bool, true> >,
42.2717 + typename Undirector<const DGR>::template CombinedArcMap<
42.2718 + _adaptor_bits::ResForwardFilter<const DGR, CM, FM, TL>,
42.2719 + _adaptor_bits::ResBackwardFilter<const DGR, CM, FM, TL> > >
42.2720 +#endif
42.2721 + {
42.2722 + public:
42.2723 +
42.2724 + /// The type of the underlying digraph.
42.2725 + typedef DGR Digraph;
42.2726 + /// The type of the capacity map.
42.2727 + typedef CM CapacityMap;
42.2728 + /// The type of the flow map.
42.2729 + typedef FM FlowMap;
42.2730 + /// The tolerance type.
42.2731 + typedef TL Tolerance;
42.2732 +
42.2733 + typedef typename CapacityMap::Value Value;
42.2734 + typedef ResidualDigraph Adaptor;
42.2735 +
42.2736 + protected:
42.2737 +
42.2738 + typedef Undirector<const Digraph> Undirected;
42.2739 +
42.2740 + typedef ConstMap<typename DGR::Node, Const<bool, true> > NodeFilter;
42.2741 +
42.2742 + typedef _adaptor_bits::ResForwardFilter<const DGR, CM,
42.2743 + FM, TL> ForwardFilter;
42.2744 +
42.2745 + typedef _adaptor_bits::ResBackwardFilter<const DGR, CM,
42.2746 + FM, TL> BackwardFilter;
42.2747 +
42.2748 + typedef typename Undirected::
42.2749 + template CombinedArcMap<ForwardFilter, BackwardFilter> ArcFilter;
42.2750 +
42.2751 + typedef SubDigraph<Undirected, NodeFilter, ArcFilter> Parent;
42.2752 +
42.2753 + const CapacityMap* _capacity;
42.2754 + FlowMap* _flow;
42.2755 +
42.2756 + Undirected _graph;
42.2757 + NodeFilter _node_filter;
42.2758 + ForwardFilter _forward_filter;
42.2759 + BackwardFilter _backward_filter;
42.2760 + ArcFilter _arc_filter;
42.2761 +
42.2762 + public:
42.2763 +
42.2764 + /// \brief Constructor
42.2765 + ///
42.2766 + /// Constructor of the residual digraph adaptor. The parameters are the
42.2767 + /// digraph, the capacity map, the flow map, and a tolerance object.
42.2768 + ResidualDigraph(const DGR& digraph, const CM& capacity,
42.2769 + FM& flow, const TL& tolerance = Tolerance())
42.2770 + : Parent(), _capacity(&capacity), _flow(&flow),
42.2771 + _graph(digraph), _node_filter(),
42.2772 + _forward_filter(capacity, flow, tolerance),
42.2773 + _backward_filter(capacity, flow, tolerance),
42.2774 + _arc_filter(_forward_filter, _backward_filter)
42.2775 + {
42.2776 + Parent::initialize(_graph, _node_filter, _arc_filter);
42.2777 + }
42.2778 +
42.2779 + typedef typename Parent::Arc Arc;
42.2780 +
42.2781 + /// \brief Returns the residual capacity of the given arc.
42.2782 + ///
42.2783 + /// Returns the residual capacity of the given arc.
42.2784 + Value residualCapacity(const Arc& a) const {
42.2785 + if (Undirected::direction(a)) {
42.2786 + return (*_capacity)[a] - (*_flow)[a];
42.2787 + } else {
42.2788 + return (*_flow)[a];
42.2789 + }
42.2790 + }
42.2791 +
42.2792 + /// \brief Augments on the given arc in the residual digraph.
42.2793 + ///
42.2794 + /// Augments on the given arc in the residual digraph. It increases
42.2795 + /// or decreases the flow value on the original arc according to the
42.2796 + /// direction of the residual arc.
42.2797 + void augment(const Arc& a, const Value& v) const {
42.2798 + if (Undirected::direction(a)) {
42.2799 + _flow->set(a, (*_flow)[a] + v);
42.2800 + } else {
42.2801 + _flow->set(a, (*_flow)[a] - v);
42.2802 + }
42.2803 + }
42.2804 +
42.2805 + /// \brief Returns \c true if the given residual arc is a forward arc.
42.2806 + ///
42.2807 + /// Returns \c true if the given residual arc has the same orientation
42.2808 + /// as the original arc, i.e. it is a so called forward arc.
42.2809 + static bool forward(const Arc& a) {
42.2810 + return Undirected::direction(a);
42.2811 + }
42.2812 +
42.2813 + /// \brief Returns \c true if the given residual arc is a backward arc.
42.2814 + ///
42.2815 + /// Returns \c true if the given residual arc has the opposite orientation
42.2816 + /// than the original arc, i.e. it is a so called backward arc.
42.2817 + static bool backward(const Arc& a) {
42.2818 + return !Undirected::direction(a);
42.2819 + }
42.2820 +
42.2821 + /// \brief Returns the forward oriented residual arc.
42.2822 + ///
42.2823 + /// Returns the forward oriented residual arc related to the given
42.2824 + /// arc of the underlying digraph.
42.2825 + static Arc forward(const typename Digraph::Arc& a) {
42.2826 + return Undirected::direct(a, true);
42.2827 + }
42.2828 +
42.2829 + /// \brief Returns the backward oriented residual arc.
42.2830 + ///
42.2831 + /// Returns the backward oriented residual arc related to the given
42.2832 + /// arc of the underlying digraph.
42.2833 + static Arc backward(const typename Digraph::Arc& a) {
42.2834 + return Undirected::direct(a, false);
42.2835 + }
42.2836 +
42.2837 + /// \brief Residual capacity map.
42.2838 + ///
42.2839 + /// This map adaptor class can be used for obtaining the residual
42.2840 + /// capacities as an arc map of the residual digraph.
42.2841 + /// Its value type is inherited from the capacity map.
42.2842 + class ResidualCapacity {
42.2843 + protected:
42.2844 + const Adaptor* _adaptor;
42.2845 + public:
42.2846 + /// The key type of the map
42.2847 + typedef Arc Key;
42.2848 + /// The value type of the map
42.2849 + typedef typename CapacityMap::Value Value;
42.2850 +
42.2851 + /// Constructor
42.2852 + ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor)
42.2853 + : _adaptor(&adaptor) {}
42.2854 +
42.2855 + /// Returns the value associated with the given residual arc
42.2856 + Value operator[](const Arc& a) const {
42.2857 + return _adaptor->residualCapacity(a);
42.2858 + }
42.2859 +
42.2860 + };
42.2861 +
42.2862 + /// \brief Returns a residual capacity map
42.2863 + ///
42.2864 + /// This function just returns a residual capacity map.
42.2865 + ResidualCapacity residualCapacity() const {
42.2866 + return ResidualCapacity(*this);
42.2867 + }
42.2868 +
42.2869 + };
42.2870 +
42.2871 + /// \brief Returns a (read-only) Residual adaptor
42.2872 + ///
42.2873 + /// This function just returns a (read-only) \ref ResidualDigraph adaptor.
42.2874 + /// \ingroup graph_adaptors
42.2875 + /// \relates ResidualDigraph
42.2876 + template<typename DGR, typename CM, typename FM>
42.2877 + ResidualDigraph<DGR, CM, FM>
42.2878 + residualDigraph(const DGR& digraph, const CM& capacity_map, FM& flow_map) {
42.2879 + return ResidualDigraph<DGR, CM, FM> (digraph, capacity_map, flow_map);
42.2880 + }
42.2881 +
42.2882 +
42.2883 + template <typename DGR>
42.2884 + class SplitNodesBase {
42.2885 + typedef DigraphAdaptorBase<const DGR> Parent;
42.2886 +
42.2887 + public:
42.2888 +
42.2889 + typedef DGR Digraph;
42.2890 + typedef SplitNodesBase Adaptor;
42.2891 +
42.2892 + typedef typename DGR::Node DigraphNode;
42.2893 + typedef typename DGR::Arc DigraphArc;
42.2894 +
42.2895 + class Node;
42.2896 + class Arc;
42.2897 +
42.2898 + private:
42.2899 +
42.2900 + template <typename T> class NodeMapBase;
42.2901 + template <typename T> class ArcMapBase;
42.2902 +
42.2903 + public:
42.2904 +
42.2905 + class Node : public DigraphNode {
42.2906 + friend class SplitNodesBase;
42.2907 + template <typename T> friend class NodeMapBase;
42.2908 + private:
42.2909 +
42.2910 + bool _in;
42.2911 + Node(DigraphNode node, bool in)
42.2912 + : DigraphNode(node), _in(in) {}
42.2913 +
42.2914 + public:
42.2915 +
42.2916 + Node() {}
42.2917 + Node(Invalid) : DigraphNode(INVALID), _in(true) {}
42.2918 +
42.2919 + bool operator==(const Node& node) const {
42.2920 + return DigraphNode::operator==(node) && _in == node._in;
42.2921 + }
42.2922 +
42.2923 + bool operator!=(const Node& node) const {
42.2924 + return !(*this == node);
42.2925 + }
42.2926 +
42.2927 + bool operator<(const Node& node) const {
42.2928 + return DigraphNode::operator<(node) ||
42.2929 + (DigraphNode::operator==(node) && _in < node._in);
42.2930 + }
42.2931 + };
42.2932 +
42.2933 + class Arc {
42.2934 + friend class SplitNodesBase;
42.2935 + template <typename T> friend class ArcMapBase;
42.2936 + private:
42.2937 + typedef BiVariant<DigraphArc, DigraphNode> ArcImpl;
42.2938 +
42.2939 + explicit Arc(const DigraphArc& arc) : _item(arc) {}
42.2940 + explicit Arc(const DigraphNode& node) : _item(node) {}
42.2941 +
42.2942 + ArcImpl _item;
42.2943 +
42.2944 + public:
42.2945 + Arc() {}
42.2946 + Arc(Invalid) : _item(DigraphArc(INVALID)) {}
42.2947 +
42.2948 + bool operator==(const Arc& arc) const {
42.2949 + if (_item.firstState()) {
42.2950 + if (arc._item.firstState()) {
42.2951 + return _item.first() == arc._item.first();
42.2952 + }
42.2953 + } else {
42.2954 + if (arc._item.secondState()) {
42.2955 + return _item.second() == arc._item.second();
42.2956 + }
42.2957 + }
42.2958 + return false;
42.2959 + }
42.2960 +
42.2961 + bool operator!=(const Arc& arc) const {
42.2962 + return !(*this == arc);
42.2963 + }
42.2964 +
42.2965 + bool operator<(const Arc& arc) const {
42.2966 + if (_item.firstState()) {
42.2967 + if (arc._item.firstState()) {
42.2968 + return _item.first() < arc._item.first();
42.2969 + }
42.2970 + return false;
42.2971 + } else {
42.2972 + if (arc._item.secondState()) {
42.2973 + return _item.second() < arc._item.second();
42.2974 + }
42.2975 + return true;
42.2976 + }
42.2977 + }
42.2978 +
42.2979 + operator DigraphArc() const { return _item.first(); }
42.2980 + operator DigraphNode() const { return _item.second(); }
42.2981 +
42.2982 + };
42.2983 +
42.2984 + void first(Node& n) const {
42.2985 + _digraph->first(n);
42.2986 + n._in = true;
42.2987 + }
42.2988 +
42.2989 + void next(Node& n) const {
42.2990 + if (n._in) {
42.2991 + n._in = false;
42.2992 + } else {
42.2993 + n._in = true;
42.2994 + _digraph->next(n);
42.2995 + }
42.2996 + }
42.2997 +
42.2998 + void first(Arc& e) const {
42.2999 + e._item.setSecond();
42.3000 + _digraph->first(e._item.second());
42.3001 + if (e._item.second() == INVALID) {
42.3002 + e._item.setFirst();
42.3003 + _digraph->first(e._item.first());
42.3004 + }
42.3005 + }
42.3006 +
42.3007 + void next(Arc& e) const {
42.3008 + if (e._item.secondState()) {
42.3009 + _digraph->next(e._item.second());
42.3010 + if (e._item.second() == INVALID) {
42.3011 + e._item.setFirst();
42.3012 + _digraph->first(e._item.first());
42.3013 + }
42.3014 + } else {
42.3015 + _digraph->next(e._item.first());
42.3016 + }
42.3017 + }
42.3018 +
42.3019 + void firstOut(Arc& e, const Node& n) const {
42.3020 + if (n._in) {
42.3021 + e._item.setSecond(n);
42.3022 + } else {
42.3023 + e._item.setFirst();
42.3024 + _digraph->firstOut(e._item.first(), n);
42.3025 + }
42.3026 + }
42.3027 +
42.3028 + void nextOut(Arc& e) const {
42.3029 + if (!e._item.firstState()) {
42.3030 + e._item.setFirst(INVALID);
42.3031 + } else {
42.3032 + _digraph->nextOut(e._item.first());
42.3033 + }
42.3034 + }
42.3035 +
42.3036 + void firstIn(Arc& e, const Node& n) const {
42.3037 + if (!n._in) {
42.3038 + e._item.setSecond(n);
42.3039 + } else {
42.3040 + e._item.setFirst();
42.3041 + _digraph->firstIn(e._item.first(), n);
42.3042 + }
42.3043 + }
42.3044 +
42.3045 + void nextIn(Arc& e) const {
42.3046 + if (!e._item.firstState()) {
42.3047 + e._item.setFirst(INVALID);
42.3048 + } else {
42.3049 + _digraph->nextIn(e._item.first());
42.3050 + }
42.3051 + }
42.3052 +
42.3053 + Node source(const Arc& e) const {
42.3054 + if (e._item.firstState()) {
42.3055 + return Node(_digraph->source(e._item.first()), false);
42.3056 + } else {
42.3057 + return Node(e._item.second(), true);
42.3058 + }
42.3059 + }
42.3060 +
42.3061 + Node target(const Arc& e) const {
42.3062 + if (e._item.firstState()) {
42.3063 + return Node(_digraph->target(e._item.first()), true);
42.3064 + } else {
42.3065 + return Node(e._item.second(), false);
42.3066 + }
42.3067 + }
42.3068 +
42.3069 + int id(const Node& n) const {
42.3070 + return (_digraph->id(n) << 1) | (n._in ? 0 : 1);
42.3071 + }
42.3072 + Node nodeFromId(int ix) const {
42.3073 + return Node(_digraph->nodeFromId(ix >> 1), (ix & 1) == 0);
42.3074 + }
42.3075 + int maxNodeId() const {
42.3076 + return 2 * _digraph->maxNodeId() + 1;
42.3077 + }
42.3078 +
42.3079 + int id(const Arc& e) const {
42.3080 + if (e._item.firstState()) {
42.3081 + return _digraph->id(e._item.first()) << 1;
42.3082 + } else {
42.3083 + return (_digraph->id(e._item.second()) << 1) | 1;
42.3084 + }
42.3085 + }
42.3086 + Arc arcFromId(int ix) const {
42.3087 + if ((ix & 1) == 0) {
42.3088 + return Arc(_digraph->arcFromId(ix >> 1));
42.3089 + } else {
42.3090 + return Arc(_digraph->nodeFromId(ix >> 1));
42.3091 + }
42.3092 + }
42.3093 + int maxArcId() const {
42.3094 + return std::max(_digraph->maxNodeId() << 1,
42.3095 + (_digraph->maxArcId() << 1) | 1);
42.3096 + }
42.3097 +
42.3098 + static bool inNode(const Node& n) {
42.3099 + return n._in;
42.3100 + }
42.3101 +
42.3102 + static bool outNode(const Node& n) {
42.3103 + return !n._in;
42.3104 + }
42.3105 +
42.3106 + static bool origArc(const Arc& e) {
42.3107 + return e._item.firstState();
42.3108 + }
42.3109 +
42.3110 + static bool bindArc(const Arc& e) {
42.3111 + return e._item.secondState();
42.3112 + }
42.3113 +
42.3114 + static Node inNode(const DigraphNode& n) {
42.3115 + return Node(n, true);
42.3116 + }
42.3117 +
42.3118 + static Node outNode(const DigraphNode& n) {
42.3119 + return Node(n, false);
42.3120 + }
42.3121 +
42.3122 + static Arc arc(const DigraphNode& n) {
42.3123 + return Arc(n);
42.3124 + }
42.3125 +
42.3126 + static Arc arc(const DigraphArc& e) {
42.3127 + return Arc(e);
42.3128 + }
42.3129 +
42.3130 + typedef True NodeNumTag;
42.3131 + int nodeNum() const {
42.3132 + return 2 * countNodes(*_digraph);
42.3133 + }
42.3134 +
42.3135 + typedef True ArcNumTag;
42.3136 + int arcNum() const {
42.3137 + return countArcs(*_digraph) + countNodes(*_digraph);
42.3138 + }
42.3139 +
42.3140 + typedef True FindArcTag;
42.3141 + Arc findArc(const Node& u, const Node& v,
42.3142 + const Arc& prev = INVALID) const {
42.3143 + if (inNode(u) && outNode(v)) {
42.3144 + if (static_cast<const DigraphNode&>(u) ==
42.3145 + static_cast<const DigraphNode&>(v) && prev == INVALID) {
42.3146 + return Arc(u);
42.3147 + }
42.3148 + }
42.3149 + else if (outNode(u) && inNode(v)) {
42.3150 + return Arc(::lemon::findArc(*_digraph, u, v, prev));
42.3151 + }
42.3152 + return INVALID;
42.3153 + }
42.3154 +
42.3155 + private:
42.3156 +
42.3157 + template <typename V>
42.3158 + class NodeMapBase
42.3159 + : public MapTraits<typename Parent::template NodeMap<V> > {
42.3160 + typedef typename Parent::template NodeMap<V> NodeImpl;
42.3161 + public:
42.3162 + typedef Node Key;
42.3163 + typedef V Value;
42.3164 + typedef typename MapTraits<NodeImpl>::ReferenceMapTag ReferenceMapTag;
42.3165 + typedef typename MapTraits<NodeImpl>::ReturnValue ReturnValue;
42.3166 + typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReturnValue;
42.3167 + typedef typename MapTraits<NodeImpl>::ReturnValue Reference;
42.3168 + typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReference;
42.3169 +
42.3170 + NodeMapBase(const SplitNodesBase<DGR>& adaptor)
42.3171 + : _in_map(*adaptor._digraph), _out_map(*adaptor._digraph) {}
42.3172 + NodeMapBase(const SplitNodesBase<DGR>& adaptor, const V& value)
42.3173 + : _in_map(*adaptor._digraph, value),
42.3174 + _out_map(*adaptor._digraph, value) {}
42.3175 +
42.3176 + void set(const Node& key, const V& val) {
42.3177 + if (SplitNodesBase<DGR>::inNode(key)) { _in_map.set(key, val); }
42.3178 + else {_out_map.set(key, val); }
42.3179 + }
42.3180 +
42.3181 + ReturnValue operator[](const Node& key) {
42.3182 + if (SplitNodesBase<DGR>::inNode(key)) { return _in_map[key]; }
42.3183 + else { return _out_map[key]; }
42.3184 + }
42.3185 +
42.3186 + ConstReturnValue operator[](const Node& key) const {
42.3187 + if (Adaptor::inNode(key)) { return _in_map[key]; }
42.3188 + else { return _out_map[key]; }
42.3189 + }
42.3190 +
42.3191 + private:
42.3192 + NodeImpl _in_map, _out_map;
42.3193 + };
42.3194 +
42.3195 + template <typename V>
42.3196 + class ArcMapBase
42.3197 + : public MapTraits<typename Parent::template ArcMap<V> > {
42.3198 + typedef typename Parent::template ArcMap<V> ArcImpl;
42.3199 + typedef typename Parent::template NodeMap<V> NodeImpl;
42.3200 + public:
42.3201 + typedef Arc Key;
42.3202 + typedef V Value;
42.3203 + typedef typename MapTraits<ArcImpl>::ReferenceMapTag ReferenceMapTag;
42.3204 + typedef typename MapTraits<ArcImpl>::ReturnValue ReturnValue;
42.3205 + typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReturnValue;
42.3206 + typedef typename MapTraits<ArcImpl>::ReturnValue Reference;
42.3207 + typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReference;
42.3208 +
42.3209 + ArcMapBase(const SplitNodesBase<DGR>& adaptor)
42.3210 + : _arc_map(*adaptor._digraph), _node_map(*adaptor._digraph) {}
42.3211 + ArcMapBase(const SplitNodesBase<DGR>& adaptor, const V& value)
42.3212 + : _arc_map(*adaptor._digraph, value),
42.3213 + _node_map(*adaptor._digraph, value) {}
42.3214 +
42.3215 + void set(const Arc& key, const V& val) {
42.3216 + if (SplitNodesBase<DGR>::origArc(key)) {
42.3217 + _arc_map.set(static_cast<const DigraphArc&>(key), val);
42.3218 + } else {
42.3219 + _node_map.set(static_cast<const DigraphNode&>(key), val);
42.3220 + }
42.3221 + }
42.3222 +
42.3223 + ReturnValue operator[](const Arc& key) {
42.3224 + if (SplitNodesBase<DGR>::origArc(key)) {
42.3225 + return _arc_map[static_cast<const DigraphArc&>(key)];
42.3226 + } else {
42.3227 + return _node_map[static_cast<const DigraphNode&>(key)];
42.3228 + }
42.3229 + }
42.3230 +
42.3231 + ConstReturnValue operator[](const Arc& key) const {
42.3232 + if (SplitNodesBase<DGR>::origArc(key)) {
42.3233 + return _arc_map[static_cast<const DigraphArc&>(key)];
42.3234 + } else {
42.3235 + return _node_map[static_cast<const DigraphNode&>(key)];
42.3236 + }
42.3237 + }
42.3238 +
42.3239 + private:
42.3240 + ArcImpl _arc_map;
42.3241 + NodeImpl _node_map;
42.3242 + };
42.3243 +
42.3244 + public:
42.3245 +
42.3246 + template <typename V>
42.3247 + class NodeMap
42.3248 + : public SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> > {
42.3249 + typedef SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> > Parent;
42.3250 +
42.3251 + public:
42.3252 + typedef V Value;
42.3253 +
42.3254 + NodeMap(const SplitNodesBase<DGR>& adaptor)
42.3255 + : Parent(adaptor) {}
42.3256 +
42.3257 + NodeMap(const SplitNodesBase<DGR>& adaptor, const V& value)
42.3258 + : Parent(adaptor, value) {}
42.3259 +
42.3260 + private:
42.3261 + NodeMap& operator=(const NodeMap& cmap) {
42.3262 + return operator=<NodeMap>(cmap);
42.3263 + }
42.3264 +
42.3265 + template <typename CMap>
42.3266 + NodeMap& operator=(const CMap& cmap) {
42.3267 + Parent::operator=(cmap);
42.3268 + return *this;
42.3269 + }
42.3270 + };
42.3271 +
42.3272 + template <typename V>
42.3273 + class ArcMap
42.3274 + : public SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> > {
42.3275 + typedef SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> > Parent;
42.3276 +
42.3277 + public:
42.3278 + typedef V Value;
42.3279 +
42.3280 + ArcMap(const SplitNodesBase<DGR>& adaptor)
42.3281 + : Parent(adaptor) {}
42.3282 +
42.3283 + ArcMap(const SplitNodesBase<DGR>& adaptor, const V& value)
42.3284 + : Parent(adaptor, value) {}
42.3285 +
42.3286 + private:
42.3287 + ArcMap& operator=(const ArcMap& cmap) {
42.3288 + return operator=<ArcMap>(cmap);
42.3289 + }
42.3290 +
42.3291 + template <typename CMap>
42.3292 + ArcMap& operator=(const CMap& cmap) {
42.3293 + Parent::operator=(cmap);
42.3294 + return *this;
42.3295 + }
42.3296 + };
42.3297 +
42.3298 + protected:
42.3299 +
42.3300 + SplitNodesBase() : _digraph(0) {}
42.3301 +
42.3302 + DGR* _digraph;
42.3303 +
42.3304 + void initialize(Digraph& digraph) {
42.3305 + _digraph = &digraph;
42.3306 + }
42.3307 +
42.3308 + };
42.3309 +
42.3310 + /// \ingroup graph_adaptors
42.3311 + ///
42.3312 + /// \brief Adaptor class for splitting the nodes of a digraph.
42.3313 + ///
42.3314 + /// SplitNodes adaptor can be used for splitting each node into an
42.3315 + /// \e in-node and an \e out-node in a digraph. Formaly, the adaptor
42.3316 + /// replaces each node \f$ u \f$ in the digraph with two nodes,
42.3317 + /// namely node \f$ u_{in} \f$ and node \f$ u_{out} \f$.
42.3318 + /// If there is a \f$ (v, u) \f$ arc in the original digraph, then the
42.3319 + /// new target of the arc will be \f$ u_{in} \f$ and similarly the
42.3320 + /// source of each original \f$ (u, v) \f$ arc will be \f$ u_{out} \f$.
42.3321 + /// The adaptor adds an additional \e bind \e arc from \f$ u_{in} \f$
42.3322 + /// to \f$ u_{out} \f$ for each node \f$ u \f$ of the original digraph.
42.3323 + ///
42.3324 + /// The aim of this class is running an algorithm with respect to node
42.3325 + /// costs or capacities if the algorithm considers only arc costs or
42.3326 + /// capacities directly.
42.3327 + /// In this case you can use \c SplitNodes adaptor, and set the node
42.3328 + /// costs/capacities of the original digraph to the \e bind \e arcs
42.3329 + /// in the adaptor.
42.3330 + ///
42.3331 + /// \tparam DGR The type of the adapted digraph.
42.3332 + /// It must conform to the \ref concepts::Digraph "Digraph" concept.
42.3333 + /// It is implicitly \c const.
42.3334 + ///
42.3335 + /// \note The \c Node type of this adaptor is converible to the \c Node
42.3336 + /// type of the adapted digraph.
42.3337 + template <typename DGR>
42.3338 +#ifdef DOXYGEN
42.3339 + class SplitNodes {
42.3340 +#else
42.3341 + class SplitNodes
42.3342 + : public DigraphAdaptorExtender<SplitNodesBase<const DGR> > {
42.3343 +#endif
42.3344 + typedef DigraphAdaptorExtender<SplitNodesBase<const DGR> > Parent;
42.3345 +
42.3346 + public:
42.3347 + typedef DGR Digraph;
42.3348 +
42.3349 + typedef typename DGR::Node DigraphNode;
42.3350 + typedef typename DGR::Arc DigraphArc;
42.3351 +
42.3352 + typedef typename Parent::Node Node;
42.3353 + typedef typename Parent::Arc Arc;
42.3354 +
42.3355 + /// \brief Constructor
42.3356 + ///
42.3357 + /// Constructor of the adaptor.
42.3358 + SplitNodes(const DGR& g) {
42.3359 + Parent::initialize(g);
42.3360 + }
42.3361 +
42.3362 + /// \brief Returns \c true if the given node is an in-node.
42.3363 + ///
42.3364 + /// Returns \c true if the given node is an in-node.
42.3365 + static bool inNode(const Node& n) {
42.3366 + return Parent::inNode(n);
42.3367 + }
42.3368 +
42.3369 + /// \brief Returns \c true if the given node is an out-node.
42.3370 + ///
42.3371 + /// Returns \c true if the given node is an out-node.
42.3372 + static bool outNode(const Node& n) {
42.3373 + return Parent::outNode(n);
42.3374 + }
42.3375 +
42.3376 + /// \brief Returns \c true if the given arc is an original arc.
42.3377 + ///
42.3378 + /// Returns \c true if the given arc is one of the arcs in the
42.3379 + /// original digraph.
42.3380 + static bool origArc(const Arc& a) {
42.3381 + return Parent::origArc(a);
42.3382 + }
42.3383 +
42.3384 + /// \brief Returns \c true if the given arc is a bind arc.
42.3385 + ///
42.3386 + /// Returns \c true if the given arc is a bind arc, i.e. it connects
42.3387 + /// an in-node and an out-node.
42.3388 + static bool bindArc(const Arc& a) {
42.3389 + return Parent::bindArc(a);
42.3390 + }
42.3391 +
42.3392 + /// \brief Returns the in-node created from the given original node.
42.3393 + ///
42.3394 + /// Returns the in-node created from the given original node.
42.3395 + static Node inNode(const DigraphNode& n) {
42.3396 + return Parent::inNode(n);
42.3397 + }
42.3398 +
42.3399 + /// \brief Returns the out-node created from the given original node.
42.3400 + ///
42.3401 + /// Returns the out-node created from the given original node.
42.3402 + static Node outNode(const DigraphNode& n) {
42.3403 + return Parent::outNode(n);
42.3404 + }
42.3405 +
42.3406 + /// \brief Returns the bind arc that corresponds to the given
42.3407 + /// original node.
42.3408 + ///
42.3409 + /// Returns the bind arc in the adaptor that corresponds to the given
42.3410 + /// original node, i.e. the arc connecting the in-node and out-node
42.3411 + /// of \c n.
42.3412 + static Arc arc(const DigraphNode& n) {
42.3413 + return Parent::arc(n);
42.3414 + }
42.3415 +
42.3416 + /// \brief Returns the arc that corresponds to the given original arc.
42.3417 + ///
42.3418 + /// Returns the arc in the adaptor that corresponds to the given
42.3419 + /// original arc.
42.3420 + static Arc arc(const DigraphArc& a) {
42.3421 + return Parent::arc(a);
42.3422 + }
42.3423 +
42.3424 + /// \brief Node map combined from two original node maps
42.3425 + ///
42.3426 + /// This map adaptor class adapts two node maps of the original digraph
42.3427 + /// to get a node map of the split digraph.
42.3428 + /// Its value type is inherited from the first node map type (\c IN).
42.3429 + /// \tparam IN The type of the node map for the in-nodes.
42.3430 + /// \tparam OUT The type of the node map for the out-nodes.
42.3431 + template <typename IN, typename OUT>
42.3432 + class CombinedNodeMap {
42.3433 + public:
42.3434 +
42.3435 + /// The key type of the map
42.3436 + typedef Node Key;
42.3437 + /// The value type of the map
42.3438 + typedef typename IN::Value Value;
42.3439 +
42.3440 + typedef typename MapTraits<IN>::ReferenceMapTag ReferenceMapTag;
42.3441 + typedef typename MapTraits<IN>::ReturnValue ReturnValue;
42.3442 + typedef typename MapTraits<IN>::ConstReturnValue ConstReturnValue;
42.3443 + typedef typename MapTraits<IN>::ReturnValue Reference;
42.3444 + typedef typename MapTraits<IN>::ConstReturnValue ConstReference;
42.3445 +
42.3446 + /// Constructor
42.3447 + CombinedNodeMap(IN& in_map, OUT& out_map)
42.3448 + : _in_map(in_map), _out_map(out_map) {}
42.3449 +
42.3450 + /// Returns the value associated with the given key.
42.3451 + Value operator[](const Key& key) const {
42.3452 + if (SplitNodesBase<const DGR>::inNode(key)) {
42.3453 + return _in_map[key];
42.3454 + } else {
42.3455 + return _out_map[key];
42.3456 + }
42.3457 + }
42.3458 +
42.3459 + /// Returns a reference to the value associated with the given key.
42.3460 + Value& operator[](const Key& key) {
42.3461 + if (SplitNodesBase<const DGR>::inNode(key)) {
42.3462 + return _in_map[key];
42.3463 + } else {
42.3464 + return _out_map[key];
42.3465 + }
42.3466 + }
42.3467 +
42.3468 + /// Sets the value associated with the given key.
42.3469 + void set(const Key& key, const Value& value) {
42.3470 + if (SplitNodesBase<const DGR>::inNode(key)) {
42.3471 + _in_map.set(key, value);
42.3472 + } else {
42.3473 + _out_map.set(key, value);
42.3474 + }
42.3475 + }
42.3476 +
42.3477 + private:
42.3478 +
42.3479 + IN& _in_map;
42.3480 + OUT& _out_map;
42.3481 +
42.3482 + };
42.3483 +
42.3484 +
42.3485 + /// \brief Returns a combined node map
42.3486 + ///
42.3487 + /// This function just returns a combined node map.
42.3488 + template <typename IN, typename OUT>
42.3489 + static CombinedNodeMap<IN, OUT>
42.3490 + combinedNodeMap(IN& in_map, OUT& out_map) {
42.3491 + return CombinedNodeMap<IN, OUT>(in_map, out_map);
42.3492 + }
42.3493 +
42.3494 + template <typename IN, typename OUT>
42.3495 + static CombinedNodeMap<const IN, OUT>
42.3496 + combinedNodeMap(const IN& in_map, OUT& out_map) {
42.3497 + return CombinedNodeMap<const IN, OUT>(in_map, out_map);
42.3498 + }
42.3499 +
42.3500 + template <typename IN, typename OUT>
42.3501 + static CombinedNodeMap<IN, const OUT>
42.3502 + combinedNodeMap(IN& in_map, const OUT& out_map) {
42.3503 + return CombinedNodeMap<IN, const OUT>(in_map, out_map);
42.3504 + }
42.3505 +
42.3506 + template <typename IN, typename OUT>
42.3507 + static CombinedNodeMap<const IN, const OUT>
42.3508 + combinedNodeMap(const IN& in_map, const OUT& out_map) {
42.3509 + return CombinedNodeMap<const IN, const OUT>(in_map, out_map);
42.3510 + }
42.3511 +
42.3512 + /// \brief Arc map combined from an arc map and a node map of the
42.3513 + /// original digraph.
42.3514 + ///
42.3515 + /// This map adaptor class adapts an arc map and a node map of the
42.3516 + /// original digraph to get an arc map of the split digraph.
42.3517 + /// Its value type is inherited from the original arc map type (\c AM).
42.3518 + /// \tparam AM The type of the arc map.
42.3519 + /// \tparam NM the type of the node map.
42.3520 + template <typename AM, typename NM>
42.3521 + class CombinedArcMap {
42.3522 + public:
42.3523 +
42.3524 + /// The key type of the map
42.3525 + typedef Arc Key;
42.3526 + /// The value type of the map
42.3527 + typedef typename AM::Value Value;
42.3528 +
42.3529 + typedef typename MapTraits<AM>::ReferenceMapTag ReferenceMapTag;
42.3530 + typedef typename MapTraits<AM>::ReturnValue ReturnValue;
42.3531 + typedef typename MapTraits<AM>::ConstReturnValue ConstReturnValue;
42.3532 + typedef typename MapTraits<AM>::ReturnValue Reference;
42.3533 + typedef typename MapTraits<AM>::ConstReturnValue ConstReference;
42.3534 +
42.3535 + /// Constructor
42.3536 + CombinedArcMap(AM& arc_map, NM& node_map)
42.3537 + : _arc_map(arc_map), _node_map(node_map) {}
42.3538 +
42.3539 + /// Returns the value associated with the given key.
42.3540 + Value operator[](const Key& arc) const {
42.3541 + if (SplitNodesBase<const DGR>::origArc(arc)) {
42.3542 + return _arc_map[arc];
42.3543 + } else {
42.3544 + return _node_map[arc];
42.3545 + }
42.3546 + }
42.3547 +
42.3548 + /// Returns a reference to the value associated with the given key.
42.3549 + Value& operator[](const Key& arc) {
42.3550 + if (SplitNodesBase<const DGR>::origArc(arc)) {
42.3551 + return _arc_map[arc];
42.3552 + } else {
42.3553 + return _node_map[arc];
42.3554 + }
42.3555 + }
42.3556 +
42.3557 + /// Sets the value associated with the given key.
42.3558 + void set(const Arc& arc, const Value& val) {
42.3559 + if (SplitNodesBase<const DGR>::origArc(arc)) {
42.3560 + _arc_map.set(arc, val);
42.3561 + } else {
42.3562 + _node_map.set(arc, val);
42.3563 + }
42.3564 + }
42.3565 +
42.3566 + private:
42.3567 +
42.3568 + AM& _arc_map;
42.3569 + NM& _node_map;
42.3570 +
42.3571 + };
42.3572 +
42.3573 + /// \brief Returns a combined arc map
42.3574 + ///
42.3575 + /// This function just returns a combined arc map.
42.3576 + template <typename ArcMap, typename NodeMap>
42.3577 + static CombinedArcMap<ArcMap, NodeMap>
42.3578 + combinedArcMap(ArcMap& arc_map, NodeMap& node_map) {
42.3579 + return CombinedArcMap<ArcMap, NodeMap>(arc_map, node_map);
42.3580 + }
42.3581 +
42.3582 + template <typename ArcMap, typename NodeMap>
42.3583 + static CombinedArcMap<const ArcMap, NodeMap>
42.3584 + combinedArcMap(const ArcMap& arc_map, NodeMap& node_map) {
42.3585 + return CombinedArcMap<const ArcMap, NodeMap>(arc_map, node_map);
42.3586 + }
42.3587 +
42.3588 + template <typename ArcMap, typename NodeMap>
42.3589 + static CombinedArcMap<ArcMap, const NodeMap>
42.3590 + combinedArcMap(ArcMap& arc_map, const NodeMap& node_map) {
42.3591 + return CombinedArcMap<ArcMap, const NodeMap>(arc_map, node_map);
42.3592 + }
42.3593 +
42.3594 + template <typename ArcMap, typename NodeMap>
42.3595 + static CombinedArcMap<const ArcMap, const NodeMap>
42.3596 + combinedArcMap(const ArcMap& arc_map, const NodeMap& node_map) {
42.3597 + return CombinedArcMap<const ArcMap, const NodeMap>(arc_map, node_map);
42.3598 + }
42.3599 +
42.3600 + };
42.3601 +
42.3602 + /// \brief Returns a (read-only) SplitNodes adaptor
42.3603 + ///
42.3604 + /// This function just returns a (read-only) \ref SplitNodes adaptor.
42.3605 + /// \ingroup graph_adaptors
42.3606 + /// \relates SplitNodes
42.3607 + template<typename DGR>
42.3608 + SplitNodes<DGR>
42.3609 + splitNodes(const DGR& digraph) {
42.3610 + return SplitNodes<DGR>(digraph);
42.3611 + }
42.3612 +
42.3613 +#undef LEMON_SCOPE_FIX
42.3614 +
42.3615 +} //namespace lemon
42.3616 +
42.3617 +#endif //LEMON_ADAPTORS_H
43.1 --- a/lemon/arg_parser.cc Fri Nov 13 12:33:33 2009 +0100
43.2 +++ b/lemon/arg_parser.cc Thu Dec 10 17:05:35 2009 +0100
43.3 @@ -2,7 +2,7 @@
43.4 *
43.5 * This file is a part of LEMON, a generic C++ optimization library.
43.6 *
43.7 - * Copyright (C) 2003-2008
43.8 + * Copyright (C) 2003-2009
43.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
43.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
43.11 *
44.1 --- a/lemon/arg_parser.h Fri Nov 13 12:33:33 2009 +0100
44.2 +++ b/lemon/arg_parser.h Thu Dec 10 17:05:35 2009 +0100
44.3 @@ -2,7 +2,7 @@
44.4 *
44.5 * This file is a part of LEMON, a generic C++ optimization library.
44.6 *
44.7 - * Copyright (C) 2003-2008
44.8 + * Copyright (C) 2003-2009
44.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
44.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
44.11 *
45.1 --- a/lemon/assert.h Fri Nov 13 12:33:33 2009 +0100
45.2 +++ b/lemon/assert.h Thu Dec 10 17:05:35 2009 +0100
45.3 @@ -2,7 +2,7 @@
45.4 *
45.5 * This file is a part of LEMON, a generic C++ optimization library.
45.6 *
45.7 - * Copyright (C) 2003-2008
45.8 + * Copyright (C) 2003-2009
45.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
45.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
45.11 *
46.1 --- a/lemon/base.cc Fri Nov 13 12:33:33 2009 +0100
46.2 +++ b/lemon/base.cc Thu Dec 10 17:05:35 2009 +0100
46.3 @@ -2,7 +2,7 @@
46.4 *
46.5 * This file is a part of LEMON, a generic C++ optimization library.
46.6 *
46.7 - * Copyright (C) 2003-2008
46.8 + * Copyright (C) 2003-2009
46.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
46.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
46.11 *
46.12 @@ -23,7 +23,7 @@
46.13 #include<lemon/core.h>
46.14 namespace lemon {
46.15
46.16 - float Tolerance<float>::def_epsilon = 1e-4;
46.17 + float Tolerance<float>::def_epsilon = static_cast<float>(1e-4);
46.18 double Tolerance<double>::def_epsilon = 1e-10;
46.19 long double Tolerance<long double>::def_epsilon = 1e-14;
46.20
47.1 --- a/lemon/bfs.h Fri Nov 13 12:33:33 2009 +0100
47.2 +++ b/lemon/bfs.h Thu Dec 10 17:05:35 2009 +0100
47.3 @@ -2,7 +2,7 @@
47.4 *
47.5 * This file is a part of LEMON, a generic C++ optimization library.
47.6 *
47.7 - * Copyright (C) 2003-2008
47.8 + * Copyright (C) 2003-2009
47.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
47.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
47.11 *
47.12 @@ -49,11 +49,11 @@
47.13 ///arcs of the shortest paths.
47.14 ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
47.15 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
47.16 - ///Instantiates a PredMap.
47.17 + ///Instantiates a \c PredMap.
47.18
47.19 - ///This function instantiates a PredMap.
47.20 + ///This function instantiates a \ref PredMap.
47.21 ///\param g is the digraph, to which we would like to define the
47.22 - ///PredMap.
47.23 + ///\ref PredMap.
47.24 static PredMap *createPredMap(const Digraph &g)
47.25 {
47.26 return new PredMap(g);
47.27 @@ -64,11 +64,11 @@
47.28 ///The type of the map that indicates which nodes are processed.
47.29 ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
47.30 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
47.31 - ///Instantiates a ProcessedMap.
47.32 + ///Instantiates a \c ProcessedMap.
47.33
47.34 - ///This function instantiates a ProcessedMap.
47.35 + ///This function instantiates a \ref ProcessedMap.
47.36 ///\param g is the digraph, to which
47.37 - ///we would like to define the ProcessedMap
47.38 + ///we would like to define the \ref ProcessedMap
47.39 #ifdef DOXYGEN
47.40 static ProcessedMap *createProcessedMap(const Digraph &g)
47.41 #else
47.42 @@ -83,11 +83,11 @@
47.43 ///The type of the map that indicates which nodes are reached.
47.44 ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
47.45 typedef typename Digraph::template NodeMap<bool> ReachedMap;
47.46 - ///Instantiates a ReachedMap.
47.47 + ///Instantiates a \c ReachedMap.
47.48
47.49 - ///This function instantiates a ReachedMap.
47.50 + ///This function instantiates a \ref ReachedMap.
47.51 ///\param g is the digraph, to which
47.52 - ///we would like to define the ReachedMap.
47.53 + ///we would like to define the \ref ReachedMap.
47.54 static ReachedMap *createReachedMap(const Digraph &g)
47.55 {
47.56 return new ReachedMap(g);
47.57 @@ -98,11 +98,11 @@
47.58 ///The type of the map that stores the distances of the nodes.
47.59 ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
47.60 typedef typename Digraph::template NodeMap<int> DistMap;
47.61 - ///Instantiates a DistMap.
47.62 + ///Instantiates a \c DistMap.
47.63
47.64 - ///This function instantiates a DistMap.
47.65 + ///This function instantiates a \ref DistMap.
47.66 ///\param g is the digraph, to which we would like to define the
47.67 - ///DistMap.
47.68 + ///\ref DistMap.
47.69 static DistMap *createDistMap(const Digraph &g)
47.70 {
47.71 return new DistMap(g);
47.72 @@ -119,13 +119,7 @@
47.73 ///used easier.
47.74 ///
47.75 ///\tparam GR The type of the digraph the algorithm runs on.
47.76 - ///The default value is \ref ListDigraph. The value of GR is not used
47.77 - ///directly by \ref Bfs, it is only passed to \ref BfsDefaultTraits.
47.78 - ///\tparam TR Traits class to set various data types used by the algorithm.
47.79 - ///The default traits class is
47.80 - ///\ref BfsDefaultTraits "BfsDefaultTraits<GR>".
47.81 - ///See \ref BfsDefaultTraits for the documentation of
47.82 - ///a Bfs traits class.
47.83 + ///The default type is \ref ListDigraph.
47.84 #ifdef DOXYGEN
47.85 template <typename GR,
47.86 typename TR>
47.87 @@ -151,7 +145,7 @@
47.88 ///The type of the paths.
47.89 typedef PredMapPath<Digraph, PredMap> Path;
47.90
47.91 - ///The traits class.
47.92 + ///The \ref BfsDefaultTraits "traits class" of the algorithm.
47.93 typedef TR Traits;
47.94
47.95 private:
47.96 @@ -213,7 +207,7 @@
47.97
47.98 typedef Bfs Create;
47.99
47.100 - ///\name Named template parameters
47.101 + ///\name Named Template Parameters
47.102
47.103 ///@{
47.104
47.105 @@ -227,10 +221,11 @@
47.106 }
47.107 };
47.108 ///\brief \ref named-templ-param "Named parameter" for setting
47.109 - ///PredMap type.
47.110 + ///\c PredMap type.
47.111 ///
47.112 ///\ref named-templ-param "Named parameter" for setting
47.113 - ///PredMap type.
47.114 + ///\c PredMap type.
47.115 + ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
47.116 template <class T>
47.117 struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
47.118 typedef Bfs< Digraph, SetPredMapTraits<T> > Create;
47.119 @@ -246,10 +241,11 @@
47.120 }
47.121 };
47.122 ///\brief \ref named-templ-param "Named parameter" for setting
47.123 - ///DistMap type.
47.124 + ///\c DistMap type.
47.125 ///
47.126 ///\ref named-templ-param "Named parameter" for setting
47.127 - ///DistMap type.
47.128 + ///\c DistMap type.
47.129 + ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
47.130 template <class T>
47.131 struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
47.132 typedef Bfs< Digraph, SetDistMapTraits<T> > Create;
47.133 @@ -265,10 +261,11 @@
47.134 }
47.135 };
47.136 ///\brief \ref named-templ-param "Named parameter" for setting
47.137 - ///ReachedMap type.
47.138 + ///\c ReachedMap type.
47.139 ///
47.140 ///\ref named-templ-param "Named parameter" for setting
47.141 - ///ReachedMap type.
47.142 + ///\c ReachedMap type.
47.143 + ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
47.144 template <class T>
47.145 struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
47.146 typedef Bfs< Digraph, SetReachedMapTraits<T> > Create;
47.147 @@ -284,10 +281,11 @@
47.148 }
47.149 };
47.150 ///\brief \ref named-templ-param "Named parameter" for setting
47.151 - ///ProcessedMap type.
47.152 + ///\c ProcessedMap type.
47.153 ///
47.154 ///\ref named-templ-param "Named parameter" for setting
47.155 - ///ProcessedMap type.
47.156 + ///\c ProcessedMap type.
47.157 + ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
47.158 template <class T>
47.159 struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
47.160 typedef Bfs< Digraph, SetProcessedMapTraits<T> > Create;
47.161 @@ -302,10 +300,10 @@
47.162 }
47.163 };
47.164 ///\brief \ref named-templ-param "Named parameter" for setting
47.165 - ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
47.166 + ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
47.167 ///
47.168 ///\ref named-templ-param "Named parameter" for setting
47.169 - ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
47.170 + ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
47.171 ///If you don't set it explicitly, it will be automatically allocated.
47.172 struct SetStandardProcessedMap :
47.173 public Bfs< Digraph, SetStandardProcessedMapTraits > {
47.174 @@ -340,9 +338,10 @@
47.175 ///Sets the map that stores the predecessor arcs.
47.176
47.177 ///Sets the map that stores the predecessor arcs.
47.178 - ///If you don't use this function before calling \ref run(),
47.179 - ///it will allocate one. The destructor deallocates this
47.180 - ///automatically allocated map, of course.
47.181 + ///If you don't use this function before calling \ref run(Node) "run()"
47.182 + ///or \ref init(), an instance will be allocated automatically.
47.183 + ///The destructor deallocates this automatically allocated map,
47.184 + ///of course.
47.185 ///\return <tt> (*this) </tt>
47.186 Bfs &predMap(PredMap &m)
47.187 {
47.188 @@ -357,9 +356,10 @@
47.189 ///Sets the map that indicates which nodes are reached.
47.190
47.191 ///Sets the map that indicates which nodes are reached.
47.192 - ///If you don't use this function before calling \ref run(),
47.193 - ///it will allocate one. The destructor deallocates this
47.194 - ///automatically allocated map, of course.
47.195 + ///If you don't use this function before calling \ref run(Node) "run()"
47.196 + ///or \ref init(), an instance will be allocated automatically.
47.197 + ///The destructor deallocates this automatically allocated map,
47.198 + ///of course.
47.199 ///\return <tt> (*this) </tt>
47.200 Bfs &reachedMap(ReachedMap &m)
47.201 {
47.202 @@ -374,9 +374,10 @@
47.203 ///Sets the map that indicates which nodes are processed.
47.204
47.205 ///Sets the map that indicates which nodes are processed.
47.206 - ///If you don't use this function before calling \ref run(),
47.207 - ///it will allocate one. The destructor deallocates this
47.208 - ///automatically allocated map, of course.
47.209 + ///If you don't use this function before calling \ref run(Node) "run()"
47.210 + ///or \ref init(), an instance will be allocated automatically.
47.211 + ///The destructor deallocates this automatically allocated map,
47.212 + ///of course.
47.213 ///\return <tt> (*this) </tt>
47.214 Bfs &processedMap(ProcessedMap &m)
47.215 {
47.216 @@ -392,9 +393,10 @@
47.217
47.218 ///Sets the map that stores the distances of the nodes calculated by
47.219 ///the algorithm.
47.220 - ///If you don't use this function before calling \ref run(),
47.221 - ///it will allocate one. The destructor deallocates this
47.222 - ///automatically allocated map, of course.
47.223 + ///If you don't use this function before calling \ref run(Node) "run()"
47.224 + ///or \ref init(), an instance will be allocated automatically.
47.225 + ///The destructor deallocates this automatically allocated map,
47.226 + ///of course.
47.227 ///\return <tt> (*this) </tt>
47.228 Bfs &distMap(DistMap &m)
47.229 {
47.230 @@ -408,22 +410,19 @@
47.231
47.232 public:
47.233
47.234 - ///\name Execution control
47.235 - ///The simplest way to execute the algorithm is to use
47.236 - ///one of the member functions called \ref lemon::Bfs::run() "run()".
47.237 - ///\n
47.238 - ///If you need more control on the execution, first you must call
47.239 - ///\ref lemon::Bfs::init() "init()", then you can add several source
47.240 - ///nodes with \ref lemon::Bfs::addSource() "addSource()".
47.241 - ///Finally \ref lemon::Bfs::start() "start()" will perform the
47.242 - ///actual path computation.
47.243 + ///\name Execution Control
47.244 + ///The simplest way to execute the BFS algorithm is to use one of the
47.245 + ///member functions called \ref run(Node) "run()".\n
47.246 + ///If you need more control on the execution, first you have to call
47.247 + ///\ref init(), then you can add several source nodes with
47.248 + ///\ref addSource(). Finally the actual path computation can be
47.249 + ///performed with one of the \ref start() functions.
47.250
47.251 ///@{
47.252
47.253 + ///\brief Initializes the internal data structures.
47.254 + ///
47.255 ///Initializes the internal data structures.
47.256 -
47.257 - ///Initializes the internal data structures.
47.258 - ///
47.259 void init()
47.260 {
47.261 create_maps();
47.262 @@ -557,16 +556,16 @@
47.263 return _queue_tail<_queue_head?_queue[_queue_tail]:INVALID;
47.264 }
47.265
47.266 - ///\brief Returns \c false if there are nodes
47.267 - ///to be processed.
47.268 - ///
47.269 - ///Returns \c false if there are nodes
47.270 - ///to be processed in the queue.
47.271 + ///Returns \c false if there are nodes to be processed.
47.272 +
47.273 + ///Returns \c false if there are nodes to be processed
47.274 + ///in the queue.
47.275 bool emptyQueue() const { return _queue_tail==_queue_head; }
47.276
47.277 ///Returns the number of the nodes to be processed.
47.278
47.279 - ///Returns the number of the nodes to be processed in the queue.
47.280 + ///Returns the number of the nodes to be processed
47.281 + ///in the queue.
47.282 int queueSize() const { return _queue_head-_queue_tail; }
47.283
47.284 ///Executes the algorithm.
47.285 @@ -731,10 +730,10 @@
47.286 ///@}
47.287
47.288 ///\name Query Functions
47.289 - ///The result of the %BFS algorithm can be obtained using these
47.290 + ///The results of the BFS algorithm can be obtained using these
47.291 ///functions.\n
47.292 - ///Either \ref lemon::Bfs::run() "run()" or \ref lemon::Bfs::start()
47.293 - ///"start()" must be called before using them.
47.294 + ///Either \ref run(Node) "run()" or \ref start() should be called
47.295 + ///before using them.
47.296
47.297 ///@{
47.298
47.299 @@ -742,49 +741,49 @@
47.300
47.301 ///Returns the shortest path to a node.
47.302 ///
47.303 - ///\warning \c t should be reachable from the root(s).
47.304 + ///\warning \c t should be reached from the root(s).
47.305 ///
47.306 - ///\pre Either \ref run() or \ref start() must be called before
47.307 - ///using this function.
47.308 + ///\pre Either \ref run(Node) "run()" or \ref init()
47.309 + ///must be called before using this function.
47.310 Path path(Node t) const { return Path(*G, *_pred, t); }
47.311
47.312 ///The distance of a node from the root(s).
47.313
47.314 ///Returns the distance of a node from the root(s).
47.315 ///
47.316 - ///\warning If node \c v is not reachable from the root(s), then
47.317 + ///\warning If node \c v is not reached from the root(s), then
47.318 ///the return value of this function is undefined.
47.319 ///
47.320 - ///\pre Either \ref run() or \ref start() must be called before
47.321 - ///using this function.
47.322 + ///\pre Either \ref run(Node) "run()" or \ref init()
47.323 + ///must be called before using this function.
47.324 int dist(Node v) const { return (*_dist)[v]; }
47.325
47.326 ///Returns the 'previous arc' of the shortest path tree for a node.
47.327
47.328 ///This function returns the 'previous arc' of the shortest path
47.329 ///tree for the node \c v, i.e. it returns the last arc of a
47.330 - ///shortest path from the root(s) to \c v. It is \c INVALID if \c v
47.331 - ///is not reachable from the root(s) or if \c v is a root.
47.332 + ///shortest path from a root to \c v. It is \c INVALID if \c v
47.333 + ///is not reached from the root(s) or if \c v is a root.
47.334 ///
47.335 ///The shortest path tree used here is equal to the shortest path
47.336 ///tree used in \ref predNode().
47.337 ///
47.338 - ///\pre Either \ref run() or \ref start() must be called before
47.339 - ///using this function.
47.340 + ///\pre Either \ref run(Node) "run()" or \ref init()
47.341 + ///must be called before using this function.
47.342 Arc predArc(Node v) const { return (*_pred)[v];}
47.343
47.344 ///Returns the 'previous node' of the shortest path tree for a node.
47.345
47.346 ///This function returns the 'previous node' of the shortest path
47.347 ///tree for the node \c v, i.e. it returns the last but one node
47.348 - ///from a shortest path from the root(s) to \c v. It is \c INVALID
47.349 - ///if \c v is not reachable from the root(s) or if \c v is a root.
47.350 + ///from a shortest path from a root to \c v. It is \c INVALID
47.351 + ///if \c v is not reached from the root(s) or if \c v is a root.
47.352 ///
47.353 ///The shortest path tree used here is equal to the shortest path
47.354 ///tree used in \ref predArc().
47.355 ///
47.356 - ///\pre Either \ref run() or \ref start() must be called before
47.357 - ///using this function.
47.358 + ///\pre Either \ref run(Node) "run()" or \ref init()
47.359 + ///must be called before using this function.
47.360 Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
47.361 G->source((*_pred)[v]); }
47.362
47.363 @@ -794,7 +793,7 @@
47.364 ///Returns a const reference to the node map that stores the distances
47.365 ///of the nodes calculated by the algorithm.
47.366 ///
47.367 - ///\pre Either \ref run() or \ref init()
47.368 + ///\pre Either \ref run(Node) "run()" or \ref init()
47.369 ///must be called before using this function.
47.370 const DistMap &distMap() const { return *_dist;}
47.371
47.372 @@ -804,14 +803,15 @@
47.373 ///Returns a const reference to the node map that stores the predecessor
47.374 ///arcs, which form the shortest path tree.
47.375 ///
47.376 - ///\pre Either \ref run() or \ref init()
47.377 + ///\pre Either \ref run(Node) "run()" or \ref init()
47.378 ///must be called before using this function.
47.379 const PredMap &predMap() const { return *_pred;}
47.380
47.381 - ///Checks if a node is reachable from the root(s).
47.382 + ///Checks if a node is reached from the root(s).
47.383
47.384 - ///Returns \c true if \c v is reachable from the root(s).
47.385 - ///\pre Either \ref run() or \ref start()
47.386 + ///Returns \c true if \c v is reached from the root(s).
47.387 + ///
47.388 + ///\pre Either \ref run(Node) "run()" or \ref init()
47.389 ///must be called before using this function.
47.390 bool reached(Node v) const { return (*_reached)[v]; }
47.391
47.392 @@ -957,8 +957,8 @@
47.393
47.394 /// This auxiliary class is created to implement the
47.395 /// \ref bfs() "function-type interface" of \ref Bfs algorithm.
47.396 - /// It does not have own \ref run() method, it uses the functions
47.397 - /// and features of the plain \ref Bfs.
47.398 + /// It does not have own \ref run(Node) "run()" method, it uses the
47.399 + /// functions and features of the plain \ref Bfs.
47.400 ///
47.401 /// This class should only be used through the \ref bfs() function,
47.402 /// which makes it easier to use the algorithm.
47.403 @@ -1178,7 +1178,7 @@
47.404 /// // Compute shortest path from s to t
47.405 /// bool reached = bfs(g).path(p).dist(d).run(s,t);
47.406 ///\endcode
47.407 - ///\warning Don't forget to put the \ref BfsWizard::run() "run()"
47.408 + ///\warning Don't forget to put the \ref BfsWizard::run(Node) "run()"
47.409 ///to the end of the parameter list.
47.410 ///\sa BfsWizard
47.411 ///\sa Bfs
47.412 @@ -1194,9 +1194,9 @@
47.413 ///
47.414 /// This class defines the interface of the BfsVisit events, and
47.415 /// it could be the base of a real visitor class.
47.416 - template <typename _Digraph>
47.417 + template <typename GR>
47.418 struct BfsVisitor {
47.419 - typedef _Digraph Digraph;
47.420 + typedef GR Digraph;
47.421 typedef typename Digraph::Arc Arc;
47.422 typedef typename Digraph::Node Node;
47.423 /// \brief Called for the source node(s) of the BFS.
47.424 @@ -1224,9 +1224,9 @@
47.425 void examine(const Arc& arc) {}
47.426 };
47.427 #else
47.428 - template <typename _Digraph>
47.429 + template <typename GR>
47.430 struct BfsVisitor {
47.431 - typedef _Digraph Digraph;
47.432 + typedef GR Digraph;
47.433 typedef typename Digraph::Arc Arc;
47.434 typedef typename Digraph::Node Node;
47.435 void start(const Node&) {}
47.436 @@ -1254,12 +1254,12 @@
47.437 /// \brief Default traits class of BfsVisit class.
47.438 ///
47.439 /// Default traits class of BfsVisit class.
47.440 - /// \tparam _Digraph The type of the digraph the algorithm runs on.
47.441 - template<class _Digraph>
47.442 + /// \tparam GR The type of the digraph the algorithm runs on.
47.443 + template<class GR>
47.444 struct BfsVisitDefaultTraits {
47.445
47.446 /// \brief The type of the digraph the algorithm runs on.
47.447 - typedef _Digraph Digraph;
47.448 + typedef GR Digraph;
47.449
47.450 /// \brief The type of the map that indicates which nodes are reached.
47.451 ///
47.452 @@ -1280,12 +1280,12 @@
47.453
47.454 /// \ingroup search
47.455 ///
47.456 - /// \brief %BFS algorithm class with visitor interface.
47.457 + /// \brief BFS algorithm class with visitor interface.
47.458 ///
47.459 - /// This class provides an efficient implementation of the %BFS algorithm
47.460 + /// This class provides an efficient implementation of the BFS algorithm
47.461 /// with visitor interface.
47.462 ///
47.463 - /// The %BfsVisit class provides an alternative interface to the Bfs
47.464 + /// The BfsVisit class provides an alternative interface to the Bfs
47.465 /// class. It works with callback mechanism, the BfsVisit object calls
47.466 /// the member functions of the \c Visitor class on every BFS event.
47.467 ///
47.468 @@ -1294,37 +1294,37 @@
47.469 /// events of the BFS algorithm. Otherwise consider to use Bfs or bfs()
47.470 /// instead.
47.471 ///
47.472 - /// \tparam _Digraph The type of the digraph the algorithm runs on.
47.473 - /// The default value is
47.474 - /// \ref ListDigraph. The value of _Digraph is not used directly by
47.475 - /// \ref BfsVisit, it is only passed to \ref BfsVisitDefaultTraits.
47.476 - /// \tparam _Visitor The Visitor type that is used by the algorithm.
47.477 - /// \ref BfsVisitor "BfsVisitor<_Digraph>" is an empty visitor, which
47.478 + /// \tparam GR The type of the digraph the algorithm runs on.
47.479 + /// The default type is \ref ListDigraph.
47.480 + /// The value of GR is not used directly by \ref BfsVisit,
47.481 + /// it is only passed to \ref BfsVisitDefaultTraits.
47.482 + /// \tparam VS The Visitor type that is used by the algorithm.
47.483 + /// \ref BfsVisitor "BfsVisitor<GR>" is an empty visitor, which
47.484 /// does not observe the BFS events. If you want to observe the BFS
47.485 /// events, you should implement your own visitor class.
47.486 - /// \tparam _Traits Traits class to set various data types used by the
47.487 + /// \tparam TR Traits class to set various data types used by the
47.488 /// algorithm. The default traits class is
47.489 - /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<_Digraph>".
47.490 + /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<GR>".
47.491 /// See \ref BfsVisitDefaultTraits for the documentation of
47.492 /// a BFS visit traits class.
47.493 #ifdef DOXYGEN
47.494 - template <typename _Digraph, typename _Visitor, typename _Traits>
47.495 + template <typename GR, typename VS, typename TR>
47.496 #else
47.497 - template <typename _Digraph = ListDigraph,
47.498 - typename _Visitor = BfsVisitor<_Digraph>,
47.499 - typename _Traits = BfsVisitDefaultTraits<_Digraph> >
47.500 + template <typename GR = ListDigraph,
47.501 + typename VS = BfsVisitor<GR>,
47.502 + typename TR = BfsVisitDefaultTraits<GR> >
47.503 #endif
47.504 class BfsVisit {
47.505 public:
47.506
47.507 ///The traits class.
47.508 - typedef _Traits Traits;
47.509 + typedef TR Traits;
47.510
47.511 ///The type of the digraph the algorithm runs on.
47.512 typedef typename Traits::Digraph Digraph;
47.513
47.514 ///The visitor type used by the algorithm.
47.515 - typedef _Visitor Visitor;
47.516 + typedef VS Visitor;
47.517
47.518 ///The type of the map that indicates which nodes are reached.
47.519 typedef typename Traits::ReachedMap ReachedMap;
47.520 @@ -1364,7 +1364,7 @@
47.521
47.522 typedef BfsVisit Create;
47.523
47.524 - /// \name Named template parameters
47.525 + /// \name Named Template Parameters
47.526
47.527 ///@{
47.528 template <class T>
47.529 @@ -1406,9 +1406,10 @@
47.530 /// \brief Sets the map that indicates which nodes are reached.
47.531 ///
47.532 /// Sets the map that indicates which nodes are reached.
47.533 - /// If you don't use this function before calling \ref run(),
47.534 - /// it will allocate one. The destructor deallocates this
47.535 - /// automatically allocated map, of course.
47.536 + /// If you don't use this function before calling \ref run(Node) "run()"
47.537 + /// or \ref init(), an instance will be allocated automatically.
47.538 + /// The destructor deallocates this automatically allocated map,
47.539 + /// of course.
47.540 /// \return <tt> (*this) </tt>
47.541 BfsVisit &reachedMap(ReachedMap &m) {
47.542 if(local_reached) {
47.543 @@ -1421,16 +1422,13 @@
47.544
47.545 public:
47.546
47.547 - /// \name Execution control
47.548 - /// The simplest way to execute the algorithm is to use
47.549 - /// one of the member functions called \ref lemon::BfsVisit::run()
47.550 - /// "run()".
47.551 - /// \n
47.552 - /// If you need more control on the execution, first you must call
47.553 - /// \ref lemon::BfsVisit::init() "init()", then you can add several
47.554 - /// source nodes with \ref lemon::BfsVisit::addSource() "addSource()".
47.555 - /// Finally \ref lemon::BfsVisit::start() "start()" will perform the
47.556 - /// actual path computation.
47.557 + /// \name Execution Control
47.558 + /// The simplest way to execute the BFS algorithm is to use one of the
47.559 + /// member functions called \ref run(Node) "run()".\n
47.560 + /// If you need more control on the execution, first you have to call
47.561 + /// \ref init(), then you can add several source nodes with
47.562 + /// \ref addSource(). Finally the actual path computation can be
47.563 + /// performed with one of the \ref start() functions.
47.564
47.565 /// @{
47.566
47.567 @@ -1730,19 +1728,20 @@
47.568 ///@}
47.569
47.570 /// \name Query Functions
47.571 - /// The result of the %BFS algorithm can be obtained using these
47.572 + /// The results of the BFS algorithm can be obtained using these
47.573 /// functions.\n
47.574 - /// Either \ref lemon::BfsVisit::run() "run()" or
47.575 - /// \ref lemon::BfsVisit::start() "start()" must be called before
47.576 - /// using them.
47.577 + /// Either \ref run(Node) "run()" or \ref start() should be called
47.578 + /// before using them.
47.579 +
47.580 ///@{
47.581
47.582 - /// \brief Checks if a node is reachable from the root(s).
47.583 + /// \brief Checks if a node is reached from the root(s).
47.584 ///
47.585 - /// Returns \c true if \c v is reachable from the root(s).
47.586 - /// \pre Either \ref run() or \ref start()
47.587 + /// Returns \c true if \c v is reached from the root(s).
47.588 + ///
47.589 + /// \pre Either \ref run(Node) "run()" or \ref init()
47.590 /// must be called before using this function.
47.591 - bool reached(Node v) { return (*_reached)[v]; }
47.592 + bool reached(Node v) const { return (*_reached)[v]; }
47.593
47.594 ///@}
47.595
48.1 --- a/lemon/bin_heap.h Fri Nov 13 12:33:33 2009 +0100
48.2 +++ b/lemon/bin_heap.h Thu Dec 10 17:05:35 2009 +0100
48.3 @@ -2,7 +2,7 @@
48.4 *
48.5 * This file is a part of LEMON, a generic C++ optimization library.
48.6 *
48.7 - * Copyright (C) 2003-2008
48.8 + * Copyright (C) 2003-2009
48.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
48.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
48.11 *
48.12 @@ -33,35 +33,36 @@
48.13 ///
48.14 ///\brief A Binary Heap implementation.
48.15 ///
48.16 - ///This class implements the \e binary \e heap data structure. A \e heap
48.17 - ///is a data structure for storing items with specified values called \e
48.18 - ///priorities in such a way that finding the item with minimum priority is
48.19 - ///efficient. \c Compare specifies the ordering of the priorities. In a heap
48.20 - ///one can change the priority of an item, add or erase an item, etc.
48.21 + ///This class implements the \e binary \e heap data structure.
48.22 ///
48.23 - ///\tparam _Prio Type of the priority of the items.
48.24 - ///\tparam _ItemIntMap A read and writable Item int map, used internally
48.25 + ///A \e heap is a data structure for storing items with specified values
48.26 + ///called \e priorities in such a way that finding the item with minimum
48.27 + ///priority is efficient. \c CMP specifies the ordering of the priorities.
48.28 + ///In a heap one can change the priority of an item, add or erase an
48.29 + ///item, etc.
48.30 + ///
48.31 + ///\tparam PR Type of the priority of the items.
48.32 + ///\tparam IM A read and writable item map with int values, used internally
48.33 ///to handle the cross references.
48.34 - ///\tparam _Compare A class for the ordering of the priorities. The
48.35 - ///default is \c std::less<_Prio>.
48.36 + ///\tparam CMP A functor class for the ordering of the priorities.
48.37 + ///The default is \c std::less<PR>.
48.38 ///
48.39 ///\sa FibHeap
48.40 ///\sa Dijkstra
48.41 - template <typename _Prio, typename _ItemIntMap,
48.42 - typename _Compare = std::less<_Prio> >
48.43 + template <typename PR, typename IM, typename CMP = std::less<PR> >
48.44 class BinHeap {
48.45
48.46 public:
48.47 ///\e
48.48 - typedef _ItemIntMap ItemIntMap;
48.49 + typedef IM ItemIntMap;
48.50 ///\e
48.51 - typedef _Prio Prio;
48.52 + typedef PR Prio;
48.53 ///\e
48.54 typedef typename ItemIntMap::Key Item;
48.55 ///\e
48.56 typedef std::pair<Item,Prio> Pair;
48.57 ///\e
48.58 - typedef _Compare Compare;
48.59 + typedef CMP Compare;
48.60
48.61 /// \brief Type to represent the items states.
48.62 ///
48.63 @@ -69,49 +70,49 @@
48.64 /// "pre heap" or "post heap". The latter two are indifferent from the
48.65 /// heap's point of view, but may be useful to the user.
48.66 ///
48.67 - /// The ItemIntMap \e should be initialized in such way that it maps
48.68 - /// PRE_HEAP (-1) to any element to be put in the heap...
48.69 + /// The item-int map must be initialized in such way that it assigns
48.70 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
48.71 enum State {
48.72 - IN_HEAP = 0,
48.73 - PRE_HEAP = -1,
48.74 - POST_HEAP = -2
48.75 + IN_HEAP = 0, ///< = 0.
48.76 + PRE_HEAP = -1, ///< = -1.
48.77 + POST_HEAP = -2 ///< = -2.
48.78 };
48.79
48.80 private:
48.81 - std::vector<Pair> data;
48.82 - Compare comp;
48.83 - ItemIntMap &iim;
48.84 + std::vector<Pair> _data;
48.85 + Compare _comp;
48.86 + ItemIntMap &_iim;
48.87
48.88 public:
48.89 /// \brief The constructor.
48.90 ///
48.91 /// The constructor.
48.92 - /// \param _iim should be given to the constructor, since it is used
48.93 + /// \param map should be given to the constructor, since it is used
48.94 /// internally to handle the cross references. The value of the map
48.95 - /// should be PRE_HEAP (-1) for each element.
48.96 - explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {}
48.97 + /// must be \c PRE_HEAP (<tt>-1</tt>) for every item.
48.98 + explicit BinHeap(ItemIntMap &map) : _iim(map) {}
48.99
48.100 /// \brief The constructor.
48.101 ///
48.102 /// The constructor.
48.103 - /// \param _iim should be given to the constructor, since it is used
48.104 + /// \param map should be given to the constructor, since it is used
48.105 /// internally to handle the cross references. The value of the map
48.106 /// should be PRE_HEAP (-1) for each element.
48.107 ///
48.108 - /// \param _comp The comparator function object.
48.109 - BinHeap(ItemIntMap &_iim, const Compare &_comp)
48.110 - : iim(_iim), comp(_comp) {}
48.111 + /// \param comp The comparator function object.
48.112 + BinHeap(ItemIntMap &map, const Compare &comp)
48.113 + : _iim(map), _comp(comp) {}
48.114
48.115
48.116 /// The number of items stored in the heap.
48.117 ///
48.118 /// \brief Returns the number of items stored in the heap.
48.119 - int size() const { return data.size(); }
48.120 + int size() const { return _data.size(); }
48.121
48.122 /// \brief Checks if the heap stores no items.
48.123 ///
48.124 /// Returns \c true if and only if the heap stores no items.
48.125 - bool empty() const { return data.empty(); }
48.126 + bool empty() const { return _data.empty(); }
48.127
48.128 /// \brief Make empty this heap.
48.129 ///
48.130 @@ -120,7 +121,7 @@
48.131 /// the heap and after that you should set the cross reference map for
48.132 /// each item to \c PRE_HEAP.
48.133 void clear() {
48.134 - data.clear();
48.135 + _data.clear();
48.136 }
48.137
48.138 private:
48.139 @@ -128,13 +129,13 @@
48.140
48.141 static int second_child(int i) { return 2*i+2; }
48.142 bool less(const Pair &p1, const Pair &p2) const {
48.143 - return comp(p1.second, p2.second);
48.144 + return _comp(p1.second, p2.second);
48.145 }
48.146
48.147 int bubble_up(int hole, Pair p) {
48.148 int par = parent(hole);
48.149 - while( hole>0 && less(p,data[par]) ) {
48.150 - move(data[par],hole);
48.151 + while( hole>0 && less(p,_data[par]) ) {
48.152 + move(_data[par],hole);
48.153 hole = par;
48.154 par = parent(hole);
48.155 }
48.156 @@ -145,18 +146,18 @@
48.157 int bubble_down(int hole, Pair p, int length) {
48.158 int child = second_child(hole);
48.159 while(child < length) {
48.160 - if( less(data[child-1], data[child]) ) {
48.161 + if( less(_data[child-1], _data[child]) ) {
48.162 --child;
48.163 }
48.164 - if( !less(data[child], p) )
48.165 + if( !less(_data[child], p) )
48.166 goto ok;
48.167 - move(data[child], hole);
48.168 + move(_data[child], hole);
48.169 hole = child;
48.170 child = second_child(hole);
48.171 }
48.172 child--;
48.173 - if( child<length && less(data[child], p) ) {
48.174 - move(data[child], hole);
48.175 + if( child<length && less(_data[child], p) ) {
48.176 + move(_data[child], hole);
48.177 hole=child;
48.178 }
48.179 ok:
48.180 @@ -165,8 +166,8 @@
48.181 }
48.182
48.183 void move(const Pair &p, int i) {
48.184 - data[i] = p;
48.185 - iim.set(p.first, i);
48.186 + _data[i] = p;
48.187 + _iim.set(p.first, i);
48.188 }
48.189
48.190 public:
48.191 @@ -175,8 +176,8 @@
48.192 /// Adds \c p.first to the heap with priority \c p.second.
48.193 /// \param p The pair to insert.
48.194 void push(const Pair &p) {
48.195 - int n = data.size();
48.196 - data.resize(n+1);
48.197 + int n = _data.size();
48.198 + _data.resize(n+1);
48.199 bubble_up(n, p);
48.200 }
48.201
48.202 @@ -193,7 +194,7 @@
48.203 /// Compare.
48.204 /// \pre The heap must be nonempty.
48.205 Item top() const {
48.206 - return data[0].first;
48.207 + return _data[0].first;
48.208 }
48.209
48.210 /// \brief Returns the minimum priority relative to \c Compare.
48.211 @@ -201,7 +202,7 @@
48.212 /// It returns the minimum priority relative to \c Compare.
48.213 /// \pre The heap must be nonempty.
48.214 Prio prio() const {
48.215 - return data[0].second;
48.216 + return _data[0].second;
48.217 }
48.218
48.219 /// \brief Deletes the item with minimum priority relative to \c Compare.
48.220 @@ -210,12 +211,12 @@
48.221 /// Compare from the heap.
48.222 /// \pre The heap must be non-empty.
48.223 void pop() {
48.224 - int n = data.size()-1;
48.225 - iim.set(data[0].first, POST_HEAP);
48.226 + int n = _data.size()-1;
48.227 + _iim.set(_data[0].first, POST_HEAP);
48.228 if (n > 0) {
48.229 - bubble_down(0, data[n], n);
48.230 + bubble_down(0, _data[n], n);
48.231 }
48.232 - data.pop_back();
48.233 + _data.pop_back();
48.234 }
48.235
48.236 /// \brief Deletes \c i from the heap.
48.237 @@ -224,26 +225,26 @@
48.238 /// \param i The item to erase.
48.239 /// \pre The item should be in the heap.
48.240 void erase(const Item &i) {
48.241 - int h = iim[i];
48.242 - int n = data.size()-1;
48.243 - iim.set(data[h].first, POST_HEAP);
48.244 + int h = _iim[i];
48.245 + int n = _data.size()-1;
48.246 + _iim.set(_data[h].first, POST_HEAP);
48.247 if( h < n ) {
48.248 - if ( bubble_up(h, data[n]) == h) {
48.249 - bubble_down(h, data[n], n);
48.250 + if ( bubble_up(h, _data[n]) == h) {
48.251 + bubble_down(h, _data[n], n);
48.252 }
48.253 }
48.254 - data.pop_back();
48.255 + _data.pop_back();
48.256 }
48.257
48.258
48.259 /// \brief Returns the priority of \c i.
48.260 ///
48.261 /// This function returns the priority of item \c i.
48.262 + /// \param i The item.
48.263 /// \pre \c i must be in the heap.
48.264 - /// \param i The item.
48.265 Prio operator[](const Item &i) const {
48.266 - int idx = iim[i];
48.267 - return data[idx].second;
48.268 + int idx = _iim[i];
48.269 + return _data[idx].second;
48.270 }
48.271
48.272 /// \brief \c i gets to the heap with priority \c p independently
48.273 @@ -254,40 +255,40 @@
48.274 /// \param i The item.
48.275 /// \param p The priority.
48.276 void set(const Item &i, const Prio &p) {
48.277 - int idx = iim[i];
48.278 + int idx = _iim[i];
48.279 if( idx < 0 ) {
48.280 push(i,p);
48.281 }
48.282 - else if( comp(p, data[idx].second) ) {
48.283 + else if( _comp(p, _data[idx].second) ) {
48.284 bubble_up(idx, Pair(i,p));
48.285 }
48.286 else {
48.287 - bubble_down(idx, Pair(i,p), data.size());
48.288 + bubble_down(idx, Pair(i,p), _data.size());
48.289 }
48.290 }
48.291
48.292 /// \brief Decreases the priority of \c i to \c p.
48.293 ///
48.294 /// This method decreases the priority of item \c i to \c p.
48.295 + /// \param i The item.
48.296 + /// \param p The priority.
48.297 /// \pre \c i must be stored in the heap with priority at least \c
48.298 /// p relative to \c Compare.
48.299 - /// \param i The item.
48.300 - /// \param p The priority.
48.301 void decrease(const Item &i, const Prio &p) {
48.302 - int idx = iim[i];
48.303 + int idx = _iim[i];
48.304 bubble_up(idx, Pair(i,p));
48.305 }
48.306
48.307 /// \brief Increases the priority of \c i to \c p.
48.308 ///
48.309 /// This method sets the priority of item \c i to \c p.
48.310 + /// \param i The item.
48.311 + /// \param p The priority.
48.312 /// \pre \c i must be stored in the heap with priority at most \c
48.313 /// p relative to \c Compare.
48.314 - /// \param i The item.
48.315 - /// \param p The priority.
48.316 void increase(const Item &i, const Prio &p) {
48.317 - int idx = iim[i];
48.318 - bubble_down(idx, Pair(i,p), data.size());
48.319 + int idx = _iim[i];
48.320 + bubble_down(idx, Pair(i,p), _data.size());
48.321 }
48.322
48.323 /// \brief Returns if \c item is in, has already been in, or has
48.324 @@ -299,7 +300,7 @@
48.325 /// get back to the heap again.
48.326 /// \param i The item.
48.327 State state(const Item &i) const {
48.328 - int s = iim[i];
48.329 + int s = _iim[i];
48.330 if( s>=0 )
48.331 s=0;
48.332 return State(s);
48.333 @@ -319,7 +320,7 @@
48.334 if (state(i) == IN_HEAP) {
48.335 erase(i);
48.336 }
48.337 - iim[i] = st;
48.338 + _iim[i] = st;
48.339 break;
48.340 case IN_HEAP:
48.341 break;
48.342 @@ -333,10 +334,10 @@
48.343 /// \c i item will out of the heap and \c j will be in the heap
48.344 /// with the same prioriority as prevoiusly the \c i item.
48.345 void replace(const Item& i, const Item& j) {
48.346 - int idx = iim[i];
48.347 - iim.set(i, iim[j]);
48.348 - iim.set(j, idx);
48.349 - data[idx].first = j;
48.350 + int idx = _iim[i];
48.351 + _iim.set(i, _iim[j]);
48.352 + _iim.set(j, idx);
48.353 + _data[idx].first = j;
48.354 }
48.355
48.356 }; // class BinHeap
49.1 --- a/lemon/bits/alteration_notifier.h Fri Nov 13 12:33:33 2009 +0100
49.2 +++ b/lemon/bits/alteration_notifier.h Thu Dec 10 17:05:35 2009 +0100
49.3 @@ -2,7 +2,7 @@
49.4 *
49.5 * This file is a part of LEMON, a generic C++ optimization library.
49.6 *
49.7 - * Copyright (C) 2003-2008
49.8 + * Copyright (C) 2003-2009
49.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
49.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
49.11 *
49.12 @@ -35,61 +35,62 @@
49.13 // \brief Notifier class to notify observes about alterations in
49.14 // a container.
49.15 //
49.16 - // The simple graph's can be refered as two containers, one node container
49.17 - // and one edge container. But they are not standard containers they
49.18 - // does not store values directly they are just key continars for more
49.19 - // value containers which are the node and edge maps.
49.20 + // The simple graphs can be refered as two containers: a node container
49.21 + // and an edge container. But they do not store values directly, they
49.22 + // are just key continars for more value containers, which are the
49.23 + // node and edge maps.
49.24 //
49.25 - // The graph's node and edge sets can be changed as we add or erase
49.26 + // The node and edge sets of the graphs can be changed as we add or erase
49.27 // nodes and edges in the graph. LEMON would like to handle easily
49.28 // that the node and edge maps should contain values for all nodes or
49.29 // edges. If we want to check on every indicing if the map contains
49.30 // the current indicing key that cause a drawback in the performance
49.31 - // in the library. We use another solution we notify all maps about
49.32 + // in the library. We use another solution: we notify all maps about
49.33 // an alteration in the graph, which cause only drawback on the
49.34 // alteration of the graph.
49.35 //
49.36 - // This class provides an interface to the container. The \e first() and \e
49.37 - // next() member functions make possible to iterate on the keys of the
49.38 - // container. The \e id() function returns an integer id for each key.
49.39 - // The \e maxId() function gives back an upper bound of the ids.
49.40 + // This class provides an interface to a node or edge container.
49.41 + // The first() and next() member functions make possible
49.42 + // to iterate on the keys of the container.
49.43 + // The id() function returns an integer id for each key.
49.44 + // The maxId() function gives back an upper bound of the ids.
49.45 //
49.46 // For the proper functonality of this class, we should notify it
49.47 - // about each alteration in the container. The alterations have four type
49.48 - // as \e add(), \e erase(), \e build() and \e clear(). The \e add() and
49.49 - // \e erase() signals that only one or few items added or erased to or
49.50 - // from the graph. If all items are erased from the graph or from an empty
49.51 - // graph a new graph is builded then it can be signaled with the
49.52 + // about each alteration in the container. The alterations have four type:
49.53 + // add(), erase(), build() and clear(). The add() and
49.54 + // erase() signal that only one or few items added or erased to or
49.55 + // from the graph. If all items are erased from the graph or if a new graph
49.56 + // is built from an empty graph, then it can be signaled with the
49.57 // clear() and build() members. Important rule that if we erase items
49.58 - // from graph we should first signal the alteration and after that erase
49.59 + // from graphs we should first signal the alteration and after that erase
49.60 // them from the container, on the other way on item addition we should
49.61 // first extend the container and just after that signal the alteration.
49.62 //
49.63 // The alteration can be observed with a class inherited from the
49.64 - // \e ObserverBase nested class. The signals can be handled with
49.65 + // ObserverBase nested class. The signals can be handled with
49.66 // overriding the virtual functions defined in the base class. The
49.67 // observer base can be attached to the notifier with the
49.68 - // \e attach() member and can be detached with detach() function. The
49.69 + // attach() member and can be detached with detach() function. The
49.70 // alteration handlers should not call any function which signals
49.71 // an other alteration in the same notifier and should not
49.72 // detach any observer from the notifier.
49.73 //
49.74 - // Alteration observers try to be exception safe. If an \e add() or
49.75 - // a \e clear() function throws an exception then the remaining
49.76 + // Alteration observers try to be exception safe. If an add() or
49.77 + // a clear() function throws an exception then the remaining
49.78 // observeres will not be notified and the fulfilled additions will
49.79 - // be rolled back by calling the \e erase() or \e clear()
49.80 - // functions. Thence the \e erase() and \e clear() should not throw
49.81 - // exception. Actullay, it can be throw only \ref ImmediateDetach
49.82 - // exception which detach the observer from the notifier.
49.83 + // be rolled back by calling the erase() or clear() functions.
49.84 + // Hence erase() and clear() should not throw exception.
49.85 + // Actullay, they can throw only \ref ImmediateDetach exception,
49.86 + // which detach the observer from the notifier.
49.87 //
49.88 - // There are some place when the alteration observing is not completly
49.89 + // There are some cases, when the alteration observing is not completly
49.90 // reliable. If we want to carry out the node degree in the graph
49.91 - // as in the \ref InDegMap and we use the reverseEdge that cause
49.92 + // as in the \ref InDegMap and we use the reverseArc(), then it cause
49.93 // unreliable functionality. Because the alteration observing signals
49.94 - // only erasing and adding but not the reversing it will stores bad
49.95 - // degrees. The sub graph adaptors cannot signal the alterations because
49.96 - // just a setting in the filter map can modify the graph and this cannot
49.97 - // be watched in any way.
49.98 + // only erasing and adding but not the reversing, it will stores bad
49.99 + // degrees. Apart form that the subgraph adaptors cannot even signal
49.100 + // the alterations because just a setting in the filter map can modify
49.101 + // the graph and this cannot be watched in any way.
49.102 //
49.103 // \param _Container The container which is observed.
49.104 // \param _Item The item type which is obserbved.
49.105 @@ -103,13 +104,13 @@
49.106 typedef _Container Container;
49.107 typedef _Item Item;
49.108
49.109 - // \brief Exception which can be called from \e clear() and
49.110 - // \e erase().
49.111 + // \brief Exception which can be called from clear() and
49.112 + // erase().
49.113 //
49.114 - // From the \e clear() and \e erase() function only this
49.115 + // From the clear() and erase() function only this
49.116 // exception is allowed to throw. The exception immediatly
49.117 // detaches the current observer from the notifier. Because the
49.118 - // \e clear() and \e erase() should not throw other exceptions
49.119 + // clear() and erase() should not throw other exceptions
49.120 // it can be used to invalidate the observer.
49.121 struct ImmediateDetach {};
49.122
49.123 @@ -121,8 +122,7 @@
49.124 //
49.125 // The observer interface contains some pure virtual functions
49.126 // to override. The add() and erase() functions are
49.127 - // to notify the oberver when one item is added or
49.128 - // erased.
49.129 + // to notify the oberver when one item is added or erased.
49.130 //
49.131 // The build() and clear() members are to notify the observer
49.132 // about the container is built from an empty container or
50.1 --- a/lemon/bits/array_map.h Fri Nov 13 12:33:33 2009 +0100
50.2 +++ b/lemon/bits/array_map.h Thu Dec 10 17:05:35 2009 +0100
50.3 @@ -2,7 +2,7 @@
50.4 *
50.5 * This file is a part of LEMON, a generic C++ optimization library.
50.6 *
50.7 - * Copyright (C) 2003-2008
50.8 + * Copyright (C) 2003-2009
50.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
50.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
50.11 *
50.12 @@ -36,25 +36,24 @@
50.13 //
50.14 // \brief Graph map based on the array storage.
50.15 //
50.16 - // The ArrayMap template class is graph map structure what
50.17 - // automatically updates the map when a key is added to or erased from
50.18 - // the map. This map uses the allocators to implement
50.19 - // the container functionality.
50.20 + // The ArrayMap template class is graph map structure that automatically
50.21 + // updates the map when a key is added to or erased from the graph.
50.22 + // This map uses the allocators to implement the container functionality.
50.23 //
50.24 - // The template parameters are the Graph the current Item type and
50.25 + // The template parameters are the Graph, the current Item type and
50.26 // the Value type of the map.
50.27 template <typename _Graph, typename _Item, typename _Value>
50.28 class ArrayMap
50.29 : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
50.30 public:
50.31 - // The graph type of the maps.
50.32 - typedef _Graph Graph;
50.33 - // The item type of the map.
50.34 + // The graph type.
50.35 + typedef _Graph GraphType;
50.36 + // The item type.
50.37 typedef _Item Item;
50.38 // The reference map tag.
50.39 typedef True ReferenceMapTag;
50.40
50.41 - // The key type of the maps.
50.42 + // The key type of the map.
50.43 typedef _Item Key;
50.44 // The value type of the map.
50.45 typedef _Value Value;
50.46 @@ -64,13 +63,17 @@
50.47 // The reference type of the map.
50.48 typedef _Value& Reference;
50.49
50.50 + // The map type.
50.51 + typedef ArrayMap Map;
50.52 +
50.53 // The notifier type.
50.54 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
50.55
50.56 + private:
50.57 +
50.58 // The MapBase of the Map which imlements the core regisitry function.
50.59 typedef typename Notifier::ObserverBase Parent;
50.60
50.61 - private:
50.62 typedef std::allocator<Value> Allocator;
50.63
50.64 public:
50.65 @@ -78,7 +81,7 @@
50.66 // \brief Graph initialized map constructor.
50.67 //
50.68 // Graph initialized map constructor.
50.69 - explicit ArrayMap(const Graph& graph) {
50.70 + explicit ArrayMap(const GraphType& graph) {
50.71 Parent::attach(graph.notifier(Item()));
50.72 allocate_memory();
50.73 Notifier* nf = Parent::notifier();
50.74 @@ -92,7 +95,7 @@
50.75 // \brief Constructor to use default value to initialize the map.
50.76 //
50.77 // It constructs a map and initialize all of the the map.
50.78 - ArrayMap(const Graph& graph, const Value& value) {
50.79 + ArrayMap(const GraphType& graph, const Value& value) {
50.80 Parent::attach(graph.notifier(Item()));
50.81 allocate_memory();
50.82 Notifier* nf = Parent::notifier();
50.83 @@ -136,7 +139,7 @@
50.84
50.85 // \brief Template assign operator.
50.86 //
50.87 - // The given parameter should be conform to the ReadMap
50.88 + // The given parameter should conform to the ReadMap
50.89 // concecpt and could be indiced by the current item set of
50.90 // the NodeMap. In this case the value for each item
50.91 // is assigned by the value of the given ReadMap.
50.92 @@ -200,7 +203,7 @@
50.93
50.94 // \brief Adds a new key to the map.
50.95 //
50.96 - // It adds a new key to the map. It called by the observer notifier
50.97 + // It adds a new key to the map. It is called by the observer notifier
50.98 // and it overrides the add() member function of the observer base.
50.99 virtual void add(const Key& key) {
50.100 Notifier* nf = Parent::notifier();
50.101 @@ -228,7 +231,7 @@
50.102
50.103 // \brief Adds more new keys to the map.
50.104 //
50.105 - // It adds more new keys to the map. It called by the observer notifier
50.106 + // It adds more new keys to the map. It is called by the observer notifier
50.107 // and it overrides the add() member function of the observer base.
50.108 virtual void add(const std::vector<Key>& keys) {
50.109 Notifier* nf = Parent::notifier();
50.110 @@ -272,7 +275,7 @@
50.111
50.112 // \brief Erase a key from the map.
50.113 //
50.114 - // Erase a key from the map. It called by the observer notifier
50.115 + // Erase a key from the map. It is called by the observer notifier
50.116 // and it overrides the erase() member function of the observer base.
50.117 virtual void erase(const Key& key) {
50.118 int id = Parent::notifier()->id(key);
50.119 @@ -281,7 +284,7 @@
50.120
50.121 // \brief Erase more keys from the map.
50.122 //
50.123 - // Erase more keys from the map. It called by the observer notifier
50.124 + // Erase more keys from the map. It is called by the observer notifier
50.125 // and it overrides the erase() member function of the observer base.
50.126 virtual void erase(const std::vector<Key>& keys) {
50.127 for (int i = 0; i < int(keys.size()); ++i) {
50.128 @@ -290,9 +293,9 @@
50.129 }
50.130 }
50.131
50.132 - // \brief Buildes the map.
50.133 + // \brief Builds the map.
50.134 //
50.135 - // It buildes the map. It called by the observer notifier
50.136 + // It builds the map. It is called by the observer notifier
50.137 // and it overrides the build() member function of the observer base.
50.138 virtual void build() {
50.139 Notifier* nf = Parent::notifier();
50.140 @@ -306,7 +309,7 @@
50.141
50.142 // \brief Clear the map.
50.143 //
50.144 - // It erase all items from the map. It called by the observer notifier
50.145 + // It erase all items from the map. It is called by the observer notifier
50.146 // and it overrides the clear() member function of the observer base.
50.147 virtual void clear() {
50.148 Notifier* nf = Parent::notifier();
51.1 --- a/lemon/bits/base_extender.h Fri Nov 13 12:33:33 2009 +0100
51.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
51.3 @@ -1,494 +0,0 @@
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-2008
51.9 - * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
51.10 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
51.11 - *
51.12 - * Permission to use, modify and distribute this software is granted
51.13 - * provided that this copyright notice appears in all copies. For
51.14 - * precise terms see the accompanying LICENSE file.
51.15 - *
51.16 - * This software is provided "AS IS" with no warranty of any kind,
51.17 - * express or implied, and with no claim as to its suitability for any
51.18 - * purpose.
51.19 - *
51.20 - */
51.21 -
51.22 -#ifndef LEMON_BITS_BASE_EXTENDER_H
51.23 -#define LEMON_BITS_BASE_EXTENDER_H
51.24 -
51.25 -#include <lemon/core.h>
51.26 -#include <lemon/error.h>
51.27 -
51.28 -#include <lemon/bits/map_extender.h>
51.29 -#include <lemon/bits/default_map.h>
51.30 -
51.31 -#include <lemon/concept_check.h>
51.32 -#include <lemon/concepts/maps.h>
51.33 -
51.34 -//\ingroup digraphbits
51.35 -//\file
51.36 -//\brief Extenders for the digraph types
51.37 -namespace lemon {
51.38 -
51.39 - // \ingroup digraphbits
51.40 - //
51.41 - // \brief BaseDigraph to BaseGraph extender
51.42 - template <typename Base>
51.43 - class UndirDigraphExtender : public Base {
51.44 -
51.45 - public:
51.46 -
51.47 - typedef Base Parent;
51.48 - typedef typename Parent::Arc Edge;
51.49 - typedef typename Parent::Node Node;
51.50 -
51.51 - typedef True UndirectedTag;
51.52 -
51.53 - class Arc : public Edge {
51.54 - friend class UndirDigraphExtender;
51.55 -
51.56 - protected:
51.57 - bool forward;
51.58 -
51.59 - Arc(const Edge &ue, bool _forward) :
51.60 - Edge(ue), forward(_forward) {}
51.61 -
51.62 - public:
51.63 - Arc() {}
51.64 -
51.65 - // Invalid arc constructor
51.66 - Arc(Invalid i) : Edge(i), forward(true) {}
51.67 -
51.68 - bool operator==(const Arc &that) const {
51.69 - return forward==that.forward && Edge(*this)==Edge(that);
51.70 - }
51.71 - bool operator!=(const Arc &that) const {
51.72 - return forward!=that.forward || Edge(*this)!=Edge(that);
51.73 - }
51.74 - bool operator<(const Arc &that) const {
51.75 - return forward<that.forward ||
51.76 - (!(that.forward<forward) && Edge(*this)<Edge(that));
51.77 - }
51.78 - };
51.79 -
51.80 - // First node of the edge
51.81 - Node u(const Edge &e) const {
51.82 - return Parent::source(e);
51.83 - }
51.84 -
51.85 - // Source of the given arc
51.86 - Node source(const Arc &e) const {
51.87 - return e.forward ? Parent::source(e) : Parent::target(e);
51.88 - }
51.89 -
51.90 - // Second node of the edge
51.91 - Node v(const Edge &e) const {
51.92 - return Parent::target(e);
51.93 - }
51.94 -
51.95 - // Target of the given arc
51.96 - Node target(const Arc &e) const {
51.97 - return e.forward ? Parent::target(e) : Parent::source(e);
51.98 - }
51.99 -
51.100 - // \brief Directed arc from an edge.
51.101 - //
51.102 - // Returns a directed arc corresponding to the specified edge.
51.103 - // If the given bool is true, the first node of the given edge and
51.104 - // the source node of the returned arc are the same.
51.105 - static Arc direct(const Edge &e, bool d) {
51.106 - return Arc(e, d);
51.107 - }
51.108 -
51.109 - // Returns whether the given directed arc has the same orientation
51.110 - // as the corresponding edge.
51.111 - static bool direction(const Arc &a) { return a.forward; }
51.112 -
51.113 - using Parent::first;
51.114 - using Parent::next;
51.115 -
51.116 - void first(Arc &e) const {
51.117 - Parent::first(e);
51.118 - e.forward=true;
51.119 - }
51.120 -
51.121 - void next(Arc &e) const {
51.122 - if( e.forward ) {
51.123 - e.forward = false;
51.124 - }
51.125 - else {
51.126 - Parent::next(e);
51.127 - e.forward = true;
51.128 - }
51.129 - }
51.130 -
51.131 - void firstOut(Arc &e, const Node &n) const {
51.132 - Parent::firstIn(e,n);
51.133 - if( Edge(e) != INVALID ) {
51.134 - e.forward = false;
51.135 - }
51.136 - else {
51.137 - Parent::firstOut(e,n);
51.138 - e.forward = true;
51.139 - }
51.140 - }
51.141 - void nextOut(Arc &e) const {
51.142 - if( ! e.forward ) {
51.143 - Node n = Parent::target(e);
51.144 - Parent::nextIn(e);
51.145 - if( Edge(e) == INVALID ) {
51.146 - Parent::firstOut(e, n);
51.147 - e.forward = true;
51.148 - }
51.149 - }
51.150 - else {
51.151 - Parent::nextOut(e);
51.152 - }
51.153 - }
51.154 -
51.155 - void firstIn(Arc &e, const Node &n) const {
51.156 - Parent::firstOut(e,n);
51.157 - if( Edge(e) != INVALID ) {
51.158 - e.forward = false;
51.159 - }
51.160 - else {
51.161 - Parent::firstIn(e,n);
51.162 - e.forward = true;
51.163 - }
51.164 - }
51.165 - void nextIn(Arc &e) const {
51.166 - if( ! e.forward ) {
51.167 - Node n = Parent::source(e);
51.168 - Parent::nextOut(e);
51.169 - if( Edge(e) == INVALID ) {
51.170 - Parent::firstIn(e, n);
51.171 - e.forward = true;
51.172 - }
51.173 - }
51.174 - else {
51.175 - Parent::nextIn(e);
51.176 - }
51.177 - }
51.178 -
51.179 - void firstInc(Edge &e, bool &d, const Node &n) const {
51.180 - d = true;
51.181 - Parent::firstOut(e, n);
51.182 - if (e != INVALID) return;
51.183 - d = false;
51.184 - Parent::firstIn(e, n);
51.185 - }
51.186 -
51.187 - void nextInc(Edge &e, bool &d) const {
51.188 - if (d) {
51.189 - Node s = Parent::source(e);
51.190 - Parent::nextOut(e);
51.191 - if (e != INVALID) return;
51.192 - d = false;
51.193 - Parent::firstIn(e, s);
51.194 - } else {
51.195 - Parent::nextIn(e);
51.196 - }
51.197 - }
51.198 -
51.199 - Node nodeFromId(int ix) const {
51.200 - return Parent::nodeFromId(ix);
51.201 - }
51.202 -
51.203 - Arc arcFromId(int ix) const {
51.204 - return direct(Parent::arcFromId(ix >> 1), bool(ix & 1));
51.205 - }
51.206 -
51.207 - Edge edgeFromId(int ix) const {
51.208 - return Parent::arcFromId(ix);
51.209 - }
51.210 -
51.211 - int id(const Node &n) const {
51.212 - return Parent::id(n);
51.213 - }
51.214 -
51.215 - int id(const Edge &e) const {
51.216 - return Parent::id(e);
51.217 - }
51.218 -
51.219 - int id(const Arc &e) const {
51.220 - return 2 * Parent::id(e) + int(e.forward);
51.221 - }
51.222 -
51.223 - int maxNodeId() const {
51.224 - return Parent::maxNodeId();
51.225 - }
51.226 -
51.227 - int maxArcId() const {
51.228 - return 2 * Parent::maxArcId() + 1;
51.229 - }
51.230 -
51.231 - int maxEdgeId() const {
51.232 - return Parent::maxArcId();
51.233 - }
51.234 -
51.235 - int arcNum() const {
51.236 - return 2 * Parent::arcNum();
51.237 - }
51.238 -
51.239 - int edgeNum() const {
51.240 - return Parent::arcNum();
51.241 - }
51.242 -
51.243 - Arc findArc(Node s, Node t, Arc p = INVALID) const {
51.244 - if (p == INVALID) {
51.245 - Edge arc = Parent::findArc(s, t);
51.246 - if (arc != INVALID) return direct(arc, true);
51.247 - arc = Parent::findArc(t, s);
51.248 - if (arc != INVALID) return direct(arc, false);
51.249 - } else if (direction(p)) {
51.250 - Edge arc = Parent::findArc(s, t, p);
51.251 - if (arc != INVALID) return direct(arc, true);
51.252 - arc = Parent::findArc(t, s);
51.253 - if (arc != INVALID) return direct(arc, false);
51.254 - } else {
51.255 - Edge arc = Parent::findArc(t, s, p);
51.256 - if (arc != INVALID) return direct(arc, false);
51.257 - }
51.258 - return INVALID;
51.259 - }
51.260 -
51.261 - Edge findEdge(Node s, Node t, Edge p = INVALID) const {
51.262 - if (s != t) {
51.263 - if (p == INVALID) {
51.264 - Edge arc = Parent::findArc(s, t);
51.265 - if (arc != INVALID) return arc;
51.266 - arc = Parent::findArc(t, s);
51.267 - if (arc != INVALID) return arc;
51.268 - } else if (Parent::s(p) == s) {
51.269 - Edge arc = Parent::findArc(s, t, p);
51.270 - if (arc != INVALID) return arc;
51.271 - arc = Parent::findArc(t, s);
51.272 - if (arc != INVALID) return arc;
51.273 - } else {
51.274 - Edge arc = Parent::findArc(t, s, p);
51.275 - if (arc != INVALID) return arc;
51.276 - }
51.277 - } else {
51.278 - return Parent::findArc(s, t, p);
51.279 - }
51.280 - return INVALID;
51.281 - }
51.282 - };
51.283 -
51.284 - template <typename Base>
51.285 - class BidirBpGraphExtender : public Base {
51.286 - public:
51.287 - typedef Base Parent;
51.288 - typedef BidirBpGraphExtender Digraph;
51.289 -
51.290 - typedef typename Parent::Node Node;
51.291 - typedef typename Parent::Edge Edge;
51.292 -
51.293 -
51.294 - using Parent::first;
51.295 - using Parent::next;
51.296 -
51.297 - using Parent::id;
51.298 -
51.299 - class Red : public Node {
51.300 - friend class BidirBpGraphExtender;
51.301 - public:
51.302 - Red() {}
51.303 - Red(const Node& node) : Node(node) {
51.304 - LEMON_DEBUG(Parent::red(node) || node == INVALID,
51.305 - typename Parent::NodeSetError());
51.306 - }
51.307 - Red& operator=(const Node& node) {
51.308 - LEMON_DEBUG(Parent::red(node) || node == INVALID,
51.309 - typename Parent::NodeSetError());
51.310 - Node::operator=(node);
51.311 - return *this;
51.312 - }
51.313 - Red(Invalid) : Node(INVALID) {}
51.314 - Red& operator=(Invalid) {
51.315 - Node::operator=(INVALID);
51.316 - return *this;
51.317 - }
51.318 - };
51.319 -
51.320 - void first(Red& node) const {
51.321 - Parent::firstRed(static_cast<Node&>(node));
51.322 - }
51.323 - void next(Red& node) const {
51.324 - Parent::nextRed(static_cast<Node&>(node));
51.325 - }
51.326 -
51.327 - int id(const Red& node) const {
51.328 - return Parent::redId(node);
51.329 - }
51.330 -
51.331 - class Blue : public Node {
51.332 - friend class BidirBpGraphExtender;
51.333 - public:
51.334 - Blue() {}
51.335 - Blue(const Node& node) : Node(node) {
51.336 - LEMON_DEBUG(Parent::blue(node) || node == INVALID,
51.337 - typename Parent::NodeSetError());
51.338 - }
51.339 - Blue& operator=(const Node& node) {
51.340 - LEMON_DEBUG(Parent::blue(node) || node == INVALID,
51.341 - typename Parent::NodeSetError());
51.342 - Node::operator=(node);
51.343 - return *this;
51.344 - }
51.345 - Blue(Invalid) : Node(INVALID) {}
51.346 - Blue& operator=(Invalid) {
51.347 - Node::operator=(INVALID);
51.348 - return *this;
51.349 - }
51.350 - };
51.351 -
51.352 - void first(Blue& node) const {
51.353 - Parent::firstBlue(static_cast<Node&>(node));
51.354 - }
51.355 - void next(Blue& node) const {
51.356 - Parent::nextBlue(static_cast<Node&>(node));
51.357 - }
51.358 -
51.359 - int id(const Blue& node) const {
51.360 - return Parent::redId(node);
51.361 - }
51.362 -
51.363 - Node source(const Edge& arc) const {
51.364 - return red(arc);
51.365 - }
51.366 - Node target(const Edge& arc) const {
51.367 - return blue(arc);
51.368 - }
51.369 -
51.370 - void firstInc(Edge& arc, bool& dir, const Node& node) const {
51.371 - if (Parent::red(node)) {
51.372 - Parent::firstFromRed(arc, node);
51.373 - dir = true;
51.374 - } else {
51.375 - Parent::firstFromBlue(arc, node);
51.376 - dir = static_cast<Edge&>(arc) == INVALID;
51.377 - }
51.378 - }
51.379 - void nextInc(Edge& arc, bool& dir) const {
51.380 - if (dir) {
51.381 - Parent::nextFromRed(arc);
51.382 - } else {
51.383 - Parent::nextFromBlue(arc);
51.384 - if (arc == INVALID) dir = true;
51.385 - }
51.386 - }
51.387 -
51.388 - class Arc : public Edge {
51.389 - friend class BidirBpGraphExtender;
51.390 - protected:
51.391 - bool forward;
51.392 -
51.393 - Arc(const Edge& arc, bool _forward)
51.394 - : Edge(arc), forward(_forward) {}
51.395 -
51.396 - public:
51.397 - Arc() {}
51.398 - Arc (Invalid) : Edge(INVALID), forward(true) {}
51.399 - bool operator==(const Arc& i) const {
51.400 - return Edge::operator==(i) && forward == i.forward;
51.401 - }
51.402 - bool operator!=(const Arc& i) const {
51.403 - return Edge::operator!=(i) || forward != i.forward;
51.404 - }
51.405 - bool operator<(const Arc& i) const {
51.406 - return Edge::operator<(i) ||
51.407 - (!(i.forward<forward) && Edge(*this)<Edge(i));
51.408 - }
51.409 - };
51.410 -
51.411 - void first(Arc& arc) const {
51.412 - Parent::first(static_cast<Edge&>(arc));
51.413 - arc.forward = true;
51.414 - }
51.415 -
51.416 - void next(Arc& arc) const {
51.417 - if (!arc.forward) {
51.418 - Parent::next(static_cast<Edge&>(arc));
51.419 - }
51.420 - arc.forward = !arc.forward;
51.421 - }
51.422 -
51.423 - void firstOut(Arc& arc, const Node& node) const {
51.424 - if (Parent::red(node)) {
51.425 - Parent::firstFromRed(arc, node);
51.426 - arc.forward = true;
51.427 - } else {
51.428 - Parent::firstFromBlue(arc, node);
51.429 - arc.forward = static_cast<Edge&>(arc) == INVALID;
51.430 - }
51.431 - }
51.432 - void nextOut(Arc& arc) const {
51.433 - if (arc.forward) {
51.434 - Parent::nextFromRed(arc);
51.435 - } else {
51.436 - Parent::nextFromBlue(arc);
51.437 - arc.forward = static_cast<Edge&>(arc) == INVALID;
51.438 - }
51.439 - }
51.440 -
51.441 - void firstIn(Arc& arc, const Node& node) const {
51.442 - if (Parent::blue(node)) {
51.443 - Parent::firstFromBlue(arc, node);
51.444 - arc.forward = true;
51.445 - } else {
51.446 - Parent::firstFromRed(arc, node);
51.447 - arc.forward = static_cast<Edge&>(arc) == INVALID;
51.448 - }
51.449 - }
51.450 - void nextIn(Arc& arc) const {
51.451 - if (arc.forward) {
51.452 - Parent::nextFromBlue(arc);
51.453 - } else {
51.454 - Parent::nextFromRed(arc);
51.455 - arc.forward = static_cast<Edge&>(arc) == INVALID;
51.456 - }
51.457 - }
51.458 -
51.459 - Node source(const Arc& arc) const {
51.460 - return arc.forward ? Parent::red(arc) : Parent::blue(arc);
51.461 - }
51.462 - Node target(const Arc& arc) const {
51.463 - return arc.forward ? Parent::blue(arc) : Parent::red(arc);
51.464 - }
51.465 -
51.466 - int id(const Arc& arc) const {
51.467 - return (Parent::id(static_cast<const Edge&>(arc)) << 1) +
51.468 - (arc.forward ? 0 : 1);
51.469 - }
51.470 - Arc arcFromId(int ix) const {
51.471 - return Arc(Parent::fromEdgeId(ix >> 1), (ix & 1) == 0);
51.472 - }
51.473 - int maxArcId() const {
51.474 - return (Parent::maxEdgeId() << 1) + 1;
51.475 - }
51.476 -
51.477 - bool direction(const Arc& arc) const {
51.478 - return arc.forward;
51.479 - }
51.480 -
51.481 - Arc direct(const Edge& arc, bool dir) const {
51.482 - return Arc(arc, dir);
51.483 - }
51.484 -
51.485 - int arcNum() const {
51.486 - return 2 * Parent::edgeNum();
51.487 - }
51.488 -
51.489 - int edgeNum() const {
51.490 - return Parent::edgeNum();
51.491 - }
51.492 -
51.493 -
51.494 - };
51.495 -}
51.496 -
51.497 -#endif
52.1 --- a/lemon/bits/bezier.h Fri Nov 13 12:33:33 2009 +0100
52.2 +++ b/lemon/bits/bezier.h Thu Dec 10 17:05:35 2009 +0100
52.3 @@ -2,7 +2,7 @@
52.4 *
52.5 * This file is a part of LEMON, a generic C++ optimization library.
52.6 *
52.7 - * Copyright (C) 2003-2008
52.8 + * Copyright (C) 2003-2009
52.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
52.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
52.11 *
53.1 --- a/lemon/bits/default_map.h Fri Nov 13 12:33:33 2009 +0100
53.2 +++ b/lemon/bits/default_map.h Thu Dec 10 17:05:35 2009 +0100
53.3 @@ -2,7 +2,7 @@
53.4 *
53.5 * This file is a part of LEMON, a generic C++ optimization library.
53.6 *
53.7 - * Copyright (C) 2003-2008
53.8 + * Copyright (C) 2003-2009
53.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
53.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
53.11 *
53.12 @@ -153,15 +153,16 @@
53.13 template <typename _Graph, typename _Item, typename _Value>
53.14 class DefaultMap
53.15 : public DefaultMapSelector<_Graph, _Item, _Value>::Map {
53.16 + typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
53.17 +
53.18 public:
53.19 - typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
53.20 typedef DefaultMap<_Graph, _Item, _Value> Map;
53.21 -
53.22 - typedef typename Parent::Graph Graph;
53.23 +
53.24 + typedef typename Parent::GraphType GraphType;
53.25 typedef typename Parent::Value Value;
53.26
53.27 - explicit DefaultMap(const Graph& graph) : Parent(graph) {}
53.28 - DefaultMap(const Graph& graph, const Value& value)
53.29 + explicit DefaultMap(const GraphType& graph) : Parent(graph) {}
53.30 + DefaultMap(const GraphType& graph, const Value& value)
53.31 : Parent(graph, value) {}
53.32
53.33 DefaultMap& operator=(const DefaultMap& cmap) {
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
54.2 +++ b/lemon/bits/edge_set_extender.h Thu Dec 10 17:05:35 2009 +0100
54.3 @@ -0,0 +1,625 @@
54.4 +/* -*- C++ -*-
54.5 + *
54.6 + * This file is a part of LEMON, a generic C++ optimization library
54.7 + *
54.8 + * Copyright (C) 2003-2008
54.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
54.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
54.11 + *
54.12 + * Permission to use, modify and distribute this software is granted
54.13 + * provided that this copyright notice appears in all copies. For
54.14 + * precise terms see the accompanying LICENSE file.
54.15 + *
54.16 + * This software is provided "AS IS" with no warranty of any kind,
54.17 + * express or implied, and with no claim as to its suitability for any
54.18 + * purpose.
54.19 + *
54.20 + */
54.21 +
54.22 +#ifndef LEMON_BITS_EDGE_SET_EXTENDER_H
54.23 +#define LEMON_BITS_EDGE_SET_EXTENDER_H
54.24 +
54.25 +#include <lemon/core.h>
54.26 +#include <lemon/error.h>
54.27 +#include <lemon/bits/default_map.h>
54.28 +#include <lemon/bits/map_extender.h>
54.29 +
54.30 +//\ingroup digraphbits
54.31 +//\file
54.32 +//\brief Extenders for the arc set types
54.33 +namespace lemon {
54.34 +
54.35 + // \ingroup digraphbits
54.36 + //
54.37 + // \brief Extender for the ArcSets
54.38 + template <typename Base>
54.39 + class ArcSetExtender : public Base {
54.40 + typedef Base Parent;
54.41 +
54.42 + public:
54.43 +
54.44 + typedef ArcSetExtender Digraph;
54.45 +
54.46 + // Base extensions
54.47 +
54.48 + typedef typename Parent::Node Node;
54.49 + typedef typename Parent::Arc Arc;
54.50 +
54.51 + int maxId(Node) const {
54.52 + return Parent::maxNodeId();
54.53 + }
54.54 +
54.55 + int maxId(Arc) const {
54.56 + return Parent::maxArcId();
54.57 + }
54.58 +
54.59 + Node fromId(int id, Node) const {
54.60 + return Parent::nodeFromId(id);
54.61 + }
54.62 +
54.63 + Arc fromId(int id, Arc) const {
54.64 + return Parent::arcFromId(id);
54.65 + }
54.66 +
54.67 + Node oppositeNode(const Node &n, const Arc &e) const {
54.68 + if (n == Parent::source(e))
54.69 + return Parent::target(e);
54.70 + else if(n==Parent::target(e))
54.71 + return Parent::source(e);
54.72 + else
54.73 + return INVALID;
54.74 + }
54.75 +
54.76 +
54.77 + // Alteration notifier extensions
54.78 +
54.79 + // The arc observer registry.
54.80 + typedef AlterationNotifier<ArcSetExtender, Arc> ArcNotifier;
54.81 +
54.82 + protected:
54.83 +
54.84 + mutable ArcNotifier arc_notifier;
54.85 +
54.86 + public:
54.87 +
54.88 + using Parent::notifier;
54.89 +
54.90 + // Gives back the arc alteration notifier.
54.91 + ArcNotifier& notifier(Arc) const {
54.92 + return arc_notifier;
54.93 + }
54.94 +
54.95 + // Iterable extensions
54.96 +
54.97 + class NodeIt : public Node {
54.98 + const Digraph* digraph;
54.99 + public:
54.100 +
54.101 + NodeIt() {}
54.102 +
54.103 + NodeIt(Invalid i) : Node(i) { }
54.104 +
54.105 + explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
54.106 + _graph.first(static_cast<Node&>(*this));
54.107 + }
54.108 +
54.109 + NodeIt(const Digraph& _graph, const Node& node)
54.110 + : Node(node), digraph(&_graph) {}
54.111 +
54.112 + NodeIt& operator++() {
54.113 + digraph->next(*this);
54.114 + return *this;
54.115 + }
54.116 +
54.117 + };
54.118 +
54.119 +
54.120 + class ArcIt : public Arc {
54.121 + const Digraph* digraph;
54.122 + public:
54.123 +
54.124 + ArcIt() { }
54.125 +
54.126 + ArcIt(Invalid i) : Arc(i) { }
54.127 +
54.128 + explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
54.129 + _graph.first(static_cast<Arc&>(*this));
54.130 + }
54.131 +
54.132 + ArcIt(const Digraph& _graph, const Arc& e) :
54.133 + Arc(e), digraph(&_graph) { }
54.134 +
54.135 + ArcIt& operator++() {
54.136 + digraph->next(*this);
54.137 + return *this;
54.138 + }
54.139 +
54.140 + };
54.141 +
54.142 +
54.143 + class OutArcIt : public Arc {
54.144 + const Digraph* digraph;
54.145 + public:
54.146 +
54.147 + OutArcIt() { }
54.148 +
54.149 + OutArcIt(Invalid i) : Arc(i) { }
54.150 +
54.151 + OutArcIt(const Digraph& _graph, const Node& node)
54.152 + : digraph(&_graph) {
54.153 + _graph.firstOut(*this, node);
54.154 + }
54.155 +
54.156 + OutArcIt(const Digraph& _graph, const Arc& arc)
54.157 + : Arc(arc), digraph(&_graph) {}
54.158 +
54.159 + OutArcIt& operator++() {
54.160 + digraph->nextOut(*this);
54.161 + return *this;
54.162 + }
54.163 +
54.164 + };
54.165 +
54.166 +
54.167 + class InArcIt : public Arc {
54.168 + const Digraph* digraph;
54.169 + public:
54.170 +
54.171 + InArcIt() { }
54.172 +
54.173 + InArcIt(Invalid i) : Arc(i) { }
54.174 +
54.175 + InArcIt(const Digraph& _graph, const Node& node)
54.176 + : digraph(&_graph) {
54.177 + _graph.firstIn(*this, node);
54.178 + }
54.179 +
54.180 + InArcIt(const Digraph& _graph, const Arc& arc) :
54.181 + Arc(arc), digraph(&_graph) {}
54.182 +
54.183 + InArcIt& operator++() {
54.184 + digraph->nextIn(*this);
54.185 + return *this;
54.186 + }
54.187 +
54.188 + };
54.189 +
54.190 + // \brief Base node of the iterator
54.191 + //
54.192 + // Returns the base node (ie. the source in this case) of the iterator
54.193 + Node baseNode(const OutArcIt &e) const {
54.194 + return Parent::source(static_cast<const Arc&>(e));
54.195 + }
54.196 + // \brief Running node of the iterator
54.197 + //
54.198 + // Returns the running node (ie. the target in this case) of the
54.199 + // iterator
54.200 + Node runningNode(const OutArcIt &e) const {
54.201 + return Parent::target(static_cast<const Arc&>(e));
54.202 + }
54.203 +
54.204 + // \brief Base node of the iterator
54.205 + //
54.206 + // Returns the base node (ie. the target in this case) of the iterator
54.207 + Node baseNode(const InArcIt &e) const {
54.208 + return Parent::target(static_cast<const Arc&>(e));
54.209 + }
54.210 + // \brief Running node of the iterator
54.211 + //
54.212 + // Returns the running node (ie. the source in this case) of the
54.213 + // iterator
54.214 + Node runningNode(const InArcIt &e) const {
54.215 + return Parent::source(static_cast<const Arc&>(e));
54.216 + }
54.217 +
54.218 + using Parent::first;
54.219 +
54.220 + // Mappable extension
54.221 +
54.222 + template <typename _Value>
54.223 + class ArcMap
54.224 + : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
54.225 + typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
54.226 +
54.227 + public:
54.228 + explicit ArcMap(const Digraph& _g)
54.229 + : Parent(_g) {}
54.230 + ArcMap(const Digraph& _g, const _Value& _v)
54.231 + : Parent(_g, _v) {}
54.232 +
54.233 + ArcMap& operator=(const ArcMap& cmap) {
54.234 + return operator=<ArcMap>(cmap);
54.235 + }
54.236 +
54.237 + template <typename CMap>
54.238 + ArcMap& operator=(const CMap& cmap) {
54.239 + Parent::operator=(cmap);
54.240 + return *this;
54.241 + }
54.242 +
54.243 + };
54.244 +
54.245 +
54.246 + // Alteration extension
54.247 +
54.248 + Arc addArc(const Node& from, const Node& to) {
54.249 + Arc arc = Parent::addArc(from, to);
54.250 + notifier(Arc()).add(arc);
54.251 + return arc;
54.252 + }
54.253 +
54.254 + void clear() {
54.255 + notifier(Arc()).clear();
54.256 + Parent::clear();
54.257 + }
54.258 +
54.259 + void erase(const Arc& arc) {
54.260 + notifier(Arc()).erase(arc);
54.261 + Parent::erase(arc);
54.262 + }
54.263 +
54.264 + ArcSetExtender() {
54.265 + arc_notifier.setContainer(*this);
54.266 + }
54.267 +
54.268 + ~ArcSetExtender() {
54.269 + arc_notifier.clear();
54.270 + }
54.271 +
54.272 + };
54.273 +
54.274 +
54.275 + // \ingroup digraphbits
54.276 + //
54.277 + // \brief Extender for the EdgeSets
54.278 + template <typename Base>
54.279 + class EdgeSetExtender : public Base {
54.280 + typedef Base Parent;
54.281 +
54.282 + public:
54.283 +
54.284 + typedef EdgeSetExtender Graph;
54.285 +
54.286 + typedef typename Parent::Node Node;
54.287 + typedef typename Parent::Arc Arc;
54.288 + typedef typename Parent::Edge Edge;
54.289 +
54.290 + int maxId(Node) const {
54.291 + return Parent::maxNodeId();
54.292 + }
54.293 +
54.294 + int maxId(Arc) const {
54.295 + return Parent::maxArcId();
54.296 + }
54.297 +
54.298 + int maxId(Edge) const {
54.299 + return Parent::maxEdgeId();
54.300 + }
54.301 +
54.302 + Node fromId(int id, Node) const {
54.303 + return Parent::nodeFromId(id);
54.304 + }
54.305 +
54.306 + Arc fromId(int id, Arc) const {
54.307 + return Parent::arcFromId(id);
54.308 + }
54.309 +
54.310 + Edge fromId(int id, Edge) const {
54.311 + return Parent::edgeFromId(id);
54.312 + }
54.313 +
54.314 + Node oppositeNode(const Node &n, const Edge &e) const {
54.315 + if( n == Parent::u(e))
54.316 + return Parent::v(e);
54.317 + else if( n == Parent::v(e))
54.318 + return Parent::u(e);
54.319 + else
54.320 + return INVALID;
54.321 + }
54.322 +
54.323 + Arc oppositeArc(const Arc &e) const {
54.324 + return Parent::direct(e, !Parent::direction(e));
54.325 + }
54.326 +
54.327 + using Parent::direct;
54.328 + Arc direct(const Edge &e, const Node &s) const {
54.329 + return Parent::direct(e, Parent::u(e) == s);
54.330 + }
54.331 +
54.332 + typedef AlterationNotifier<EdgeSetExtender, Arc> ArcNotifier;
54.333 + typedef AlterationNotifier<EdgeSetExtender, Edge> EdgeNotifier;
54.334 +
54.335 +
54.336 + protected:
54.337 +
54.338 + mutable ArcNotifier arc_notifier;
54.339 + mutable EdgeNotifier edge_notifier;
54.340 +
54.341 + public:
54.342 +
54.343 + using Parent::notifier;
54.344 +
54.345 + ArcNotifier& notifier(Arc) const {
54.346 + return arc_notifier;
54.347 + }
54.348 +
54.349 + EdgeNotifier& notifier(Edge) const {
54.350 + return edge_notifier;
54.351 + }
54.352 +
54.353 +
54.354 + class NodeIt : public Node {
54.355 + const Graph* graph;
54.356 + public:
54.357 +
54.358 + NodeIt() {}
54.359 +
54.360 + NodeIt(Invalid i) : Node(i) { }
54.361 +
54.362 + explicit NodeIt(const Graph& _graph) : graph(&_graph) {
54.363 + _graph.first(static_cast<Node&>(*this));
54.364 + }
54.365 +
54.366 + NodeIt(const Graph& _graph, const Node& node)
54.367 + : Node(node), graph(&_graph) {}
54.368 +
54.369 + NodeIt& operator++() {
54.370 + graph->next(*this);
54.371 + return *this;
54.372 + }
54.373 +
54.374 + };
54.375 +
54.376 +
54.377 + class ArcIt : public Arc {
54.378 + const Graph* graph;
54.379 + public:
54.380 +
54.381 + ArcIt() { }
54.382 +
54.383 + ArcIt(Invalid i) : Arc(i) { }
54.384 +
54.385 + explicit ArcIt(const Graph& _graph) : graph(&_graph) {
54.386 + _graph.first(static_cast<Arc&>(*this));
54.387 + }
54.388 +
54.389 + ArcIt(const Graph& _graph, const Arc& e) :
54.390 + Arc(e), graph(&_graph) { }
54.391 +
54.392 + ArcIt& operator++() {
54.393 + graph->next(*this);
54.394 + return *this;
54.395 + }
54.396 +
54.397 + };
54.398 +
54.399 +
54.400 + class OutArcIt : public Arc {
54.401 + const Graph* graph;
54.402 + public:
54.403 +
54.404 + OutArcIt() { }
54.405 +
54.406 + OutArcIt(Invalid i) : Arc(i) { }
54.407 +
54.408 + OutArcIt(const Graph& _graph, const Node& node)
54.409 + : graph(&_graph) {
54.410 + _graph.firstOut(*this, node);
54.411 + }
54.412 +
54.413 + OutArcIt(const Graph& _graph, const Arc& arc)
54.414 + : Arc(arc), graph(&_graph) {}
54.415 +
54.416 + OutArcIt& operator++() {
54.417 + graph->nextOut(*this);
54.418 + return *this;
54.419 + }
54.420 +
54.421 + };
54.422 +
54.423 +
54.424 + class InArcIt : public Arc {
54.425 + const Graph* graph;
54.426 + public:
54.427 +
54.428 + InArcIt() { }
54.429 +
54.430 + InArcIt(Invalid i) : Arc(i) { }
54.431 +
54.432 + InArcIt(const Graph& _graph, const Node& node)
54.433 + : graph(&_graph) {
54.434 + _graph.firstIn(*this, node);
54.435 + }
54.436 +
54.437 + InArcIt(const Graph& _graph, const Arc& arc) :
54.438 + Arc(arc), graph(&_graph) {}
54.439 +
54.440 + InArcIt& operator++() {
54.441 + graph->nextIn(*this);
54.442 + return *this;
54.443 + }
54.444 +
54.445 + };
54.446 +
54.447 +
54.448 + class EdgeIt : public Parent::Edge {
54.449 + const Graph* graph;
54.450 + public:
54.451 +
54.452 + EdgeIt() { }
54.453 +
54.454 + EdgeIt(Invalid i) : Edge(i) { }
54.455 +
54.456 + explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
54.457 + _graph.first(static_cast<Edge&>(*this));
54.458 + }
54.459 +
54.460 + EdgeIt(const Graph& _graph, const Edge& e) :
54.461 + Edge(e), graph(&_graph) { }
54.462 +
54.463 + EdgeIt& operator++() {
54.464 + graph->next(*this);
54.465 + return *this;
54.466 + }
54.467 +
54.468 + };
54.469 +
54.470 + class IncEdgeIt : public Parent::Edge {
54.471 + friend class EdgeSetExtender;
54.472 + const Graph* graph;
54.473 + bool direction;
54.474 + public:
54.475 +
54.476 + IncEdgeIt() { }
54.477 +
54.478 + IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
54.479 +
54.480 + IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
54.481 + _graph.firstInc(*this, direction, n);
54.482 + }
54.483 +
54.484 + IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n)
54.485 + : graph(&_graph), Edge(ue) {
54.486 + direction = (_graph.source(ue) == n);
54.487 + }
54.488 +
54.489 + IncEdgeIt& operator++() {
54.490 + graph->nextInc(*this, direction);
54.491 + return *this;
54.492 + }
54.493 + };
54.494 +
54.495 + // \brief Base node of the iterator
54.496 + //
54.497 + // Returns the base node (ie. the source in this case) of the iterator
54.498 + Node baseNode(const OutArcIt &e) const {
54.499 + return Parent::source(static_cast<const Arc&>(e));
54.500 + }
54.501 + // \brief Running node of the iterator
54.502 + //
54.503 + // Returns the running node (ie. the target in this case) of the
54.504 + // iterator
54.505 + Node runningNode(const OutArcIt &e) const {
54.506 + return Parent::target(static_cast<const Arc&>(e));
54.507 + }
54.508 +
54.509 + // \brief Base node of the iterator
54.510 + //
54.511 + // Returns the base node (ie. the target in this case) of the iterator
54.512 + Node baseNode(const InArcIt &e) const {
54.513 + return Parent::target(static_cast<const Arc&>(e));
54.514 + }
54.515 + // \brief Running node of the iterator
54.516 + //
54.517 + // Returns the running node (ie. the source in this case) of the
54.518 + // iterator
54.519 + Node runningNode(const InArcIt &e) const {
54.520 + return Parent::source(static_cast<const Arc&>(e));
54.521 + }
54.522 +
54.523 + // Base node of the iterator
54.524 + //
54.525 + // Returns the base node of the iterator
54.526 + Node baseNode(const IncEdgeIt &e) const {
54.527 + return e.direction ? u(e) : v(e);
54.528 + }
54.529 + // Running node of the iterator
54.530 + //
54.531 + // Returns the running node of the iterator
54.532 + Node runningNode(const IncEdgeIt &e) const {
54.533 + return e.direction ? v(e) : u(e);
54.534 + }
54.535 +
54.536 +
54.537 + template <typename _Value>
54.538 + class ArcMap
54.539 + : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
54.540 + typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
54.541 +
54.542 + public:
54.543 + ArcMap(const Graph& _g)
54.544 + : Parent(_g) {}
54.545 + ArcMap(const Graph& _g, const _Value& _v)
54.546 + : Parent(_g, _v) {}
54.547 +
54.548 + ArcMap& operator=(const ArcMap& cmap) {
54.549 + return operator=<ArcMap>(cmap);
54.550 + }
54.551 +
54.552 + template <typename CMap>
54.553 + ArcMap& operator=(const CMap& cmap) {
54.554 + Parent::operator=(cmap);
54.555 + return *this;
54.556 + }
54.557 +
54.558 + };
54.559 +
54.560 +
54.561 + template <typename _Value>
54.562 + class EdgeMap
54.563 + : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
54.564 + typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
54.565 +
54.566 + public:
54.567 + EdgeMap(const Graph& _g)
54.568 + : Parent(_g) {}
54.569 +
54.570 + EdgeMap(const Graph& _g, const _Value& _v)
54.571 + : Parent(_g, _v) {}
54.572 +
54.573 + EdgeMap& operator=(const EdgeMap& cmap) {
54.574 + return operator=<EdgeMap>(cmap);
54.575 + }
54.576 +
54.577 + template <typename CMap>
54.578 + EdgeMap& operator=(const CMap& cmap) {
54.579 + Parent::operator=(cmap);
54.580 + return *this;
54.581 + }
54.582 +
54.583 + };
54.584 +
54.585 +
54.586 + // Alteration extension
54.587 +
54.588 + Edge addEdge(const Node& from, const Node& to) {
54.589 + Edge edge = Parent::addEdge(from, to);
54.590 + notifier(Edge()).add(edge);
54.591 + std::vector<Arc> arcs;
54.592 + arcs.push_back(Parent::direct(edge, true));
54.593 + arcs.push_back(Parent::direct(edge, false));
54.594 + notifier(Arc()).add(arcs);
54.595 + return edge;
54.596 + }
54.597 +
54.598 + void clear() {
54.599 + notifier(Arc()).clear();
54.600 + notifier(Edge()).clear();
54.601 + Parent::clear();
54.602 + }
54.603 +
54.604 + void erase(const Edge& edge) {
54.605 + std::vector<Arc> arcs;
54.606 + arcs.push_back(Parent::direct(edge, true));
54.607 + arcs.push_back(Parent::direct(edge, false));
54.608 + notifier(Arc()).erase(arcs);
54.609 + notifier(Edge()).erase(edge);
54.610 + Parent::erase(edge);
54.611 + }
54.612 +
54.613 +
54.614 + EdgeSetExtender() {
54.615 + arc_notifier.setContainer(*this);
54.616 + edge_notifier.setContainer(*this);
54.617 + }
54.618 +
54.619 + ~EdgeSetExtender() {
54.620 + edge_notifier.clear();
54.621 + arc_notifier.clear();
54.622 + }
54.623 +
54.624 + };
54.625 +
54.626 +}
54.627 +
54.628 +#endif
55.1 --- a/lemon/bits/enable_if.h Fri Nov 13 12:33:33 2009 +0100
55.2 +++ b/lemon/bits/enable_if.h Thu Dec 10 17:05:35 2009 +0100
55.3 @@ -2,7 +2,7 @@
55.4 *
55.5 * This file is a part of LEMON, a generic C++ optimization library.
55.6 *
55.7 - * Copyright (C) 2003-2008
55.8 + * Copyright (C) 2003-2009
55.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
55.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
55.11 *
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
56.2 +++ b/lemon/bits/graph_adaptor_extender.h Thu Dec 10 17:05:35 2009 +0100
56.3 @@ -0,0 +1,399 @@
56.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
56.5 + *
56.6 + * This file is a part of LEMON, a generic C++ optimization library.
56.7 + *
56.8 + * Copyright (C) 2003-2009
56.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
56.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
56.11 + *
56.12 + * Permission to use, modify and distribute this software is granted
56.13 + * provided that this copyright notice appears in all copies. For
56.14 + * precise terms see the accompanying LICENSE file.
56.15 + *
56.16 + * This software is provided "AS IS" with no warranty of any kind,
56.17 + * express or implied, and with no claim as to its suitability for any
56.18 + * purpose.
56.19 + *
56.20 + */
56.21 +
56.22 +#ifndef LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
56.23 +#define LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
56.24 +
56.25 +#include <lemon/core.h>
56.26 +#include <lemon/error.h>
56.27 +
56.28 +namespace lemon {
56.29 +
56.30 + template <typename _Digraph>
56.31 + class DigraphAdaptorExtender : public _Digraph {
56.32 + typedef _Digraph Parent;
56.33 +
56.34 + public:
56.35 +
56.36 + typedef _Digraph Digraph;
56.37 + typedef DigraphAdaptorExtender Adaptor;
56.38 +
56.39 + // Base extensions
56.40 +
56.41 + typedef typename Parent::Node Node;
56.42 + typedef typename Parent::Arc Arc;
56.43 +
56.44 + int maxId(Node) const {
56.45 + return Parent::maxNodeId();
56.46 + }
56.47 +
56.48 + int maxId(Arc) const {
56.49 + return Parent::maxArcId();
56.50 + }
56.51 +
56.52 + Node fromId(int id, Node) const {
56.53 + return Parent::nodeFromId(id);
56.54 + }
56.55 +
56.56 + Arc fromId(int id, Arc) const {
56.57 + return Parent::arcFromId(id);
56.58 + }
56.59 +
56.60 + Node oppositeNode(const Node &n, const Arc &e) const {
56.61 + if (n == Parent::source(e))
56.62 + return Parent::target(e);
56.63 + else if(n==Parent::target(e))
56.64 + return Parent::source(e);
56.65 + else
56.66 + return INVALID;
56.67 + }
56.68 +
56.69 + class NodeIt : public Node {
56.70 + const Adaptor* _adaptor;
56.71 + public:
56.72 +
56.73 + NodeIt() {}
56.74 +
56.75 + NodeIt(Invalid i) : Node(i) { }
56.76 +
56.77 + explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
56.78 + _adaptor->first(static_cast<Node&>(*this));
56.79 + }
56.80 +
56.81 + NodeIt(const Adaptor& adaptor, const Node& node)
56.82 + : Node(node), _adaptor(&adaptor) {}
56.83 +
56.84 + NodeIt& operator++() {
56.85 + _adaptor->next(*this);
56.86 + return *this;
56.87 + }
56.88 +
56.89 + };
56.90 +
56.91 +
56.92 + class ArcIt : public Arc {
56.93 + const Adaptor* _adaptor;
56.94 + public:
56.95 +
56.96 + ArcIt() { }
56.97 +
56.98 + ArcIt(Invalid i) : Arc(i) { }
56.99 +
56.100 + explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
56.101 + _adaptor->first(static_cast<Arc&>(*this));
56.102 + }
56.103 +
56.104 + ArcIt(const Adaptor& adaptor, const Arc& e) :
56.105 + Arc(e), _adaptor(&adaptor) { }
56.106 +
56.107 + ArcIt& operator++() {
56.108 + _adaptor->next(*this);
56.109 + return *this;
56.110 + }
56.111 +
56.112 + };
56.113 +
56.114 +
56.115 + class OutArcIt : public Arc {
56.116 + const Adaptor* _adaptor;
56.117 + public:
56.118 +
56.119 + OutArcIt() { }
56.120 +
56.121 + OutArcIt(Invalid i) : Arc(i) { }
56.122 +
56.123 + OutArcIt(const Adaptor& adaptor, const Node& node)
56.124 + : _adaptor(&adaptor) {
56.125 + _adaptor->firstOut(*this, node);
56.126 + }
56.127 +
56.128 + OutArcIt(const Adaptor& adaptor, const Arc& arc)
56.129 + : Arc(arc), _adaptor(&adaptor) {}
56.130 +
56.131 + OutArcIt& operator++() {
56.132 + _adaptor->nextOut(*this);
56.133 + return *this;
56.134 + }
56.135 +
56.136 + };
56.137 +
56.138 +
56.139 + class InArcIt : public Arc {
56.140 + const Adaptor* _adaptor;
56.141 + public:
56.142 +
56.143 + InArcIt() { }
56.144 +
56.145 + InArcIt(Invalid i) : Arc(i) { }
56.146 +
56.147 + InArcIt(const Adaptor& adaptor, const Node& node)
56.148 + : _adaptor(&adaptor) {
56.149 + _adaptor->firstIn(*this, node);
56.150 + }
56.151 +
56.152 + InArcIt(const Adaptor& adaptor, const Arc& arc) :
56.153 + Arc(arc), _adaptor(&adaptor) {}
56.154 +
56.155 + InArcIt& operator++() {
56.156 + _adaptor->nextIn(*this);
56.157 + return *this;
56.158 + }
56.159 +
56.160 + };
56.161 +
56.162 + Node baseNode(const OutArcIt &e) const {
56.163 + return Parent::source(e);
56.164 + }
56.165 + Node runningNode(const OutArcIt &e) const {
56.166 + return Parent::target(e);
56.167 + }
56.168 +
56.169 + Node baseNode(const InArcIt &e) const {
56.170 + return Parent::target(e);
56.171 + }
56.172 + Node runningNode(const InArcIt &e) const {
56.173 + return Parent::source(e);
56.174 + }
56.175 +
56.176 + };
56.177 +
56.178 + template <typename _Graph>
56.179 + class GraphAdaptorExtender : public _Graph {
56.180 + typedef _Graph Parent;
56.181 +
56.182 + public:
56.183 +
56.184 + typedef _Graph Graph;
56.185 + typedef GraphAdaptorExtender Adaptor;
56.186 +
56.187 + typedef typename Parent::Node Node;
56.188 + typedef typename Parent::Arc Arc;
56.189 + typedef typename Parent::Edge Edge;
56.190 +
56.191 + // Graph extension
56.192 +
56.193 + int maxId(Node) const {
56.194 + return Parent::maxNodeId();
56.195 + }
56.196 +
56.197 + int maxId(Arc) const {
56.198 + return Parent::maxArcId();
56.199 + }
56.200 +
56.201 + int maxId(Edge) const {
56.202 + return Parent::maxEdgeId();
56.203 + }
56.204 +
56.205 + Node fromId(int id, Node) const {
56.206 + return Parent::nodeFromId(id);
56.207 + }
56.208 +
56.209 + Arc fromId(int id, Arc) const {
56.210 + return Parent::arcFromId(id);
56.211 + }
56.212 +
56.213 + Edge fromId(int id, Edge) const {
56.214 + return Parent::edgeFromId(id);
56.215 + }
56.216 +
56.217 + Node oppositeNode(const Node &n, const Edge &e) const {
56.218 + if( n == Parent::u(e))
56.219 + return Parent::v(e);
56.220 + else if( n == Parent::v(e))
56.221 + return Parent::u(e);
56.222 + else
56.223 + return INVALID;
56.224 + }
56.225 +
56.226 + Arc oppositeArc(const Arc &a) const {
56.227 + return Parent::direct(a, !Parent::direction(a));
56.228 + }
56.229 +
56.230 + using Parent::direct;
56.231 + Arc direct(const Edge &e, const Node &s) const {
56.232 + return Parent::direct(e, Parent::u(e) == s);
56.233 + }
56.234 +
56.235 +
56.236 + class NodeIt : public Node {
56.237 + const Adaptor* _adaptor;
56.238 + public:
56.239 +
56.240 + NodeIt() {}
56.241 +
56.242 + NodeIt(Invalid i) : Node(i) { }
56.243 +
56.244 + explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
56.245 + _adaptor->first(static_cast<Node&>(*this));
56.246 + }
56.247 +
56.248 + NodeIt(const Adaptor& adaptor, const Node& node)
56.249 + : Node(node), _adaptor(&adaptor) {}
56.250 +
56.251 + NodeIt& operator++() {
56.252 + _adaptor->next(*this);
56.253 + return *this;
56.254 + }
56.255 +
56.256 + };
56.257 +
56.258 +
56.259 + class ArcIt : public Arc {
56.260 + const Adaptor* _adaptor;
56.261 + public:
56.262 +
56.263 + ArcIt() { }
56.264 +
56.265 + ArcIt(Invalid i) : Arc(i) { }
56.266 +
56.267 + explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
56.268 + _adaptor->first(static_cast<Arc&>(*this));
56.269 + }
56.270 +
56.271 + ArcIt(const Adaptor& adaptor, const Arc& e) :
56.272 + Arc(e), _adaptor(&adaptor) { }
56.273 +
56.274 + ArcIt& operator++() {
56.275 + _adaptor->next(*this);
56.276 + return *this;
56.277 + }
56.278 +
56.279 + };
56.280 +
56.281 +
56.282 + class OutArcIt : public Arc {
56.283 + const Adaptor* _adaptor;
56.284 + public:
56.285 +
56.286 + OutArcIt() { }
56.287 +
56.288 + OutArcIt(Invalid i) : Arc(i) { }
56.289 +
56.290 + OutArcIt(const Adaptor& adaptor, const Node& node)
56.291 + : _adaptor(&adaptor) {
56.292 + _adaptor->firstOut(*this, node);
56.293 + }
56.294 +
56.295 + OutArcIt(const Adaptor& adaptor, const Arc& arc)
56.296 + : Arc(arc), _adaptor(&adaptor) {}
56.297 +
56.298 + OutArcIt& operator++() {
56.299 + _adaptor->nextOut(*this);
56.300 + return *this;
56.301 + }
56.302 +
56.303 + };
56.304 +
56.305 +
56.306 + class InArcIt : public Arc {
56.307 + const Adaptor* _adaptor;
56.308 + public:
56.309 +
56.310 + InArcIt() { }
56.311 +
56.312 + InArcIt(Invalid i) : Arc(i) { }
56.313 +
56.314 + InArcIt(const Adaptor& adaptor, const Node& node)
56.315 + : _adaptor(&adaptor) {
56.316 + _adaptor->firstIn(*this, node);
56.317 + }
56.318 +
56.319 + InArcIt(const Adaptor& adaptor, const Arc& arc) :
56.320 + Arc(arc), _adaptor(&adaptor) {}
56.321 +
56.322 + InArcIt& operator++() {
56.323 + _adaptor->nextIn(*this);
56.324 + return *this;
56.325 + }
56.326 +
56.327 + };
56.328 +
56.329 + class EdgeIt : public Parent::Edge {
56.330 + const Adaptor* _adaptor;
56.331 + public:
56.332 +
56.333 + EdgeIt() { }
56.334 +
56.335 + EdgeIt(Invalid i) : Edge(i) { }
56.336 +
56.337 + explicit EdgeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
56.338 + _adaptor->first(static_cast<Edge&>(*this));
56.339 + }
56.340 +
56.341 + EdgeIt(const Adaptor& adaptor, const Edge& e) :
56.342 + Edge(e), _adaptor(&adaptor) { }
56.343 +
56.344 + EdgeIt& operator++() {
56.345 + _adaptor->next(*this);
56.346 + return *this;
56.347 + }
56.348 +
56.349 + };
56.350 +
56.351 + class IncEdgeIt : public Edge {
56.352 + friend class GraphAdaptorExtender;
56.353 + const Adaptor* _adaptor;
56.354 + bool direction;
56.355 + public:
56.356 +
56.357 + IncEdgeIt() { }
56.358 +
56.359 + IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
56.360 +
56.361 + IncEdgeIt(const Adaptor& adaptor, const Node &n) : _adaptor(&adaptor) {
56.362 + _adaptor->firstInc(static_cast<Edge&>(*this), direction, n);
56.363 + }
56.364 +
56.365 + IncEdgeIt(const Adaptor& adaptor, const Edge &e, const Node &n)
56.366 + : _adaptor(&adaptor), Edge(e) {
56.367 + direction = (_adaptor->u(e) == n);
56.368 + }
56.369 +
56.370 + IncEdgeIt& operator++() {
56.371 + _adaptor->nextInc(*this, direction);
56.372 + return *this;
56.373 + }
56.374 + };
56.375 +
56.376 + Node baseNode(const OutArcIt &a) const {
56.377 + return Parent::source(a);
56.378 + }
56.379 + Node runningNode(const OutArcIt &a) const {
56.380 + return Parent::target(a);
56.381 + }
56.382 +
56.383 + Node baseNode(const InArcIt &a) const {
56.384 + return Parent::target(a);
56.385 + }
56.386 + Node runningNode(const InArcIt &a) const {
56.387 + return Parent::source(a);
56.388 + }
56.389 +
56.390 + Node baseNode(const IncEdgeIt &e) const {
56.391 + return e.direction ? Parent::u(e) : Parent::v(e);
56.392 + }
56.393 + Node runningNode(const IncEdgeIt &e) const {
56.394 + return e.direction ? Parent::v(e) : Parent::u(e);
56.395 + }
56.396 +
56.397 + };
56.398 +
56.399 +}
56.400 +
56.401 +
56.402 +#endif
57.1 --- a/lemon/bits/graph_extender.h Fri Nov 13 12:33:33 2009 +0100
57.2 +++ b/lemon/bits/graph_extender.h Thu Dec 10 17:05:35 2009 +0100
57.3 @@ -2,7 +2,7 @@
57.4 *
57.5 * This file is a part of LEMON, a generic C++ optimization library.
57.6 *
57.7 - * Copyright (C) 2003-2008
57.8 + * Copyright (C) 2003-2009
57.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
57.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
57.11 *
57.12 @@ -29,17 +29,18 @@
57.13
57.14 //\ingroup graphbits
57.15 //\file
57.16 -//\brief Extenders for the digraph types
57.17 +//\brief Extenders for the graph types
57.18 namespace lemon {
57.19
57.20 // \ingroup graphbits
57.21 //
57.22 - // \brief Extender for the Digraphs
57.23 + // \brief Extender for the digraph implementations
57.24 template <typename Base>
57.25 class DigraphExtender : public Base {
57.26 + typedef Base Parent;
57.27 +
57.28 public:
57.29
57.30 - typedef Base Parent;
57.31 typedef DigraphExtender Digraph;
57.32
57.33 // Base extensions
57.34 @@ -218,10 +219,9 @@
57.35 template <typename _Value>
57.36 class NodeMap
57.37 : public MapExtender<DefaultMap<Digraph, Node, _Value> > {
57.38 - public:
57.39 - typedef DigraphExtender Digraph;
57.40 typedef MapExtender<DefaultMap<Digraph, Node, _Value> > Parent;
57.41
57.42 + public:
57.43 explicit NodeMap(const Digraph& digraph)
57.44 : Parent(digraph) {}
57.45 NodeMap(const Digraph& digraph, const _Value& value)
57.46 @@ -243,10 +243,9 @@
57.47 template <typename _Value>
57.48 class ArcMap
57.49 : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
57.50 - public:
57.51 - typedef DigraphExtender Digraph;
57.52 typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
57.53
57.54 + public:
57.55 explicit ArcMap(const Digraph& digraph)
57.56 : Parent(digraph) {}
57.57 ArcMap(const Digraph& digraph, const _Value& value)
57.58 @@ -330,9 +329,10 @@
57.59 // \brief Extender for the Graphs
57.60 template <typename Base>
57.61 class GraphExtender : public Base {
57.62 + typedef Base Parent;
57.63 +
57.64 public:
57.65
57.66 - typedef Base Parent;
57.67 typedef GraphExtender Graph;
57.68
57.69 typedef True UndirectedTag;
57.70 @@ -601,10 +601,9 @@
57.71 template <typename _Value>
57.72 class NodeMap
57.73 : public MapExtender<DefaultMap<Graph, Node, _Value> > {
57.74 - public:
57.75 - typedef GraphExtender Graph;
57.76 typedef MapExtender<DefaultMap<Graph, Node, _Value> > Parent;
57.77
57.78 + public:
57.79 NodeMap(const Graph& graph)
57.80 : Parent(graph) {}
57.81 NodeMap(const Graph& graph, const _Value& value)
57.82 @@ -626,10 +625,9 @@
57.83 template <typename _Value>
57.84 class ArcMap
57.85 : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
57.86 - public:
57.87 - typedef GraphExtender Graph;
57.88 typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
57.89
57.90 + public:
57.91 ArcMap(const Graph& graph)
57.92 : Parent(graph) {}
57.93 ArcMap(const Graph& graph, const _Value& value)
57.94 @@ -651,10 +649,9 @@
57.95 template <typename _Value>
57.96 class EdgeMap
57.97 : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
57.98 - public:
57.99 - typedef GraphExtender Graph;
57.100 typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
57.101
57.102 + public:
57.103 EdgeMap(const Graph& graph)
57.104 : Parent(graph) {}
57.105
58.1 --- a/lemon/bits/map_extender.h Fri Nov 13 12:33:33 2009 +0100
58.2 +++ b/lemon/bits/map_extender.h Thu Dec 10 17:05:35 2009 +0100
58.3 @@ -2,7 +2,7 @@
58.4 *
58.5 * This file is a part of LEMON, a generic C++ optimization library.
58.6 *
58.7 - * Copyright (C) 2003-2008
58.8 + * Copyright (C) 2003-2009
58.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
58.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
58.11 *
58.12 @@ -36,17 +36,20 @@
58.13 // \brief Extender for maps
58.14 template <typename _Map>
58.15 class MapExtender : public _Map {
58.16 + typedef _Map Parent;
58.17 + typedef typename Parent::GraphType GraphType;
58.18 +
58.19 public:
58.20
58.21 - typedef _Map Parent;
58.22 typedef MapExtender Map;
58.23 -
58.24 -
58.25 - typedef typename Parent::Graph Graph;
58.26 typedef typename Parent::Key Item;
58.27
58.28 typedef typename Parent::Key Key;
58.29 typedef typename Parent::Value Value;
58.30 + typedef typename Parent::Reference Reference;
58.31 + typedef typename Parent::ConstReference ConstReference;
58.32 +
58.33 + typedef typename Parent::ReferenceMapTag ReferenceMapTag;
58.34
58.35 class MapIt;
58.36 class ConstMapIt;
58.37 @@ -56,10 +59,10 @@
58.38
58.39 public:
58.40
58.41 - MapExtender(const Graph& graph)
58.42 + MapExtender(const GraphType& graph)
58.43 : Parent(graph) {}
58.44
58.45 - MapExtender(const Graph& graph, const Value& value)
58.46 + MapExtender(const GraphType& graph, const Value& value)
58.47 : Parent(graph, value) {}
58.48
58.49 private:
58.50 @@ -75,9 +78,10 @@
58.51
58.52 public:
58.53 class MapIt : public Item {
58.54 + typedef Item Parent;
58.55 +
58.56 public:
58.57
58.58 - typedef Item Parent;
58.59 typedef typename Map::Value Value;
58.60
58.61 MapIt() : map(NULL) {}
58.62 @@ -114,10 +118,10 @@
58.63 };
58.64
58.65 class ConstMapIt : public Item {
58.66 + typedef Item Parent;
58.67 +
58.68 public:
58.69
58.70 - typedef Item Parent;
58.71 -
58.72 typedef typename Map::Value Value;
58.73
58.74 ConstMapIt() : map(NULL) {}
58.75 @@ -145,12 +149,12 @@
58.76 };
58.77
58.78 class ItemIt : public Item {
58.79 - public:
58.80 -
58.81 typedef Item Parent;
58.82
58.83 + public:
58.84 ItemIt() : map(NULL) {}
58.85
58.86 +
58.87 ItemIt(Invalid i) : Parent(i), map(NULL) {}
58.88
58.89 explicit ItemIt(Map& _map) : map(&_map) {
58.90 @@ -176,17 +180,20 @@
58.91 // \brief Extender for maps which use a subset of the items.
58.92 template <typename _Graph, typename _Map>
58.93 class SubMapExtender : public _Map {
58.94 + typedef _Map Parent;
58.95 + typedef _Graph GraphType;
58.96 +
58.97 public:
58.98
58.99 - typedef _Map Parent;
58.100 typedef SubMapExtender Map;
58.101 -
58.102 - typedef _Graph Graph;
58.103 -
58.104 typedef typename Parent::Key Item;
58.105
58.106 typedef typename Parent::Key Key;
58.107 typedef typename Parent::Value Value;
58.108 + typedef typename Parent::Reference Reference;
58.109 + typedef typename Parent::ConstReference ConstReference;
58.110 +
58.111 + typedef typename Parent::ReferenceMapTag ReferenceMapTag;
58.112
58.113 class MapIt;
58.114 class ConstMapIt;
58.115 @@ -196,10 +203,10 @@
58.116
58.117 public:
58.118
58.119 - SubMapExtender(const Graph& _graph)
58.120 + SubMapExtender(const GraphType& _graph)
58.121 : Parent(_graph), graph(_graph) {}
58.122
58.123 - SubMapExtender(const Graph& _graph, const Value& _value)
58.124 + SubMapExtender(const GraphType& _graph, const Value& _value)
58.125 : Parent(_graph, _value), graph(_graph) {}
58.126
58.127 private:
58.128 @@ -219,9 +226,9 @@
58.129
58.130 public:
58.131 class MapIt : public Item {
58.132 + typedef Item Parent;
58.133 +
58.134 public:
58.135 -
58.136 - typedef Item Parent;
58.137 typedef typename Map::Value Value;
58.138
58.139 MapIt() : map(NULL) {}
58.140 @@ -258,10 +265,10 @@
58.141 };
58.142
58.143 class ConstMapIt : public Item {
58.144 + typedef Item Parent;
58.145 +
58.146 public:
58.147
58.148 - typedef Item Parent;
58.149 -
58.150 typedef typename Map::Value Value;
58.151
58.152 ConstMapIt() : map(NULL) {}
58.153 @@ -289,12 +296,12 @@
58.154 };
58.155
58.156 class ItemIt : public Item {
58.157 - public:
58.158 -
58.159 typedef Item Parent;
58.160
58.161 + public:
58.162 ItemIt() : map(NULL) {}
58.163
58.164 +
58.165 ItemIt(Invalid i) : Parent(i), map(NULL) { }
58.166
58.167 explicit ItemIt(Map& _map) : map(&_map) {
58.168 @@ -316,7 +323,7 @@
58.169
58.170 private:
58.171
58.172 - const Graph& graph;
58.173 + const GraphType& graph;
58.174
58.175 };
58.176
59.1 --- a/lemon/bits/path_dump.h Fri Nov 13 12:33:33 2009 +0100
59.2 +++ b/lemon/bits/path_dump.h Thu Dec 10 17:05:35 2009 +0100
59.3 @@ -2,7 +2,7 @@
59.4 *
59.5 * This file is a part of LEMON, a generic C++ optimization library.
59.6 *
59.7 - * Copyright (C) 2003-2008
59.8 + * Copyright (C) 2003-2009
59.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
59.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
59.11 *
59.12 @@ -16,8 +16,11 @@
59.13 *
59.14 */
59.15
59.16 -#ifndef LEMON_BITS_PRED_MAP_PATH_H
59.17 -#define LEMON_BITS_PRED_MAP_PATH_H
59.18 +#ifndef LEMON_BITS_PATH_DUMP_H
59.19 +#define LEMON_BITS_PATH_DUMP_H
59.20 +
59.21 +#include <lemon/core.h>
59.22 +#include <lemon/concept_check.h>
59.23
59.24 namespace lemon {
59.25
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
60.2 +++ b/lemon/bits/solver_bits.h Thu Dec 10 17:05:35 2009 +0100
60.3 @@ -0,0 +1,193 @@
60.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
60.5 + *
60.6 + * This file is a part of LEMON, a generic C++ optimization library.
60.7 + *
60.8 + * Copyright (C) 2003-2008
60.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
60.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
60.11 + *
60.12 + * Permission to use, modify and distribute this software is granted
60.13 + * provided that this copyright notice appears in all copies. For
60.14 + * precise terms see the accompanying LICENSE file.
60.15 + *
60.16 + * This software is provided "AS IS" with no warranty of any kind,
60.17 + * express or implied, and with no claim as to its suitability for any
60.18 + * purpose.
60.19 + *
60.20 + */
60.21 +
60.22 +#ifndef LEMON_BITS_SOLVER_BITS_H
60.23 +#define LEMON_BITS_SOLVER_BITS_H
60.24 +
60.25 +#include <vector>
60.26 +
60.27 +namespace lemon {
60.28 +
60.29 + namespace _solver_bits {
60.30 +
60.31 + class VarIndex {
60.32 + private:
60.33 + struct ItemT {
60.34 + int prev, next;
60.35 + int index;
60.36 + };
60.37 + std::vector<ItemT> items;
60.38 + int first_item, last_item, first_free_item;
60.39 +
60.40 + std::vector<int> cross;
60.41 +
60.42 + public:
60.43 +
60.44 + VarIndex()
60.45 + : first_item(-1), last_item(-1), first_free_item(-1) {
60.46 + }
60.47 +
60.48 + void clear() {
60.49 + first_item = -1;
60.50 + first_free_item = -1;
60.51 + items.clear();
60.52 + cross.clear();
60.53 + }
60.54 +
60.55 + int addIndex(int idx) {
60.56 + int n;
60.57 + if (first_free_item == -1) {
60.58 + n = items.size();
60.59 + items.push_back(ItemT());
60.60 + } else {
60.61 + n = first_free_item;
60.62 + first_free_item = items[n].next;
60.63 + if (first_free_item != -1) {
60.64 + items[first_free_item].prev = -1;
60.65 + }
60.66 + }
60.67 + items[n].index = idx;
60.68 + if (static_cast<int>(cross.size()) <= idx) {
60.69 + cross.resize(idx + 1, -1);
60.70 + }
60.71 + cross[idx] = n;
60.72 +
60.73 + items[n].prev = last_item;
60.74 + items[n].next = -1;
60.75 + if (last_item != -1) {
60.76 + items[last_item].next = n;
60.77 + } else {
60.78 + first_item = n;
60.79 + }
60.80 + last_item = n;
60.81 +
60.82 + return n;
60.83 + }
60.84 +
60.85 + int addIndex(int idx, int n) {
60.86 + while (n >= static_cast<int>(items.size())) {
60.87 + items.push_back(ItemT());
60.88 + items.back().prev = -1;
60.89 + items.back().next = first_free_item;
60.90 + if (first_free_item != -1) {
60.91 + items[first_free_item].prev = items.size() - 1;
60.92 + }
60.93 + first_free_item = items.size() - 1;
60.94 + }
60.95 + if (items[n].next != -1) {
60.96 + items[items[n].next].prev = items[n].prev;
60.97 + }
60.98 + if (items[n].prev != -1) {
60.99 + items[items[n].prev].next = items[n].next;
60.100 + } else {
60.101 + first_free_item = items[n].next;
60.102 + }
60.103 +
60.104 + items[n].index = idx;
60.105 + if (static_cast<int>(cross.size()) <= idx) {
60.106 + cross.resize(idx + 1, -1);
60.107 + }
60.108 + cross[idx] = n;
60.109 +
60.110 + items[n].prev = last_item;
60.111 + items[n].next = -1;
60.112 + if (last_item != -1) {
60.113 + items[last_item].next = n;
60.114 + } else {
60.115 + first_item = n;
60.116 + }
60.117 + last_item = n;
60.118 +
60.119 + return n;
60.120 + }
60.121 +
60.122 + void eraseIndex(int idx) {
60.123 + int n = cross[idx];
60.124 +
60.125 + if (items[n].prev != -1) {
60.126 + items[items[n].prev].next = items[n].next;
60.127 + } else {
60.128 + first_item = items[n].next;
60.129 + }
60.130 + if (items[n].next != -1) {
60.131 + items[items[n].next].prev = items[n].prev;
60.132 + } else {
60.133 + last_item = items[n].prev;
60.134 + }
60.135 +
60.136 + if (first_free_item != -1) {
60.137 + items[first_free_item].prev = n;
60.138 + }
60.139 + items[n].next = first_free_item;
60.140 + items[n].prev = -1;
60.141 + first_free_item = n;
60.142 +
60.143 + while (!cross.empty() && cross.back() == -1) {
60.144 + cross.pop_back();
60.145 + }
60.146 + }
60.147 +
60.148 + int maxIndex() const {
60.149 + return cross.size() - 1;
60.150 + }
60.151 +
60.152 + void shiftIndices(int idx) {
60.153 + for (int i = idx + 1; i < static_cast<int>(cross.size()); ++i) {
60.154 + cross[i - 1] = cross[i];
60.155 + if (cross[i] != -1) {
60.156 + --items[cross[i]].index;
60.157 + }
60.158 + }
60.159 + cross.back() = -1;
60.160 + cross.pop_back();
60.161 + while (!cross.empty() && cross.back() == -1) {
60.162 + cross.pop_back();
60.163 + }
60.164 + }
60.165 +
60.166 + void relocateIndex(int idx, int jdx) {
60.167 + cross[idx] = cross[jdx];
60.168 + items[cross[jdx]].index = idx;
60.169 + cross[jdx] = -1;
60.170 +
60.171 + while (!cross.empty() && cross.back() == -1) {
60.172 + cross.pop_back();
60.173 + }
60.174 + }
60.175 +
60.176 + int operator[](int idx) const {
60.177 + return cross[idx];
60.178 + }
60.179 +
60.180 + int operator()(int fdx) const {
60.181 + return items[fdx].index;
60.182 + }
60.183 +
60.184 + void firstItem(int& fdx) const {
60.185 + fdx = first_item;
60.186 + }
60.187 +
60.188 + void nextItem(int& fdx) const {
60.189 + fdx = items[fdx].next;
60.190 + }
60.191 +
60.192 + };
60.193 + }
60.194 +}
60.195 +
60.196 +#endif
61.1 --- a/lemon/bits/traits.h Fri Nov 13 12:33:33 2009 +0100
61.2 +++ b/lemon/bits/traits.h Thu Dec 10 17:05:35 2009 +0100
61.3 @@ -2,7 +2,7 @@
61.4 *
61.5 * This file is a part of LEMON, a generic C++ optimization library.
61.6 *
61.7 - * Copyright (C) 2003-2008
61.8 + * Copyright (C) 2003-2009
61.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
61.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
61.11 *
61.12 @@ -29,117 +29,123 @@
61.13
61.14 struct InvalidType {};
61.15
61.16 - template <typename _Graph, typename _Item>
61.17 + template <typename GR, typename _Item>
61.18 class ItemSetTraits {};
61.19
61.20
61.21 - template <typename Graph, typename Enable = void>
61.22 + template <typename GR, typename Enable = void>
61.23 struct NodeNotifierIndicator {
61.24 typedef InvalidType Type;
61.25 };
61.26 - template <typename Graph>
61.27 + template <typename GR>
61.28 struct NodeNotifierIndicator<
61.29 - Graph,
61.30 - typename enable_if<typename Graph::NodeNotifier::Notifier, void>::type
61.31 + GR,
61.32 + typename enable_if<typename GR::NodeNotifier::Notifier, void>::type
61.33 > {
61.34 - typedef typename Graph::NodeNotifier Type;
61.35 + typedef typename GR::NodeNotifier Type;
61.36 };
61.37
61.38 - template <typename _Graph>
61.39 - class ItemSetTraits<_Graph, typename _Graph::Node> {
61.40 + template <typename GR>
61.41 + class ItemSetTraits<GR, typename GR::Node> {
61.42 public:
61.43
61.44 - typedef _Graph Graph;
61.45 + typedef GR Graph;
61.46 + typedef GR Digraph;
61.47
61.48 - typedef typename Graph::Node Item;
61.49 - typedef typename Graph::NodeIt ItemIt;
61.50 + typedef typename GR::Node Item;
61.51 + typedef typename GR::NodeIt ItemIt;
61.52
61.53 - typedef typename NodeNotifierIndicator<Graph>::Type ItemNotifier;
61.54 + typedef typename NodeNotifierIndicator<GR>::Type ItemNotifier;
61.55
61.56 - template <typename _Value>
61.57 - class Map : public Graph::template NodeMap<_Value> {
61.58 + template <typename V>
61.59 + class Map : public GR::template NodeMap<V> {
61.60 + typedef typename GR::template NodeMap<V> Parent;
61.61 +
61.62 public:
61.63 - typedef typename Graph::template NodeMap<_Value> Parent;
61.64 - typedef typename Graph::template NodeMap<_Value> Type;
61.65 + typedef typename GR::template NodeMap<V> Type;
61.66 typedef typename Parent::Value Value;
61.67
61.68 - Map(const Graph& _digraph) : Parent(_digraph) {}
61.69 - Map(const Graph& _digraph, const Value& _value)
61.70 + Map(const GR& _digraph) : Parent(_digraph) {}
61.71 + Map(const GR& _digraph, const Value& _value)
61.72 : Parent(_digraph, _value) {}
61.73
61.74 };
61.75
61.76 };
61.77
61.78 - template <typename Graph, typename Enable = void>
61.79 + template <typename GR, typename Enable = void>
61.80 struct ArcNotifierIndicator {
61.81 typedef InvalidType Type;
61.82 };
61.83 - template <typename Graph>
61.84 + template <typename GR>
61.85 struct ArcNotifierIndicator<
61.86 - Graph,
61.87 - typename enable_if<typename Graph::ArcNotifier::Notifier, void>::type
61.88 + GR,
61.89 + typename enable_if<typename GR::ArcNotifier::Notifier, void>::type
61.90 > {
61.91 - typedef typename Graph::ArcNotifier Type;
61.92 + typedef typename GR::ArcNotifier Type;
61.93 };
61.94
61.95 - template <typename _Graph>
61.96 - class ItemSetTraits<_Graph, typename _Graph::Arc> {
61.97 + template <typename GR>
61.98 + class ItemSetTraits<GR, typename GR::Arc> {
61.99 public:
61.100
61.101 - typedef _Graph Graph;
61.102 + typedef GR Graph;
61.103 + typedef GR Digraph;
61.104
61.105 - typedef typename Graph::Arc Item;
61.106 - typedef typename Graph::ArcIt ItemIt;
61.107 + typedef typename GR::Arc Item;
61.108 + typedef typename GR::ArcIt ItemIt;
61.109
61.110 - typedef typename ArcNotifierIndicator<Graph>::Type ItemNotifier;
61.111 + typedef typename ArcNotifierIndicator<GR>::Type ItemNotifier;
61.112
61.113 - template <typename _Value>
61.114 - class Map : public Graph::template ArcMap<_Value> {
61.115 + template <typename V>
61.116 + class Map : public GR::template ArcMap<V> {
61.117 + typedef typename GR::template ArcMap<V> Parent;
61.118 +
61.119 public:
61.120 - typedef typename Graph::template ArcMap<_Value> Parent;
61.121 - typedef typename Graph::template ArcMap<_Value> Type;
61.122 + typedef typename GR::template ArcMap<V> Type;
61.123 typedef typename Parent::Value Value;
61.124
61.125 - Map(const Graph& _digraph) : Parent(_digraph) {}
61.126 - Map(const Graph& _digraph, const Value& _value)
61.127 + Map(const GR& _digraph) : Parent(_digraph) {}
61.128 + Map(const GR& _digraph, const Value& _value)
61.129 : Parent(_digraph, _value) {}
61.130 };
61.131
61.132 };
61.133
61.134 - template <typename Graph, typename Enable = void>
61.135 + template <typename GR, typename Enable = void>
61.136 struct EdgeNotifierIndicator {
61.137 typedef InvalidType Type;
61.138 };
61.139 - template <typename Graph>
61.140 + template <typename GR>
61.141 struct EdgeNotifierIndicator<
61.142 - Graph,
61.143 - typename enable_if<typename Graph::EdgeNotifier::Notifier, void>::type
61.144 + GR,
61.145 + typename enable_if<typename GR::EdgeNotifier::Notifier, void>::type
61.146 > {
61.147 - typedef typename Graph::EdgeNotifier Type;
61.148 + typedef typename GR::EdgeNotifier Type;
61.149 };
61.150
61.151 - template <typename _Graph>
61.152 - class ItemSetTraits<_Graph, typename _Graph::Edge> {
61.153 + template <typename GR>
61.154 + class ItemSetTraits<GR, typename GR::Edge> {
61.155 public:
61.156
61.157 - typedef _Graph Graph;
61.158 + typedef GR Graph;
61.159 + typedef GR Digraph;
61.160
61.161 - typedef typename Graph::Edge Item;
61.162 - typedef typename Graph::EdgeIt ItemIt;
61.163 + typedef typename GR::Edge Item;
61.164 + typedef typename GR::EdgeIt ItemIt;
61.165
61.166 - typedef typename EdgeNotifierIndicator<Graph>::Type ItemNotifier;
61.167 + typedef typename EdgeNotifierIndicator<GR>::Type ItemNotifier;
61.168
61.169 - template <typename _Value>
61.170 - class Map : public Graph::template EdgeMap<_Value> {
61.171 + template <typename V>
61.172 + class Map : public GR::template EdgeMap<V> {
61.173 + typedef typename GR::template EdgeMap<V> Parent;
61.174 +
61.175 public:
61.176 - typedef typename Graph::template EdgeMap<_Value> Parent;
61.177 - typedef typename Graph::template EdgeMap<_Value> Type;
61.178 + typedef typename GR::template EdgeMap<V> Type;
61.179 typedef typename Parent::Value Value;
61.180
61.181 - Map(const Graph& _digraph) : Parent(_digraph) {}
61.182 - Map(const Graph& _digraph, const Value& _value)
61.183 + Map(const GR& _digraph) : Parent(_digraph) {}
61.184 + Map(const GR& _digraph, const Value& _value)
61.185 : Parent(_digraph, _value) {}
61.186 };
61.187
61.188 @@ -204,67 +210,93 @@
61.189
61.190 // Indicators for the tags
61.191
61.192 - template <typename Graph, typename Enable = void>
61.193 + template <typename GR, typename Enable = void>
61.194 struct NodeNumTagIndicator {
61.195 static const bool value = false;
61.196 };
61.197
61.198 - template <typename Graph>
61.199 + template <typename GR>
61.200 struct NodeNumTagIndicator<
61.201 - Graph,
61.202 - typename enable_if<typename Graph::NodeNumTag, void>::type
61.203 + GR,
61.204 + typename enable_if<typename GR::NodeNumTag, void>::type
61.205 > {
61.206 static const bool value = true;
61.207 };
61.208
61.209 - template <typename Graph, typename Enable = void>
61.210 + template <typename GR, typename Enable = void>
61.211 + struct ArcNumTagIndicator {
61.212 + static const bool value = false;
61.213 + };
61.214 +
61.215 + template <typename GR>
61.216 + struct ArcNumTagIndicator<
61.217 + GR,
61.218 + typename enable_if<typename GR::ArcNumTag, void>::type
61.219 + > {
61.220 + static const bool value = true;
61.221 + };
61.222 +
61.223 + template <typename GR, typename Enable = void>
61.224 struct EdgeNumTagIndicator {
61.225 static const bool value = false;
61.226 };
61.227
61.228 - template <typename Graph>
61.229 + template <typename GR>
61.230 struct EdgeNumTagIndicator<
61.231 - Graph,
61.232 - typename enable_if<typename Graph::EdgeNumTag, void>::type
61.233 + GR,
61.234 + typename enable_if<typename GR::EdgeNumTag, void>::type
61.235 > {
61.236 static const bool value = true;
61.237 };
61.238
61.239 - template <typename Graph, typename Enable = void>
61.240 + template <typename GR, typename Enable = void>
61.241 + struct FindArcTagIndicator {
61.242 + static const bool value = false;
61.243 + };
61.244 +
61.245 + template <typename GR>
61.246 + struct FindArcTagIndicator<
61.247 + GR,
61.248 + typename enable_if<typename GR::FindArcTag, void>::type
61.249 + > {
61.250 + static const bool value = true;
61.251 + };
61.252 +
61.253 + template <typename GR, typename Enable = void>
61.254 struct FindEdgeTagIndicator {
61.255 static const bool value = false;
61.256 };
61.257
61.258 - template <typename Graph>
61.259 + template <typename GR>
61.260 struct FindEdgeTagIndicator<
61.261 - Graph,
61.262 - typename enable_if<typename Graph::FindEdgeTag, void>::type
61.263 + GR,
61.264 + typename enable_if<typename GR::FindEdgeTag, void>::type
61.265 > {
61.266 static const bool value = true;
61.267 };
61.268
61.269 - template <typename Graph, typename Enable = void>
61.270 + template <typename GR, typename Enable = void>
61.271 struct UndirectedTagIndicator {
61.272 static const bool value = false;
61.273 };
61.274
61.275 - template <typename Graph>
61.276 + template <typename GR>
61.277 struct UndirectedTagIndicator<
61.278 - Graph,
61.279 - typename enable_if<typename Graph::UndirectedTag, void>::type
61.280 + GR,
61.281 + typename enable_if<typename GR::UndirectedTag, void>::type
61.282 > {
61.283 static const bool value = true;
61.284 };
61.285
61.286 - template <typename Graph, typename Enable = void>
61.287 + template <typename GR, typename Enable = void>
61.288 struct BuildTagIndicator {
61.289 static const bool value = false;
61.290 };
61.291
61.292 - template <typename Graph>
61.293 + template <typename GR>
61.294 struct BuildTagIndicator<
61.295 - Graph,
61.296 - typename enable_if<typename Graph::BuildTag, void>::type
61.297 + GR,
61.298 + typename enable_if<typename GR::BuildTag, void>::type
61.299 > {
61.300 static const bool value = true;
61.301 };
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
62.2 +++ b/lemon/bits/variant.h Thu Dec 10 17:05:35 2009 +0100
62.3 @@ -0,0 +1,494 @@
62.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
62.5 + *
62.6 + * This file is a part of LEMON, a generic C++ optimization library.
62.7 + *
62.8 + * Copyright (C) 2003-2009
62.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
62.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
62.11 + *
62.12 + * Permission to use, modify and distribute this software is granted
62.13 + * provided that this copyright notice appears in all copies. For
62.14 + * precise terms see the accompanying LICENSE file.
62.15 + *
62.16 + * This software is provided "AS IS" with no warranty of any kind,
62.17 + * express or implied, and with no claim as to its suitability for any
62.18 + * purpose.
62.19 + *
62.20 + */
62.21 +
62.22 +#ifndef LEMON_BITS_VARIANT_H
62.23 +#define LEMON_BITS_VARIANT_H
62.24 +
62.25 +#include <lemon/assert.h>
62.26 +
62.27 +// \file
62.28 +// \brief Variant types
62.29 +
62.30 +namespace lemon {
62.31 +
62.32 + namespace _variant_bits {
62.33 +
62.34 + template <int left, int right>
62.35 + struct CTMax {
62.36 + static const int value = left < right ? right : left;
62.37 + };
62.38 +
62.39 + }
62.40 +
62.41 +
62.42 + // \brief Simple Variant type for two types
62.43 + //
62.44 + // Simple Variant type for two types. The Variant type is a type-safe
62.45 + // union. C++ has strong limitations for using unions, for
62.46 + // example you cannot store a type with non-default constructor or
62.47 + // destructor in a union. This class always knowns the current
62.48 + // state of the variant and it cares for the proper construction
62.49 + // and destruction.
62.50 + template <typename _First, typename _Second>
62.51 + class BiVariant {
62.52 + public:
62.53 +
62.54 + // \brief The \c First type.
62.55 + typedef _First First;
62.56 + // \brief The \c Second type.
62.57 + typedef _Second Second;
62.58 +
62.59 + // \brief Constructor
62.60 + //
62.61 + // This constructor initalizes to the default value of the \c First
62.62 + // type.
62.63 + BiVariant() {
62.64 + flag = true;
62.65 + new(reinterpret_cast<First*>(data)) First();
62.66 + }
62.67 +
62.68 + // \brief Constructor
62.69 + //
62.70 + // This constructor initalizes to the given value of the \c First
62.71 + // type.
62.72 + BiVariant(const First& f) {
62.73 + flag = true;
62.74 + new(reinterpret_cast<First*>(data)) First(f);
62.75 + }
62.76 +
62.77 + // \brief Constructor
62.78 + //
62.79 + // This constructor initalizes to the given value of the \c
62.80 + // Second type.
62.81 + BiVariant(const Second& s) {
62.82 + flag = false;
62.83 + new(reinterpret_cast<Second*>(data)) Second(s);
62.84 + }
62.85 +
62.86 + // \brief Copy constructor
62.87 + //
62.88 + // Copy constructor
62.89 + BiVariant(const BiVariant& bivariant) {
62.90 + flag = bivariant.flag;
62.91 + if (flag) {
62.92 + new(reinterpret_cast<First*>(data)) First(bivariant.first());
62.93 + } else {
62.94 + new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
62.95 + }
62.96 + }
62.97 +
62.98 + // \brief Destrcutor
62.99 + //
62.100 + // Destructor
62.101 + ~BiVariant() {
62.102 + destroy();
62.103 + }
62.104 +
62.105 + // \brief Set to the default value of the \c First type.
62.106 + //
62.107 + // This function sets the variant to the default value of the \c
62.108 + // First type.
62.109 + BiVariant& setFirst() {
62.110 + destroy();
62.111 + flag = true;
62.112 + new(reinterpret_cast<First*>(data)) First();
62.113 + return *this;
62.114 + }
62.115 +
62.116 + // \brief Set to the given value of the \c First type.
62.117 + //
62.118 + // This function sets the variant to the given value of the \c
62.119 + // First type.
62.120 + BiVariant& setFirst(const First& f) {
62.121 + destroy();
62.122 + flag = true;
62.123 + new(reinterpret_cast<First*>(data)) First(f);
62.124 + return *this;
62.125 + }
62.126 +
62.127 + // \brief Set to the default value of the \c Second type.
62.128 + //
62.129 + // This function sets the variant to the default value of the \c
62.130 + // Second type.
62.131 + BiVariant& setSecond() {
62.132 + destroy();
62.133 + flag = false;
62.134 + new(reinterpret_cast<Second*>(data)) Second();
62.135 + return *this;
62.136 + }
62.137 +
62.138 + // \brief Set to the given value of the \c Second type.
62.139 + //
62.140 + // This function sets the variant to the given value of the \c
62.141 + // Second type.
62.142 + BiVariant& setSecond(const Second& s) {
62.143 + destroy();
62.144 + flag = false;
62.145 + new(reinterpret_cast<Second*>(data)) Second(s);
62.146 + return *this;
62.147 + }
62.148 +
62.149 + // \brief Operator form of the \c setFirst()
62.150 + BiVariant& operator=(const First& f) {
62.151 + return setFirst(f);
62.152 + }
62.153 +
62.154 + // \brief Operator form of the \c setSecond()
62.155 + BiVariant& operator=(const Second& s) {
62.156 + return setSecond(s);
62.157 + }
62.158 +
62.159 + // \brief Assign operator
62.160 + BiVariant& operator=(const BiVariant& bivariant) {
62.161 + if (this == &bivariant) return *this;
62.162 + destroy();
62.163 + flag = bivariant.flag;
62.164 + if (flag) {
62.165 + new(reinterpret_cast<First*>(data)) First(bivariant.first());
62.166 + } else {
62.167 + new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
62.168 + }
62.169 + return *this;
62.170 + }
62.171 +
62.172 + // \brief Reference to the value
62.173 + //
62.174 + // Reference to the value of the \c First type.
62.175 + // \pre The BiVariant should store value of \c First type.
62.176 + First& first() {
62.177 + LEMON_DEBUG(flag, "Variant wrong state");
62.178 + return *reinterpret_cast<First*>(data);
62.179 + }
62.180 +
62.181 + // \brief Const reference to the value
62.182 + //
62.183 + // Const reference to the value of the \c First type.
62.184 + // \pre The BiVariant should store value of \c First type.
62.185 + const First& first() const {
62.186 + LEMON_DEBUG(flag, "Variant wrong state");
62.187 + return *reinterpret_cast<const First*>(data);
62.188 + }
62.189 +
62.190 + // \brief Operator form of the \c first()
62.191 + operator First&() { return first(); }
62.192 + // \brief Operator form of the const \c first()
62.193 + operator const First&() const { return first(); }
62.194 +
62.195 + // \brief Reference to the value
62.196 + //
62.197 + // Reference to the value of the \c Second type.
62.198 + // \pre The BiVariant should store value of \c Second type.
62.199 + Second& second() {
62.200 + LEMON_DEBUG(!flag, "Variant wrong state");
62.201 + return *reinterpret_cast<Second*>(data);
62.202 + }
62.203 +
62.204 + // \brief Const reference to the value
62.205 + //
62.206 + // Const reference to the value of the \c Second type.
62.207 + // \pre The BiVariant should store value of \c Second type.
62.208 + const Second& second() const {
62.209 + LEMON_DEBUG(!flag, "Variant wrong state");
62.210 + return *reinterpret_cast<const Second*>(data);
62.211 + }
62.212 +
62.213 + // \brief Operator form of the \c second()
62.214 + operator Second&() { return second(); }
62.215 + // \brief Operator form of the const \c second()
62.216 + operator const Second&() const { return second(); }
62.217 +
62.218 + // \brief %True when the variant is in the first state
62.219 + //
62.220 + // %True when the variant stores value of the \c First type.
62.221 + bool firstState() const { return flag; }
62.222 +
62.223 + // \brief %True when the variant is in the second state
62.224 + //
62.225 + // %True when the variant stores value of the \c Second type.
62.226 + bool secondState() const { return !flag; }
62.227 +
62.228 + private:
62.229 +
62.230 + void destroy() {
62.231 + if (flag) {
62.232 + reinterpret_cast<First*>(data)->~First();
62.233 + } else {
62.234 + reinterpret_cast<Second*>(data)->~Second();
62.235 + }
62.236 + }
62.237 +
62.238 + char data[_variant_bits::CTMax<sizeof(First), sizeof(Second)>::value];
62.239 + bool flag;
62.240 + };
62.241 +
62.242 + namespace _variant_bits {
62.243 +
62.244 + template <int _idx, typename _TypeMap>
62.245 + struct Memory {
62.246 +
62.247 + typedef typename _TypeMap::template Map<_idx>::Type Current;
62.248 +
62.249 + static void destroy(int index, char* place) {
62.250 + if (index == _idx) {
62.251 + reinterpret_cast<Current*>(place)->~Current();
62.252 + } else {
62.253 + Memory<_idx - 1, _TypeMap>::destroy(index, place);
62.254 + }
62.255 + }
62.256 +
62.257 + static void copy(int index, char* to, const char* from) {
62.258 + if (index == _idx) {
62.259 + new (reinterpret_cast<Current*>(to))
62.260 + Current(reinterpret_cast<const Current*>(from));
62.261 + } else {
62.262 + Memory<_idx - 1, _TypeMap>::copy(index, to, from);
62.263 + }
62.264 + }
62.265 +
62.266 + };
62.267 +
62.268 + template <typename _TypeMap>
62.269 + struct Memory<-1, _TypeMap> {
62.270 +
62.271 + static void destroy(int, char*) {
62.272 + LEMON_DEBUG(false, "Variant wrong index.");
62.273 + }
62.274 +
62.275 + static void copy(int, char*, const char*) {
62.276 + LEMON_DEBUG(false, "Variant wrong index.");
62.277 + }
62.278 + };
62.279 +
62.280 + template <int _idx, typename _TypeMap>
62.281 + struct Size {
62.282 + static const int value =
62.283 + CTMax<sizeof(typename _TypeMap::template Map<_idx>::Type),
62.284 + Size<_idx - 1, _TypeMap>::value>::value;
62.285 + };
62.286 +
62.287 + template <typename _TypeMap>
62.288 + struct Size<0, _TypeMap> {
62.289 + static const int value =
62.290 + sizeof(typename _TypeMap::template Map<0>::Type);
62.291 + };
62.292 +
62.293 + }
62.294 +
62.295 + // \brief Variant type
62.296 + //
62.297 + // Simple Variant type. The Variant type is a type-safe union.
62.298 + // C++ has strong limitations for using unions, for example you
62.299 + // cannot store type with non-default constructor or destructor in
62.300 + // a union. This class always knowns the current state of the
62.301 + // variant and it cares for the proper construction and
62.302 + // destruction.
62.303 + //
62.304 + // \param _num The number of the types which can be stored in the
62.305 + // variant type.
62.306 + // \param _TypeMap This class describes the types of the Variant. The
62.307 + // _TypeMap::Map<index>::Type should be a valid type for each index
62.308 + // in the range {0, 1, ..., _num - 1}. The \c VariantTypeMap is helper
62.309 + // class to define such type mappings up to 10 types.
62.310 + //
62.311 + // And the usage of the class:
62.312 + //\code
62.313 + // typedef Variant<3, VariantTypeMap<int, std::string, double> > MyVariant;
62.314 + // MyVariant var;
62.315 + // var.set<0>(12);
62.316 + // std::cout << var.get<0>() << std::endl;
62.317 + // var.set<1>("alpha");
62.318 + // std::cout << var.get<1>() << std::endl;
62.319 + // var.set<2>(0.75);
62.320 + // std::cout << var.get<2>() << std::endl;
62.321 + //\endcode
62.322 + //
62.323 + // The result of course:
62.324 + //\code
62.325 + // 12
62.326 + // alpha
62.327 + // 0.75
62.328 + //\endcode
62.329 + template <int _num, typename _TypeMap>
62.330 + class Variant {
62.331 + public:
62.332 +
62.333 + static const int num = _num;
62.334 +
62.335 + typedef _TypeMap TypeMap;
62.336 +
62.337 + // \brief Constructor
62.338 + //
62.339 + // This constructor initalizes to the default value of the \c type
62.340 + // with 0 index.
62.341 + Variant() {
62.342 + flag = 0;
62.343 + new(reinterpret_cast<typename TypeMap::template Map<0>::Type*>(data))
62.344 + typename TypeMap::template Map<0>::Type();
62.345 + }
62.346 +
62.347 +
62.348 + // \brief Copy constructor
62.349 + //
62.350 + // Copy constructor
62.351 + Variant(const Variant& variant) {
62.352 + flag = variant.flag;
62.353 + _variant_bits::Memory<num - 1, TypeMap>::copy(flag, data, variant.data);
62.354 + }
62.355 +
62.356 + // \brief Assign operator
62.357 + //
62.358 + // Assign operator
62.359 + Variant& operator=(const Variant& variant) {
62.360 + if (this == &variant) return *this;
62.361 + _variant_bits::Memory<num - 1, TypeMap>::
62.362 + destroy(flag, data);
62.363 + flag = variant.flag;
62.364 + _variant_bits::Memory<num - 1, TypeMap>::
62.365 + copy(flag, data, variant.data);
62.366 + return *this;
62.367 + }
62.368 +
62.369 + // \brief Destrcutor
62.370 + //
62.371 + // Destructor
62.372 + ~Variant() {
62.373 + _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
62.374 + }
62.375 +
62.376 + // \brief Set to the default value of the type with \c _idx index.
62.377 + //
62.378 + // This function sets the variant to the default value of the
62.379 + // type with \c _idx index.
62.380 + template <int _idx>
62.381 + Variant& set() {
62.382 + _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
62.383 + flag = _idx;
62.384 + new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
62.385 + typename TypeMap::template Map<_idx>::Type();
62.386 + return *this;
62.387 + }
62.388 +
62.389 + // \brief Set to the given value of the type with \c _idx index.
62.390 + //
62.391 + // This function sets the variant to the given value of the type
62.392 + // with \c _idx index.
62.393 + template <int _idx>
62.394 + Variant& set(const typename _TypeMap::template Map<_idx>::Type& init) {
62.395 + _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
62.396 + flag = _idx;
62.397 + new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
62.398 + typename TypeMap::template Map<_idx>::Type(init);
62.399 + return *this;
62.400 + }
62.401 +
62.402 + // \brief Gets the current value of the type with \c _idx index.
62.403 + //
62.404 + // Gets the current value of the type with \c _idx index.
62.405 + template <int _idx>
62.406 + const typename TypeMap::template Map<_idx>::Type& get() const {
62.407 + LEMON_DEBUG(_idx == flag, "Variant wrong index");
62.408 + return *reinterpret_cast<const typename TypeMap::
62.409 + template Map<_idx>::Type*>(data);
62.410 + }
62.411 +
62.412 + // \brief Gets the current value of the type with \c _idx index.
62.413 + //
62.414 + // Gets the current value of the type with \c _idx index.
62.415 + template <int _idx>
62.416 + typename _TypeMap::template Map<_idx>::Type& get() {
62.417 + LEMON_DEBUG(_idx == flag, "Variant wrong index");
62.418 + return *reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>
62.419 + (data);
62.420 + }
62.421 +
62.422 + // \brief Returns the current state of the variant.
62.423 + //
62.424 + // Returns the current state of the variant.
62.425 + int state() const {
62.426 + return flag;
62.427 + }
62.428 +
62.429 + private:
62.430 +
62.431 + char data[_variant_bits::Size<num - 1, TypeMap>::value];
62.432 + int flag;
62.433 + };
62.434 +
62.435 + namespace _variant_bits {
62.436 +
62.437 + template <int _index, typename _List>
62.438 + struct Get {
62.439 + typedef typename Get<_index - 1, typename _List::Next>::Type Type;
62.440 + };
62.441 +
62.442 + template <typename _List>
62.443 + struct Get<0, _List> {
62.444 + typedef typename _List::Type Type;
62.445 + };
62.446 +
62.447 + struct List {};
62.448 +
62.449 + template <typename _Type, typename _List>
62.450 + struct Insert {
62.451 + typedef _List Next;
62.452 + typedef _Type Type;
62.453 + };
62.454 +
62.455 + template <int _idx, typename _T0, typename _T1, typename _T2,
62.456 + typename _T3, typename _T4, typename _T5, typename _T6,
62.457 + typename _T7, typename _T8, typename _T9>
62.458 + struct Mapper {
62.459 + typedef List L10;
62.460 + typedef Insert<_T9, L10> L9;
62.461 + typedef Insert<_T8, L9> L8;
62.462 + typedef Insert<_T7, L8> L7;
62.463 + typedef Insert<_T6, L7> L6;
62.464 + typedef Insert<_T5, L6> L5;
62.465 + typedef Insert<_T4, L5> L4;
62.466 + typedef Insert<_T3, L4> L3;
62.467 + typedef Insert<_T2, L3> L2;
62.468 + typedef Insert<_T1, L2> L1;
62.469 + typedef Insert<_T0, L1> L0;
62.470 + typedef typename Get<_idx, L0>::Type Type;
62.471 + };
62.472 +
62.473 + }
62.474 +
62.475 + // \brief Helper class for Variant
62.476 + //
62.477 + // Helper class to define type mappings for Variant. This class
62.478 + // converts the template parameters to be mappable by integer.
62.479 + // \see Variant
62.480 + template <
62.481 + typename _T0,
62.482 + typename _T1 = void, typename _T2 = void, typename _T3 = void,
62.483 + typename _T4 = void, typename _T5 = void, typename _T6 = void,
62.484 + typename _T7 = void, typename _T8 = void, typename _T9 = void>
62.485 + struct VariantTypeMap {
62.486 + template <int _idx>
62.487 + struct Map {
62.488 + typedef typename _variant_bits::
62.489 + Mapper<_idx, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>::Type
62.490 + Type;
62.491 + };
62.492 + };
62.493 +
62.494 +}
62.495 +
62.496 +
62.497 +#endif
63.1 --- a/lemon/bits/vector_map.h Fri Nov 13 12:33:33 2009 +0100
63.2 +++ b/lemon/bits/vector_map.h Thu Dec 10 17:05:35 2009 +0100
63.3 @@ -2,7 +2,7 @@
63.4 *
63.5 * This file is a part of LEMON, a generic C++ optimization library.
63.6 *
63.7 - * Copyright (C) 2003-2008
63.8 + * Copyright (C) 2003-2009
63.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
63.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
63.11 *
63.12 @@ -38,9 +38,9 @@
63.13 //
63.14 // \brief Graph map based on the std::vector storage.
63.15 //
63.16 - // The VectorMap template class is graph map structure what
63.17 - // automatically updates the map when a key is added to or erased from
63.18 - // the map. This map type uses the std::vector to store the values.
63.19 + // The VectorMap template class is graph map structure that automatically
63.20 + // updates the map when a key is added to or erased from the graph.
63.21 + // This map type uses std::vector to store the values.
63.22 //
63.23 // \tparam _Graph The graph this map is attached to.
63.24 // \tparam _Item The item type of the graph items.
63.25 @@ -56,7 +56,7 @@
63.26 public:
63.27
63.28 // The graph type of the map.
63.29 - typedef _Graph Graph;
63.30 + typedef _Graph GraphType;
63.31 // The item type of the map.
63.32 typedef _Item Item;
63.33 // The reference map tag.
63.34 @@ -72,20 +72,24 @@
63.35
63.36 // The map type.
63.37 typedef VectorMap Map;
63.38 - // The base class of the map.
63.39 - typedef typename Notifier::ObserverBase Parent;
63.40
63.41 // The reference type of the map;
63.42 typedef typename Container::reference Reference;
63.43 // The const reference type of the map;
63.44 typedef typename Container::const_reference ConstReference;
63.45
63.46 + private:
63.47 +
63.48 + // The base class of the map.
63.49 + typedef typename Notifier::ObserverBase Parent;
63.50 +
63.51 + public:
63.52
63.53 // \brief Constructor to attach the new map into the notifier.
63.54 //
63.55 // It constructs a map and attachs it into the notifier.
63.56 // It adds all the items of the graph to the map.
63.57 - VectorMap(const Graph& graph) {
63.58 + VectorMap(const GraphType& graph) {
63.59 Parent::attach(graph.notifier(Item()));
63.60 container.resize(Parent::notifier()->maxId() + 1);
63.61 }
63.62 @@ -94,7 +98,7 @@
63.63 //
63.64 // It constructs a map uses a given value to initialize the map.
63.65 // It adds all the items of the graph to the map.
63.66 - VectorMap(const Graph& graph, const Value& value) {
63.67 + VectorMap(const GraphType& graph, const Value& value) {
63.68 Parent::attach(graph.notifier(Item()));
63.69 container.resize(Parent::notifier()->maxId() + 1, value);
63.70 }
63.71 @@ -124,7 +128,7 @@
63.72
63.73 // \brief Template assign operator.
63.74 //
63.75 - // The given parameter should be conform to the ReadMap
63.76 + // The given parameter should conform to the ReadMap
63.77 // concecpt and could be indiced by the current item set of
63.78 // the NodeMap. In this case the value for each item
63.79 // is assigned by the value of the given ReadMap.
63.80 @@ -169,7 +173,7 @@
63.81
63.82 // \brief Adds a new key to the map.
63.83 //
63.84 - // It adds a new key to the map. It called by the observer notifier
63.85 + // It adds a new key to the map. It is called by the observer notifier
63.86 // and it overrides the add() member function of the observer base.
63.87 virtual void add(const Key& key) {
63.88 int id = Parent::notifier()->id(key);
63.89 @@ -180,7 +184,7 @@
63.90
63.91 // \brief Adds more new keys to the map.
63.92 //
63.93 - // It adds more new keys to the map. It called by the observer notifier
63.94 + // It adds more new keys to the map. It is called by the observer notifier
63.95 // and it overrides the add() member function of the observer base.
63.96 virtual void add(const std::vector<Key>& keys) {
63.97 int max = container.size() - 1;
63.98 @@ -195,7 +199,7 @@
63.99
63.100 // \brief Erase a key from the map.
63.101 //
63.102 - // Erase a key from the map. It called by the observer notifier
63.103 + // Erase a key from the map. It is called by the observer notifier
63.104 // and it overrides the erase() member function of the observer base.
63.105 virtual void erase(const Key& key) {
63.106 container[Parent::notifier()->id(key)] = Value();
63.107 @@ -203,7 +207,7 @@
63.108
63.109 // \brief Erase more keys from the map.
63.110 //
63.111 - // Erase more keys from the map. It called by the observer notifier
63.112 + // It erases more keys from the map. It is called by the observer notifier
63.113 // and it overrides the erase() member function of the observer base.
63.114 virtual void erase(const std::vector<Key>& keys) {
63.115 for (int i = 0; i < int(keys.size()); ++i) {
63.116 @@ -211,9 +215,9 @@
63.117 }
63.118 }
63.119
63.120 - // \brief Buildes the map.
63.121 + // \brief Build the map.
63.122 //
63.123 - // It buildes the map. It called by the observer notifier
63.124 + // It builds the map. It is called by the observer notifier
63.125 // and it overrides the build() member function of the observer base.
63.126 virtual void build() {
63.127 int size = Parent::notifier()->maxId() + 1;
63.128 @@ -223,7 +227,7 @@
63.129
63.130 // \brief Clear the map.
63.131 //
63.132 - // It erase all items from the map. It called by the observer notifier
63.133 + // It erases all items from the map. It is called by the observer notifier
63.134 // and it overrides the clear() member function of the observer base.
63.135 virtual void clear() {
63.136 container.clear();
64.1 --- a/lemon/bits/windows.h Fri Nov 13 12:33:33 2009 +0100
64.2 +++ b/lemon/bits/windows.h Thu Dec 10 17:05:35 2009 +0100
64.3 @@ -16,8 +16,8 @@
64.4 *
64.5 */
64.6
64.7 -#ifndef LEMON_WINDOWS_H
64.8 -#define LEMON_WINDOWS_H
64.9 +#ifndef LEMON_BITS_WINDOWS_H
64.10 +#define LEMON_BITS_WINDOWS_H
64.11
64.12 #include <string>
64.13
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
65.2 +++ b/lemon/bucket_heap.h Thu Dec 10 17:05:35 2009 +0100
65.3 @@ -0,0 +1,567 @@
65.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
65.5 + *
65.6 + * This file is a part of LEMON, a generic C++ optimization library.
65.7 + *
65.8 + * Copyright (C) 2003-2009
65.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
65.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
65.11 + *
65.12 + * Permission to use, modify and distribute this software is granted
65.13 + * provided that this copyright notice appears in all copies. For
65.14 + * precise terms see the accompanying LICENSE file.
65.15 + *
65.16 + * This software is provided "AS IS" with no warranty of any kind,
65.17 + * express or implied, and with no claim as to its suitability for any
65.18 + * purpose.
65.19 + *
65.20 + */
65.21 +
65.22 +#ifndef LEMON_BUCKET_HEAP_H
65.23 +#define LEMON_BUCKET_HEAP_H
65.24 +
65.25 +///\ingroup auxdat
65.26 +///\file
65.27 +///\brief Bucket Heap implementation.
65.28 +
65.29 +#include <vector>
65.30 +#include <utility>
65.31 +#include <functional>
65.32 +
65.33 +namespace lemon {
65.34 +
65.35 + namespace _bucket_heap_bits {
65.36 +
65.37 + template <bool MIN>
65.38 + struct DirectionTraits {
65.39 + static bool less(int left, int right) {
65.40 + return left < right;
65.41 + }
65.42 + static void increase(int& value) {
65.43 + ++value;
65.44 + }
65.45 + };
65.46 +
65.47 + template <>
65.48 + struct DirectionTraits<false> {
65.49 + static bool less(int left, int right) {
65.50 + return left > right;
65.51 + }
65.52 + static void increase(int& value) {
65.53 + --value;
65.54 + }
65.55 + };
65.56 +
65.57 + }
65.58 +
65.59 + /// \ingroup auxdat
65.60 + ///
65.61 + /// \brief A Bucket Heap implementation.
65.62 + ///
65.63 + /// This class implements the \e bucket \e heap data structure. A \e heap
65.64 + /// is a data structure for storing items with specified values called \e
65.65 + /// priorities in such a way that finding the item with minimum priority is
65.66 + /// efficient. The bucket heap is very simple implementation, it can store
65.67 + /// only integer priorities and it stores for each priority in the
65.68 + /// \f$ [0..C) \f$ range a list of items. So it should be used only when
65.69 + /// the priorities are small. It is not intended to use as dijkstra heap.
65.70 + ///
65.71 + /// \param IM A read and write Item int map, used internally
65.72 + /// to handle the cross references.
65.73 + /// \param MIN If the given parameter is false then instead of the
65.74 + /// minimum value the maximum can be retrivied with the top() and
65.75 + /// prio() member functions.
65.76 + template <typename IM, bool MIN = true>
65.77 + class BucketHeap {
65.78 +
65.79 + public:
65.80 + /// \e
65.81 + typedef typename IM::Key Item;
65.82 + /// \e
65.83 + typedef int Prio;
65.84 + /// \e
65.85 + typedef std::pair<Item, Prio> Pair;
65.86 + /// \e
65.87 + typedef IM ItemIntMap;
65.88 +
65.89 + private:
65.90 +
65.91 + typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
65.92 +
65.93 + public:
65.94 +
65.95 + /// \brief Type to represent the items states.
65.96 + ///
65.97 + /// Each Item element have a state associated to it. It may be "in heap",
65.98 + /// "pre heap" or "post heap". The latter two are indifferent from the
65.99 + /// heap's point of view, but may be useful to the user.
65.100 + ///
65.101 + /// The item-int map must be initialized in such way that it assigns
65.102 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
65.103 + enum State {
65.104 + IN_HEAP = 0, ///< = 0.
65.105 + PRE_HEAP = -1, ///< = -1.
65.106 + POST_HEAP = -2 ///< = -2.
65.107 + };
65.108 +
65.109 + public:
65.110 + /// \brief The constructor.
65.111 + ///
65.112 + /// The constructor.
65.113 + /// \param map should be given to the constructor, since it is used
65.114 + /// internally to handle the cross references. The value of the map
65.115 + /// should be PRE_HEAP (-1) for each element.
65.116 + explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
65.117 +
65.118 + /// The number of items stored in the heap.
65.119 + ///
65.120 + /// \brief Returns the number of items stored in the heap.
65.121 + int size() const { return _data.size(); }
65.122 +
65.123 + /// \brief Checks if the heap stores no items.
65.124 + ///
65.125 + /// Returns \c true if and only if the heap stores no items.
65.126 + bool empty() const { return _data.empty(); }
65.127 +
65.128 + /// \brief Make empty this heap.
65.129 + ///
65.130 + /// Make empty this heap. It does not change the cross reference
65.131 + /// map. If you want to reuse a heap what is not surely empty you
65.132 + /// should first clear the heap and after that you should set the
65.133 + /// cross reference map for each item to \c PRE_HEAP.
65.134 + void clear() {
65.135 + _data.clear(); _first.clear(); _minimum = 0;
65.136 + }
65.137 +
65.138 + private:
65.139 +
65.140 + void relocate_last(int idx) {
65.141 + if (idx + 1 < int(_data.size())) {
65.142 + _data[idx] = _data.back();
65.143 + if (_data[idx].prev != -1) {
65.144 + _data[_data[idx].prev].next = idx;
65.145 + } else {
65.146 + _first[_data[idx].value] = idx;
65.147 + }
65.148 + if (_data[idx].next != -1) {
65.149 + _data[_data[idx].next].prev = idx;
65.150 + }
65.151 + _iim[_data[idx].item] = idx;
65.152 + }
65.153 + _data.pop_back();
65.154 + }
65.155 +
65.156 + void unlace(int idx) {
65.157 + if (_data[idx].prev != -1) {
65.158 + _data[_data[idx].prev].next = _data[idx].next;
65.159 + } else {
65.160 + _first[_data[idx].value] = _data[idx].next;
65.161 + }
65.162 + if (_data[idx].next != -1) {
65.163 + _data[_data[idx].next].prev = _data[idx].prev;
65.164 + }
65.165 + }
65.166 +
65.167 + void lace(int idx) {
65.168 + if (int(_first.size()) <= _data[idx].value) {
65.169 + _first.resize(_data[idx].value + 1, -1);
65.170 + }
65.171 + _data[idx].next = _first[_data[idx].value];
65.172 + if (_data[idx].next != -1) {
65.173 + _data[_data[idx].next].prev = idx;
65.174 + }
65.175 + _first[_data[idx].value] = idx;
65.176 + _data[idx].prev = -1;
65.177 + }
65.178 +
65.179 + public:
65.180 + /// \brief Insert a pair of item and priority into the heap.
65.181 + ///
65.182 + /// Adds \c p.first to the heap with priority \c p.second.
65.183 + /// \param p The pair to insert.
65.184 + void push(const Pair& p) {
65.185 + push(p.first, p.second);
65.186 + }
65.187 +
65.188 + /// \brief Insert an item into the heap with the given priority.
65.189 + ///
65.190 + /// Adds \c i to the heap with priority \c p.
65.191 + /// \param i The item to insert.
65.192 + /// \param p The priority of the item.
65.193 + void push(const Item &i, const Prio &p) {
65.194 + int idx = _data.size();
65.195 + _iim[i] = idx;
65.196 + _data.push_back(BucketItem(i, p));
65.197 + lace(idx);
65.198 + if (Direction::less(p, _minimum)) {
65.199 + _minimum = p;
65.200 + }
65.201 + }
65.202 +
65.203 + /// \brief Returns the item with minimum priority.
65.204 + ///
65.205 + /// This method returns the item with minimum priority.
65.206 + /// \pre The heap must be nonempty.
65.207 + Item top() const {
65.208 + while (_first[_minimum] == -1) {
65.209 + Direction::increase(_minimum);
65.210 + }
65.211 + return _data[_first[_minimum]].item;
65.212 + }
65.213 +
65.214 + /// \brief Returns the minimum priority.
65.215 + ///
65.216 + /// It returns the minimum priority.
65.217 + /// \pre The heap must be nonempty.
65.218 + Prio prio() const {
65.219 + while (_first[_minimum] == -1) {
65.220 + Direction::increase(_minimum);
65.221 + }
65.222 + return _minimum;
65.223 + }
65.224 +
65.225 + /// \brief Deletes the item with minimum priority.
65.226 + ///
65.227 + /// This method deletes the item with minimum priority from the heap.
65.228 + /// \pre The heap must be non-empty.
65.229 + void pop() {
65.230 + while (_first[_minimum] == -1) {
65.231 + Direction::increase(_minimum);
65.232 + }
65.233 + int idx = _first[_minimum];
65.234 + _iim[_data[idx].item] = -2;
65.235 + unlace(idx);
65.236 + relocate_last(idx);
65.237 + }
65.238 +
65.239 + /// \brief Deletes \c i from the heap.
65.240 + ///
65.241 + /// This method deletes item \c i from the heap, if \c i was
65.242 + /// already stored in the heap.
65.243 + /// \param i The item to erase.
65.244 + void erase(const Item &i) {
65.245 + int idx = _iim[i];
65.246 + _iim[_data[idx].item] = -2;
65.247 + unlace(idx);
65.248 + relocate_last(idx);
65.249 + }
65.250 +
65.251 +
65.252 + /// \brief Returns the priority of \c i.
65.253 + ///
65.254 + /// This function returns the priority of item \c i.
65.255 + /// \pre \c i must be in the heap.
65.256 + /// \param i The item.
65.257 + Prio operator[](const Item &i) const {
65.258 + int idx = _iim[i];
65.259 + return _data[idx].value;
65.260 + }
65.261 +
65.262 + /// \brief \c i gets to the heap with priority \c p independently
65.263 + /// if \c i was already there.
65.264 + ///
65.265 + /// This method calls \ref push(\c i, \c p) if \c i is not stored
65.266 + /// in the heap and sets the priority of \c i to \c p otherwise.
65.267 + /// \param i The item.
65.268 + /// \param p The priority.
65.269 + void set(const Item &i, const Prio &p) {
65.270 + int idx = _iim[i];
65.271 + if (idx < 0) {
65.272 + push(i, p);
65.273 + } else if (Direction::less(p, _data[idx].value)) {
65.274 + decrease(i, p);
65.275 + } else {
65.276 + increase(i, p);
65.277 + }
65.278 + }
65.279 +
65.280 + /// \brief Decreases the priority of \c i to \c p.
65.281 + ///
65.282 + /// This method decreases the priority of item \c i to \c p.
65.283 + /// \pre \c i must be stored in the heap with priority at least \c
65.284 + /// p relative to \c Compare.
65.285 + /// \param i The item.
65.286 + /// \param p The priority.
65.287 + void decrease(const Item &i, const Prio &p) {
65.288 + int idx = _iim[i];
65.289 + unlace(idx);
65.290 + _data[idx].value = p;
65.291 + if (Direction::less(p, _minimum)) {
65.292 + _minimum = p;
65.293 + }
65.294 + lace(idx);
65.295 + }
65.296 +
65.297 + /// \brief Increases the priority of \c i to \c p.
65.298 + ///
65.299 + /// This method sets the priority of item \c i to \c p.
65.300 + /// \pre \c i must be stored in the heap with priority at most \c
65.301 + /// p relative to \c Compare.
65.302 + /// \param i The item.
65.303 + /// \param p The priority.
65.304 + void increase(const Item &i, const Prio &p) {
65.305 + int idx = _iim[i];
65.306 + unlace(idx);
65.307 + _data[idx].value = p;
65.308 + lace(idx);
65.309 + }
65.310 +
65.311 + /// \brief Returns if \c item is in, has already been in, or has
65.312 + /// never been in the heap.
65.313 + ///
65.314 + /// This method returns PRE_HEAP if \c item has never been in the
65.315 + /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
65.316 + /// otherwise. In the latter case it is possible that \c item will
65.317 + /// get back to the heap again.
65.318 + /// \param i The item.
65.319 + State state(const Item &i) const {
65.320 + int idx = _iim[i];
65.321 + if (idx >= 0) idx = 0;
65.322 + return State(idx);
65.323 + }
65.324 +
65.325 + /// \brief Sets the state of the \c item in the heap.
65.326 + ///
65.327 + /// Sets the state of the \c item in the heap. It can be used to
65.328 + /// manually clear the heap when it is important to achive the
65.329 + /// better time complexity.
65.330 + /// \param i The item.
65.331 + /// \param st The state. It should not be \c IN_HEAP.
65.332 + void state(const Item& i, State st) {
65.333 + switch (st) {
65.334 + case POST_HEAP:
65.335 + case PRE_HEAP:
65.336 + if (state(i) == IN_HEAP) {
65.337 + erase(i);
65.338 + }
65.339 + _iim[i] = st;
65.340 + break;
65.341 + case IN_HEAP:
65.342 + break;
65.343 + }
65.344 + }
65.345 +
65.346 + private:
65.347 +
65.348 + struct BucketItem {
65.349 + BucketItem(const Item& _item, int _value)
65.350 + : item(_item), value(_value) {}
65.351 +
65.352 + Item item;
65.353 + int value;
65.354 +
65.355 + int prev, next;
65.356 + };
65.357 +
65.358 + ItemIntMap& _iim;
65.359 + std::vector<int> _first;
65.360 + std::vector<BucketItem> _data;
65.361 + mutable int _minimum;
65.362 +
65.363 + }; // class BucketHeap
65.364 +
65.365 + /// \ingroup auxdat
65.366 + ///
65.367 + /// \brief A Simplified Bucket Heap implementation.
65.368 + ///
65.369 + /// This class implements a simplified \e bucket \e heap data
65.370 + /// structure. It does not provide some functionality but it faster
65.371 + /// and simplier data structure than the BucketHeap. The main
65.372 + /// difference is that the BucketHeap stores for every key a double
65.373 + /// linked list while this class stores just simple lists. In the
65.374 + /// other way it does not support erasing each elements just the
65.375 + /// minimal and it does not supports key increasing, decreasing.
65.376 + ///
65.377 + /// \param IM A read and write Item int map, used internally
65.378 + /// to handle the cross references.
65.379 + /// \param MIN If the given parameter is false then instead of the
65.380 + /// minimum value the maximum can be retrivied with the top() and
65.381 + /// prio() member functions.
65.382 + ///
65.383 + /// \sa BucketHeap
65.384 + template <typename IM, bool MIN = true >
65.385 + class SimpleBucketHeap {
65.386 +
65.387 + public:
65.388 + typedef typename IM::Key Item;
65.389 + typedef int Prio;
65.390 + typedef std::pair<Item, Prio> Pair;
65.391 + typedef IM ItemIntMap;
65.392 +
65.393 + private:
65.394 +
65.395 + typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
65.396 +
65.397 + public:
65.398 +
65.399 + /// \brief Type to represent the items states.
65.400 + ///
65.401 + /// Each Item element have a state associated to it. It may be "in heap",
65.402 + /// "pre heap" or "post heap". The latter two are indifferent from the
65.403 + /// heap's point of view, but may be useful to the user.
65.404 + ///
65.405 + /// The item-int map must be initialized in such way that it assigns
65.406 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
65.407 + enum State {
65.408 + IN_HEAP = 0, ///< = 0.
65.409 + PRE_HEAP = -1, ///< = -1.
65.410 + POST_HEAP = -2 ///< = -2.
65.411 + };
65.412 +
65.413 + public:
65.414 +
65.415 + /// \brief The constructor.
65.416 + ///
65.417 + /// The constructor.
65.418 + /// \param map should be given to the constructor, since it is used
65.419 + /// internally to handle the cross references. The value of the map
65.420 + /// should be PRE_HEAP (-1) for each element.
65.421 + explicit SimpleBucketHeap(ItemIntMap &map)
65.422 + : _iim(map), _free(-1), _num(0), _minimum(0) {}
65.423 +
65.424 + /// \brief Returns the number of items stored in the heap.
65.425 + ///
65.426 + /// The number of items stored in the heap.
65.427 + int size() const { return _num; }
65.428 +
65.429 + /// \brief Checks if the heap stores no items.
65.430 + ///
65.431 + /// Returns \c true if and only if the heap stores no items.
65.432 + bool empty() const { return _num == 0; }
65.433 +
65.434 + /// \brief Make empty this heap.
65.435 + ///
65.436 + /// Make empty this heap. It does not change the cross reference
65.437 + /// map. If you want to reuse a heap what is not surely empty you
65.438 + /// should first clear the heap and after that you should set the
65.439 + /// cross reference map for each item to \c PRE_HEAP.
65.440 + void clear() {
65.441 + _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
65.442 + }
65.443 +
65.444 + /// \brief Insert a pair of item and priority into the heap.
65.445 + ///
65.446 + /// Adds \c p.first to the heap with priority \c p.second.
65.447 + /// \param p The pair to insert.
65.448 + void push(const Pair& p) {
65.449 + push(p.first, p.second);
65.450 + }
65.451 +
65.452 + /// \brief Insert an item into the heap with the given priority.
65.453 + ///
65.454 + /// Adds \c i to the heap with priority \c p.
65.455 + /// \param i The item to insert.
65.456 + /// \param p The priority of the item.
65.457 + void push(const Item &i, const Prio &p) {
65.458 + int idx;
65.459 + if (_free == -1) {
65.460 + idx = _data.size();
65.461 + _data.push_back(BucketItem(i));
65.462 + } else {
65.463 + idx = _free;
65.464 + _free = _data[idx].next;
65.465 + _data[idx].item = i;
65.466 + }
65.467 + _iim[i] = idx;
65.468 + if (p >= int(_first.size())) _first.resize(p + 1, -1);
65.469 + _data[idx].next = _first[p];
65.470 + _first[p] = idx;
65.471 + if (Direction::less(p, _minimum)) {
65.472 + _minimum = p;
65.473 + }
65.474 + ++_num;
65.475 + }
65.476 +
65.477 + /// \brief Returns the item with minimum priority.
65.478 + ///
65.479 + /// This method returns the item with minimum priority.
65.480 + /// \pre The heap must be nonempty.
65.481 + Item top() const {
65.482 + while (_first[_minimum] == -1) {
65.483 + Direction::increase(_minimum);
65.484 + }
65.485 + return _data[_first[_minimum]].item;
65.486 + }
65.487 +
65.488 + /// \brief Returns the minimum priority.
65.489 + ///
65.490 + /// It returns the minimum priority.
65.491 + /// \pre The heap must be nonempty.
65.492 + Prio prio() const {
65.493 + while (_first[_minimum] == -1) {
65.494 + Direction::increase(_minimum);
65.495 + }
65.496 + return _minimum;
65.497 + }
65.498 +
65.499 + /// \brief Deletes the item with minimum priority.
65.500 + ///
65.501 + /// This method deletes the item with minimum priority from the heap.
65.502 + /// \pre The heap must be non-empty.
65.503 + void pop() {
65.504 + while (_first[_minimum] == -1) {
65.505 + Direction::increase(_minimum);
65.506 + }
65.507 + int idx = _first[_minimum];
65.508 + _iim[_data[idx].item] = -2;
65.509 + _first[_minimum] = _data[idx].next;
65.510 + _data[idx].next = _free;
65.511 + _free = idx;
65.512 + --_num;
65.513 + }
65.514 +
65.515 + /// \brief Returns the priority of \c i.
65.516 + ///
65.517 + /// This function returns the priority of item \c i.
65.518 + /// \warning This operator is not a constant time function
65.519 + /// because it scans the whole data structure to find the proper
65.520 + /// value.
65.521 + /// \pre \c i must be in the heap.
65.522 + /// \param i The item.
65.523 + Prio operator[](const Item &i) const {
65.524 + for (int k = 0; k < _first.size(); ++k) {
65.525 + int idx = _first[k];
65.526 + while (idx != -1) {
65.527 + if (_data[idx].item == i) {
65.528 + return k;
65.529 + }
65.530 + idx = _data[idx].next;
65.531 + }
65.532 + }
65.533 + return -1;
65.534 + }
65.535 +
65.536 + /// \brief Returns if \c item is in, has already been in, or has
65.537 + /// never been in the heap.
65.538 + ///
65.539 + /// This method returns PRE_HEAP if \c item has never been in the
65.540 + /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
65.541 + /// otherwise. In the latter case it is possible that \c item will
65.542 + /// get back to the heap again.
65.543 + /// \param i The item.
65.544 + State state(const Item &i) const {
65.545 + int idx = _iim[i];
65.546 + if (idx >= 0) idx = 0;
65.547 + return State(idx);
65.548 + }
65.549 +
65.550 + private:
65.551 +
65.552 + struct BucketItem {
65.553 + BucketItem(const Item& _item)
65.554 + : item(_item) {}
65.555 +
65.556 + Item item;
65.557 + int next;
65.558 + };
65.559 +
65.560 + ItemIntMap& _iim;
65.561 + std::vector<int> _first;
65.562 + std::vector<BucketItem> _data;
65.563 + int _free, _num;
65.564 + mutable int _minimum;
65.565 +
65.566 + }; // class SimpleBucketHeap
65.567 +
65.568 +}
65.569 +
65.570 +#endif
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
66.2 +++ b/lemon/cbc.cc Thu Dec 10 17:05:35 2009 +0100
66.3 @@ -0,0 +1,463 @@
66.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
66.5 + *
66.6 + * This file is a part of LEMON, a generic C++ optimization library.
66.7 + *
66.8 + * Copyright (C) 2003-2009
66.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
66.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
66.11 + *
66.12 + * Permission to use, modify and distribute this software is granted
66.13 + * provided that this copyright notice appears in all copies. For
66.14 + * precise terms see the accompanying LICENSE file.
66.15 + *
66.16 + * This software is provided "AS IS" with no warranty of any kind,
66.17 + * express or implied, and with no claim as to its suitability for any
66.18 + * purpose.
66.19 + *
66.20 + */
66.21 +
66.22 +///\file
66.23 +///\brief Implementation of the CBC MIP solver interface.
66.24 +
66.25 +#include "cbc.h"
66.26 +
66.27 +#include <coin/CoinModel.hpp>
66.28 +#include <coin/CbcModel.hpp>
66.29 +#include <coin/OsiSolverInterface.hpp>
66.30 +
66.31 +#ifdef COIN_HAS_CLP
66.32 +#include "coin/OsiClpSolverInterface.hpp"
66.33 +#endif
66.34 +#ifdef COIN_HAS_OSL
66.35 +#include "coin/OsiOslSolverInterface.hpp"
66.36 +#endif
66.37 +
66.38 +#include "coin/CbcCutGenerator.hpp"
66.39 +#include "coin/CbcHeuristicLocal.hpp"
66.40 +#include "coin/CbcHeuristicGreedy.hpp"
66.41 +#include "coin/CbcHeuristicFPump.hpp"
66.42 +#include "coin/CbcHeuristicRINS.hpp"
66.43 +
66.44 +#include "coin/CglGomory.hpp"
66.45 +#include "coin/CglProbing.hpp"
66.46 +#include "coin/CglKnapsackCover.hpp"
66.47 +#include "coin/CglOddHole.hpp"
66.48 +#include "coin/CglClique.hpp"
66.49 +#include "coin/CglFlowCover.hpp"
66.50 +#include "coin/CglMixedIntegerRounding.hpp"
66.51 +
66.52 +#include "coin/CbcHeuristic.hpp"
66.53 +
66.54 +namespace lemon {
66.55 +
66.56 + CbcMip::CbcMip() {
66.57 + _prob = new CoinModel();
66.58 + _prob->setProblemName("LEMON");
66.59 + _osi_solver = 0;
66.60 + _cbc_model = 0;
66.61 + messageLevel(MESSAGE_NOTHING);
66.62 + }
66.63 +
66.64 + CbcMip::CbcMip(const CbcMip& other) {
66.65 + _prob = new CoinModel(*other._prob);
66.66 + _prob->setProblemName("LEMON");
66.67 + _osi_solver = 0;
66.68 + _cbc_model = 0;
66.69 + messageLevel(MESSAGE_NOTHING);
66.70 + }
66.71 +
66.72 + CbcMip::~CbcMip() {
66.73 + delete _prob;
66.74 + if (_osi_solver) delete _osi_solver;
66.75 + if (_cbc_model) delete _cbc_model;
66.76 + }
66.77 +
66.78 + const char* CbcMip::_solverName() const { return "CbcMip"; }
66.79 +
66.80 + int CbcMip::_addCol() {
66.81 + _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0, 0, false);
66.82 + return _prob->numberColumns() - 1;
66.83 + }
66.84 +
66.85 + CbcMip* CbcMip::newSolver() const {
66.86 + CbcMip* newlp = new CbcMip;
66.87 + return newlp;
66.88 + }
66.89 +
66.90 + CbcMip* CbcMip::cloneSolver() const {
66.91 + CbcMip* copylp = new CbcMip(*this);
66.92 + return copylp;
66.93 + }
66.94 +
66.95 + int CbcMip::_addRow() {
66.96 + _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
66.97 + return _prob->numberRows() - 1;
66.98 + }
66.99 +
66.100 +
66.101 + void CbcMip::_eraseCol(int i) {
66.102 + _prob->deleteColumn(i);
66.103 + }
66.104 +
66.105 + void CbcMip::_eraseRow(int i) {
66.106 + _prob->deleteRow(i);
66.107 + }
66.108 +
66.109 + void CbcMip::_eraseColId(int i) {
66.110 + cols.eraseIndex(i);
66.111 + }
66.112 +
66.113 + void CbcMip::_eraseRowId(int i) {
66.114 + rows.eraseIndex(i);
66.115 + }
66.116 +
66.117 + void CbcMip::_getColName(int c, std::string& name) const {
66.118 + name = _prob->getColumnName(c);
66.119 + }
66.120 +
66.121 + void CbcMip::_setColName(int c, const std::string& name) {
66.122 + _prob->setColumnName(c, name.c_str());
66.123 + }
66.124 +
66.125 + int CbcMip::_colByName(const std::string& name) const {
66.126 + return _prob->column(name.c_str());
66.127 + }
66.128 +
66.129 + void CbcMip::_getRowName(int r, std::string& name) const {
66.130 + name = _prob->getRowName(r);
66.131 + }
66.132 +
66.133 + void CbcMip::_setRowName(int r, const std::string& name) {
66.134 + _prob->setRowName(r, name.c_str());
66.135 + }
66.136 +
66.137 + int CbcMip::_rowByName(const std::string& name) const {
66.138 + return _prob->row(name.c_str());
66.139 + }
66.140 +
66.141 + void CbcMip::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
66.142 + for (ExprIterator it = b; it != e; ++it) {
66.143 + _prob->setElement(i, it->first, it->second);
66.144 + }
66.145 + }
66.146 +
66.147 + void CbcMip::_getRowCoeffs(int ix, InsertIterator b) const {
66.148 + int length = _prob->numberRows();
66.149 +
66.150 + std::vector<int> indices(length);
66.151 + std::vector<Value> values(length);
66.152 +
66.153 + length = _prob->getRow(ix, &indices[0], &values[0]);
66.154 +
66.155 + for (int i = 0; i < length; ++i) {
66.156 + *b = std::make_pair(indices[i], values[i]);
66.157 + ++b;
66.158 + }
66.159 + }
66.160 +
66.161 + void CbcMip::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
66.162 + for (ExprIterator it = b; it != e; ++it) {
66.163 + _prob->setElement(it->first, ix, it->second);
66.164 + }
66.165 + }
66.166 +
66.167 + void CbcMip::_getColCoeffs(int ix, InsertIterator b) const {
66.168 + int length = _prob->numberColumns();
66.169 +
66.170 + std::vector<int> indices(length);
66.171 + std::vector<Value> values(length);
66.172 +
66.173 + length = _prob->getColumn(ix, &indices[0], &values[0]);
66.174 +
66.175 + for (int i = 0; i < length; ++i) {
66.176 + *b = std::make_pair(indices[i], values[i]);
66.177 + ++b;
66.178 + }
66.179 + }
66.180 +
66.181 + void CbcMip::_setCoeff(int ix, int jx, Value value) {
66.182 + _prob->setElement(ix, jx, value);
66.183 + }
66.184 +
66.185 + CbcMip::Value CbcMip::_getCoeff(int ix, int jx) const {
66.186 + return _prob->getElement(ix, jx);
66.187 + }
66.188 +
66.189 +
66.190 + void CbcMip::_setColLowerBound(int i, Value lo) {
66.191 + LEMON_ASSERT(lo != INF, "Invalid bound");
66.192 + _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
66.193 + }
66.194 +
66.195 + CbcMip::Value CbcMip::_getColLowerBound(int i) const {
66.196 + double val = _prob->getColumnLower(i);
66.197 + return val == - COIN_DBL_MAX ? - INF : val;
66.198 + }
66.199 +
66.200 + void CbcMip::_setColUpperBound(int i, Value up) {
66.201 + LEMON_ASSERT(up != -INF, "Invalid bound");
66.202 + _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
66.203 + }
66.204 +
66.205 + CbcMip::Value CbcMip::_getColUpperBound(int i) const {
66.206 + double val = _prob->getColumnUpper(i);
66.207 + return val == COIN_DBL_MAX ? INF : val;
66.208 + }
66.209 +
66.210 + void CbcMip::_setRowLowerBound(int i, Value lo) {
66.211 + LEMON_ASSERT(lo != INF, "Invalid bound");
66.212 + _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
66.213 + }
66.214 +
66.215 + CbcMip::Value CbcMip::_getRowLowerBound(int i) const {
66.216 + double val = _prob->getRowLower(i);
66.217 + return val == - COIN_DBL_MAX ? - INF : val;
66.218 + }
66.219 +
66.220 + void CbcMip::_setRowUpperBound(int i, Value up) {
66.221 + LEMON_ASSERT(up != -INF, "Invalid bound");
66.222 + _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
66.223 + }
66.224 +
66.225 + CbcMip::Value CbcMip::_getRowUpperBound(int i) const {
66.226 + double val = _prob->getRowUpper(i);
66.227 + return val == COIN_DBL_MAX ? INF : val;
66.228 + }
66.229 +
66.230 + void CbcMip::_setObjCoeffs(ExprIterator b, ExprIterator e) {
66.231 + int num = _prob->numberColumns();
66.232 + for (int i = 0; i < num; ++i) {
66.233 + _prob->setColumnObjective(i, 0.0);
66.234 + }
66.235 + for (ExprIterator it = b; it != e; ++it) {
66.236 + _prob->setColumnObjective(it->first, it->second);
66.237 + }
66.238 + }
66.239 +
66.240 + void CbcMip::_getObjCoeffs(InsertIterator b) const {
66.241 + int num = _prob->numberColumns();
66.242 + for (int i = 0; i < num; ++i) {
66.243 + Value coef = _prob->getColumnObjective(i);
66.244 + if (coef != 0.0) {
66.245 + *b = std::make_pair(i, coef);
66.246 + ++b;
66.247 + }
66.248 + }
66.249 + }
66.250 +
66.251 + void CbcMip::_setObjCoeff(int i, Value obj_coef) {
66.252 + _prob->setColumnObjective(i, obj_coef);
66.253 + }
66.254 +
66.255 + CbcMip::Value CbcMip::_getObjCoeff(int i) const {
66.256 + return _prob->getColumnObjective(i);
66.257 + }
66.258 +
66.259 + CbcMip::SolveExitStatus CbcMip::_solve() {
66.260 +
66.261 + if (_osi_solver) {
66.262 + delete _osi_solver;
66.263 + }
66.264 +#ifdef COIN_HAS_CLP
66.265 + _osi_solver = new OsiClpSolverInterface();
66.266 +#elif COIN_HAS_OSL
66.267 + _osi_solver = new OsiOslSolverInterface();
66.268 +#else
66.269 +#error Cannot instantiate Osi solver
66.270 +#endif
66.271 +
66.272 + _osi_solver->loadFromCoinModel(*_prob);
66.273 +
66.274 + if (_cbc_model) {
66.275 + delete _cbc_model;
66.276 + }
66.277 + _cbc_model= new CbcModel(*_osi_solver);
66.278 +
66.279 + _osi_solver->messageHandler()->setLogLevel(_message_level);
66.280 + _cbc_model->setLogLevel(_message_level);
66.281 +
66.282 + _cbc_model->initialSolve();
66.283 + _cbc_model->solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
66.284 +
66.285 + if (!_cbc_model->isInitialSolveAbandoned() &&
66.286 + _cbc_model->isInitialSolveProvenOptimal() &&
66.287 + !_cbc_model->isInitialSolveProvenPrimalInfeasible() &&
66.288 + !_cbc_model->isInitialSolveProvenDualInfeasible()) {
66.289 +
66.290 + CglProbing generator1;
66.291 + generator1.setUsingObjective(true);
66.292 + generator1.setMaxPass(3);
66.293 + generator1.setMaxProbe(100);
66.294 + generator1.setMaxLook(50);
66.295 + generator1.setRowCuts(3);
66.296 + _cbc_model->addCutGenerator(&generator1, -1, "Probing");
66.297 +
66.298 + CglGomory generator2;
66.299 + generator2.setLimit(300);
66.300 + _cbc_model->addCutGenerator(&generator2, -1, "Gomory");
66.301 +
66.302 + CglKnapsackCover generator3;
66.303 + _cbc_model->addCutGenerator(&generator3, -1, "Knapsack");
66.304 +
66.305 + CglOddHole generator4;
66.306 + generator4.setMinimumViolation(0.005);
66.307 + generator4.setMinimumViolationPer(0.00002);
66.308 + generator4.setMaximumEntries(200);
66.309 + _cbc_model->addCutGenerator(&generator4, -1, "OddHole");
66.310 +
66.311 + CglClique generator5;
66.312 + generator5.setStarCliqueReport(false);
66.313 + generator5.setRowCliqueReport(false);
66.314 + _cbc_model->addCutGenerator(&generator5, -1, "Clique");
66.315 +
66.316 + CglMixedIntegerRounding mixedGen;
66.317 + _cbc_model->addCutGenerator(&mixedGen, -1, "MixedIntegerRounding");
66.318 +
66.319 + CglFlowCover flowGen;
66.320 + _cbc_model->addCutGenerator(&flowGen, -1, "FlowCover");
66.321 +
66.322 +#ifdef COIN_HAS_CLP
66.323 + OsiClpSolverInterface* osiclp =
66.324 + dynamic_cast<OsiClpSolverInterface*>(_cbc_model->solver());
66.325 + if (osiclp->getNumRows() < 300 && osiclp->getNumCols() < 500) {
66.326 + osiclp->setupForRepeatedUse(2, 0);
66.327 + }
66.328 +#endif
66.329 +
66.330 + CbcRounding heuristic1(*_cbc_model);
66.331 + heuristic1.setWhen(3);
66.332 + _cbc_model->addHeuristic(&heuristic1);
66.333 +
66.334 + CbcHeuristicLocal heuristic2(*_cbc_model);
66.335 + heuristic2.setWhen(3);
66.336 + _cbc_model->addHeuristic(&heuristic2);
66.337 +
66.338 + CbcHeuristicGreedyCover heuristic3(*_cbc_model);
66.339 + heuristic3.setAlgorithm(11);
66.340 + heuristic3.setWhen(3);
66.341 + _cbc_model->addHeuristic(&heuristic3);
66.342 +
66.343 + CbcHeuristicFPump heuristic4(*_cbc_model);
66.344 + heuristic4.setWhen(3);
66.345 + _cbc_model->addHeuristic(&heuristic4);
66.346 +
66.347 + CbcHeuristicRINS heuristic5(*_cbc_model);
66.348 + heuristic5.setWhen(3);
66.349 + _cbc_model->addHeuristic(&heuristic5);
66.350 +
66.351 + if (_cbc_model->getNumCols() < 500) {
66.352 + _cbc_model->setMaximumCutPassesAtRoot(-100);
66.353 + } else if (_cbc_model->getNumCols() < 5000) {
66.354 + _cbc_model->setMaximumCutPassesAtRoot(100);
66.355 + } else {
66.356 + _cbc_model->setMaximumCutPassesAtRoot(20);
66.357 + }
66.358 +
66.359 + if (_cbc_model->getNumCols() < 5000) {
66.360 + _cbc_model->setNumberStrong(10);
66.361 + }
66.362 +
66.363 + _cbc_model->solver()->setIntParam(OsiMaxNumIterationHotStart, 100);
66.364 + _cbc_model->branchAndBound();
66.365 + }
66.366 +
66.367 + if (_cbc_model->isAbandoned()) {
66.368 + return UNSOLVED;
66.369 + } else {
66.370 + return SOLVED;
66.371 + }
66.372 + }
66.373 +
66.374 + CbcMip::Value CbcMip::_getSol(int i) const {
66.375 + return _cbc_model->getColSolution()[i];
66.376 + }
66.377 +
66.378 + CbcMip::Value CbcMip::_getSolValue() const {
66.379 + return _cbc_model->getObjValue();
66.380 + }
66.381 +
66.382 + CbcMip::ProblemType CbcMip::_getType() const {
66.383 + if (_cbc_model->isProvenOptimal()) {
66.384 + return OPTIMAL;
66.385 + } else if (_cbc_model->isContinuousUnbounded()) {
66.386 + return UNBOUNDED;
66.387 + }
66.388 + return FEASIBLE;
66.389 + }
66.390 +
66.391 + void CbcMip::_setSense(Sense sense) {
66.392 + switch (sense) {
66.393 + case MIN:
66.394 + _prob->setOptimizationDirection(1.0);
66.395 + break;
66.396 + case MAX:
66.397 + _prob->setOptimizationDirection(- 1.0);
66.398 + break;
66.399 + }
66.400 + }
66.401 +
66.402 + CbcMip::Sense CbcMip::_getSense() const {
66.403 + if (_prob->optimizationDirection() > 0.0) {
66.404 + return MIN;
66.405 + } else if (_prob->optimizationDirection() < 0.0) {
66.406 + return MAX;
66.407 + } else {
66.408 + LEMON_ASSERT(false, "Wrong sense");
66.409 + return CbcMip::Sense();
66.410 + }
66.411 + }
66.412 +
66.413 + void CbcMip::_setColType(int i, CbcMip::ColTypes col_type) {
66.414 + switch (col_type){
66.415 + case INTEGER:
66.416 + _prob->setInteger(i);
66.417 + break;
66.418 + case REAL:
66.419 + _prob->setContinuous(i);
66.420 + break;
66.421 + default:;
66.422 + LEMON_ASSERT(false, "Wrong sense");
66.423 + }
66.424 + }
66.425 +
66.426 + CbcMip::ColTypes CbcMip::_getColType(int i) const {
66.427 + return _prob->getColumnIsInteger(i) ? INTEGER : REAL;
66.428 + }
66.429 +
66.430 + void CbcMip::_clear() {
66.431 + delete _prob;
66.432 + if (_osi_solver) {
66.433 + delete _osi_solver;
66.434 + _osi_solver = 0;
66.435 + }
66.436 + if (_cbc_model) {
66.437 + delete _cbc_model;
66.438 + _cbc_model = 0;
66.439 + }
66.440 +
66.441 + _prob = new CoinModel();
66.442 + rows.clear();
66.443 + cols.clear();
66.444 + }
66.445 +
66.446 + void CbcMip::_messageLevel(MessageLevel level) {
66.447 + switch (level) {
66.448 + case MESSAGE_NOTHING:
66.449 + _message_level = 0;
66.450 + break;
66.451 + case MESSAGE_ERROR:
66.452 + _message_level = 1;
66.453 + break;
66.454 + case MESSAGE_WARNING:
66.455 + _message_level = 1;
66.456 + break;
66.457 + case MESSAGE_NORMAL:
66.458 + _message_level = 2;
66.459 + break;
66.460 + case MESSAGE_VERBOSE:
66.461 + _message_level = 3;
66.462 + break;
66.463 + }
66.464 + }
66.465 +
66.466 +} //END OF NAMESPACE LEMON
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
67.2 +++ b/lemon/cbc.h Thu Dec 10 17:05:35 2009 +0100
67.3 @@ -0,0 +1,129 @@
67.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
67.5 + *
67.6 + * This file is a part of LEMON, a generic C++ optimization library.
67.7 + *
67.8 + * Copyright (C) 2003-2009
67.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
67.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
67.11 + *
67.12 + * Permission to use, modify and distribute this software is granted
67.13 + * provided that this copyright notice appears in all copies. For
67.14 + * precise terms see the accompanying LICENSE file.
67.15 + *
67.16 + * This software is provided "AS IS" with no warranty of any kind,
67.17 + * express or implied, and with no claim as to its suitability for any
67.18 + * purpose.
67.19 + *
67.20 + */
67.21 +
67.22 +// -*- C++ -*-
67.23 +#ifndef LEMON_CBC_H
67.24 +#define LEMON_CBC_H
67.25 +
67.26 +///\file
67.27 +///\brief Header of the LEMON-CBC mip solver interface.
67.28 +///\ingroup lp_group
67.29 +
67.30 +#include <lemon/lp_base.h>
67.31 +
67.32 +class CoinModel;
67.33 +class OsiSolverInterface;
67.34 +class CbcModel;
67.35 +
67.36 +namespace lemon {
67.37 +
67.38 + /// \brief Interface for the CBC MIP solver
67.39 + ///
67.40 + /// This class implements an interface for the CBC MIP solver.
67.41 + ///\ingroup lp_group
67.42 + class CbcMip : public MipSolver {
67.43 + protected:
67.44 +
67.45 + CoinModel *_prob;
67.46 + OsiSolverInterface *_osi_solver;
67.47 + CbcModel *_cbc_model;
67.48 +
67.49 + public:
67.50 +
67.51 + /// \e
67.52 + CbcMip();
67.53 + /// \e
67.54 + CbcMip(const CbcMip&);
67.55 + /// \e
67.56 + ~CbcMip();
67.57 + /// \e
67.58 + virtual CbcMip* newSolver() const;
67.59 + /// \e
67.60 + virtual CbcMip* cloneSolver() const;
67.61 +
67.62 + protected:
67.63 +
67.64 + virtual const char* _solverName() const;
67.65 +
67.66 + virtual int _addCol();
67.67 + virtual int _addRow();
67.68 +
67.69 + virtual void _eraseCol(int i);
67.70 + virtual void _eraseRow(int i);
67.71 +
67.72 + virtual void _eraseColId(int i);
67.73 + virtual void _eraseRowId(int i);
67.74 +
67.75 + virtual void _getColName(int col, std::string& name) const;
67.76 + virtual void _setColName(int col, const std::string& name);
67.77 + virtual int _colByName(const std::string& name) const;
67.78 +
67.79 + virtual void _getRowName(int row, std::string& name) const;
67.80 + virtual void _setRowName(int row, const std::string& name);
67.81 + virtual int _rowByName(const std::string& name) const;
67.82 +
67.83 + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
67.84 + virtual void _getRowCoeffs(int i, InsertIterator b) const;
67.85 +
67.86 + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
67.87 + virtual void _getColCoeffs(int i, InsertIterator b) const;
67.88 +
67.89 + virtual void _setCoeff(int row, int col, Value value);
67.90 + virtual Value _getCoeff(int row, int col) const;
67.91 +
67.92 + virtual void _setColLowerBound(int i, Value value);
67.93 + virtual Value _getColLowerBound(int i) const;
67.94 + virtual void _setColUpperBound(int i, Value value);
67.95 + virtual Value _getColUpperBound(int i) const;
67.96 +
67.97 + virtual void _setRowLowerBound(int i, Value value);
67.98 + virtual Value _getRowLowerBound(int i) const;
67.99 + virtual void _setRowUpperBound(int i, Value value);
67.100 + virtual Value _getRowUpperBound(int i) const;
67.101 +
67.102 + virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
67.103 + virtual void _getObjCoeffs(InsertIterator b) const;
67.104 +
67.105 + virtual void _setObjCoeff(int i, Value obj_coef);
67.106 + virtual Value _getObjCoeff(int i) const;
67.107 +
67.108 + virtual void _setSense(Sense sense);
67.109 + virtual Sense _getSense() const;
67.110 +
67.111 + virtual ColTypes _getColType(int col) const;
67.112 + virtual void _setColType(int col, ColTypes col_type);
67.113 +
67.114 + virtual SolveExitStatus _solve();
67.115 + virtual ProblemType _getType() const;
67.116 + virtual Value _getSol(int i) const;
67.117 + virtual Value _getSolValue() const;
67.118 +
67.119 + virtual void _clear();
67.120 +
67.121 + virtual void _messageLevel(MessageLevel level);
67.122 + void _applyMessageLevel();
67.123 +
67.124 + int _message_level;
67.125 +
67.126 +
67.127 +
67.128 + };
67.129 +
67.130 +}
67.131 +
67.132 +#endif
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
68.2 +++ b/lemon/circulation.h Thu Dec 10 17:05:35 2009 +0100
68.3 @@ -0,0 +1,794 @@
68.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
68.5 + *
68.6 + * This file is a part of LEMON, a generic C++ optimization library.
68.7 + *
68.8 + * Copyright (C) 2003-2009
68.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
68.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
68.11 + *
68.12 + * Permission to use, modify and distribute this software is granted
68.13 + * provided that this copyright notice appears in all copies. For
68.14 + * precise terms see the accompanying LICENSE file.
68.15 + *
68.16 + * This software is provided "AS IS" with no warranty of any kind,
68.17 + * express or implied, and with no claim as to its suitability for any
68.18 + * purpose.
68.19 + *
68.20 + */
68.21 +
68.22 +#ifndef LEMON_CIRCULATION_H
68.23 +#define LEMON_CIRCULATION_H
68.24 +
68.25 +#include <lemon/tolerance.h>
68.26 +#include <lemon/elevator.h>
68.27 +#include <limits>
68.28 +
68.29 +///\ingroup max_flow
68.30 +///\file
68.31 +///\brief Push-relabel algorithm for finding a feasible circulation.
68.32 +///
68.33 +namespace lemon {
68.34 +
68.35 + /// \brief Default traits class of Circulation class.
68.36 + ///
68.37 + /// Default traits class of Circulation class.
68.38 + ///
68.39 + /// \tparam GR Type of the digraph the algorithm runs on.
68.40 + /// \tparam LM The type of the lower bound map.
68.41 + /// \tparam UM The type of the upper bound (capacity) map.
68.42 + /// \tparam SM The type of the supply map.
68.43 + template <typename GR, typename LM,
68.44 + typename UM, typename SM>
68.45 + struct CirculationDefaultTraits {
68.46 +
68.47 + /// \brief The type of the digraph the algorithm runs on.
68.48 + typedef GR Digraph;
68.49 +
68.50 + /// \brief The type of the lower bound map.
68.51 + ///
68.52 + /// The type of the map that stores the lower bounds on the arcs.
68.53 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
68.54 + typedef LM LowerMap;
68.55 +
68.56 + /// \brief The type of the upper bound (capacity) map.
68.57 + ///
68.58 + /// The type of the map that stores the upper bounds (capacities)
68.59 + /// on the arcs.
68.60 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
68.61 + typedef UM UpperMap;
68.62 +
68.63 + /// \brief The type of supply map.
68.64 + ///
68.65 + /// The type of the map that stores the signed supply values of the
68.66 + /// nodes.
68.67 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
68.68 + typedef SM SupplyMap;
68.69 +
68.70 + /// \brief The type of the flow and supply values.
68.71 + typedef typename SupplyMap::Value Value;
68.72 +
68.73 + /// \brief The type of the map that stores the flow values.
68.74 + ///
68.75 + /// The type of the map that stores the flow values.
68.76 + /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
68.77 + /// concept.
68.78 + typedef typename Digraph::template ArcMap<Value> FlowMap;
68.79 +
68.80 + /// \brief Instantiates a FlowMap.
68.81 + ///
68.82 + /// This function instantiates a \ref FlowMap.
68.83 + /// \param digraph The digraph for which we would like to define
68.84 + /// the flow map.
68.85 + static FlowMap* createFlowMap(const Digraph& digraph) {
68.86 + return new FlowMap(digraph);
68.87 + }
68.88 +
68.89 + /// \brief The elevator type used by the algorithm.
68.90 + ///
68.91 + /// The elevator type used by the algorithm.
68.92 + ///
68.93 + /// \sa Elevator
68.94 + /// \sa LinkedElevator
68.95 + typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
68.96 +
68.97 + /// \brief Instantiates an Elevator.
68.98 + ///
68.99 + /// This function instantiates an \ref Elevator.
68.100 + /// \param digraph The digraph for which we would like to define
68.101 + /// the elevator.
68.102 + /// \param max_level The maximum level of the elevator.
68.103 + static Elevator* createElevator(const Digraph& digraph, int max_level) {
68.104 + return new Elevator(digraph, max_level);
68.105 + }
68.106 +
68.107 + /// \brief The tolerance used by the algorithm
68.108 + ///
68.109 + /// The tolerance used by the algorithm to handle inexact computation.
68.110 + typedef lemon::Tolerance<Value> Tolerance;
68.111 +
68.112 + };
68.113 +
68.114 + /**
68.115 + \brief Push-relabel algorithm for the network circulation problem.
68.116 +
68.117 + \ingroup max_flow
68.118 + This class implements a push-relabel algorithm for the \e network
68.119 + \e circulation problem.
68.120 + It is to find a feasible circulation when lower and upper bounds
68.121 + are given for the flow values on the arcs and lower bounds are
68.122 + given for the difference between the outgoing and incoming flow
68.123 + at the nodes.
68.124 +
68.125 + The exact formulation of this problem is the following.
68.126 + Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$
68.127 + \f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and
68.128 + upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$
68.129 + holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
68.130 + denotes the signed supply values of the nodes.
68.131 + If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
68.132 + supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
68.133 + \f$-sup(u)\f$ demand.
68.134 + A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$
68.135 + solution of the following problem.
68.136 +
68.137 + \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
68.138 + \geq sup(u) \quad \forall u\in V, \f]
68.139 + \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
68.140 +
68.141 + The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
68.142 + zero or negative in order to have a feasible solution (since the sum
68.143 + of the expressions on the left-hand side of the inequalities is zero).
68.144 + It means that the total demand must be greater or equal to the total
68.145 + supply and all the supplies have to be carried out from the supply nodes,
68.146 + but there could be demands that are not satisfied.
68.147 + If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
68.148 + constraints have to be satisfied with equality, i.e. all demands
68.149 + have to be satisfied and all supplies have to be used.
68.150 +
68.151 + If you need the opposite inequalities in the supply/demand constraints
68.152 + (i.e. the total demand is less than the total supply and all the demands
68.153 + have to be satisfied while there could be supplies that are not used),
68.154 + then you could easily transform the problem to the above form by reversing
68.155 + the direction of the arcs and taking the negative of the supply values
68.156 + (e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
68.157 +
68.158 + This algorithm either calculates a feasible circulation, or provides
68.159 + a \ref barrier() "barrier", which prooves that a feasible soultion
68.160 + cannot exist.
68.161 +
68.162 + Note that this algorithm also provides a feasible solution for the
68.163 + \ref min_cost_flow "minimum cost flow problem".
68.164 +
68.165 + \tparam GR The type of the digraph the algorithm runs on.
68.166 + \tparam LM The type of the lower bound map. The default
68.167 + map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
68.168 + \tparam UM The type of the upper bound (capacity) map.
68.169 + The default map type is \c LM.
68.170 + \tparam SM The type of the supply map. The default map type is
68.171 + \ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>".
68.172 + */
68.173 +#ifdef DOXYGEN
68.174 +template< typename GR,
68.175 + typename LM,
68.176 + typename UM,
68.177 + typename SM,
68.178 + typename TR >
68.179 +#else
68.180 +template< typename GR,
68.181 + typename LM = typename GR::template ArcMap<int>,
68.182 + typename UM = LM,
68.183 + typename SM = typename GR::template NodeMap<typename UM::Value>,
68.184 + typename TR = CirculationDefaultTraits<GR, LM, UM, SM> >
68.185 +#endif
68.186 + class Circulation {
68.187 + public:
68.188 +
68.189 + ///The \ref CirculationDefaultTraits "traits class" of the algorithm.
68.190 + typedef TR Traits;
68.191 + ///The type of the digraph the algorithm runs on.
68.192 + typedef typename Traits::Digraph Digraph;
68.193 + ///The type of the flow and supply values.
68.194 + typedef typename Traits::Value Value;
68.195 +
68.196 + ///The type of the lower bound map.
68.197 + typedef typename Traits::LowerMap LowerMap;
68.198 + ///The type of the upper bound (capacity) map.
68.199 + typedef typename Traits::UpperMap UpperMap;
68.200 + ///The type of the supply map.
68.201 + typedef typename Traits::SupplyMap SupplyMap;
68.202 + ///The type of the flow map.
68.203 + typedef typename Traits::FlowMap FlowMap;
68.204 +
68.205 + ///The type of the elevator.
68.206 + typedef typename Traits::Elevator Elevator;
68.207 + ///The type of the tolerance.
68.208 + typedef typename Traits::Tolerance Tolerance;
68.209 +
68.210 + private:
68.211 +
68.212 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
68.213 +
68.214 + const Digraph &_g;
68.215 + int _node_num;
68.216 +
68.217 + const LowerMap *_lo;
68.218 + const UpperMap *_up;
68.219 + const SupplyMap *_supply;
68.220 +
68.221 + FlowMap *_flow;
68.222 + bool _local_flow;
68.223 +
68.224 + Elevator* _level;
68.225 + bool _local_level;
68.226 +
68.227 + typedef typename Digraph::template NodeMap<Value> ExcessMap;
68.228 + ExcessMap* _excess;
68.229 +
68.230 + Tolerance _tol;
68.231 + int _el;
68.232 +
68.233 + public:
68.234 +
68.235 + typedef Circulation Create;
68.236 +
68.237 + ///\name Named Template Parameters
68.238 +
68.239 + ///@{
68.240 +
68.241 + template <typename T>
68.242 + struct SetFlowMapTraits : public Traits {
68.243 + typedef T FlowMap;
68.244 + static FlowMap *createFlowMap(const Digraph&) {
68.245 + LEMON_ASSERT(false, "FlowMap is not initialized");
68.246 + return 0; // ignore warnings
68.247 + }
68.248 + };
68.249 +
68.250 + /// \brief \ref named-templ-param "Named parameter" for setting
68.251 + /// FlowMap type
68.252 + ///
68.253 + /// \ref named-templ-param "Named parameter" for setting FlowMap
68.254 + /// type.
68.255 + template <typename T>
68.256 + struct SetFlowMap
68.257 + : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
68.258 + SetFlowMapTraits<T> > {
68.259 + typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
68.260 + SetFlowMapTraits<T> > Create;
68.261 + };
68.262 +
68.263 + template <typename T>
68.264 + struct SetElevatorTraits : public Traits {
68.265 + typedef T Elevator;
68.266 + static Elevator *createElevator(const Digraph&, int) {
68.267 + LEMON_ASSERT(false, "Elevator is not initialized");
68.268 + return 0; // ignore warnings
68.269 + }
68.270 + };
68.271 +
68.272 + /// \brief \ref named-templ-param "Named parameter" for setting
68.273 + /// Elevator type
68.274 + ///
68.275 + /// \ref named-templ-param "Named parameter" for setting Elevator
68.276 + /// type. If this named parameter is used, then an external
68.277 + /// elevator object must be passed to the algorithm using the
68.278 + /// \ref elevator(Elevator&) "elevator()" function before calling
68.279 + /// \ref run() or \ref init().
68.280 + /// \sa SetStandardElevator
68.281 + template <typename T>
68.282 + struct SetElevator
68.283 + : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
68.284 + SetElevatorTraits<T> > {
68.285 + typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
68.286 + SetElevatorTraits<T> > Create;
68.287 + };
68.288 +
68.289 + template <typename T>
68.290 + struct SetStandardElevatorTraits : public Traits {
68.291 + typedef T Elevator;
68.292 + static Elevator *createElevator(const Digraph& digraph, int max_level) {
68.293 + return new Elevator(digraph, max_level);
68.294 + }
68.295 + };
68.296 +
68.297 + /// \brief \ref named-templ-param "Named parameter" for setting
68.298 + /// Elevator type with automatic allocation
68.299 + ///
68.300 + /// \ref named-templ-param "Named parameter" for setting Elevator
68.301 + /// type with automatic allocation.
68.302 + /// The Elevator should have standard constructor interface to be
68.303 + /// able to automatically created by the algorithm (i.e. the
68.304 + /// digraph and the maximum level should be passed to it).
68.305 + /// However an external elevator object could also be passed to the
68.306 + /// algorithm with the \ref elevator(Elevator&) "elevator()" function
68.307 + /// before calling \ref run() or \ref init().
68.308 + /// \sa SetElevator
68.309 + template <typename T>
68.310 + struct SetStandardElevator
68.311 + : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
68.312 + SetStandardElevatorTraits<T> > {
68.313 + typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
68.314 + SetStandardElevatorTraits<T> > Create;
68.315 + };
68.316 +
68.317 + /// @}
68.318 +
68.319 + protected:
68.320 +
68.321 + Circulation() {}
68.322 +
68.323 + public:
68.324 +
68.325 + /// Constructor.
68.326 +
68.327 + /// The constructor of the class.
68.328 + ///
68.329 + /// \param graph The digraph the algorithm runs on.
68.330 + /// \param lower The lower bounds for the flow values on the arcs.
68.331 + /// \param upper The upper bounds (capacities) for the flow values
68.332 + /// on the arcs.
68.333 + /// \param supply The signed supply values of the nodes.
68.334 + Circulation(const Digraph &graph, const LowerMap &lower,
68.335 + const UpperMap &upper, const SupplyMap &supply)
68.336 + : _g(graph), _lo(&lower), _up(&upper), _supply(&supply),
68.337 + _flow(NULL), _local_flow(false), _level(NULL), _local_level(false),
68.338 + _excess(NULL) {}
68.339 +
68.340 + /// Destructor.
68.341 + ~Circulation() {
68.342 + destroyStructures();
68.343 + }
68.344 +
68.345 +
68.346 + private:
68.347 +
68.348 + bool checkBoundMaps() {
68.349 + for (ArcIt e(_g);e!=INVALID;++e) {
68.350 + if (_tol.less((*_up)[e], (*_lo)[e])) return false;
68.351 + }
68.352 + return true;
68.353 + }
68.354 +
68.355 + void createStructures() {
68.356 + _node_num = _el = countNodes(_g);
68.357 +
68.358 + if (!_flow) {
68.359 + _flow = Traits::createFlowMap(_g);
68.360 + _local_flow = true;
68.361 + }
68.362 + if (!_level) {
68.363 + _level = Traits::createElevator(_g, _node_num);
68.364 + _local_level = true;
68.365 + }
68.366 + if (!_excess) {
68.367 + _excess = new ExcessMap(_g);
68.368 + }
68.369 + }
68.370 +
68.371 + void destroyStructures() {
68.372 + if (_local_flow) {
68.373 + delete _flow;
68.374 + }
68.375 + if (_local_level) {
68.376 + delete _level;
68.377 + }
68.378 + if (_excess) {
68.379 + delete _excess;
68.380 + }
68.381 + }
68.382 +
68.383 + public:
68.384 +
68.385 + /// Sets the lower bound map.
68.386 +
68.387 + /// Sets the lower bound map.
68.388 + /// \return <tt>(*this)</tt>
68.389 + Circulation& lowerMap(const LowerMap& map) {
68.390 + _lo = ↦
68.391 + return *this;
68.392 + }
68.393 +
68.394 + /// Sets the upper bound (capacity) map.
68.395 +
68.396 + /// Sets the upper bound (capacity) map.
68.397 + /// \return <tt>(*this)</tt>
68.398 + Circulation& upperMap(const UpperMap& map) {
68.399 + _up = ↦
68.400 + return *this;
68.401 + }
68.402 +
68.403 + /// Sets the supply map.
68.404 +
68.405 + /// Sets the supply map.
68.406 + /// \return <tt>(*this)</tt>
68.407 + Circulation& supplyMap(const SupplyMap& map) {
68.408 + _supply = ↦
68.409 + return *this;
68.410 + }
68.411 +
68.412 + /// \brief Sets the flow map.
68.413 + ///
68.414 + /// Sets the flow map.
68.415 + /// If you don't use this function before calling \ref run() or
68.416 + /// \ref init(), an instance will be allocated automatically.
68.417 + /// The destructor deallocates this automatically allocated map,
68.418 + /// of course.
68.419 + /// \return <tt>(*this)</tt>
68.420 + Circulation& flowMap(FlowMap& map) {
68.421 + if (_local_flow) {
68.422 + delete _flow;
68.423 + _local_flow = false;
68.424 + }
68.425 + _flow = ↦
68.426 + return *this;
68.427 + }
68.428 +
68.429 + /// \brief Sets the elevator used by algorithm.
68.430 + ///
68.431 + /// Sets the elevator used by algorithm.
68.432 + /// If you don't use this function before calling \ref run() or
68.433 + /// \ref init(), an instance will be allocated automatically.
68.434 + /// The destructor deallocates this automatically allocated elevator,
68.435 + /// of course.
68.436 + /// \return <tt>(*this)</tt>
68.437 + Circulation& elevator(Elevator& elevator) {
68.438 + if (_local_level) {
68.439 + delete _level;
68.440 + _local_level = false;
68.441 + }
68.442 + _level = &elevator;
68.443 + return *this;
68.444 + }
68.445 +
68.446 + /// \brief Returns a const reference to the elevator.
68.447 + ///
68.448 + /// Returns a const reference to the elevator.
68.449 + ///
68.450 + /// \pre Either \ref run() or \ref init() must be called before
68.451 + /// using this function.
68.452 + const Elevator& elevator() const {
68.453 + return *_level;
68.454 + }
68.455 +
68.456 + /// \brief Sets the tolerance used by algorithm.
68.457 + ///
68.458 + /// Sets the tolerance used by algorithm.
68.459 + Circulation& tolerance(const Tolerance& tolerance) const {
68.460 + _tol = tolerance;
68.461 + return *this;
68.462 + }
68.463 +
68.464 + /// \brief Returns a const reference to the tolerance.
68.465 + ///
68.466 + /// Returns a const reference to the tolerance.
68.467 + const Tolerance& tolerance() const {
68.468 + return tolerance;
68.469 + }
68.470 +
68.471 + /// \name Execution Control
68.472 + /// The simplest way to execute the algorithm is to call \ref run().\n
68.473 + /// If you need more control on the initial solution or the execution,
68.474 + /// first you have to call one of the \ref init() functions, then
68.475 + /// the \ref start() function.
68.476 +
68.477 + ///@{
68.478 +
68.479 + /// Initializes the internal data structures.
68.480 +
68.481 + /// Initializes the internal data structures and sets all flow values
68.482 + /// to the lower bound.
68.483 + void init()
68.484 + {
68.485 + LEMON_DEBUG(checkBoundMaps(),
68.486 + "Upper bounds must be greater or equal to the lower bounds");
68.487 +
68.488 + createStructures();
68.489 +
68.490 + for(NodeIt n(_g);n!=INVALID;++n) {
68.491 + (*_excess)[n] = (*_supply)[n];
68.492 + }
68.493 +
68.494 + for (ArcIt e(_g);e!=INVALID;++e) {
68.495 + _flow->set(e, (*_lo)[e]);
68.496 + (*_excess)[_g.target(e)] += (*_flow)[e];
68.497 + (*_excess)[_g.source(e)] -= (*_flow)[e];
68.498 + }
68.499 +
68.500 + // global relabeling tested, but in general case it provides
68.501 + // worse performance for random digraphs
68.502 + _level->initStart();
68.503 + for(NodeIt n(_g);n!=INVALID;++n)
68.504 + _level->initAddItem(n);
68.505 + _level->initFinish();
68.506 + for(NodeIt n(_g);n!=INVALID;++n)
68.507 + if(_tol.positive((*_excess)[n]))
68.508 + _level->activate(n);
68.509 + }
68.510 +
68.511 + /// Initializes the internal data structures using a greedy approach.
68.512 +
68.513 + /// Initializes the internal data structures using a greedy approach
68.514 + /// to construct the initial solution.
68.515 + void greedyInit()
68.516 + {
68.517 + LEMON_DEBUG(checkBoundMaps(),
68.518 + "Upper bounds must be greater or equal to the lower bounds");
68.519 +
68.520 + createStructures();
68.521 +
68.522 + for(NodeIt n(_g);n!=INVALID;++n) {
68.523 + (*_excess)[n] = (*_supply)[n];
68.524 + }
68.525 +
68.526 + for (ArcIt e(_g);e!=INVALID;++e) {
68.527 + if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) {
68.528 + _flow->set(e, (*_up)[e]);
68.529 + (*_excess)[_g.target(e)] += (*_up)[e];
68.530 + (*_excess)[_g.source(e)] -= (*_up)[e];
68.531 + } else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) {
68.532 + _flow->set(e, (*_lo)[e]);
68.533 + (*_excess)[_g.target(e)] += (*_lo)[e];
68.534 + (*_excess)[_g.source(e)] -= (*_lo)[e];
68.535 + } else {
68.536 + Value fc = -(*_excess)[_g.target(e)];
68.537 + _flow->set(e, fc);
68.538 + (*_excess)[_g.target(e)] = 0;
68.539 + (*_excess)[_g.source(e)] -= fc;
68.540 + }
68.541 + }
68.542 +
68.543 + _level->initStart();
68.544 + for(NodeIt n(_g);n!=INVALID;++n)
68.545 + _level->initAddItem(n);
68.546 + _level->initFinish();
68.547 + for(NodeIt n(_g);n!=INVALID;++n)
68.548 + if(_tol.positive((*_excess)[n]))
68.549 + _level->activate(n);
68.550 + }
68.551 +
68.552 + ///Executes the algorithm
68.553 +
68.554 + ///This function executes the algorithm.
68.555 + ///
68.556 + ///\return \c true if a feasible circulation is found.
68.557 + ///
68.558 + ///\sa barrier()
68.559 + ///\sa barrierMap()
68.560 + bool start()
68.561 + {
68.562 +
68.563 + Node act;
68.564 + Node bact=INVALID;
68.565 + Node last_activated=INVALID;
68.566 + while((act=_level->highestActive())!=INVALID) {
68.567 + int actlevel=(*_level)[act];
68.568 + int mlevel=_node_num;
68.569 + Value exc=(*_excess)[act];
68.570 +
68.571 + for(OutArcIt e(_g,act);e!=INVALID; ++e) {
68.572 + Node v = _g.target(e);
68.573 + Value fc=(*_up)[e]-(*_flow)[e];
68.574 + if(!_tol.positive(fc)) continue;
68.575 + if((*_level)[v]<actlevel) {
68.576 + if(!_tol.less(fc, exc)) {
68.577 + _flow->set(e, (*_flow)[e] + exc);
68.578 + (*_excess)[v] += exc;
68.579 + if(!_level->active(v) && _tol.positive((*_excess)[v]))
68.580 + _level->activate(v);
68.581 + (*_excess)[act] = 0;
68.582 + _level->deactivate(act);
68.583 + goto next_l;
68.584 + }
68.585 + else {
68.586 + _flow->set(e, (*_up)[e]);
68.587 + (*_excess)[v] += fc;
68.588 + if(!_level->active(v) && _tol.positive((*_excess)[v]))
68.589 + _level->activate(v);
68.590 + exc-=fc;
68.591 + }
68.592 + }
68.593 + else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
68.594 + }
68.595 + for(InArcIt e(_g,act);e!=INVALID; ++e) {
68.596 + Node v = _g.source(e);
68.597 + Value fc=(*_flow)[e]-(*_lo)[e];
68.598 + if(!_tol.positive(fc)) continue;
68.599 + if((*_level)[v]<actlevel) {
68.600 + if(!_tol.less(fc, exc)) {
68.601 + _flow->set(e, (*_flow)[e] - exc);
68.602 + (*_excess)[v] += exc;
68.603 + if(!_level->active(v) && _tol.positive((*_excess)[v]))
68.604 + _level->activate(v);
68.605 + (*_excess)[act] = 0;
68.606 + _level->deactivate(act);
68.607 + goto next_l;
68.608 + }
68.609 + else {
68.610 + _flow->set(e, (*_lo)[e]);
68.611 + (*_excess)[v] += fc;
68.612 + if(!_level->active(v) && _tol.positive((*_excess)[v]))
68.613 + _level->activate(v);
68.614 + exc-=fc;
68.615 + }
68.616 + }
68.617 + else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
68.618 + }
68.619 +
68.620 + (*_excess)[act] = exc;
68.621 + if(!_tol.positive(exc)) _level->deactivate(act);
68.622 + else if(mlevel==_node_num) {
68.623 + _level->liftHighestActiveToTop();
68.624 + _el = _node_num;
68.625 + return false;
68.626 + }
68.627 + else {
68.628 + _level->liftHighestActive(mlevel+1);
68.629 + if(_level->onLevel(actlevel)==0) {
68.630 + _el = actlevel;
68.631 + return false;
68.632 + }
68.633 + }
68.634 + next_l:
68.635 + ;
68.636 + }
68.637 + return true;
68.638 + }
68.639 +
68.640 + /// Runs the algorithm.
68.641 +
68.642 + /// This function runs the algorithm.
68.643 + ///
68.644 + /// \return \c true if a feasible circulation is found.
68.645 + ///
68.646 + /// \note Apart from the return value, c.run() is just a shortcut of
68.647 + /// the following code.
68.648 + /// \code
68.649 + /// c.greedyInit();
68.650 + /// c.start();
68.651 + /// \endcode
68.652 + bool run() {
68.653 + greedyInit();
68.654 + return start();
68.655 + }
68.656 +
68.657 + /// @}
68.658 +
68.659 + /// \name Query Functions
68.660 + /// The results of the circulation algorithm can be obtained using
68.661 + /// these functions.\n
68.662 + /// Either \ref run() or \ref start() should be called before
68.663 + /// using them.
68.664 +
68.665 + ///@{
68.666 +
68.667 + /// \brief Returns the flow value on the given arc.
68.668 + ///
68.669 + /// Returns the flow value on the given arc.
68.670 + ///
68.671 + /// \pre Either \ref run() or \ref init() must be called before
68.672 + /// using this function.
68.673 + Value flow(const Arc& arc) const {
68.674 + return (*_flow)[arc];
68.675 + }
68.676 +
68.677 + /// \brief Returns a const reference to the flow map.
68.678 + ///
68.679 + /// Returns a const reference to the arc map storing the found flow.
68.680 + ///
68.681 + /// \pre Either \ref run() or \ref init() must be called before
68.682 + /// using this function.
68.683 + const FlowMap& flowMap() const {
68.684 + return *_flow;
68.685 + }
68.686 +
68.687 + /**
68.688 + \brief Returns \c true if the given node is in a barrier.
68.689 +
68.690 + Barrier is a set \e B of nodes for which
68.691 +
68.692 + \f[ \sum_{uv\in A: u\in B} upper(uv) -
68.693 + \sum_{uv\in A: v\in B} lower(uv) < \sum_{v\in B} sup(v) \f]
68.694 +
68.695 + holds. The existence of a set with this property prooves that a
68.696 + feasible circualtion cannot exist.
68.697 +
68.698 + This function returns \c true if the given node is in the found
68.699 + barrier. If a feasible circulation is found, the function
68.700 + gives back \c false for every node.
68.701 +
68.702 + \pre Either \ref run() or \ref init() must be called before
68.703 + using this function.
68.704 +
68.705 + \sa barrierMap()
68.706 + \sa checkBarrier()
68.707 + */
68.708 + bool barrier(const Node& node) const
68.709 + {
68.710 + return (*_level)[node] >= _el;
68.711 + }
68.712 +
68.713 + /// \brief Gives back a barrier.
68.714 + ///
68.715 + /// This function sets \c bar to the characteristic vector of the
68.716 + /// found barrier. \c bar should be a \ref concepts::WriteMap "writable"
68.717 + /// node map with \c bool (or convertible) value type.
68.718 + ///
68.719 + /// If a feasible circulation is found, the function gives back an
68.720 + /// empty set, so \c bar[v] will be \c false for all nodes \c v.
68.721 + ///
68.722 + /// \note This function calls \ref barrier() for each node,
68.723 + /// so it runs in O(n) time.
68.724 + ///
68.725 + /// \pre Either \ref run() or \ref init() must be called before
68.726 + /// using this function.
68.727 + ///
68.728 + /// \sa barrier()
68.729 + /// \sa checkBarrier()
68.730 + template<class BarrierMap>
68.731 + void barrierMap(BarrierMap &bar) const
68.732 + {
68.733 + for(NodeIt n(_g);n!=INVALID;++n)
68.734 + bar.set(n, (*_level)[n] >= _el);
68.735 + }
68.736 +
68.737 + /// @}
68.738 +
68.739 + /// \name Checker Functions
68.740 + /// The feasibility of the results can be checked using
68.741 + /// these functions.\n
68.742 + /// Either \ref run() or \ref start() should be called before
68.743 + /// using them.
68.744 +
68.745 + ///@{
68.746 +
68.747 + ///Check if the found flow is a feasible circulation
68.748 +
68.749 + ///Check if the found flow is a feasible circulation,
68.750 + ///
68.751 + bool checkFlow() const {
68.752 + for(ArcIt e(_g);e!=INVALID;++e)
68.753 + if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false;
68.754 + for(NodeIt n(_g);n!=INVALID;++n)
68.755 + {
68.756 + Value dif=-(*_supply)[n];
68.757 + for(InArcIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e];
68.758 + for(OutArcIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e];
68.759 + if(_tol.negative(dif)) return false;
68.760 + }
68.761 + return true;
68.762 + }
68.763 +
68.764 + ///Check whether or not the last execution provides a barrier
68.765 +
68.766 + ///Check whether or not the last execution provides a barrier.
68.767 + ///\sa barrier()
68.768 + ///\sa barrierMap()
68.769 + bool checkBarrier() const
68.770 + {
68.771 + Value delta=0;
68.772 + Value inf_cap = std::numeric_limits<Value>::has_infinity ?
68.773 + std::numeric_limits<Value>::infinity() :
68.774 + std::numeric_limits<Value>::max();
68.775 + for(NodeIt n(_g);n!=INVALID;++n)
68.776 + if(barrier(n))
68.777 + delta-=(*_supply)[n];
68.778 + for(ArcIt e(_g);e!=INVALID;++e)
68.779 + {
68.780 + Node s=_g.source(e);
68.781 + Node t=_g.target(e);
68.782 + if(barrier(s)&&!barrier(t)) {
68.783 + if (_tol.less(inf_cap - (*_up)[e], delta)) return false;
68.784 + delta+=(*_up)[e];
68.785 + }
68.786 + else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
68.787 + }
68.788 + return _tol.negative(delta);
68.789 + }
68.790 +
68.791 + /// @}
68.792 +
68.793 + };
68.794 +
68.795 +}
68.796 +
68.797 +#endif
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
69.2 +++ b/lemon/clp.cc Thu Dec 10 17:05:35 2009 +0100
69.3 @@ -0,0 +1,453 @@
69.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
69.5 + *
69.6 + * This file is a part of LEMON, a generic C++ optimization library.
69.7 + *
69.8 + * Copyright (C) 2003-2008
69.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
69.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
69.11 + *
69.12 + * Permission to use, modify and distribute this software is granted
69.13 + * provided that this copyright notice appears in all copies. For
69.14 + * precise terms see the accompanying LICENSE file.
69.15 + *
69.16 + * This software is provided "AS IS" with no warranty of any kind,
69.17 + * express or implied, and with no claim as to its suitability for any
69.18 + * purpose.
69.19 + *
69.20 + */
69.21 +
69.22 +#include <lemon/clp.h>
69.23 +#include <coin/ClpSimplex.hpp>
69.24 +
69.25 +namespace lemon {
69.26 +
69.27 + ClpLp::ClpLp() {
69.28 + _prob = new ClpSimplex();
69.29 + _init_temporals();
69.30 + messageLevel(MESSAGE_NOTHING);
69.31 + }
69.32 +
69.33 + ClpLp::ClpLp(const ClpLp& other) {
69.34 + _prob = new ClpSimplex(*other._prob);
69.35 + rows = other.rows;
69.36 + cols = other.cols;
69.37 + _init_temporals();
69.38 + messageLevel(MESSAGE_NOTHING);
69.39 + }
69.40 +
69.41 + ClpLp::~ClpLp() {
69.42 + delete _prob;
69.43 + _clear_temporals();
69.44 + }
69.45 +
69.46 + void ClpLp::_init_temporals() {
69.47 + _primal_ray = 0;
69.48 + _dual_ray = 0;
69.49 + }
69.50 +
69.51 + void ClpLp::_clear_temporals() {
69.52 + if (_primal_ray) {
69.53 + delete[] _primal_ray;
69.54 + _primal_ray = 0;
69.55 + }
69.56 + if (_dual_ray) {
69.57 + delete[] _dual_ray;
69.58 + _dual_ray = 0;
69.59 + }
69.60 + }
69.61 +
69.62 + ClpLp* ClpLp::newSolver() const {
69.63 + ClpLp* newlp = new ClpLp;
69.64 + return newlp;
69.65 + }
69.66 +
69.67 + ClpLp* ClpLp::cloneSolver() const {
69.68 + ClpLp* copylp = new ClpLp(*this);
69.69 + return copylp;
69.70 + }
69.71 +
69.72 + const char* ClpLp::_solverName() const { return "ClpLp"; }
69.73 +
69.74 + int ClpLp::_addCol() {
69.75 + _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0);
69.76 + return _prob->numberColumns() - 1;
69.77 + }
69.78 +
69.79 + int ClpLp::_addRow() {
69.80 + _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
69.81 + return _prob->numberRows() - 1;
69.82 + }
69.83 +
69.84 +
69.85 + void ClpLp::_eraseCol(int c) {
69.86 + _col_names_ref.erase(_prob->getColumnName(c));
69.87 + _prob->deleteColumns(1, &c);
69.88 + }
69.89 +
69.90 + void ClpLp::_eraseRow(int r) {
69.91 + _row_names_ref.erase(_prob->getRowName(r));
69.92 + _prob->deleteRows(1, &r);
69.93 + }
69.94 +
69.95 + void ClpLp::_eraseColId(int i) {
69.96 + cols.eraseIndex(i);
69.97 + cols.shiftIndices(i);
69.98 + }
69.99 +
69.100 + void ClpLp::_eraseRowId(int i) {
69.101 + rows.eraseIndex(i);
69.102 + rows.shiftIndices(i);
69.103 + }
69.104 +
69.105 + void ClpLp::_getColName(int c, std::string& name) const {
69.106 + name = _prob->getColumnName(c);
69.107 + }
69.108 +
69.109 + void ClpLp::_setColName(int c, const std::string& name) {
69.110 + _prob->setColumnName(c, const_cast<std::string&>(name));
69.111 + _col_names_ref[name] = c;
69.112 + }
69.113 +
69.114 + int ClpLp::_colByName(const std::string& name) const {
69.115 + std::map<std::string, int>::const_iterator it = _col_names_ref.find(name);
69.116 + return it != _col_names_ref.end() ? it->second : -1;
69.117 + }
69.118 +
69.119 + void ClpLp::_getRowName(int r, std::string& name) const {
69.120 + name = _prob->getRowName(r);
69.121 + }
69.122 +
69.123 + void ClpLp::_setRowName(int r, const std::string& name) {
69.124 + _prob->setRowName(r, const_cast<std::string&>(name));
69.125 + _row_names_ref[name] = r;
69.126 + }
69.127 +
69.128 + int ClpLp::_rowByName(const std::string& name) const {
69.129 + std::map<std::string, int>::const_iterator it = _row_names_ref.find(name);
69.130 + return it != _row_names_ref.end() ? it->second : -1;
69.131 + }
69.132 +
69.133 +
69.134 + void ClpLp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) {
69.135 + std::map<int, Value> coeffs;
69.136 +
69.137 + int n = _prob->clpMatrix()->getNumCols();
69.138 +
69.139 + const int* indices = _prob->clpMatrix()->getIndices();
69.140 + const double* elements = _prob->clpMatrix()->getElements();
69.141 +
69.142 + for (int i = 0; i < n; ++i) {
69.143 + CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
69.144 + CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
69.145 +
69.146 + const int* it = std::lower_bound(indices + begin, indices + end, ix);
69.147 + if (it != indices + end && *it == ix && elements[it - indices] != 0.0) {
69.148 + coeffs[i] = 0.0;
69.149 + }
69.150 + }
69.151 +
69.152 + for (ExprIterator it = b; it != e; ++it) {
69.153 + coeffs[it->first] = it->second;
69.154 + }
69.155 +
69.156 + for (std::map<int, Value>::iterator it = coeffs.begin();
69.157 + it != coeffs.end(); ++it) {
69.158 + _prob->modifyCoefficient(ix, it->first, it->second);
69.159 + }
69.160 + }
69.161 +
69.162 + void ClpLp::_getRowCoeffs(int ix, InsertIterator b) const {
69.163 + int n = _prob->clpMatrix()->getNumCols();
69.164 +
69.165 + const int* indices = _prob->clpMatrix()->getIndices();
69.166 + const double* elements = _prob->clpMatrix()->getElements();
69.167 +
69.168 + for (int i = 0; i < n; ++i) {
69.169 + CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
69.170 + CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
69.171 +
69.172 + const int* it = std::lower_bound(indices + begin, indices + end, ix);
69.173 + if (it != indices + end && *it == ix) {
69.174 + *b = std::make_pair(i, elements[it - indices]);
69.175 + }
69.176 + }
69.177 + }
69.178 +
69.179 + void ClpLp::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
69.180 + std::map<int, Value> coeffs;
69.181 +
69.182 + CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
69.183 + CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
69.184 +
69.185 + const int* indices = _prob->clpMatrix()->getIndices();
69.186 + const double* elements = _prob->clpMatrix()->getElements();
69.187 +
69.188 + for (CoinBigIndex i = begin; i != end; ++i) {
69.189 + if (elements[i] != 0.0) {
69.190 + coeffs[indices[i]] = 0.0;
69.191 + }
69.192 + }
69.193 + for (ExprIterator it = b; it != e; ++it) {
69.194 + coeffs[it->first] = it->second;
69.195 + }
69.196 + for (std::map<int, Value>::iterator it = coeffs.begin();
69.197 + it != coeffs.end(); ++it) {
69.198 + _prob->modifyCoefficient(it->first, ix, it->second);
69.199 + }
69.200 + }
69.201 +
69.202 + void ClpLp::_getColCoeffs(int ix, InsertIterator b) const {
69.203 + CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
69.204 + CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
69.205 +
69.206 + const int* indices = _prob->clpMatrix()->getIndices();
69.207 + const double* elements = _prob->clpMatrix()->getElements();
69.208 +
69.209 + for (CoinBigIndex i = begin; i != end; ++i) {
69.210 + *b = std::make_pair(indices[i], elements[i]);
69.211 + ++b;
69.212 + }
69.213 + }
69.214 +
69.215 + void ClpLp::_setCoeff(int ix, int jx, Value value) {
69.216 + _prob->modifyCoefficient(ix, jx, value);
69.217 + }
69.218 +
69.219 + ClpLp::Value ClpLp::_getCoeff(int ix, int jx) const {
69.220 + CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
69.221 + CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
69.222 +
69.223 + const int* indices = _prob->clpMatrix()->getIndices();
69.224 + const double* elements = _prob->clpMatrix()->getElements();
69.225 +
69.226 + const int* it = std::lower_bound(indices + begin, indices + end, jx);
69.227 + if (it != indices + end && *it == jx) {
69.228 + return elements[it - indices];
69.229 + } else {
69.230 + return 0.0;
69.231 + }
69.232 + }
69.233 +
69.234 + void ClpLp::_setColLowerBound(int i, Value lo) {
69.235 + _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
69.236 + }
69.237 +
69.238 + ClpLp::Value ClpLp::_getColLowerBound(int i) const {
69.239 + double val = _prob->getColLower()[i];
69.240 + return val == - COIN_DBL_MAX ? - INF : val;
69.241 + }
69.242 +
69.243 + void ClpLp::_setColUpperBound(int i, Value up) {
69.244 + _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
69.245 + }
69.246 +
69.247 + ClpLp::Value ClpLp::_getColUpperBound(int i) const {
69.248 + double val = _prob->getColUpper()[i];
69.249 + return val == COIN_DBL_MAX ? INF : val;
69.250 + }
69.251 +
69.252 + void ClpLp::_setRowLowerBound(int i, Value lo) {
69.253 + _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
69.254 + }
69.255 +
69.256 + ClpLp::Value ClpLp::_getRowLowerBound(int i) const {
69.257 + double val = _prob->getRowLower()[i];
69.258 + return val == - COIN_DBL_MAX ? - INF : val;
69.259 + }
69.260 +
69.261 + void ClpLp::_setRowUpperBound(int i, Value up) {
69.262 + _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
69.263 + }
69.264 +
69.265 + ClpLp::Value ClpLp::_getRowUpperBound(int i) const {
69.266 + double val = _prob->getRowUpper()[i];
69.267 + return val == COIN_DBL_MAX ? INF : val;
69.268 + }
69.269 +
69.270 + void ClpLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
69.271 + int num = _prob->clpMatrix()->getNumCols();
69.272 + for (int i = 0; i < num; ++i) {
69.273 + _prob->setObjectiveCoefficient(i, 0.0);
69.274 + }
69.275 + for (ExprIterator it = b; it != e; ++it) {
69.276 + _prob->setObjectiveCoefficient(it->first, it->second);
69.277 + }
69.278 + }
69.279 +
69.280 + void ClpLp::_getObjCoeffs(InsertIterator b) const {
69.281 + int num = _prob->clpMatrix()->getNumCols();
69.282 + for (int i = 0; i < num; ++i) {
69.283 + Value coef = _prob->getObjCoefficients()[i];
69.284 + if (coef != 0.0) {
69.285 + *b = std::make_pair(i, coef);
69.286 + ++b;
69.287 + }
69.288 + }
69.289 + }
69.290 +
69.291 + void ClpLp::_setObjCoeff(int i, Value obj_coef) {
69.292 + _prob->setObjectiveCoefficient(i, obj_coef);
69.293 + }
69.294 +
69.295 + ClpLp::Value ClpLp::_getObjCoeff(int i) const {
69.296 + return _prob->getObjCoefficients()[i];
69.297 + }
69.298 +
69.299 + ClpLp::SolveExitStatus ClpLp::_solve() {
69.300 + return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
69.301 + }
69.302 +
69.303 + ClpLp::SolveExitStatus ClpLp::solvePrimal() {
69.304 + return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
69.305 + }
69.306 +
69.307 + ClpLp::SolveExitStatus ClpLp::solveDual() {
69.308 + return _prob->dual() >= 0 ? SOLVED : UNSOLVED;
69.309 + }
69.310 +
69.311 + ClpLp::SolveExitStatus ClpLp::solveBarrier() {
69.312 + return _prob->barrier() >= 0 ? SOLVED : UNSOLVED;
69.313 + }
69.314 +
69.315 + ClpLp::Value ClpLp::_getPrimal(int i) const {
69.316 + return _prob->primalColumnSolution()[i];
69.317 + }
69.318 + ClpLp::Value ClpLp::_getPrimalValue() const {
69.319 + return _prob->objectiveValue();
69.320 + }
69.321 +
69.322 + ClpLp::Value ClpLp::_getDual(int i) const {
69.323 + return _prob->dualRowSolution()[i];
69.324 + }
69.325 +
69.326 + ClpLp::Value ClpLp::_getPrimalRay(int i) const {
69.327 + if (!_primal_ray) {
69.328 + _primal_ray = _prob->unboundedRay();
69.329 + LEMON_ASSERT(_primal_ray != 0, "Primal ray is not provided");
69.330 + }
69.331 + return _primal_ray[i];
69.332 + }
69.333 +
69.334 + ClpLp::Value ClpLp::_getDualRay(int i) const {
69.335 + if (!_dual_ray) {
69.336 + _dual_ray = _prob->infeasibilityRay();
69.337 + LEMON_ASSERT(_dual_ray != 0, "Dual ray is not provided");
69.338 + }
69.339 + return _dual_ray[i];
69.340 + }
69.341 +
69.342 + ClpLp::VarStatus ClpLp::_getColStatus(int i) const {
69.343 + switch (_prob->getColumnStatus(i)) {
69.344 + case ClpSimplex::basic:
69.345 + return BASIC;
69.346 + case ClpSimplex::isFree:
69.347 + return FREE;
69.348 + case ClpSimplex::atUpperBound:
69.349 + return UPPER;
69.350 + case ClpSimplex::atLowerBound:
69.351 + return LOWER;
69.352 + case ClpSimplex::isFixed:
69.353 + return FIXED;
69.354 + case ClpSimplex::superBasic:
69.355 + return FREE;
69.356 + default:
69.357 + LEMON_ASSERT(false, "Wrong column status");
69.358 + return VarStatus();
69.359 + }
69.360 + }
69.361 +
69.362 + ClpLp::VarStatus ClpLp::_getRowStatus(int i) const {
69.363 + switch (_prob->getColumnStatus(i)) {
69.364 + case ClpSimplex::basic:
69.365 + return BASIC;
69.366 + case ClpSimplex::isFree:
69.367 + return FREE;
69.368 + case ClpSimplex::atUpperBound:
69.369 + return UPPER;
69.370 + case ClpSimplex::atLowerBound:
69.371 + return LOWER;
69.372 + case ClpSimplex::isFixed:
69.373 + return FIXED;
69.374 + case ClpSimplex::superBasic:
69.375 + return FREE;
69.376 + default:
69.377 + LEMON_ASSERT(false, "Wrong row status");
69.378 + return VarStatus();
69.379 + }
69.380 + }
69.381 +
69.382 +
69.383 + ClpLp::ProblemType ClpLp::_getPrimalType() const {
69.384 + if (_prob->isProvenOptimal()) {
69.385 + return OPTIMAL;
69.386 + } else if (_prob->isProvenPrimalInfeasible()) {
69.387 + return INFEASIBLE;
69.388 + } else if (_prob->isProvenDualInfeasible()) {
69.389 + return UNBOUNDED;
69.390 + } else {
69.391 + return UNDEFINED;
69.392 + }
69.393 + }
69.394 +
69.395 + ClpLp::ProblemType ClpLp::_getDualType() const {
69.396 + if (_prob->isProvenOptimal()) {
69.397 + return OPTIMAL;
69.398 + } else if (_prob->isProvenDualInfeasible()) {
69.399 + return INFEASIBLE;
69.400 + } else if (_prob->isProvenPrimalInfeasible()) {
69.401 + return INFEASIBLE;
69.402 + } else {
69.403 + return UNDEFINED;
69.404 + }
69.405 + }
69.406 +
69.407 + void ClpLp::_setSense(ClpLp::Sense sense) {
69.408 + switch (sense) {
69.409 + case MIN:
69.410 + _prob->setOptimizationDirection(1);
69.411 + break;
69.412 + case MAX:
69.413 + _prob->setOptimizationDirection(-1);
69.414 + break;
69.415 + }
69.416 + }
69.417 +
69.418 + ClpLp::Sense ClpLp::_getSense() const {
69.419 + double dir = _prob->optimizationDirection();
69.420 + if (dir > 0.0) {
69.421 + return MIN;
69.422 + } else {
69.423 + return MAX;
69.424 + }
69.425 + }
69.426 +
69.427 + void ClpLp::_clear() {
69.428 + delete _prob;
69.429 + _prob = new ClpSimplex();
69.430 + rows.clear();
69.431 + cols.clear();
69.432 + _col_names_ref.clear();
69.433 + _clear_temporals();
69.434 + }
69.435 +
69.436 + void ClpLp::_messageLevel(MessageLevel level) {
69.437 + switch (level) {
69.438 + case MESSAGE_NOTHING:
69.439 + _prob->setLogLevel(0);
69.440 + break;
69.441 + case MESSAGE_ERROR:
69.442 + _prob->setLogLevel(1);
69.443 + break;
69.444 + case MESSAGE_WARNING:
69.445 + _prob->setLogLevel(2);
69.446 + break;
69.447 + case MESSAGE_NORMAL:
69.448 + _prob->setLogLevel(3);
69.449 + break;
69.450 + case MESSAGE_VERBOSE:
69.451 + _prob->setLogLevel(4);
69.452 + break;
69.453 + }
69.454 + }
69.455 +
69.456 +} //END OF NAMESPACE LEMON
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
70.2 +++ b/lemon/clp.h Thu Dec 10 17:05:35 2009 +0100
70.3 @@ -0,0 +1,163 @@
70.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
70.5 + *
70.6 + * This file is a part of LEMON, a generic C++ optimization library.
70.7 + *
70.8 + * Copyright (C) 2003-2008
70.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
70.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
70.11 + *
70.12 + * Permission to use, modify and distribute this software is granted
70.13 + * provided that this copyright notice appears in all copies. For
70.14 + * precise terms see the accompanying LICENSE file.
70.15 + *
70.16 + * This software is provided "AS IS" with no warranty of any kind,
70.17 + * express or implied, and with no claim as to its suitability for any
70.18 + * purpose.
70.19 + *
70.20 + */
70.21 +
70.22 +#ifndef LEMON_CLP_H
70.23 +#define LEMON_CLP_H
70.24 +
70.25 +///\file
70.26 +///\brief Header of the LEMON-CLP lp solver interface.
70.27 +
70.28 +#include <vector>
70.29 +#include <string>
70.30 +
70.31 +#include <lemon/lp_base.h>
70.32 +
70.33 +class ClpSimplex;
70.34 +
70.35 +namespace lemon {
70.36 +
70.37 + /// \ingroup lp_group
70.38 + ///
70.39 + /// \brief Interface for the CLP solver
70.40 + ///
70.41 + /// This class implements an interface for the Clp LP solver. The
70.42 + /// Clp library is an object oriented lp solver library developed at
70.43 + /// the IBM. The CLP is part of the COIN-OR package and it can be
70.44 + /// used with Common Public License.
70.45 + class ClpLp : public LpSolver {
70.46 + protected:
70.47 +
70.48 + ClpSimplex* _prob;
70.49 +
70.50 + std::map<std::string, int> _col_names_ref;
70.51 + std::map<std::string, int> _row_names_ref;
70.52 +
70.53 + public:
70.54 +
70.55 + /// \e
70.56 + ClpLp();
70.57 + /// \e
70.58 + ClpLp(const ClpLp&);
70.59 + /// \e
70.60 + ~ClpLp();
70.61 +
70.62 + /// \e
70.63 + virtual ClpLp* newSolver() const;
70.64 + /// \e
70.65 + virtual ClpLp* cloneSolver() const;
70.66 +
70.67 + protected:
70.68 +
70.69 + mutable double* _primal_ray;
70.70 + mutable double* _dual_ray;
70.71 +
70.72 + void _init_temporals();
70.73 + void _clear_temporals();
70.74 +
70.75 + protected:
70.76 +
70.77 + virtual const char* _solverName() const;
70.78 +
70.79 + virtual int _addCol();
70.80 + virtual int _addRow();
70.81 +
70.82 + virtual void _eraseCol(int i);
70.83 + virtual void _eraseRow(int i);
70.84 +
70.85 + virtual void _eraseColId(int i);
70.86 + virtual void _eraseRowId(int i);
70.87 +
70.88 + virtual void _getColName(int col, std::string& name) const;
70.89 + virtual void _setColName(int col, const std::string& name);
70.90 + virtual int _colByName(const std::string& name) const;
70.91 +
70.92 + virtual void _getRowName(int row, std::string& name) const;
70.93 + virtual void _setRowName(int row, const std::string& name);
70.94 + virtual int _rowByName(const std::string& name) const;
70.95 +
70.96 + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
70.97 + virtual void _getRowCoeffs(int i, InsertIterator b) const;
70.98 +
70.99 + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
70.100 + virtual void _getColCoeffs(int i, InsertIterator b) const;
70.101 +
70.102 + virtual void _setCoeff(int row, int col, Value value);
70.103 + virtual Value _getCoeff(int row, int col) const;
70.104 +
70.105 + virtual void _setColLowerBound(int i, Value value);
70.106 + virtual Value _getColLowerBound(int i) const;
70.107 + virtual void _setColUpperBound(int i, Value value);
70.108 + virtual Value _getColUpperBound(int i) const;
70.109 +
70.110 + virtual void _setRowLowerBound(int i, Value value);
70.111 + virtual Value _getRowLowerBound(int i) const;
70.112 + virtual void _setRowUpperBound(int i, Value value);
70.113 + virtual Value _getRowUpperBound(int i) const;
70.114 +
70.115 + virtual void _setObjCoeffs(ExprIterator, ExprIterator);
70.116 + virtual void _getObjCoeffs(InsertIterator) const;
70.117 +
70.118 + virtual void _setObjCoeff(int i, Value obj_coef);
70.119 + virtual Value _getObjCoeff(int i) const;
70.120 +
70.121 + virtual void _setSense(Sense sense);
70.122 + virtual Sense _getSense() const;
70.123 +
70.124 + virtual SolveExitStatus _solve();
70.125 +
70.126 + virtual Value _getPrimal(int i) const;
70.127 + virtual Value _getDual(int i) const;
70.128 +
70.129 + virtual Value _getPrimalValue() const;
70.130 +
70.131 + virtual Value _getPrimalRay(int i) const;
70.132 + virtual Value _getDualRay(int i) const;
70.133 +
70.134 + virtual VarStatus _getColStatus(int i) const;
70.135 + virtual VarStatus _getRowStatus(int i) const;
70.136 +
70.137 + virtual ProblemType _getPrimalType() const;
70.138 + virtual ProblemType _getDualType() const;
70.139 +
70.140 + virtual void _clear();
70.141 +
70.142 + virtual void _messageLevel(MessageLevel);
70.143 +
70.144 + public:
70.145 +
70.146 + ///Solves LP with primal simplex method.
70.147 + SolveExitStatus solvePrimal();
70.148 +
70.149 + ///Solves LP with dual simplex method.
70.150 + SolveExitStatus solveDual();
70.151 +
70.152 + ///Solves LP with barrier method.
70.153 + SolveExitStatus solveBarrier();
70.154 +
70.155 + ///Returns the constraint identifier understood by CLP.
70.156 + int clpRow(Row r) const { return rows(id(r)); }
70.157 +
70.158 + ///Returns the variable identifier understood by CLP.
70.159 + int clpCol(Col c) const { return cols(id(c)); }
70.160 +
70.161 + };
70.162 +
70.163 +} //END OF NAMESPACE LEMON
70.164 +
70.165 +#endif //LEMON_CLP_H
70.166 +
71.1 --- a/lemon/color.cc Fri Nov 13 12:33:33 2009 +0100
71.2 +++ b/lemon/color.cc Thu Dec 10 17:05:35 2009 +0100
71.3 @@ -2,7 +2,7 @@
71.4 *
71.5 * This file is a part of LEMON, a generic C++ optimization library.
71.6 *
71.7 - * Copyright (C) 2003-2008
71.8 + * Copyright (C) 2003-2009
71.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
71.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
71.11 *
72.1 --- a/lemon/color.h Fri Nov 13 12:33:33 2009 +0100
72.2 +++ b/lemon/color.h Thu Dec 10 17:05:35 2009 +0100
72.3 @@ -2,7 +2,7 @@
72.4 *
72.5 * This file is a part of LEMON, a generic C++ optimization library.
72.6 *
72.7 - * Copyright (C) 2003-2008
72.8 + * Copyright (C) 2003-2009
72.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
72.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
72.11 *
73.1 --- a/lemon/concept_check.h Fri Nov 13 12:33:33 2009 +0100
73.2 +++ b/lemon/concept_check.h Thu Dec 10 17:05:35 2009 +0100
73.3 @@ -2,7 +2,7 @@
73.4 *
73.5 * This file is a part of LEMON, a generic C++ optimization library.
73.6 *
73.7 - * Copyright (C) 2003-2008
73.8 + * Copyright (C) 2003-2009
73.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
73.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
73.11 *
74.1 --- a/lemon/concepts/digraph.h Fri Nov 13 12:33:33 2009 +0100
74.2 +++ b/lemon/concepts/digraph.h Thu Dec 10 17:05:35 2009 +0100
74.3 @@ -2,7 +2,7 @@
74.4 *
74.5 * This file is a part of LEMON, a generic C++ optimization library.
74.6 *
74.7 - * Copyright (C) 2003-2008
74.8 + * Copyright (C) 2003-2009
74.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
74.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
74.11 *
74.12 @@ -16,8 +16,8 @@
74.13 *
74.14 */
74.15
74.16 -#ifndef LEMON_CONCEPT_DIGRAPH_H
74.17 -#define LEMON_CONCEPT_DIGRAPH_H
74.18 +#ifndef LEMON_CONCEPTS_DIGRAPH_H
74.19 +#define LEMON_CONCEPTS_DIGRAPH_H
74.20
74.21 ///\ingroup graph_concepts
74.22 ///\file
74.23 @@ -421,12 +421,11 @@
74.24 /// Gives back the opposite node on the given arc.
74.25 Node oppositeNode(const Node&, const Arc&) const { return INVALID; }
74.26
74.27 - /// \brief Read write map of the nodes to type \c T.
74.28 + /// \brief Reference map of the nodes to type \c T.
74.29 ///
74.30 - /// ReadWrite map of the nodes to type \c T.
74.31 - /// \sa Reference
74.32 + /// Reference map of the nodes to type \c T.
74.33 template<class T>
74.34 - class NodeMap : public ReadWriteMap< Node, T > {
74.35 + class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
74.36 public:
74.37
74.38 ///\e
74.39 @@ -436,7 +435,8 @@
74.40
74.41 private:
74.42 ///Copy constructor
74.43 - NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
74.44 + NodeMap(const NodeMap& nm) :
74.45 + ReferenceMap<Node, T, T&, const T&>(nm) { }
74.46 ///Assignment operator
74.47 template <typename CMap>
74.48 NodeMap& operator=(const CMap&) {
74.49 @@ -445,12 +445,11 @@
74.50 }
74.51 };
74.52
74.53 - /// \brief Read write map of the arcs to type \c T.
74.54 + /// \brief Reference map of the arcs to type \c T.
74.55 ///
74.56 /// Reference map of the arcs to type \c T.
74.57 - /// \sa Reference
74.58 template<class T>
74.59 - class ArcMap : public ReadWriteMap<Arc,T> {
74.60 + class ArcMap : public ReferenceMap<Arc, T, T&, const T&> {
74.61 public:
74.62
74.63 ///\e
74.64 @@ -459,7 +458,8 @@
74.65 ArcMap(const Digraph&, T) { }
74.66 private:
74.67 ///Copy constructor
74.68 - ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { }
74.69 + ArcMap(const ArcMap& em) :
74.70 + ReferenceMap<Arc, T, T&, const T&>(em) { }
74.71 ///Assignment operator
74.72 template <typename CMap>
74.73 ArcMap& operator=(const CMap&) {
74.74 @@ -471,6 +471,7 @@
74.75 template <typename _Digraph>
74.76 struct Constraints {
74.77 void constraints() {
74.78 + checkConcept<BaseDigraphComponent, _Digraph>();
74.79 checkConcept<IterableDigraphComponent<>, _Digraph>();
74.80 checkConcept<IDableDigraphComponent<>, _Digraph>();
74.81 checkConcept<MappableDigraphComponent<>, _Digraph>();
74.82 @@ -484,4 +485,4 @@
74.83
74.84
74.85
74.86 -#endif // LEMON_CONCEPT_DIGRAPH_H
74.87 +#endif
75.1 --- a/lemon/concepts/graph.h Fri Nov 13 12:33:33 2009 +0100
75.2 +++ b/lemon/concepts/graph.h Thu Dec 10 17:05:35 2009 +0100
75.3 @@ -2,7 +2,7 @@
75.4 *
75.5 * This file is a part of LEMON, a generic C++ optimization library.
75.6 *
75.7 - * Copyright (C) 2003-2008
75.8 + * Copyright (C) 2003-2009
75.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
75.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
75.11 *
75.12 @@ -20,11 +20,10 @@
75.13 ///\file
75.14 ///\brief The concept of Undirected Graphs.
75.15
75.16 -#ifndef LEMON_CONCEPT_GRAPH_H
75.17 -#define LEMON_CONCEPT_GRAPH_H
75.18 +#ifndef LEMON_CONCEPTS_GRAPH_H
75.19 +#define LEMON_CONCEPTS_GRAPH_H
75.20
75.21 #include <lemon/concepts/graph_components.h>
75.22 -#include <lemon/concepts/graph.h>
75.23 #include <lemon/core.h>
75.24
75.25 namespace lemon {
75.26 @@ -311,8 +310,8 @@
75.27
75.28 /// The directed arc type. It can be converted to the
75.29 /// edge or it should be inherited from the undirected
75.30 - /// arc.
75.31 - class Arc : public Edge {
75.32 + /// edge.
75.33 + class Arc {
75.34 public:
75.35 /// Default constructor
75.36
75.37 @@ -323,7 +322,7 @@
75.38
75.39 /// Copy constructor.
75.40 ///
75.41 - Arc(const Arc& e) : Edge(e) { }
75.42 + Arc(const Arc&) { }
75.43 /// Initialize the iterator to be invalid.
75.44
75.45 /// Initialize the iterator to be invalid.
75.46 @@ -350,6 +349,8 @@
75.47 /// ordering of the items.
75.48 bool operator<(Arc) const { return false; }
75.49
75.50 + /// Converison to Edge
75.51 + operator Edge() const { return Edge(); }
75.52 };
75.53 /// This iterator goes through each directed arc.
75.54
75.55 @@ -498,12 +499,11 @@
75.56 InArcIt& operator++() { return *this; }
75.57 };
75.58
75.59 - /// \brief Read write map of the nodes to type \c T.
75.60 + /// \brief Reference map of the nodes to type \c T.
75.61 ///
75.62 - /// ReadWrite map of the nodes to type \c T.
75.63 - /// \sa Reference
75.64 + /// Reference map of the nodes to type \c T.
75.65 template<class T>
75.66 - class NodeMap : public ReadWriteMap< Node, T >
75.67 + class NodeMap : public ReferenceMap<Node, T, T&, const T&>
75.68 {
75.69 public:
75.70
75.71 @@ -514,7 +514,8 @@
75.72
75.73 private:
75.74 ///Copy constructor
75.75 - NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
75.76 + NodeMap(const NodeMap& nm) :
75.77 + ReferenceMap<Node, T, T&, const T&>(nm) { }
75.78 ///Assignment operator
75.79 template <typename CMap>
75.80 NodeMap& operator=(const CMap&) {
75.81 @@ -523,12 +524,11 @@
75.82 }
75.83 };
75.84
75.85 - /// \brief Read write map of the directed arcs to type \c T.
75.86 + /// \brief Reference map of the arcs to type \c T.
75.87 ///
75.88 - /// Reference map of the directed arcs to type \c T.
75.89 - /// \sa Reference
75.90 + /// Reference map of the arcs to type \c T.
75.91 template<class T>
75.92 - class ArcMap : public ReadWriteMap<Arc,T>
75.93 + class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
75.94 {
75.95 public:
75.96
75.97 @@ -538,7 +538,8 @@
75.98 ArcMap(const Graph&, T) { }
75.99 private:
75.100 ///Copy constructor
75.101 - ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { }
75.102 + ArcMap(const ArcMap& em) :
75.103 + ReferenceMap<Arc, T, T&, const T&>(em) { }
75.104 ///Assignment operator
75.105 template <typename CMap>
75.106 ArcMap& operator=(const CMap&) {
75.107 @@ -547,12 +548,11 @@
75.108 }
75.109 };
75.110
75.111 - /// Read write map of the edges to type \c T.
75.112 + /// Reference map of the edges to type \c T.
75.113
75.114 - /// Reference map of the arcs to type \c T.
75.115 - /// \sa Reference
75.116 + /// Reference map of the edges to type \c T.
75.117 template<class T>
75.118 - class EdgeMap : public ReadWriteMap<Edge,T>
75.119 + class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
75.120 {
75.121 public:
75.122
75.123 @@ -562,7 +562,8 @@
75.124 EdgeMap(const Graph&, T) { }
75.125 private:
75.126 ///Copy constructor
75.127 - EdgeMap(const EdgeMap& em) : ReadWriteMap<Edge,T>(em) {}
75.128 + EdgeMap(const EdgeMap& em) :
75.129 + ReferenceMap<Edge, T, T&, const T&>(em) {}
75.130 ///Assignment operator
75.131 template <typename CMap>
75.132 EdgeMap& operator=(const CMap&) {
75.133 @@ -602,23 +603,35 @@
75.134
75.135 /// \brief Opposite node on an arc
75.136 ///
75.137 - /// \return the opposite of the given Node on the given Edge
75.138 + /// \return The opposite of the given node on the given edge.
75.139 Node oppositeNode(Node, Edge) const { return INVALID; }
75.140
75.141 /// \brief First node of the edge.
75.142 ///
75.143 - /// \return the first node of the given Edge.
75.144 + /// \return The first node of the given edge.
75.145 ///
75.146 /// Naturally edges don't have direction and thus
75.147 - /// don't have source and target node. But we use these two methods
75.148 - /// to query the two nodes of the arc. The direction of the arc
75.149 - /// which arises this way is called the inherent direction of the
75.150 + /// don't have source and target node. However we use \c u() and \c v()
75.151 + /// methods to query the two nodes of the arc. The direction of the
75.152 + /// arc which arises this way is called the inherent direction of the
75.153 /// edge, and is used to define the "default" direction
75.154 /// of the directed versions of the arcs.
75.155 - /// \sa direction
75.156 + /// \sa v()
75.157 + /// \sa direction()
75.158 Node u(Edge) const { return INVALID; }
75.159
75.160 /// \brief Second node of the edge.
75.161 + ///
75.162 + /// \return The second node of the given edge.
75.163 + ///
75.164 + /// Naturally edges don't have direction and thus
75.165 + /// don't have source and target node. However we use \c u() and \c v()
75.166 + /// methods to query the two nodes of the arc. The direction of the
75.167 + /// arc which arises this way is called the inherent direction of the
75.168 + /// edge, and is used to define the "default" direction
75.169 + /// of the directed versions of the arcs.
75.170 + /// \sa u()
75.171 + /// \sa direction()
75.172 Node v(Edge) const { return INVALID; }
75.173
75.174 /// \brief Source node of the directed arc.
75.175 @@ -737,6 +750,7 @@
75.176 template <typename _Graph>
75.177 struct Constraints {
75.178 void constraints() {
75.179 + checkConcept<BaseGraphComponent, _Graph>();
75.180 checkConcept<IterableGraphComponent<>, _Graph>();
75.181 checkConcept<IDableGraphComponent<>, _Graph>();
75.182 checkConcept<MappableGraphComponent<>, _Graph>();
76.1 --- a/lemon/concepts/graph_components.h Fri Nov 13 12:33:33 2009 +0100
76.2 +++ b/lemon/concepts/graph_components.h Thu Dec 10 17:05:35 2009 +0100
76.3 @@ -2,7 +2,7 @@
76.4 *
76.5 * This file is a part of LEMON, a generic C++ optimization library.
76.6 *
76.7 - * Copyright (C) 2003-2008
76.8 + * Copyright (C) 2003-2009
76.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
76.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
76.11 *
76.12 @@ -20,9 +20,8 @@
76.13 ///\file
76.14 ///\brief The concept of graph components.
76.15
76.16 -
76.17 -#ifndef LEMON_CONCEPT_GRAPH_COMPONENTS_H
76.18 -#define LEMON_CONCEPT_GRAPH_COMPONENTS_H
76.19 +#ifndef LEMON_CONCEPTS_GRAPH_COMPONENTS_H
76.20 +#define LEMON_CONCEPTS_GRAPH_COMPONENTS_H
76.21
76.22 #include <lemon/core.h>
76.23 #include <lemon/concepts/maps.h>
76.24 @@ -32,75 +31,83 @@
76.25 namespace lemon {
76.26 namespace concepts {
76.27
76.28 - /// \brief Skeleton class for graph Node and Arc types
76.29 + /// \brief Concept class for \c Node, \c Arc and \c Edge types.
76.30 ///
76.31 - /// This class describes the interface of Node and Arc (and Edge
76.32 - /// in undirected graphs) subtypes of graph types.
76.33 + /// This class describes the concept of \c Node, \c Arc and \c Edge
76.34 + /// subtypes of digraph and graph types.
76.35 ///
76.36 /// \note This class is a template class so that we can use it to
76.37 - /// create graph skeleton classes. The reason for this is than Node
76.38 - /// and Arc types should \em not derive from the same base class.
76.39 - /// For Node you should instantiate it with character 'n' and for Arc
76.40 - /// with 'a'.
76.41 -
76.42 + /// create graph skeleton classes. The reason for this is that \c Node
76.43 + /// and \c Arc (or \c Edge) types should \e not derive from the same
76.44 + /// base class. For \c Node you should instantiate it with character
76.45 + /// \c 'n', for \c Arc with \c 'a' and for \c Edge with \c 'e'.
76.46 #ifndef DOXYGEN
76.47 - template <char _selector = '0'>
76.48 + template <char sel = '0'>
76.49 #endif
76.50 class GraphItem {
76.51 public:
76.52 /// \brief Default constructor.
76.53 ///
76.54 + /// Default constructor.
76.55 /// \warning The default constructor is not required to set
76.56 /// the item to some well-defined value. So you should consider it
76.57 /// as uninitialized.
76.58 GraphItem() {}
76.59 +
76.60 /// \brief Copy constructor.
76.61 ///
76.62 /// Copy constructor.
76.63 + GraphItem(const GraphItem &) {}
76.64 +
76.65 + /// \brief Constructor for conversion from \c INVALID.
76.66 ///
76.67 - GraphItem(const GraphItem &) {}
76.68 - /// \brief Invalid constructor \& conversion.
76.69 - ///
76.70 - /// This constructor initializes the item to be invalid.
76.71 + /// Constructor for conversion from \c INVALID.
76.72 + /// It initializes the item to be invalid.
76.73 /// \sa Invalid for more details.
76.74 GraphItem(Invalid) {}
76.75 - /// \brief Assign operator for nodes.
76.76 +
76.77 + /// \brief Assignment operator.
76.78 ///
76.79 - /// The nodes are assignable.
76.80 + /// Assignment operator for the item.
76.81 + GraphItem& operator=(const GraphItem&) { return *this; }
76.82 +
76.83 + /// \brief Assignment operator for INVALID.
76.84 ///
76.85 - GraphItem& operator=(GraphItem const&) { return *this; }
76.86 + /// This operator makes the item invalid.
76.87 + GraphItem& operator=(Invalid) { return *this; }
76.88 +
76.89 /// \brief Equality operator.
76.90 ///
76.91 - /// Two iterators are equal if and only if they represents the
76.92 - /// same node in the graph or both are invalid.
76.93 - bool operator==(GraphItem) const { return false; }
76.94 + /// Equality operator.
76.95 + bool operator==(const GraphItem&) const { return false; }
76.96 +
76.97 /// \brief Inequality operator.
76.98 ///
76.99 - /// \sa operator==(const Node& n)
76.100 + /// Inequality operator.
76.101 + bool operator!=(const GraphItem&) const { return false; }
76.102 +
76.103 + /// \brief Ordering operator.
76.104 ///
76.105 - bool operator!=(GraphItem) const { return false; }
76.106 -
76.107 - /// \brief Artificial ordering operator.
76.108 - ///
76.109 - /// To allow the use of graph descriptors as key type in std::map or
76.110 - /// similar associative container we require this.
76.111 + /// This operator defines an ordering of the items.
76.112 + /// It makes possible to use graph item types as key types in
76.113 + /// associative containers (e.g. \c std::map).
76.114 ///
76.115 /// \note This operator only have to define some strict ordering of
76.116 /// the items; this order has nothing to do with the iteration
76.117 /// ordering of the items.
76.118 - bool operator<(GraphItem) const { return false; }
76.119 + bool operator<(const GraphItem&) const { return false; }
76.120
76.121 template<typename _GraphItem>
76.122 struct Constraints {
76.123 void constraints() {
76.124 _GraphItem i1;
76.125 + i1=INVALID;
76.126 _GraphItem i2 = i1;
76.127 _GraphItem i3 = INVALID;
76.128
76.129 i1 = i2 = i3;
76.130
76.131 bool b;
76.132 - // b = (ia == ib) && (ia != ib) && (ia < ib);
76.133 b = (ia == ib) && (ia != ib);
76.134 b = (ia == INVALID) && (ib != INVALID);
76.135 b = (ia < ib);
76.136 @@ -111,13 +118,12 @@
76.137 };
76.138 };
76.139
76.140 - /// \brief An empty base directed graph class.
76.141 + /// \brief Base skeleton class for directed graphs.
76.142 ///
76.143 - /// This class provides the minimal set of features needed for a
76.144 - /// directed graph structure. All digraph concepts have to be
76.145 - /// conform to this base directed graph. It just provides types
76.146 - /// for nodes and arcs and functions to get the source and the
76.147 - /// target of the arcs.
76.148 + /// This class describes the base interface of directed graph types.
76.149 + /// All digraph %concepts have to conform to this class.
76.150 + /// It just provides types for nodes and arcs and functions
76.151 + /// to get the source and the target nodes of arcs.
76.152 class BaseDigraphComponent {
76.153 public:
76.154
76.155 @@ -125,31 +131,27 @@
76.156
76.157 /// \brief Node class of the digraph.
76.158 ///
76.159 - /// This class represents the Nodes of the digraph.
76.160 - ///
76.161 + /// This class represents the nodes of the digraph.
76.162 typedef GraphItem<'n'> Node;
76.163
76.164 /// \brief Arc class of the digraph.
76.165 ///
76.166 - /// This class represents the Arcs of the digraph.
76.167 + /// This class represents the arcs of the digraph.
76.168 + typedef GraphItem<'a'> Arc;
76.169 +
76.170 + /// \brief Return the source node of an arc.
76.171 ///
76.172 - typedef GraphItem<'e'> Arc;
76.173 + /// This function returns the source node of an arc.
76.174 + Node source(const Arc&) const { return INVALID; }
76.175
76.176 - /// \brief Gives back the target node of an arc.
76.177 + /// \brief Return the target node of an arc.
76.178 ///
76.179 - /// Gives back the target node of an arc.
76.180 + /// This function returns the target node of an arc.
76.181 + Node target(const Arc&) const { return INVALID; }
76.182 +
76.183 + /// \brief Return the opposite node on the given arc.
76.184 ///
76.185 - Node target(const Arc&) const { return INVALID;}
76.186 -
76.187 - /// \brief Gives back the source node of an arc.
76.188 - ///
76.189 - /// Gives back the source node of an arc.
76.190 - ///
76.191 - Node source(const Arc&) const { return INVALID;}
76.192 -
76.193 - /// \brief Gives back the opposite node on the given arc.
76.194 - ///
76.195 - /// Gives back the opposite node on the given arc.
76.196 + /// This function returns the opposite node on the given arc.
76.197 Node oppositeNode(const Node&, const Arc&) const {
76.198 return INVALID;
76.199 }
76.200 @@ -175,91 +177,92 @@
76.201 };
76.202 };
76.203
76.204 - /// \brief An empty base undirected graph class.
76.205 + /// \brief Base skeleton class for undirected graphs.
76.206 ///
76.207 - /// This class provides the minimal set of features needed for an
76.208 - /// undirected graph structure. All undirected graph concepts have
76.209 - /// to be conform to this base graph. It just provides types for
76.210 - /// nodes, arcs and edges and functions to get the
76.211 - /// source and the target of the arcs and edges,
76.212 - /// conversion from arcs to edges and function to get
76.213 - /// both direction of the edges.
76.214 + /// This class describes the base interface of undirected graph types.
76.215 + /// All graph %concepts have to conform to this class.
76.216 + /// It extends the interface of \ref BaseDigraphComponent with an
76.217 + /// \c Edge type and functions to get the end nodes of edges,
76.218 + /// to convert from arcs to edges and to get both direction of edges.
76.219 class BaseGraphComponent : public BaseDigraphComponent {
76.220 public:
76.221 +
76.222 + typedef BaseGraphComponent Graph;
76.223 +
76.224 typedef BaseDigraphComponent::Node Node;
76.225 typedef BaseDigraphComponent::Arc Arc;
76.226 - /// \brief Undirected arc class of the graph.
76.227 +
76.228 + /// \brief Undirected edge class of the graph.
76.229 ///
76.230 - /// This class represents the edges of the graph.
76.231 - /// The undirected graphs can be used as a directed graph which
76.232 - /// for each arc contains the opposite arc too so the graph is
76.233 - /// bidirected. The edge represents two opposite
76.234 - /// directed arcs.
76.235 - class Edge : public GraphItem<'u'> {
76.236 + /// This class represents the undirected edges of the graph.
76.237 + /// Undirected graphs can be used as directed graphs, each edge is
76.238 + /// represented by two opposite directed arcs.
76.239 + class Edge : public GraphItem<'e'> {
76.240 + typedef GraphItem<'e'> Parent;
76.241 +
76.242 public:
76.243 - typedef GraphItem<'u'> Parent;
76.244 /// \brief Default constructor.
76.245 ///
76.246 + /// Default constructor.
76.247 /// \warning The default constructor is not required to set
76.248 /// the item to some well-defined value. So you should consider it
76.249 /// as uninitialized.
76.250 Edge() {}
76.251 +
76.252 /// \brief Copy constructor.
76.253 ///
76.254 /// Copy constructor.
76.255 + Edge(const Edge &) : Parent() {}
76.256 +
76.257 + /// \brief Constructor for conversion from \c INVALID.
76.258 ///
76.259 - Edge(const Edge &) : Parent() {}
76.260 - /// \brief Invalid constructor \& conversion.
76.261 - ///
76.262 - /// This constructor initializes the item to be invalid.
76.263 + /// Constructor for conversion from \c INVALID.
76.264 + /// It initializes the item to be invalid.
76.265 /// \sa Invalid for more details.
76.266 Edge(Invalid) {}
76.267 - /// \brief Converter from arc to edge.
76.268 +
76.269 + /// \brief Constructor for conversion from an arc.
76.270 ///
76.271 + /// Constructor for conversion from an arc.
76.272 /// Besides the core graph item functionality each arc should
76.273 /// be convertible to the represented edge.
76.274 Edge(const Arc&) {}
76.275 - /// \brief Assign arc to edge.
76.276 - ///
76.277 - /// Besides the core graph item functionality each arc should
76.278 - /// be convertible to the represented edge.
76.279 - Edge& operator=(const Arc&) { return *this; }
76.280 - };
76.281 + };
76.282
76.283 - /// \brief Returns the direction of the arc.
76.284 + /// \brief Return one end node of an edge.
76.285 + ///
76.286 + /// This function returns one end node of an edge.
76.287 + Node u(const Edge&) const { return INVALID; }
76.288 +
76.289 + /// \brief Return the other end node of an edge.
76.290 + ///
76.291 + /// This function returns the other end node of an edge.
76.292 + Node v(const Edge&) const { return INVALID; }
76.293 +
76.294 + /// \brief Return a directed arc related to an edge.
76.295 + ///
76.296 + /// This function returns a directed arc from its direction and the
76.297 + /// represented edge.
76.298 + Arc direct(const Edge&, bool) const { return INVALID; }
76.299 +
76.300 + /// \brief Return a directed arc related to an edge.
76.301 + ///
76.302 + /// This function returns a directed arc from its source node and the
76.303 + /// represented edge.
76.304 + Arc direct(const Edge&, const Node&) const { return INVALID; }
76.305 +
76.306 + /// \brief Return the direction of the arc.
76.307 ///
76.308 /// Returns the direction of the arc. Each arc represents an
76.309 /// edge with a direction. It gives back the
76.310 /// direction.
76.311 bool direction(const Arc&) const { return true; }
76.312
76.313 - /// \brief Returns the directed arc.
76.314 + /// \brief Return the opposite arc.
76.315 ///
76.316 - /// Returns the directed arc from its direction and the
76.317 - /// represented edge.
76.318 - Arc direct(const Edge&, bool) const { return INVALID;}
76.319 -
76.320 - /// \brief Returns the directed arc.
76.321 - ///
76.322 - /// Returns the directed arc from its source and the
76.323 - /// represented edge.
76.324 - Arc direct(const Edge&, const Node&) const { return INVALID;}
76.325 -
76.326 - /// \brief Returns the opposite arc.
76.327 - ///
76.328 - /// Returns the opposite arc. It is the arc representing the
76.329 - /// same edge and has opposite direction.
76.330 - Arc oppositeArc(const Arc&) const { return INVALID;}
76.331 -
76.332 - /// \brief Gives back one ending of an edge.
76.333 - ///
76.334 - /// Gives back one ending of an edge.
76.335 - Node u(const Edge&) const { return INVALID;}
76.336 -
76.337 - /// \brief Gives back the other ending of an edge.
76.338 - ///
76.339 - /// Gives back the other ending of an edge.
76.340 - Node v(const Edge&) const { return INVALID;}
76.341 + /// This function returns the opposite arc, i.e. the arc representing
76.342 + /// the same edge and has opposite direction.
76.343 + Arc oppositeArc(const Arc&) const { return INVALID; }
76.344
76.345 template <typename _Graph>
76.346 struct Constraints {
76.347 @@ -269,7 +272,7 @@
76.348
76.349 void constraints() {
76.350 checkConcept<BaseDigraphComponent, _Graph>();
76.351 - checkConcept<GraphItem<'u'>, Edge>();
76.352 + checkConcept<GraphItem<'e'>, Edge>();
76.353 {
76.354 Node n;
76.355 Edge ue(INVALID);
76.356 @@ -277,6 +280,7 @@
76.357 n = graph.u(ue);
76.358 n = graph.v(ue);
76.359 e = graph.direct(ue, true);
76.360 + e = graph.direct(ue, false);
76.361 e = graph.direct(ue, n);
76.362 e = graph.oppositeArc(e);
76.363 ue = e;
76.364 @@ -290,59 +294,57 @@
76.365
76.366 };
76.367
76.368 - /// \brief An empty idable base digraph class.
76.369 + /// \brief Skeleton class for \e idable directed graphs.
76.370 ///
76.371 - /// This class provides beside the core digraph features
76.372 - /// core id functions for the digraph structure.
76.373 - /// The most of the base digraphs should be conform to this concept.
76.374 - /// The id's are unique and immutable.
76.375 - template <typename _Base = BaseDigraphComponent>
76.376 - class IDableDigraphComponent : public _Base {
76.377 + /// This class describes the interface of \e idable directed graphs.
76.378 + /// It extends \ref BaseDigraphComponent with the core ID functions.
76.379 + /// The ids of the items must be unique and immutable.
76.380 + /// This concept is part of the Digraph concept.
76.381 + template <typename BAS = BaseDigraphComponent>
76.382 + class IDableDigraphComponent : public BAS {
76.383 public:
76.384
76.385 - typedef _Base Base;
76.386 + typedef BAS Base;
76.387 typedef typename Base::Node Node;
76.388 typedef typename Base::Arc Arc;
76.389
76.390 - /// \brief Gives back an unique integer id for the Node.
76.391 + /// \brief Return a unique integer id for the given node.
76.392 ///
76.393 - /// Gives back an unique integer id for the Node.
76.394 + /// This function returns a unique integer id for the given node.
76.395 + int id(const Node&) const { return -1; }
76.396 +
76.397 + /// \brief Return the node by its unique id.
76.398 ///
76.399 - int id(const Node&) const { return -1;}
76.400 + /// This function returns the node by its unique id.
76.401 + /// If the digraph does not contain a node with the given id,
76.402 + /// then the result of the function is undefined.
76.403 + Node nodeFromId(int) const { return INVALID; }
76.404
76.405 - /// \brief Gives back the node by the unique id.
76.406 + /// \brief Return a unique integer id for the given arc.
76.407 ///
76.408 - /// Gives back the node by the unique id.
76.409 - /// If the digraph does not contain node with the given id
76.410 - /// then the result of the function is undetermined.
76.411 - Node nodeFromId(int) const { return INVALID;}
76.412 + /// This function returns a unique integer id for the given arc.
76.413 + int id(const Arc&) const { return -1; }
76.414
76.415 - /// \brief Gives back an unique integer id for the Arc.
76.416 + /// \brief Return the arc by its unique id.
76.417 ///
76.418 - /// Gives back an unique integer id for the Arc.
76.419 + /// This function returns the arc by its unique id.
76.420 + /// If the digraph does not contain an arc with the given id,
76.421 + /// then the result of the function is undefined.
76.422 + Arc arcFromId(int) const { return INVALID; }
76.423 +
76.424 + /// \brief Return an integer greater or equal to the maximum
76.425 + /// node id.
76.426 ///
76.427 - int id(const Arc&) const { return -1;}
76.428 + /// This function returns an integer greater or equal to the
76.429 + /// maximum node id.
76.430 + int maxNodeId() const { return -1; }
76.431
76.432 - /// \brief Gives back the arc by the unique id.
76.433 + /// \brief Return an integer greater or equal to the maximum
76.434 + /// arc id.
76.435 ///
76.436 - /// Gives back the arc by the unique id.
76.437 - /// If the digraph does not contain arc with the given id
76.438 - /// then the result of the function is undetermined.
76.439 - Arc arcFromId(int) const { return INVALID;}
76.440 -
76.441 - /// \brief Gives back an integer greater or equal to the maximum
76.442 - /// Node id.
76.443 - ///
76.444 - /// Gives back an integer greater or equal to the maximum Node
76.445 - /// id.
76.446 - int maxNodeId() const { return -1;}
76.447 -
76.448 - /// \brief Gives back an integer greater or equal to the maximum
76.449 - /// Arc id.
76.450 - ///
76.451 - /// Gives back an integer greater or equal to the maximum Arc
76.452 - /// id.
76.453 - int maxArcId() const { return -1;}
76.454 + /// This function returns an integer greater or equal to the
76.455 + /// maximum arc id.
76.456 + int maxArcId() const { return -1; }
76.457
76.458 template <typename _Digraph>
76.459 struct Constraints {
76.460 @@ -350,10 +352,12 @@
76.461 void constraints() {
76.462 checkConcept<Base, _Digraph >();
76.463 typename _Digraph::Node node;
76.464 + node=INVALID;
76.465 int nid = digraph.id(node);
76.466 nid = digraph.id(node);
76.467 node = digraph.nodeFromId(nid);
76.468 typename _Digraph::Arc arc;
76.469 + arc=INVALID;
76.470 int eid = digraph.id(arc);
76.471 eid = digraph.id(arc);
76.472 arc = digraph.arcFromId(eid);
76.473 @@ -368,46 +372,45 @@
76.474 };
76.475 };
76.476
76.477 - /// \brief An empty idable base undirected graph class.
76.478 + /// \brief Skeleton class for \e idable undirected graphs.
76.479 ///
76.480 - /// This class provides beside the core undirected graph features
76.481 - /// core id functions for the undirected graph structure. The
76.482 - /// most of the base undirected graphs should be conform to this
76.483 - /// concept. The id's are unique and immutable.
76.484 - template <typename _Base = BaseGraphComponent>
76.485 - class IDableGraphComponent : public IDableDigraphComponent<_Base> {
76.486 + /// This class describes the interface of \e idable undirected
76.487 + /// graphs. It extends \ref IDableDigraphComponent with the core ID
76.488 + /// functions of undirected graphs.
76.489 + /// The ids of the items must be unique and immutable.
76.490 + /// This concept is part of the Graph concept.
76.491 + template <typename BAS = BaseGraphComponent>
76.492 + class IDableGraphComponent : public IDableDigraphComponent<BAS> {
76.493 public:
76.494
76.495 - typedef _Base Base;
76.496 + typedef BAS Base;
76.497 typedef typename Base::Edge Edge;
76.498
76.499 - using IDableDigraphComponent<_Base>::id;
76.500 + using IDableDigraphComponent<Base>::id;
76.501
76.502 - /// \brief Gives back an unique integer id for the Edge.
76.503 + /// \brief Return a unique integer id for the given edge.
76.504 ///
76.505 - /// Gives back an unique integer id for the Edge.
76.506 + /// This function returns a unique integer id for the given edge.
76.507 + int id(const Edge&) const { return -1; }
76.508 +
76.509 + /// \brief Return the edge by its unique id.
76.510 ///
76.511 - int id(const Edge&) const { return -1;}
76.512 + /// This function returns the edge by its unique id.
76.513 + /// If the graph does not contain an edge with the given id,
76.514 + /// then the result of the function is undefined.
76.515 + Edge edgeFromId(int) const { return INVALID; }
76.516
76.517 - /// \brief Gives back the edge by the unique id.
76.518 + /// \brief Return an integer greater or equal to the maximum
76.519 + /// edge id.
76.520 ///
76.521 - /// Gives back the edge by the unique id. If the
76.522 - /// graph does not contain arc with the given id then the
76.523 - /// result of the function is undetermined.
76.524 - Edge edgeFromId(int) const { return INVALID;}
76.525 -
76.526 - /// \brief Gives back an integer greater or equal to the maximum
76.527 - /// Edge id.
76.528 - ///
76.529 - /// Gives back an integer greater or equal to the maximum Edge
76.530 - /// id.
76.531 - int maxEdgeId() const { return -1;}
76.532 + /// This function returns an integer greater or equal to the
76.533 + /// maximum edge id.
76.534 + int maxEdgeId() const { return -1; }
76.535
76.536 template <typename _Graph>
76.537 struct Constraints {
76.538
76.539 void constraints() {
76.540 - checkConcept<Base, _Graph >();
76.541 checkConcept<IDableDigraphComponent<Base>, _Graph >();
76.542 typename _Graph::Edge edge;
76.543 int ueid = graph.id(edge);
76.544 @@ -421,231 +424,243 @@
76.545 };
76.546 };
76.547
76.548 - /// \brief Skeleton class for graph NodeIt and ArcIt
76.549 + /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types.
76.550 ///
76.551 - /// Skeleton class for graph NodeIt and ArcIt.
76.552 - ///
76.553 - template <typename _Graph, typename _Item>
76.554 - class GraphItemIt : public _Item {
76.555 + /// This class describes the concept of \c NodeIt, \c ArcIt and
76.556 + /// \c EdgeIt subtypes of digraph and graph types.
76.557 + template <typename GR, typename Item>
76.558 + class GraphItemIt : public Item {
76.559 public:
76.560 /// \brief Default constructor.
76.561 ///
76.562 - /// @warning The default constructor sets the iterator
76.563 - /// to an undefined value.
76.564 + /// Default constructor.
76.565 + /// \warning The default constructor is not required to set
76.566 + /// the iterator to some well-defined value. So you should consider it
76.567 + /// as uninitialized.
76.568 GraphItemIt() {}
76.569 +
76.570 /// \brief Copy constructor.
76.571 ///
76.572 /// Copy constructor.
76.573 + GraphItemIt(const GraphItemIt& it) : Item(it) {}
76.574 +
76.575 + /// \brief Constructor that sets the iterator to the first item.
76.576 ///
76.577 - GraphItemIt(const GraphItemIt& ) {}
76.578 - /// \brief Sets the iterator to the first item.
76.579 + /// Constructor that sets the iterator to the first item.
76.580 + explicit GraphItemIt(const GR&) {}
76.581 +
76.582 + /// \brief Constructor for conversion from \c INVALID.
76.583 ///
76.584 - /// Sets the iterator to the first item of \c the graph.
76.585 - ///
76.586 - explicit GraphItemIt(const _Graph&) {}
76.587 - /// \brief Invalid constructor \& conversion.
76.588 - ///
76.589 - /// This constructor initializes the item to be invalid.
76.590 + /// Constructor for conversion from \c INVALID.
76.591 + /// It initializes the iterator to be invalid.
76.592 /// \sa Invalid for more details.
76.593 GraphItemIt(Invalid) {}
76.594 - /// \brief Assign operator for items.
76.595 +
76.596 + /// \brief Assignment operator.
76.597 ///
76.598 - /// The items are assignable.
76.599 + /// Assignment operator for the iterator.
76.600 + GraphItemIt& operator=(const GraphItemIt&) { return *this; }
76.601 +
76.602 + /// \brief Increment the iterator.
76.603 ///
76.604 - GraphItemIt& operator=(const GraphItemIt&) { return *this; }
76.605 - /// \brief Next item.
76.606 - ///
76.607 - /// Assign the iterator to the next item.
76.608 - ///
76.609 + /// This operator increments the iterator, i.e. assigns it to the
76.610 + /// next item.
76.611 GraphItemIt& operator++() { return *this; }
76.612 +
76.613 /// \brief Equality operator
76.614 ///
76.615 + /// Equality operator.
76.616 /// Two iterators are equal if and only if they point to the
76.617 /// same object or both are invalid.
76.618 bool operator==(const GraphItemIt&) const { return true;}
76.619 +
76.620 /// \brief Inequality operator
76.621 ///
76.622 - /// \sa operator==(Node n)
76.623 - ///
76.624 + /// Inequality operator.
76.625 + /// Two iterators are equal if and only if they point to the
76.626 + /// same object or both are invalid.
76.627 bool operator!=(const GraphItemIt&) const { return true;}
76.628
76.629 template<typename _GraphItemIt>
76.630 struct Constraints {
76.631 void constraints() {
76.632 + checkConcept<GraphItem<>, _GraphItemIt>();
76.633 _GraphItemIt it1(g);
76.634 _GraphItemIt it2;
76.635 + _GraphItemIt it3 = it1;
76.636 + _GraphItemIt it4 = INVALID;
76.637
76.638 it2 = ++it1;
76.639 ++it2 = it1;
76.640 ++(++it1);
76.641
76.642 - _Item bi = it1;
76.643 + Item bi = it1;
76.644 bi = it2;
76.645 }
76.646 - _Graph& g;
76.647 + const GR& g;
76.648 };
76.649 };
76.650
76.651 - /// \brief Skeleton class for graph InArcIt and OutArcIt
76.652 + /// \brief Concept class for \c InArcIt, \c OutArcIt and
76.653 + /// \c IncEdgeIt types.
76.654 ///
76.655 - /// \note Because InArcIt and OutArcIt may not inherit from the same
76.656 - /// base class, the _selector is a additional template parameter. For
76.657 - /// InArcIt you should instantiate it with character 'i' and for
76.658 - /// OutArcIt with 'o'.
76.659 - template <typename _Graph,
76.660 - typename _Item = typename _Graph::Arc,
76.661 - typename _Base = typename _Graph::Node,
76.662 - char _selector = '0'>
76.663 - class GraphIncIt : public _Item {
76.664 + /// This class describes the concept of \c InArcIt, \c OutArcIt
76.665 + /// and \c IncEdgeIt subtypes of digraph and graph types.
76.666 + ///
76.667 + /// \note Since these iterator classes do not inherit from the same
76.668 + /// base class, there is an additional template parameter (selector)
76.669 + /// \c sel. For \c InArcIt you should instantiate it with character
76.670 + /// \c 'i', for \c OutArcIt with \c 'o' and for \c IncEdgeIt with \c 'e'.
76.671 + template <typename GR,
76.672 + typename Item = typename GR::Arc,
76.673 + typename Base = typename GR::Node,
76.674 + char sel = '0'>
76.675 + class GraphIncIt : public Item {
76.676 public:
76.677 /// \brief Default constructor.
76.678 ///
76.679 - /// @warning The default constructor sets the iterator
76.680 - /// to an undefined value.
76.681 + /// Default constructor.
76.682 + /// \warning The default constructor is not required to set
76.683 + /// the iterator to some well-defined value. So you should consider it
76.684 + /// as uninitialized.
76.685 GraphIncIt() {}
76.686 +
76.687 /// \brief Copy constructor.
76.688 ///
76.689 /// Copy constructor.
76.690 + GraphIncIt(const GraphIncIt& it) : Item(it) {}
76.691 +
76.692 + /// \brief Constructor that sets the iterator to the first
76.693 + /// incoming or outgoing arc.
76.694 ///
76.695 - GraphIncIt(GraphIncIt const& gi) : _Item(gi) {}
76.696 - /// \brief Sets the iterator to the first arc incoming into or outgoing
76.697 - /// from the node.
76.698 + /// Constructor that sets the iterator to the first arc
76.699 + /// incoming to or outgoing from the given node.
76.700 + explicit GraphIncIt(const GR&, const Base&) {}
76.701 +
76.702 + /// \brief Constructor for conversion from \c INVALID.
76.703 ///
76.704 - /// Sets the iterator to the first arc incoming into or outgoing
76.705 - /// from the node.
76.706 - ///
76.707 - explicit GraphIncIt(const _Graph&, const _Base&) {}
76.708 - /// \brief Invalid constructor \& conversion.
76.709 - ///
76.710 - /// This constructor initializes the item to be invalid.
76.711 + /// Constructor for conversion from \c INVALID.
76.712 + /// It initializes the iterator to be invalid.
76.713 /// \sa Invalid for more details.
76.714 GraphIncIt(Invalid) {}
76.715 - /// \brief Assign operator for iterators.
76.716 +
76.717 + /// \brief Assignment operator.
76.718 ///
76.719 - /// The iterators are assignable.
76.720 + /// Assignment operator for the iterator.
76.721 + GraphIncIt& operator=(const GraphIncIt&) { return *this; }
76.722 +
76.723 + /// \brief Increment the iterator.
76.724 ///
76.725 - GraphIncIt& operator=(GraphIncIt const&) { return *this; }
76.726 - /// \brief Next item.
76.727 - ///
76.728 - /// Assign the iterator to the next item.
76.729 - ///
76.730 + /// This operator increments the iterator, i.e. assigns it to the
76.731 + /// next arc incoming to or outgoing from the given node.
76.732 GraphIncIt& operator++() { return *this; }
76.733
76.734 /// \brief Equality operator
76.735 ///
76.736 + /// Equality operator.
76.737 /// Two iterators are equal if and only if they point to the
76.738 /// same object or both are invalid.
76.739 bool operator==(const GraphIncIt&) const { return true;}
76.740
76.741 /// \brief Inequality operator
76.742 ///
76.743 - /// \sa operator==(Node n)
76.744 - ///
76.745 + /// Inequality operator.
76.746 + /// Two iterators are equal if and only if they point to the
76.747 + /// same object or both are invalid.
76.748 bool operator!=(const GraphIncIt&) const { return true;}
76.749
76.750 template <typename _GraphIncIt>
76.751 struct Constraints {
76.752 void constraints() {
76.753 - checkConcept<GraphItem<_selector>, _GraphIncIt>();
76.754 + checkConcept<GraphItem<sel>, _GraphIncIt>();
76.755 _GraphIncIt it1(graph, node);
76.756 _GraphIncIt it2;
76.757 + _GraphIncIt it3 = it1;
76.758 + _GraphIncIt it4 = INVALID;
76.759
76.760 it2 = ++it1;
76.761 ++it2 = it1;
76.762 ++(++it1);
76.763 - _Item e = it1;
76.764 + Item e = it1;
76.765 e = it2;
76.766 -
76.767 }
76.768 -
76.769 - _Item arc;
76.770 - _Base node;
76.771 - _Graph graph;
76.772 - _GraphIncIt it;
76.773 + const Base& node;
76.774 + const GR& graph;
76.775 };
76.776 };
76.777
76.778 -
76.779 - /// \brief An empty iterable digraph class.
76.780 + /// \brief Skeleton class for iterable directed graphs.
76.781 ///
76.782 - /// This class provides beside the core digraph features
76.783 - /// iterator based iterable interface for the digraph structure.
76.784 + /// This class describes the interface of iterable directed
76.785 + /// graphs. It extends \ref BaseDigraphComponent with the core
76.786 + /// iterable interface.
76.787 /// This concept is part of the Digraph concept.
76.788 - template <typename _Base = BaseDigraphComponent>
76.789 - class IterableDigraphComponent : public _Base {
76.790 + template <typename BAS = BaseDigraphComponent>
76.791 + class IterableDigraphComponent : public BAS {
76.792
76.793 public:
76.794
76.795 - typedef _Base Base;
76.796 + typedef BAS Base;
76.797 typedef typename Base::Node Node;
76.798 typedef typename Base::Arc Arc;
76.799
76.800 typedef IterableDigraphComponent Digraph;
76.801
76.802 - /// \name Base iteration
76.803 + /// \name Base Iteration
76.804 ///
76.805 - /// This interface provides functions for iteration on digraph items
76.806 + /// This interface provides functions for iteration on digraph items.
76.807 ///
76.808 /// @{
76.809
76.810 - /// \brief Gives back the first node in the iterating order.
76.811 + /// \brief Return the first node.
76.812 ///
76.813 - /// Gives back the first node in the iterating order.
76.814 - ///
76.815 + /// This function gives back the first node in the iteration order.
76.816 void first(Node&) const {}
76.817
76.818 - /// \brief Gives back the next node in the iterating order.
76.819 + /// \brief Return the next node.
76.820 ///
76.821 - /// Gives back the next node in the iterating order.
76.822 - ///
76.823 + /// This function gives back the next node in the iteration order.
76.824 void next(Node&) const {}
76.825
76.826 - /// \brief Gives back the first arc in the iterating order.
76.827 + /// \brief Return the first arc.
76.828 ///
76.829 - /// Gives back the first arc in the iterating order.
76.830 - ///
76.831 + /// This function gives back the first arc in the iteration order.
76.832 void first(Arc&) const {}
76.833
76.834 - /// \brief Gives back the next arc in the iterating order.
76.835 + /// \brief Return the next arc.
76.836 ///
76.837 - /// Gives back the next arc in the iterating order.
76.838 - ///
76.839 + /// This function gives back the next arc in the iteration order.
76.840 void next(Arc&) const {}
76.841
76.842 -
76.843 - /// \brief Gives back the first of the arcs point to the given
76.844 - /// node.
76.845 + /// \brief Return the first arc incomming to the given node.
76.846 ///
76.847 - /// Gives back the first of the arcs point to the given node.
76.848 - ///
76.849 + /// This function gives back the first arc incomming to the
76.850 + /// given node.
76.851 void firstIn(Arc&, const Node&) const {}
76.852
76.853 - /// \brief Gives back the next of the arcs points to the given
76.854 - /// node.
76.855 + /// \brief Return the next arc incomming to the given node.
76.856 ///
76.857 - /// Gives back the next of the arcs points to the given node.
76.858 - ///
76.859 + /// This function gives back the next arc incomming to the
76.860 + /// given node.
76.861 void nextIn(Arc&) const {}
76.862
76.863 - /// \brief Gives back the first of the arcs start from the
76.864 + /// \brief Return the first arc outgoing form the given node.
76.865 + ///
76.866 + /// This function gives back the first arc outgoing form the
76.867 /// given node.
76.868 - ///
76.869 - /// Gives back the first of the arcs start from the given node.
76.870 - ///
76.871 void firstOut(Arc&, const Node&) const {}
76.872
76.873 - /// \brief Gives back the next of the arcs start from the given
76.874 - /// node.
76.875 + /// \brief Return the next arc outgoing form the given node.
76.876 ///
76.877 - /// Gives back the next of the arcs start from the given node.
76.878 - ///
76.879 + /// This function gives back the next arc outgoing form the
76.880 + /// given node.
76.881 void nextOut(Arc&) const {}
76.882
76.883 /// @}
76.884
76.885 - /// \name Class based iteration
76.886 + /// \name Class Based Iteration
76.887 ///
76.888 - /// This interface provides functions for iteration on digraph items
76.889 + /// This interface provides iterator classes for digraph items.
76.890 ///
76.891 /// @{
76.892
76.893 @@ -655,15 +670,15 @@
76.894 ///
76.895 typedef GraphItemIt<Digraph, Node> NodeIt;
76.896
76.897 - /// \brief This iterator goes through each node.
76.898 + /// \brief This iterator goes through each arc.
76.899 ///
76.900 - /// This iterator goes through each node.
76.901 + /// This iterator goes through each arc.
76.902 ///
76.903 typedef GraphItemIt<Digraph, Arc> ArcIt;
76.904
76.905 /// \brief This iterator goes trough the incoming arcs of a node.
76.906 ///
76.907 - /// This iterator goes trough the \e inccoming arcs of a certain node
76.908 + /// This iterator goes trough the \e incoming arcs of a certain node
76.909 /// of a digraph.
76.910 typedef GraphIncIt<Digraph, Arc, Node, 'i'> InArcIt;
76.911
76.912 @@ -675,26 +690,26 @@
76.913
76.914 /// \brief The base node of the iterator.
76.915 ///
76.916 - /// Gives back the base node of the iterator.
76.917 - /// It is always the target of the pointed arc.
76.918 + /// This function gives back the base node of the iterator.
76.919 + /// It is always the target node of the pointed arc.
76.920 Node baseNode(const InArcIt&) const { return INVALID; }
76.921
76.922 /// \brief The running node of the iterator.
76.923 ///
76.924 - /// Gives back the running node of the iterator.
76.925 - /// It is always the source of the pointed arc.
76.926 + /// This function gives back the running node of the iterator.
76.927 + /// It is always the source node of the pointed arc.
76.928 Node runningNode(const InArcIt&) const { return INVALID; }
76.929
76.930 /// \brief The base node of the iterator.
76.931 ///
76.932 - /// Gives back the base node of the iterator.
76.933 - /// It is always the source of the pointed arc.
76.934 + /// This function gives back the base node of the iterator.
76.935 + /// It is always the source node of the pointed arc.
76.936 Node baseNode(const OutArcIt&) const { return INVALID; }
76.937
76.938 /// \brief The running node of the iterator.
76.939 ///
76.940 - /// Gives back the running node of the iterator.
76.941 - /// It is always the target of the pointed arc.
76.942 + /// This function gives back the running node of the iterator.
76.943 + /// It is always the target node of the pointed arc.
76.944 Node runningNode(const OutArcIt&) const { return INVALID; }
76.945
76.946 /// @}
76.947 @@ -736,31 +751,31 @@
76.948 typename _Digraph::Node, 'o'>, typename _Digraph::OutArcIt>();
76.949
76.950 typename _Digraph::Node n;
76.951 - typename _Digraph::InArcIt ieit(INVALID);
76.952 - typename _Digraph::OutArcIt oeit(INVALID);
76.953 - n = digraph.baseNode(ieit);
76.954 - n = digraph.runningNode(ieit);
76.955 - n = digraph.baseNode(oeit);
76.956 - n = digraph.runningNode(oeit);
76.957 + const typename _Digraph::InArcIt iait(INVALID);
76.958 + const typename _Digraph::OutArcIt oait(INVALID);
76.959 + n = digraph.baseNode(iait);
76.960 + n = digraph.runningNode(iait);
76.961 + n = digraph.baseNode(oait);
76.962 + n = digraph.runningNode(oait);
76.963 ignore_unused_variable_warning(n);
76.964 }
76.965 }
76.966
76.967 const _Digraph& digraph;
76.968 -
76.969 };
76.970 };
76.971
76.972 - /// \brief An empty iterable undirected graph class.
76.973 + /// \brief Skeleton class for iterable undirected graphs.
76.974 ///
76.975 - /// This class provides beside the core graph features iterator
76.976 - /// based iterable interface for the undirected graph structure.
76.977 + /// This class describes the interface of iterable undirected
76.978 + /// graphs. It extends \ref IterableDigraphComponent with the core
76.979 + /// iterable interface of undirected graphs.
76.980 /// This concept is part of the Graph concept.
76.981 - template <typename _Base = BaseGraphComponent>
76.982 - class IterableGraphComponent : public IterableDigraphComponent<_Base> {
76.983 + template <typename BAS = BaseGraphComponent>
76.984 + class IterableGraphComponent : public IterableDigraphComponent<BAS> {
76.985 public:
76.986
76.987 - typedef _Base Base;
76.988 + typedef BAS Base;
76.989 typedef typename Base::Node Node;
76.990 typedef typename Base::Arc Arc;
76.991 typedef typename Base::Edge Edge;
76.992 @@ -768,75 +783,71 @@
76.993
76.994 typedef IterableGraphComponent Graph;
76.995
76.996 - /// \name Base iteration
76.997 + /// \name Base Iteration
76.998 ///
76.999 - /// This interface provides functions for iteration on graph items
76.1000 + /// This interface provides functions for iteration on edges.
76.1001 + ///
76.1002 /// @{
76.1003
76.1004 - using IterableDigraphComponent<_Base>::first;
76.1005 - using IterableDigraphComponent<_Base>::next;
76.1006 + using IterableDigraphComponent<Base>::first;
76.1007 + using IterableDigraphComponent<Base>::next;
76.1008
76.1009 - /// \brief Gives back the first edge in the iterating
76.1010 - /// order.
76.1011 + /// \brief Return the first edge.
76.1012 ///
76.1013 - /// Gives back the first edge in the iterating order.
76.1014 - ///
76.1015 + /// This function gives back the first edge in the iteration order.
76.1016 void first(Edge&) const {}
76.1017
76.1018 - /// \brief Gives back the next edge in the iterating
76.1019 - /// order.
76.1020 + /// \brief Return the next edge.
76.1021 ///
76.1022 - /// Gives back the next edge in the iterating order.
76.1023 - ///
76.1024 + /// This function gives back the next edge in the iteration order.
76.1025 void next(Edge&) const {}
76.1026
76.1027 -
76.1028 - /// \brief Gives back the first of the edges from the
76.1029 + /// \brief Return the first edge incident to the given node.
76.1030 + ///
76.1031 + /// This function gives back the first edge incident to the given
76.1032 + /// node. The bool parameter gives back the direction for which the
76.1033 + /// source node of the directed arc representing the edge is the
76.1034 /// given node.
76.1035 - ///
76.1036 - /// Gives back the first of the edges from the given
76.1037 - /// node. The bool parameter gives back that direction which
76.1038 - /// gives a good direction of the edge so the source of the
76.1039 - /// directed arc is the given node.
76.1040 void firstInc(Edge&, bool&, const Node&) const {}
76.1041
76.1042 /// \brief Gives back the next of the edges from the
76.1043 /// given node.
76.1044 ///
76.1045 - /// Gives back the next of the edges from the given
76.1046 - /// node. The bool parameter should be used as the \c firstInc()
76.1047 - /// use it.
76.1048 + /// This function gives back the next edge incident to the given
76.1049 + /// node. The bool parameter should be used as \c firstInc() use it.
76.1050 void nextInc(Edge&, bool&) const {}
76.1051
76.1052 - using IterableDigraphComponent<_Base>::baseNode;
76.1053 - using IterableDigraphComponent<_Base>::runningNode;
76.1054 + using IterableDigraphComponent<Base>::baseNode;
76.1055 + using IterableDigraphComponent<Base>::runningNode;
76.1056
76.1057 /// @}
76.1058
76.1059 - /// \name Class based iteration
76.1060 + /// \name Class Based Iteration
76.1061 ///
76.1062 - /// This interface provides functions for iteration on graph items
76.1063 + /// This interface provides iterator classes for edges.
76.1064 ///
76.1065 /// @{
76.1066
76.1067 - /// \brief This iterator goes through each node.
76.1068 + /// \brief This iterator goes through each edge.
76.1069 ///
76.1070 - /// This iterator goes through each node.
76.1071 + /// This iterator goes through each edge.
76.1072 typedef GraphItemIt<Graph, Edge> EdgeIt;
76.1073 - /// \brief This iterator goes trough the incident arcs of a
76.1074 +
76.1075 + /// \brief This iterator goes trough the incident edges of a
76.1076 /// node.
76.1077 ///
76.1078 - /// This iterator goes trough the incident arcs of a certain
76.1079 + /// This iterator goes trough the incident edges of a certain
76.1080 /// node of a graph.
76.1081 - typedef GraphIncIt<Graph, Edge, Node, 'u'> IncEdgeIt;
76.1082 + typedef GraphIncIt<Graph, Edge, Node, 'e'> IncEdgeIt;
76.1083 +
76.1084 /// \brief The base node of the iterator.
76.1085 ///
76.1086 - /// Gives back the base node of the iterator.
76.1087 + /// This function gives back the base node of the iterator.
76.1088 Node baseNode(const IncEdgeIt&) const { return INVALID; }
76.1089
76.1090 /// \brief The running node of the iterator.
76.1091 ///
76.1092 - /// Gives back the running node of the iterator.
76.1093 + /// This function gives back the running node of the iterator.
76.1094 Node runningNode(const IncEdgeIt&) const { return INVALID; }
76.1095
76.1096 /// @}
76.1097 @@ -865,54 +876,54 @@
76.1098 checkConcept<GraphItemIt<_Graph, typename _Graph::Edge>,
76.1099 typename _Graph::EdgeIt >();
76.1100 checkConcept<GraphIncIt<_Graph, typename _Graph::Edge,
76.1101 - typename _Graph::Node, 'u'>, typename _Graph::IncEdgeIt>();
76.1102 + typename _Graph::Node, 'e'>, typename _Graph::IncEdgeIt>();
76.1103
76.1104 typename _Graph::Node n;
76.1105 - typename _Graph::IncEdgeIt ueit(INVALID);
76.1106 - n = graph.baseNode(ueit);
76.1107 - n = graph.runningNode(ueit);
76.1108 + const typename _Graph::IncEdgeIt ieit(INVALID);
76.1109 + n = graph.baseNode(ieit);
76.1110 + n = graph.runningNode(ieit);
76.1111 }
76.1112 }
76.1113
76.1114 const _Graph& graph;
76.1115 -
76.1116 };
76.1117 };
76.1118
76.1119 - /// \brief An empty alteration notifier digraph class.
76.1120 + /// \brief Skeleton class for alterable directed graphs.
76.1121 ///
76.1122 - /// This class provides beside the core digraph features alteration
76.1123 - /// notifier interface for the digraph structure. This implements
76.1124 + /// This class describes the interface of alterable directed
76.1125 + /// graphs. It extends \ref BaseDigraphComponent with the alteration
76.1126 + /// notifier interface. It implements
76.1127 /// an observer-notifier pattern for each digraph item. More
76.1128 /// obsevers can be registered into the notifier and whenever an
76.1129 - /// alteration occured in the digraph all the observers will
76.1130 + /// alteration occured in the digraph all the observers will be
76.1131 /// notified about it.
76.1132 - template <typename _Base = BaseDigraphComponent>
76.1133 - class AlterableDigraphComponent : public _Base {
76.1134 + template <typename BAS = BaseDigraphComponent>
76.1135 + class AlterableDigraphComponent : public BAS {
76.1136 public:
76.1137
76.1138 - typedef _Base Base;
76.1139 + typedef BAS Base;
76.1140 typedef typename Base::Node Node;
76.1141 typedef typename Base::Arc Arc;
76.1142
76.1143
76.1144 - /// The node observer registry.
76.1145 + /// Node alteration notifier class.
76.1146 typedef AlterationNotifier<AlterableDigraphComponent, Node>
76.1147 NodeNotifier;
76.1148 - /// The arc observer registry.
76.1149 + /// Arc alteration notifier class.
76.1150 typedef AlterationNotifier<AlterableDigraphComponent, Arc>
76.1151 ArcNotifier;
76.1152
76.1153 - /// \brief Gives back the node alteration notifier.
76.1154 + /// \brief Return the node alteration notifier.
76.1155 ///
76.1156 - /// Gives back the node alteration notifier.
76.1157 + /// This function gives back the node alteration notifier.
76.1158 NodeNotifier& notifier(Node) const {
76.1159 - return NodeNotifier();
76.1160 + return NodeNotifier();
76.1161 }
76.1162
76.1163 - /// \brief Gives back the arc alteration notifier.
76.1164 + /// \brief Return the arc alteration notifier.
76.1165 ///
76.1166 - /// Gives back the arc alteration notifier.
76.1167 + /// This function gives back the arc alteration notifier.
76.1168 ArcNotifier& notifier(Arc) const {
76.1169 return ArcNotifier();
76.1170 }
76.1171 @@ -932,34 +943,33 @@
76.1172 }
76.1173
76.1174 const _Digraph& digraph;
76.1175 -
76.1176 };
76.1177 -
76.1178 };
76.1179
76.1180 - /// \brief An empty alteration notifier undirected graph class.
76.1181 + /// \brief Skeleton class for alterable undirected graphs.
76.1182 ///
76.1183 - /// This class provides beside the core graph features alteration
76.1184 - /// notifier interface for the graph structure. This implements
76.1185 - /// an observer-notifier pattern for each graph item. More
76.1186 + /// This class describes the interface of alterable undirected
76.1187 + /// graphs. It extends \ref AlterableDigraphComponent with the alteration
76.1188 + /// notifier interface of undirected graphs. It implements
76.1189 + /// an observer-notifier pattern for the edges. More
76.1190 /// obsevers can be registered into the notifier and whenever an
76.1191 - /// alteration occured in the graph all the observers will
76.1192 + /// alteration occured in the graph all the observers will be
76.1193 /// notified about it.
76.1194 - template <typename _Base = BaseGraphComponent>
76.1195 - class AlterableGraphComponent : public AlterableDigraphComponent<_Base> {
76.1196 + template <typename BAS = BaseGraphComponent>
76.1197 + class AlterableGraphComponent : public AlterableDigraphComponent<BAS> {
76.1198 public:
76.1199
76.1200 - typedef _Base Base;
76.1201 + typedef BAS Base;
76.1202 typedef typename Base::Edge Edge;
76.1203
76.1204
76.1205 - /// The arc observer registry.
76.1206 + /// Edge alteration notifier class.
76.1207 typedef AlterationNotifier<AlterableGraphComponent, Edge>
76.1208 EdgeNotifier;
76.1209
76.1210 - /// \brief Gives back the arc alteration notifier.
76.1211 + /// \brief Return the edge alteration notifier.
76.1212 ///
76.1213 - /// Gives back the arc alteration notifier.
76.1214 + /// This function gives back the edge alteration notifier.
76.1215 EdgeNotifier& notifier(Edge) const {
76.1216 return EdgeNotifier();
76.1217 }
76.1218 @@ -967,44 +977,48 @@
76.1219 template <typename _Graph>
76.1220 struct Constraints {
76.1221 void constraints() {
76.1222 - checkConcept<AlterableGraphComponent<Base>, _Graph>();
76.1223 + checkConcept<AlterableDigraphComponent<Base>, _Graph>();
76.1224 typename _Graph::EdgeNotifier& uen
76.1225 = graph.notifier(typename _Graph::Edge());
76.1226 ignore_unused_variable_warning(uen);
76.1227 }
76.1228
76.1229 const _Graph& graph;
76.1230 -
76.1231 };
76.1232 -
76.1233 };
76.1234
76.1235 - /// \brief Class describing the concept of graph maps
76.1236 + /// \brief Concept class for standard graph maps.
76.1237 ///
76.1238 - /// This class describes the common interface of the graph maps
76.1239 - /// (NodeMap, ArcMap), that is maps that can be used to
76.1240 - /// associate data to graph descriptors (nodes or arcs).
76.1241 - template <typename _Graph, typename _Item, typename _Value>
76.1242 - class GraphMap : public ReadWriteMap<_Item, _Value> {
76.1243 + /// This class describes the concept of standard graph maps, i.e.
76.1244 + /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and
76.1245 + /// graph types, which can be used for associating data to graph items.
76.1246 + /// The standard graph maps must conform to the ReferenceMap concept.
76.1247 + template <typename GR, typename K, typename V>
76.1248 + class GraphMap : public ReferenceMap<K, V, V&, const V&> {
76.1249 + typedef ReferenceMap<K, V, V&, const V&> Parent;
76.1250 +
76.1251 public:
76.1252
76.1253 - typedef ReadWriteMap<_Item, _Value> Parent;
76.1254 + /// The key type of the map.
76.1255 + typedef K Key;
76.1256 + /// The value type of the map.
76.1257 + typedef V Value;
76.1258 + /// The reference type of the map.
76.1259 + typedef Value& Reference;
76.1260 + /// The const reference type of the map.
76.1261 + typedef const Value& ConstReference;
76.1262
76.1263 - /// The graph type of the map.
76.1264 - typedef _Graph Graph;
76.1265 - /// The key type of the map.
76.1266 - typedef _Item Key;
76.1267 - /// The value type of the map.
76.1268 - typedef _Value Value;
76.1269 + // The reference map tag.
76.1270 + typedef True ReferenceMapTag;
76.1271
76.1272 /// \brief Construct a new map.
76.1273 ///
76.1274 /// Construct a new map for the graph.
76.1275 - explicit GraphMap(const Graph&) {}
76.1276 + explicit GraphMap(const GR&) {}
76.1277 /// \brief Construct a new map with default value.
76.1278 ///
76.1279 - /// Construct a new map for the graph and initalise the values.
76.1280 - GraphMap(const Graph&, const Value&) {}
76.1281 + /// Construct a new map for the graph and initalize the values.
76.1282 + GraphMap(const GR&, const Value&) {}
76.1283
76.1284 private:
76.1285 /// \brief Copy constructor.
76.1286 @@ -1012,9 +1026,9 @@
76.1287 /// Copy Constructor.
76.1288 GraphMap(const GraphMap&) : Parent() {}
76.1289
76.1290 - /// \brief Assign operator.
76.1291 + /// \brief Assignment operator.
76.1292 ///
76.1293 - /// Assign operator. It does not mofify the underlying graph,
76.1294 + /// Assignment operator. It does not mofify the underlying graph,
76.1295 /// it just iterates on the current item set and set the map
76.1296 /// with the value returned by the assigned map.
76.1297 template <typename CMap>
76.1298 @@ -1027,53 +1041,55 @@
76.1299 template<typename _Map>
76.1300 struct Constraints {
76.1301 void constraints() {
76.1302 - checkConcept<ReadWriteMap<Key, Value>, _Map >();
76.1303 - // Construction with a graph parameter
76.1304 - _Map a(g);
76.1305 - // Constructor with a graph and a default value parameter
76.1306 - _Map a2(g,t);
76.1307 - // Copy constructor.
76.1308 - // _Map b(c);
76.1309 + checkConcept
76.1310 + <ReferenceMap<Key, Value, Value&, const Value&>, _Map>();
76.1311 + _Map m1(g);
76.1312 + _Map m2(g,t);
76.1313 +
76.1314 + // Copy constructor
76.1315 + // _Map m3(m);
76.1316
76.1317 + // Assignment operator
76.1318 // ReadMap<Key, Value> cmap;
76.1319 - // b = cmap;
76.1320 + // m3 = cmap;
76.1321
76.1322 - ignore_unused_variable_warning(a);
76.1323 - ignore_unused_variable_warning(a2);
76.1324 - // ignore_unused_variable_warning(b);
76.1325 + ignore_unused_variable_warning(m1);
76.1326 + ignore_unused_variable_warning(m2);
76.1327 + // ignore_unused_variable_warning(m3);
76.1328 }
76.1329
76.1330 - const _Map &c;
76.1331 - const Graph &g;
76.1332 + const _Map &m;
76.1333 + const GR &g;
76.1334 const typename GraphMap::Value &t;
76.1335 };
76.1336
76.1337 };
76.1338
76.1339 - /// \brief An empty mappable digraph class.
76.1340 + /// \brief Skeleton class for mappable directed graphs.
76.1341 ///
76.1342 - /// This class provides beside the core digraph features
76.1343 - /// map interface for the digraph structure.
76.1344 + /// This class describes the interface of mappable directed graphs.
76.1345 + /// It extends \ref BaseDigraphComponent with the standard digraph
76.1346 + /// map classes, namely \c NodeMap and \c ArcMap.
76.1347 /// This concept is part of the Digraph concept.
76.1348 - template <typename _Base = BaseDigraphComponent>
76.1349 - class MappableDigraphComponent : public _Base {
76.1350 + template <typename BAS = BaseDigraphComponent>
76.1351 + class MappableDigraphComponent : public BAS {
76.1352 public:
76.1353
76.1354 - typedef _Base Base;
76.1355 + typedef BAS Base;
76.1356 typedef typename Base::Node Node;
76.1357 typedef typename Base::Arc Arc;
76.1358
76.1359 typedef MappableDigraphComponent Digraph;
76.1360
76.1361 - /// \brief ReadWrite map of the nodes.
76.1362 + /// \brief Standard graph map for the nodes.
76.1363 ///
76.1364 - /// ReadWrite map of the nodes.
76.1365 - ///
76.1366 - template <typename _Value>
76.1367 - class NodeMap : public GraphMap<Digraph, Node, _Value> {
76.1368 + /// Standard graph map for the nodes.
76.1369 + /// It conforms to the ReferenceMap concept.
76.1370 + template <typename V>
76.1371 + class NodeMap : public GraphMap<MappableDigraphComponent, Node, V> {
76.1372 + typedef GraphMap<MappableDigraphComponent, Node, V> Parent;
76.1373 +
76.1374 public:
76.1375 - typedef GraphMap<MappableDigraphComponent, Node, _Value> Parent;
76.1376 -
76.1377 /// \brief Construct a new map.
76.1378 ///
76.1379 /// Construct a new map for the digraph.
76.1380 @@ -1082,8 +1098,8 @@
76.1381
76.1382 /// \brief Construct a new map with default value.
76.1383 ///
76.1384 - /// Construct a new map for the digraph and initalise the values.
76.1385 - NodeMap(const MappableDigraphComponent& digraph, const _Value& value)
76.1386 + /// Construct a new map for the digraph and initalize the values.
76.1387 + NodeMap(const MappableDigraphComponent& digraph, const V& value)
76.1388 : Parent(digraph, value) {}
76.1389
76.1390 private:
76.1391 @@ -1092,26 +1108,26 @@
76.1392 /// Copy Constructor.
76.1393 NodeMap(const NodeMap& nm) : Parent(nm) {}
76.1394
76.1395 - /// \brief Assign operator.
76.1396 + /// \brief Assignment operator.
76.1397 ///
76.1398 - /// Assign operator.
76.1399 + /// Assignment operator.
76.1400 template <typename CMap>
76.1401 NodeMap& operator=(const CMap&) {
76.1402 - checkConcept<ReadMap<Node, _Value>, CMap>();
76.1403 + checkConcept<ReadMap<Node, V>, CMap>();
76.1404 return *this;
76.1405 }
76.1406
76.1407 };
76.1408
76.1409 - /// \brief ReadWrite map of the arcs.
76.1410 + /// \brief Standard graph map for the arcs.
76.1411 ///
76.1412 - /// ReadWrite map of the arcs.
76.1413 - ///
76.1414 - template <typename _Value>
76.1415 - class ArcMap : public GraphMap<Digraph, Arc, _Value> {
76.1416 + /// Standard graph map for the arcs.
76.1417 + /// It conforms to the ReferenceMap concept.
76.1418 + template <typename V>
76.1419 + class ArcMap : public GraphMap<MappableDigraphComponent, Arc, V> {
76.1420 + typedef GraphMap<MappableDigraphComponent, Arc, V> Parent;
76.1421 +
76.1422 public:
76.1423 - typedef GraphMap<MappableDigraphComponent, Arc, _Value> Parent;
76.1424 -
76.1425 /// \brief Construct a new map.
76.1426 ///
76.1427 /// Construct a new map for the digraph.
76.1428 @@ -1120,8 +1136,8 @@
76.1429
76.1430 /// \brief Construct a new map with default value.
76.1431 ///
76.1432 - /// Construct a new map for the digraph and initalise the values.
76.1433 - ArcMap(const MappableDigraphComponent& digraph, const _Value& value)
76.1434 + /// Construct a new map for the digraph and initalize the values.
76.1435 + ArcMap(const MappableDigraphComponent& digraph, const V& value)
76.1436 : Parent(digraph, value) {}
76.1437
76.1438 private:
76.1439 @@ -1130,12 +1146,12 @@
76.1440 /// Copy Constructor.
76.1441 ArcMap(const ArcMap& nm) : Parent(nm) {}
76.1442
76.1443 - /// \brief Assign operator.
76.1444 + /// \brief Assignment operator.
76.1445 ///
76.1446 - /// Assign operator.
76.1447 + /// Assignment operator.
76.1448 template <typename CMap>
76.1449 ArcMap& operator=(const CMap&) {
76.1450 - checkConcept<ReadMap<Arc, _Value>, CMap>();
76.1451 + checkConcept<ReadMap<Arc, V>, CMap>();
76.1452 return *this;
76.1453 }
76.1454
76.1455 @@ -1182,33 +1198,34 @@
76.1456 }
76.1457 }
76.1458
76.1459 - _Digraph& digraph;
76.1460 + const _Digraph& digraph;
76.1461 };
76.1462 };
76.1463
76.1464 - /// \brief An empty mappable base bipartite graph class.
76.1465 + /// \brief Skeleton class for mappable undirected graphs.
76.1466 ///
76.1467 - /// This class provides beside the core graph features
76.1468 - /// map interface for the graph structure.
76.1469 + /// This class describes the interface of mappable undirected graphs.
76.1470 + /// It extends \ref MappableDigraphComponent with the standard graph
76.1471 + /// map class for edges (\c EdgeMap).
76.1472 /// This concept is part of the Graph concept.
76.1473 - template <typename _Base = BaseGraphComponent>
76.1474 - class MappableGraphComponent : public MappableDigraphComponent<_Base> {
76.1475 + template <typename BAS = BaseGraphComponent>
76.1476 + class MappableGraphComponent : public MappableDigraphComponent<BAS> {
76.1477 public:
76.1478
76.1479 - typedef _Base Base;
76.1480 + typedef BAS Base;
76.1481 typedef typename Base::Edge Edge;
76.1482
76.1483 typedef MappableGraphComponent Graph;
76.1484
76.1485 - /// \brief ReadWrite map of the edges.
76.1486 + /// \brief Standard graph map for the edges.
76.1487 ///
76.1488 - /// ReadWrite map of the edges.
76.1489 - ///
76.1490 - template <typename _Value>
76.1491 - class EdgeMap : public GraphMap<Graph, Edge, _Value> {
76.1492 + /// Standard graph map for the edges.
76.1493 + /// It conforms to the ReferenceMap concept.
76.1494 + template <typename V>
76.1495 + class EdgeMap : public GraphMap<MappableGraphComponent, Edge, V> {
76.1496 + typedef GraphMap<MappableGraphComponent, Edge, V> Parent;
76.1497 +
76.1498 public:
76.1499 - typedef GraphMap<MappableGraphComponent, Edge, _Value> Parent;
76.1500 -
76.1501 /// \brief Construct a new map.
76.1502 ///
76.1503 /// Construct a new map for the graph.
76.1504 @@ -1217,8 +1234,8 @@
76.1505
76.1506 /// \brief Construct a new map with default value.
76.1507 ///
76.1508 - /// Construct a new map for the graph and initalise the values.
76.1509 - EdgeMap(const MappableGraphComponent& graph, const _Value& value)
76.1510 + /// Construct a new map for the graph and initalize the values.
76.1511 + EdgeMap(const MappableGraphComponent& graph, const V& value)
76.1512 : Parent(graph, value) {}
76.1513
76.1514 private:
76.1515 @@ -1227,12 +1244,12 @@
76.1516 /// Copy Constructor.
76.1517 EdgeMap(const EdgeMap& nm) : Parent(nm) {}
76.1518
76.1519 - /// \brief Assign operator.
76.1520 + /// \brief Assignment operator.
76.1521 ///
76.1522 - /// Assign operator.
76.1523 + /// Assignment operator.
76.1524 template <typename CMap>
76.1525 EdgeMap& operator=(const CMap&) {
76.1526 - checkConcept<ReadMap<Edge, _Value>, CMap>();
76.1527 + checkConcept<ReadMap<Edge, V>, CMap>();
76.1528 return *this;
76.1529 }
76.1530
76.1531 @@ -1249,7 +1266,7 @@
76.1532 };
76.1533
76.1534 void constraints() {
76.1535 - checkConcept<MappableGraphComponent<Base>, _Graph>();
76.1536 + checkConcept<MappableDigraphComponent<Base>, _Graph>();
76.1537
76.1538 { // int map test
76.1539 typedef typename _Graph::template EdgeMap<int> IntEdgeMap;
76.1540 @@ -1266,35 +1283,35 @@
76.1541 }
76.1542 }
76.1543
76.1544 - _Graph& graph;
76.1545 + const _Graph& graph;
76.1546 };
76.1547 };
76.1548
76.1549 - /// \brief An empty extendable digraph class.
76.1550 + /// \brief Skeleton class for extendable directed graphs.
76.1551 ///
76.1552 - /// This class provides beside the core digraph features digraph
76.1553 - /// extendable interface for the digraph structure. The main
76.1554 - /// difference between the base and this interface is that the
76.1555 - /// digraph alterations should handled already on this level.
76.1556 - template <typename _Base = BaseDigraphComponent>
76.1557 - class ExtendableDigraphComponent : public _Base {
76.1558 + /// This class describes the interface of extendable directed graphs.
76.1559 + /// It extends \ref BaseDigraphComponent with functions for adding
76.1560 + /// nodes and arcs to the digraph.
76.1561 + /// This concept requires \ref AlterableDigraphComponent.
76.1562 + template <typename BAS = BaseDigraphComponent>
76.1563 + class ExtendableDigraphComponent : public BAS {
76.1564 public:
76.1565 - typedef _Base Base;
76.1566 + typedef BAS Base;
76.1567
76.1568 - typedef typename _Base::Node Node;
76.1569 - typedef typename _Base::Arc Arc;
76.1570 + typedef typename Base::Node Node;
76.1571 + typedef typename Base::Arc Arc;
76.1572
76.1573 - /// \brief Adds a new node to the digraph.
76.1574 + /// \brief Add a new node to the digraph.
76.1575 ///
76.1576 - /// Adds a new node to the digraph.
76.1577 - ///
76.1578 + /// This function adds a new node to the digraph.
76.1579 Node addNode() {
76.1580 return INVALID;
76.1581 }
76.1582
76.1583 - /// \brief Adds a new arc connects the given two nodes.
76.1584 + /// \brief Add a new arc connecting the given two nodes.
76.1585 ///
76.1586 - /// Adds a new arc connects the the given two nodes.
76.1587 + /// This function adds a new arc connecting the given two nodes
76.1588 + /// of the digraph.
76.1589 Arc addArc(const Node&, const Node&) {
76.1590 return INVALID;
76.1591 }
76.1592 @@ -1314,33 +1331,32 @@
76.1593 };
76.1594 };
76.1595
76.1596 - /// \brief An empty extendable base undirected graph class.
76.1597 + /// \brief Skeleton class for extendable undirected graphs.
76.1598 ///
76.1599 - /// This class provides beside the core undirected graph features
76.1600 - /// core undircted graph extend interface for the graph structure.
76.1601 - /// The main difference between the base and this interface is
76.1602 - /// that the graph alterations should handled already on this
76.1603 - /// level.
76.1604 - template <typename _Base = BaseGraphComponent>
76.1605 - class ExtendableGraphComponent : public _Base {
76.1606 + /// This class describes the interface of extendable undirected graphs.
76.1607 + /// It extends \ref BaseGraphComponent with functions for adding
76.1608 + /// nodes and edges to the graph.
76.1609 + /// This concept requires \ref AlterableGraphComponent.
76.1610 + template <typename BAS = BaseGraphComponent>
76.1611 + class ExtendableGraphComponent : public BAS {
76.1612 public:
76.1613
76.1614 - typedef _Base Base;
76.1615 - typedef typename _Base::Node Node;
76.1616 - typedef typename _Base::Edge Edge;
76.1617 + typedef BAS Base;
76.1618 + typedef typename Base::Node Node;
76.1619 + typedef typename Base::Edge Edge;
76.1620
76.1621 - /// \brief Adds a new node to the graph.
76.1622 + /// \brief Add a new node to the digraph.
76.1623 ///
76.1624 - /// Adds a new node to the graph.
76.1625 - ///
76.1626 + /// This function adds a new node to the digraph.
76.1627 Node addNode() {
76.1628 return INVALID;
76.1629 }
76.1630
76.1631 - /// \brief Adds a new arc connects the given two nodes.
76.1632 + /// \brief Add a new edge connecting the given two nodes.
76.1633 ///
76.1634 - /// Adds a new arc connects the the given two nodes.
76.1635 - Edge addArc(const Node&, const Node&) {
76.1636 + /// This function adds a new edge connecting the given two nodes
76.1637 + /// of the graph.
76.1638 + Edge addEdge(const Node&, const Node&) {
76.1639 return INVALID;
76.1640 }
76.1641
76.1642 @@ -1359,39 +1375,38 @@
76.1643 };
76.1644 };
76.1645
76.1646 - /// \brief An empty erasable digraph class.
76.1647 + /// \brief Skeleton class for erasable directed graphs.
76.1648 ///
76.1649 - /// This class provides beside the core digraph features core erase
76.1650 - /// functions for the digraph structure. The main difference between
76.1651 - /// the base and this interface is that the digraph alterations
76.1652 - /// should handled already on this level.
76.1653 - template <typename _Base = BaseDigraphComponent>
76.1654 - class ErasableDigraphComponent : public _Base {
76.1655 + /// This class describes the interface of erasable directed graphs.
76.1656 + /// It extends \ref BaseDigraphComponent with functions for removing
76.1657 + /// nodes and arcs from the digraph.
76.1658 + /// This concept requires \ref AlterableDigraphComponent.
76.1659 + template <typename BAS = BaseDigraphComponent>
76.1660 + class ErasableDigraphComponent : public BAS {
76.1661 public:
76.1662
76.1663 - typedef _Base Base;
76.1664 + typedef BAS Base;
76.1665 typedef typename Base::Node Node;
76.1666 typedef typename Base::Arc Arc;
76.1667
76.1668 /// \brief Erase a node from the digraph.
76.1669 ///
76.1670 - /// Erase a node from the digraph. This function should
76.1671 - /// erase all arcs connecting to the node.
76.1672 + /// This function erases the given node from the digraph and all arcs
76.1673 + /// connected to the node.
76.1674 void erase(const Node&) {}
76.1675
76.1676 /// \brief Erase an arc from the digraph.
76.1677 ///
76.1678 - /// Erase an arc from the digraph.
76.1679 - ///
76.1680 + /// This function erases the given arc from the digraph.
76.1681 void erase(const Arc&) {}
76.1682
76.1683 template <typename _Digraph>
76.1684 struct Constraints {
76.1685 void constraints() {
76.1686 checkConcept<Base, _Digraph>();
76.1687 - typename _Digraph::Node node;
76.1688 + const typename _Digraph::Node node(INVALID);
76.1689 digraph.erase(node);
76.1690 - typename _Digraph::Arc arc;
76.1691 + const typename _Digraph::Arc arc(INVALID);
76.1692 digraph.erase(arc);
76.1693 }
76.1694
76.1695 @@ -1399,39 +1414,38 @@
76.1696 };
76.1697 };
76.1698
76.1699 - /// \brief An empty erasable base undirected graph class.
76.1700 + /// \brief Skeleton class for erasable undirected graphs.
76.1701 ///
76.1702 - /// This class provides beside the core undirected graph features
76.1703 - /// core erase functions for the undirceted graph structure. The
76.1704 - /// main difference between the base and this interface is that
76.1705 - /// the graph alterations should handled already on this level.
76.1706 - template <typename _Base = BaseGraphComponent>
76.1707 - class ErasableGraphComponent : public _Base {
76.1708 + /// This class describes the interface of erasable undirected graphs.
76.1709 + /// It extends \ref BaseGraphComponent with functions for removing
76.1710 + /// nodes and edges from the graph.
76.1711 + /// This concept requires \ref AlterableGraphComponent.
76.1712 + template <typename BAS = BaseGraphComponent>
76.1713 + class ErasableGraphComponent : public BAS {
76.1714 public:
76.1715
76.1716 - typedef _Base Base;
76.1717 + typedef BAS Base;
76.1718 typedef typename Base::Node Node;
76.1719 typedef typename Base::Edge Edge;
76.1720
76.1721 /// \brief Erase a node from the graph.
76.1722 ///
76.1723 - /// Erase a node from the graph. This function should erase
76.1724 - /// arcs connecting to the node.
76.1725 + /// This function erases the given node from the graph and all edges
76.1726 + /// connected to the node.
76.1727 void erase(const Node&) {}
76.1728
76.1729 - /// \brief Erase an arc from the graph.
76.1730 + /// \brief Erase an edge from the digraph.
76.1731 ///
76.1732 - /// Erase an arc from the graph.
76.1733 - ///
76.1734 + /// This function erases the given edge from the digraph.
76.1735 void erase(const Edge&) {}
76.1736
76.1737 template <typename _Graph>
76.1738 struct Constraints {
76.1739 void constraints() {
76.1740 checkConcept<Base, _Graph>();
76.1741 - typename _Graph::Node node;
76.1742 + const typename _Graph::Node node(INVALID);
76.1743 graph.erase(node);
76.1744 - typename _Graph::Edge edge;
76.1745 + const typename _Graph::Edge edge(INVALID);
76.1746 graph.erase(edge);
76.1747 }
76.1748
76.1749 @@ -1439,22 +1453,21 @@
76.1750 };
76.1751 };
76.1752
76.1753 - /// \brief An empty clearable base digraph class.
76.1754 + /// \brief Skeleton class for clearable directed graphs.
76.1755 ///
76.1756 - /// This class provides beside the core digraph features core clear
76.1757 - /// functions for the digraph structure. The main difference between
76.1758 - /// the base and this interface is that the digraph alterations
76.1759 - /// should handled already on this level.
76.1760 - template <typename _Base = BaseDigraphComponent>
76.1761 - class ClearableDigraphComponent : public _Base {
76.1762 + /// This class describes the interface of clearable directed graphs.
76.1763 + /// It extends \ref BaseDigraphComponent with a function for clearing
76.1764 + /// the digraph.
76.1765 + /// This concept requires \ref AlterableDigraphComponent.
76.1766 + template <typename BAS = BaseDigraphComponent>
76.1767 + class ClearableDigraphComponent : public BAS {
76.1768 public:
76.1769
76.1770 - typedef _Base Base;
76.1771 + typedef BAS Base;
76.1772
76.1773 /// \brief Erase all nodes and arcs from the digraph.
76.1774 ///
76.1775 - /// Erase all nodes and arcs from the digraph.
76.1776 - ///
76.1777 + /// This function erases all nodes and arcs from the digraph.
76.1778 void clear() {}
76.1779
76.1780 template <typename _Digraph>
76.1781 @@ -1464,29 +1477,35 @@
76.1782 digraph.clear();
76.1783 }
76.1784
76.1785 - _Digraph digraph;
76.1786 + _Digraph& digraph;
76.1787 };
76.1788 };
76.1789
76.1790 - /// \brief An empty clearable base undirected graph class.
76.1791 + /// \brief Skeleton class for clearable undirected graphs.
76.1792 ///
76.1793 - /// This class provides beside the core undirected graph features
76.1794 - /// core clear functions for the undirected graph structure. The
76.1795 - /// main difference between the base and this interface is that
76.1796 - /// the graph alterations should handled already on this level.
76.1797 - template <typename _Base = BaseGraphComponent>
76.1798 - class ClearableGraphComponent : public ClearableDigraphComponent<_Base> {
76.1799 + /// This class describes the interface of clearable undirected graphs.
76.1800 + /// It extends \ref BaseGraphComponent with a function for clearing
76.1801 + /// the graph.
76.1802 + /// This concept requires \ref AlterableGraphComponent.
76.1803 + template <typename BAS = BaseGraphComponent>
76.1804 + class ClearableGraphComponent : public ClearableDigraphComponent<BAS> {
76.1805 public:
76.1806
76.1807 - typedef _Base Base;
76.1808 + typedef BAS Base;
76.1809 +
76.1810 + /// \brief Erase all nodes and edges from the graph.
76.1811 + ///
76.1812 + /// This function erases all nodes and edges from the graph.
76.1813 + void clear() {}
76.1814
76.1815 template <typename _Graph>
76.1816 struct Constraints {
76.1817 void constraints() {
76.1818 - checkConcept<ClearableGraphComponent<Base>, _Graph>();
76.1819 + checkConcept<Base, _Graph>();
76.1820 + graph.clear();
76.1821 }
76.1822
76.1823 - _Graph graph;
76.1824 + _Graph& graph;
76.1825 };
76.1826 };
76.1827
77.1 --- a/lemon/concepts/heap.h Fri Nov 13 12:33:33 2009 +0100
77.2 +++ b/lemon/concepts/heap.h Thu Dec 10 17:05:35 2009 +0100
77.3 @@ -2,7 +2,7 @@
77.4 *
77.5 * This file is a part of LEMON, a generic C++ optimization library.
77.6 *
77.7 - * Copyright (C) 2003-2008
77.8 + * Copyright (C) 2003-2009
77.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
77.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
77.11 *
77.12 @@ -20,10 +20,11 @@
77.13 ///\file
77.14 ///\brief The concept of heaps.
77.15
77.16 -#ifndef LEMON_CONCEPT_HEAP_H
77.17 -#define LEMON_CONCEPT_HEAP_H
77.18 +#ifndef LEMON_CONCEPTS_HEAP_H
77.19 +#define LEMON_CONCEPTS_HEAP_H
77.20
77.21 #include <lemon/core.h>
77.22 +#include <lemon/concept_check.h>
77.23
77.24 namespace lemon {
77.25
77.26 @@ -34,17 +35,32 @@
77.27
77.28 /// \brief The heap concept.
77.29 ///
77.30 - /// Concept class describing the main interface of heaps.
77.31 - template <typename Priority, typename ItemIntMap>
77.32 + /// Concept class describing the main interface of heaps. A \e heap
77.33 + /// is a data structure for storing items with specified values called
77.34 + /// \e priorities in such a way that finding the item with minimum
77.35 + /// priority is efficient. In a heap one can change the priority of an
77.36 + /// item, add or erase an item, etc.
77.37 + ///
77.38 + /// \tparam PR Type of the priority of the items.
77.39 + /// \tparam IM A read and writable item map with int values, used
77.40 + /// internally to handle the cross references.
77.41 + /// \tparam Comp A functor class for the ordering of the priorities.
77.42 + /// The default is \c std::less<PR>.
77.43 +#ifdef DOXYGEN
77.44 + template <typename PR, typename IM, typename Comp = std::less<PR> >
77.45 +#else
77.46 + template <typename PR, typename IM>
77.47 +#endif
77.48 class Heap {
77.49 public:
77.50
77.51 + /// Type of the item-int map.
77.52 + typedef IM ItemIntMap;
77.53 + /// Type of the priorities.
77.54 + typedef PR Prio;
77.55 /// Type of the items stored in the heap.
77.56 typedef typename ItemIntMap::Key Item;
77.57
77.58 - /// Type of the priorities.
77.59 - typedef Priority Prio;
77.60 -
77.61 /// \brief Type to represent the states of the items.
77.62 ///
77.63 /// Each item has a state associated to it. It can be "in heap",
77.64 @@ -52,12 +68,12 @@
77.65 /// from the point of view of the heap, but may be useful for
77.66 /// the user.
77.67 ///
77.68 - /// The \c ItemIntMap must be initialized in such a way, that it
77.69 - /// assigns \c PRE_HEAP (<tt>-1</tt>) to every item.
77.70 + /// The item-int map must be initialized in such way that it assigns
77.71 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
77.72 enum State {
77.73 - IN_HEAP = 0,
77.74 - PRE_HEAP = -1,
77.75 - POST_HEAP = -2
77.76 + IN_HEAP = 0, ///< = 0. The "in heap" state constant.
77.77 + PRE_HEAP = -1, ///< = -1. The "pre heap" state constant.
77.78 + POST_HEAP = -2 ///< = -2. The "post heap" state constant.
77.79 };
77.80
77.81 /// \brief The constructor.
77.82 @@ -118,8 +134,8 @@
77.83 /// \brief The priority of an item.
77.84 ///
77.85 /// Returns the priority of the given item.
77.86 + /// \param i The item.
77.87 /// \pre \c i must be in the heap.
77.88 - /// \param i The item.
77.89 Prio operator[](const Item &i) const {}
77.90
77.91 /// \brief Sets the priority of an item or inserts it, if it is
77.92 @@ -136,17 +152,17 @@
77.93 /// \brief Decreases the priority of an item to the given value.
77.94 ///
77.95 /// Decreases the priority of an item to the given value.
77.96 - /// \pre \c i must be stored in the heap with priority at least \c p.
77.97 /// \param i The item.
77.98 /// \param p The priority.
77.99 + /// \pre \c i must be stored in the heap with priority at least \c p.
77.100 void decrease(const Item &i, const Prio &p) {}
77.101
77.102 /// \brief Increases the priority of an item to the given value.
77.103 ///
77.104 /// Increases the priority of an item to the given value.
77.105 - /// \pre \c i must be stored in the heap with priority at most \c p.
77.106 /// \param i The item.
77.107 /// \param p The priority.
77.108 + /// \pre \c i must be stored in the heap with priority at most \c p.
77.109 void increase(const Item &i, const Prio &p) {}
77.110
77.111 /// \brief Returns if an item is in, has already been in, or has
77.112 @@ -242,4 +258,4 @@
77.113 /// @}
77.114 } // namespace lemon
77.115 }
77.116 -#endif // LEMON_CONCEPT_PATH_H
77.117 +#endif
78.1 --- a/lemon/concepts/maps.h Fri Nov 13 12:33:33 2009 +0100
78.2 +++ b/lemon/concepts/maps.h Thu Dec 10 17:05:35 2009 +0100
78.3 @@ -2,7 +2,7 @@
78.4 *
78.5 * This file is a part of LEMON, a generic C++ optimization library.
78.6 *
78.7 - * Copyright (C) 2003-2008
78.8 + * Copyright (C) 2003-2009
78.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
78.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
78.11 *
78.12 @@ -16,8 +16,8 @@
78.13 *
78.14 */
78.15
78.16 -#ifndef LEMON_CONCEPT_MAPS_H
78.17 -#define LEMON_CONCEPT_MAPS_H
78.18 +#ifndef LEMON_CONCEPTS_MAPS_H
78.19 +#define LEMON_CONCEPTS_MAPS_H
78.20
78.21 #include <lemon/core.h>
78.22 #include <lemon/concept_check.h>
78.23 @@ -182,7 +182,8 @@
78.24
78.25 template<typename _ReferenceMap>
78.26 struct Constraints {
78.27 - void constraints() {
78.28 + typename enable_if<typename _ReferenceMap::ReferenceMapTag, void>::type
78.29 + constraints() {
78.30 checkConcept<ReadWriteMap<K, T>, _ReferenceMap >();
78.31 ref = m[key];
78.32 m[key] = val;
78.33 @@ -213,4 +214,4 @@
78.34
78.35 } //namespace lemon
78.36
78.37 -#endif // LEMON_CONCEPT_MAPS_H
78.38 +#endif
79.1 --- a/lemon/concepts/path.h Fri Nov 13 12:33:33 2009 +0100
79.2 +++ b/lemon/concepts/path.h Thu Dec 10 17:05:35 2009 +0100
79.3 @@ -2,7 +2,7 @@
79.4 *
79.5 * This file is a part of LEMON, a generic C++ optimization library.
79.6 *
79.7 - * Copyright (C) 2003-2008
79.8 + * Copyright (C) 2003-2009
79.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
79.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
79.11 *
79.12 @@ -21,8 +21,8 @@
79.13 ///\brief Classes for representing paths in digraphs.
79.14 ///
79.15
79.16 -#ifndef LEMON_CONCEPT_PATH_H
79.17 -#define LEMON_CONCEPT_PATH_H
79.18 +#ifndef LEMON_CONCEPTS_PATH_H
79.19 +#define LEMON_CONCEPTS_PATH_H
79.20
79.21 #include <lemon/core.h>
79.22 #include <lemon/concept_check.h>
79.23 @@ -38,19 +38,19 @@
79.24 ///
79.25 /// A skeleton structure for representing directed paths in a
79.26 /// digraph.
79.27 - /// \tparam _Digraph The digraph type in which the path is.
79.28 + /// \tparam GR The digraph type in which the path is.
79.29 ///
79.30 /// In a sense, the path can be treated as a list of arcs. The
79.31 /// lemon path type stores just this list. As a consequence it
79.32 /// cannot enumerate the nodes in the path and the zero length
79.33 /// paths cannot store the source.
79.34 ///
79.35 - template <typename _Digraph>
79.36 + template <typename GR>
79.37 class Path {
79.38 public:
79.39
79.40 /// Type of the underlying digraph.
79.41 - typedef _Digraph Digraph;
79.42 + typedef GR Digraph;
79.43 /// Arc type of the underlying digraph.
79.44 typedef typename Digraph::Arc Arc;
79.45
79.46 @@ -205,18 +205,17 @@
79.47 /// LEMON such algorithms gives back a path dumper what can
79.48 /// assigned to a real path and the dumpers can be implemented as
79.49 /// an adaptor class to the predecessor map.
79.50 -
79.51 - /// \tparam _Digraph The digraph type in which the path is.
79.52 + ///
79.53 + /// \tparam GR The digraph type in which the path is.
79.54 ///
79.55 /// The paths can be constructed from any path type by a
79.56 /// template constructor or a template assignment operator.
79.57 - ///
79.58 - template <typename _Digraph>
79.59 + template <typename GR>
79.60 class PathDumper {
79.61 public:
79.62
79.63 /// Type of the underlying digraph.
79.64 - typedef _Digraph Digraph;
79.65 + typedef GR Digraph;
79.66 /// Arc type of the underlying digraph.
79.67 typedef typename Digraph::Arc Arc;
79.68
79.69 @@ -305,4 +304,4 @@
79.70
79.71 } // namespace lemon
79.72
79.73 -#endif // LEMON_CONCEPT_PATH_H
79.74 +#endif
80.1 --- a/lemon/config.h.cmake Fri Nov 13 12:33:33 2009 +0100
80.2 +++ b/lemon/config.h.cmake Thu Dec 10 17:05:35 2009 +0100
80.3 @@ -1,1 +1,8 @@
80.4 +#define LEMON_VERSION "@PROJECT_VERSION@"
80.5 #cmakedefine LEMON_HAVE_LONG_LONG 1
80.6 +#cmakedefine LEMON_HAVE_LP 1
80.7 +#cmakedefine LEMON_HAVE_MIP 1
80.8 +#cmakedefine LEMON_HAVE_GLPK 1
80.9 +#cmakedefine LEMON_HAVE_CPLEX 1
80.10 +#cmakedefine LEMON_HAVE_CLP 1
80.11 +#cmakedefine LEMON_HAVE_CBC 1
81.1 --- a/lemon/config.h.in Fri Nov 13 12:33:33 2009 +0100
81.2 +++ b/lemon/config.h.in Thu Dec 10 17:05:35 2009 +0100
81.3 @@ -1,8 +1,26 @@
81.4 +/* The version string */
81.5 +#undef LEMON_VERSION
81.6 +
81.7 +/* Define to 1 if you have long long */
81.8 +#undef LEMON_HAVE_LONG_LONG
81.9 +
81.10 +/* Define to 1 if you have any LP solver. */
81.11 +#undef LEMON_HAVE_LP
81.12 +
81.13 +/* Define to 1 if you have any MIP solver. */
81.14 +#undef LEMON_HAVE_MIP
81.15 +
81.16 /* Define to 1 if you have CPLEX. */
81.17 #undef LEMON_HAVE_CPLEX
81.18
81.19 /* Define to 1 if you have GLPK. */
81.20 #undef LEMON_HAVE_GLPK
81.21
81.22 -/* Define to 1 if you have long long */
81.23 -#undef LEMON_HAVE_LONG_LONG
81.24 +/* Define to 1 if you have SOPLEX */
81.25 +#undef LEMON_HAVE_SOPLEX
81.26 +
81.27 +/* Define to 1 if you have CLP */
81.28 +#undef LEMON_HAVE_CLP
81.29 +
81.30 +/* Define to 1 if you have CBC */
81.31 +#undef LEMON_HAVE_CBC
82.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
82.2 +++ b/lemon/connectivity.h Thu Dec 10 17:05:35 2009 +0100
82.3 @@ -0,0 +1,1665 @@
82.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
82.5 + *
82.6 + * This file is a part of LEMON, a generic C++ optimization library.
82.7 + *
82.8 + * Copyright (C) 2003-2009
82.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
82.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
82.11 + *
82.12 + * Permission to use, modify and distribute this software is granted
82.13 + * provided that this copyright notice appears in all copies. For
82.14 + * precise terms see the accompanying LICENSE file.
82.15 + *
82.16 + * This software is provided "AS IS" with no warranty of any kind,
82.17 + * express or implied, and with no claim as to its suitability for any
82.18 + * purpose.
82.19 + *
82.20 + */
82.21 +
82.22 +#ifndef LEMON_CONNECTIVITY_H
82.23 +#define LEMON_CONNECTIVITY_H
82.24 +
82.25 +#include <lemon/dfs.h>
82.26 +#include <lemon/bfs.h>
82.27 +#include <lemon/core.h>
82.28 +#include <lemon/maps.h>
82.29 +#include <lemon/adaptors.h>
82.30 +
82.31 +#include <lemon/concepts/digraph.h>
82.32 +#include <lemon/concepts/graph.h>
82.33 +#include <lemon/concept_check.h>
82.34 +
82.35 +#include <stack>
82.36 +#include <functional>
82.37 +
82.38 +/// \ingroup graph_properties
82.39 +/// \file
82.40 +/// \brief Connectivity algorithms
82.41 +///
82.42 +/// Connectivity algorithms
82.43 +
82.44 +namespace lemon {
82.45 +
82.46 + /// \ingroup graph_properties
82.47 + ///
82.48 + /// \brief Check whether an undirected graph is connected.
82.49 + ///
82.50 + /// This function checks whether the given undirected graph is connected,
82.51 + /// i.e. there is a path between any two nodes in the graph.
82.52 + ///
82.53 + /// \return \c true if the graph is connected.
82.54 + /// \note By definition, the empty graph is connected.
82.55 + ///
82.56 + /// \see countConnectedComponents(), connectedComponents()
82.57 + /// \see stronglyConnected()
82.58 + template <typename Graph>
82.59 + bool connected(const Graph& graph) {
82.60 + checkConcept<concepts::Graph, Graph>();
82.61 + typedef typename Graph::NodeIt NodeIt;
82.62 + if (NodeIt(graph) == INVALID) return true;
82.63 + Dfs<Graph> dfs(graph);
82.64 + dfs.run(NodeIt(graph));
82.65 + for (NodeIt it(graph); it != INVALID; ++it) {
82.66 + if (!dfs.reached(it)) {
82.67 + return false;
82.68 + }
82.69 + }
82.70 + return true;
82.71 + }
82.72 +
82.73 + /// \ingroup graph_properties
82.74 + ///
82.75 + /// \brief Count the number of connected components of an undirected graph
82.76 + ///
82.77 + /// This function counts the number of connected components of the given
82.78 + /// undirected graph.
82.79 + ///
82.80 + /// The connected components are the classes of an equivalence relation
82.81 + /// on the nodes of an undirected graph. Two nodes are in the same class
82.82 + /// if they are connected with a path.
82.83 + ///
82.84 + /// \return The number of connected components.
82.85 + /// \note By definition, the empty graph consists
82.86 + /// of zero connected components.
82.87 + ///
82.88 + /// \see connected(), connectedComponents()
82.89 + template <typename Graph>
82.90 + int countConnectedComponents(const Graph &graph) {
82.91 + checkConcept<concepts::Graph, Graph>();
82.92 + typedef typename Graph::Node Node;
82.93 + typedef typename Graph::Arc Arc;
82.94 +
82.95 + typedef NullMap<Node, Arc> PredMap;
82.96 + typedef NullMap<Node, int> DistMap;
82.97 +
82.98 + int compNum = 0;
82.99 + typename Bfs<Graph>::
82.100 + template SetPredMap<PredMap>::
82.101 + template SetDistMap<DistMap>::
82.102 + Create bfs(graph);
82.103 +
82.104 + PredMap predMap;
82.105 + bfs.predMap(predMap);
82.106 +
82.107 + DistMap distMap;
82.108 + bfs.distMap(distMap);
82.109 +
82.110 + bfs.init();
82.111 + for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
82.112 + if (!bfs.reached(n)) {
82.113 + bfs.addSource(n);
82.114 + bfs.start();
82.115 + ++compNum;
82.116 + }
82.117 + }
82.118 + return compNum;
82.119 + }
82.120 +
82.121 + /// \ingroup graph_properties
82.122 + ///
82.123 + /// \brief Find the connected components of an undirected graph
82.124 + ///
82.125 + /// This function finds the connected components of the given undirected
82.126 + /// graph.
82.127 + ///
82.128 + /// The connected components are the classes of an equivalence relation
82.129 + /// on the nodes of an undirected graph. Two nodes are in the same class
82.130 + /// if they are connected with a path.
82.131 + ///
82.132 + /// \image html connected_components.png
82.133 + /// \image latex connected_components.eps "Connected components" width=\textwidth
82.134 + ///
82.135 + /// \param graph The undirected graph.
82.136 + /// \retval compMap A writable node map. The values will be set from 0 to
82.137 + /// the number of the connected components minus one. Each value of the map
82.138 + /// will be set exactly once, and the values of a certain component will be
82.139 + /// set continuously.
82.140 + /// \return The number of connected components.
82.141 + /// \note By definition, the empty graph consists
82.142 + /// of zero connected components.
82.143 + ///
82.144 + /// \see connected(), countConnectedComponents()
82.145 + template <class Graph, class NodeMap>
82.146 + int connectedComponents(const Graph &graph, NodeMap &compMap) {
82.147 + checkConcept<concepts::Graph, Graph>();
82.148 + typedef typename Graph::Node Node;
82.149 + typedef typename Graph::Arc Arc;
82.150 + checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
82.151 +
82.152 + typedef NullMap<Node, Arc> PredMap;
82.153 + typedef NullMap<Node, int> DistMap;
82.154 +
82.155 + int compNum = 0;
82.156 + typename Bfs<Graph>::
82.157 + template SetPredMap<PredMap>::
82.158 + template SetDistMap<DistMap>::
82.159 + Create bfs(graph);
82.160 +
82.161 + PredMap predMap;
82.162 + bfs.predMap(predMap);
82.163 +
82.164 + DistMap distMap;
82.165 + bfs.distMap(distMap);
82.166 +
82.167 + bfs.init();
82.168 + for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
82.169 + if(!bfs.reached(n)) {
82.170 + bfs.addSource(n);
82.171 + while (!bfs.emptyQueue()) {
82.172 + compMap.set(bfs.nextNode(), compNum);
82.173 + bfs.processNextNode();
82.174 + }
82.175 + ++compNum;
82.176 + }
82.177 + }
82.178 + return compNum;
82.179 + }
82.180 +
82.181 + namespace _connectivity_bits {
82.182 +
82.183 + template <typename Digraph, typename Iterator >
82.184 + struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
82.185 + public:
82.186 + typedef typename Digraph::Node Node;
82.187 + LeaveOrderVisitor(Iterator it) : _it(it) {}
82.188 +
82.189 + void leave(const Node& node) {
82.190 + *(_it++) = node;
82.191 + }
82.192 +
82.193 + private:
82.194 + Iterator _it;
82.195 + };
82.196 +
82.197 + template <typename Digraph, typename Map>
82.198 + struct FillMapVisitor : public DfsVisitor<Digraph> {
82.199 + public:
82.200 + typedef typename Digraph::Node Node;
82.201 + typedef typename Map::Value Value;
82.202 +
82.203 + FillMapVisitor(Map& map, Value& value)
82.204 + : _map(map), _value(value) {}
82.205 +
82.206 + void reach(const Node& node) {
82.207 + _map.set(node, _value);
82.208 + }
82.209 + private:
82.210 + Map& _map;
82.211 + Value& _value;
82.212 + };
82.213 +
82.214 + template <typename Digraph, typename ArcMap>
82.215 + struct StronglyConnectedCutArcsVisitor : public DfsVisitor<Digraph> {
82.216 + public:
82.217 + typedef typename Digraph::Node Node;
82.218 + typedef typename Digraph::Arc Arc;
82.219 +
82.220 + StronglyConnectedCutArcsVisitor(const Digraph& digraph,
82.221 + ArcMap& cutMap,
82.222 + int& cutNum)
82.223 + : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
82.224 + _compMap(digraph, -1), _num(-1) {
82.225 + }
82.226 +
82.227 + void start(const Node&) {
82.228 + ++_num;
82.229 + }
82.230 +
82.231 + void reach(const Node& node) {
82.232 + _compMap.set(node, _num);
82.233 + }
82.234 +
82.235 + void examine(const Arc& arc) {
82.236 + if (_compMap[_digraph.source(arc)] !=
82.237 + _compMap[_digraph.target(arc)]) {
82.238 + _cutMap.set(arc, true);
82.239 + ++_cutNum;
82.240 + }
82.241 + }
82.242 + private:
82.243 + const Digraph& _digraph;
82.244 + ArcMap& _cutMap;
82.245 + int& _cutNum;
82.246 +
82.247 + typename Digraph::template NodeMap<int> _compMap;
82.248 + int _num;
82.249 + };
82.250 +
82.251 + }
82.252 +
82.253 +
82.254 + /// \ingroup graph_properties
82.255 + ///
82.256 + /// \brief Check whether a directed graph is strongly connected.
82.257 + ///
82.258 + /// This function checks whether the given directed graph is strongly
82.259 + /// connected, i.e. any two nodes of the digraph are
82.260 + /// connected with directed paths in both direction.
82.261 + ///
82.262 + /// \return \c true if the digraph is strongly connected.
82.263 + /// \note By definition, the empty digraph is strongly connected.
82.264 + ///
82.265 + /// \see countStronglyConnectedComponents(), stronglyConnectedComponents()
82.266 + /// \see connected()
82.267 + template <typename Digraph>
82.268 + bool stronglyConnected(const Digraph& digraph) {
82.269 + checkConcept<concepts::Digraph, Digraph>();
82.270 +
82.271 + typedef typename Digraph::Node Node;
82.272 + typedef typename Digraph::NodeIt NodeIt;
82.273 +
82.274 + typename Digraph::Node source = NodeIt(digraph);
82.275 + if (source == INVALID) return true;
82.276 +
82.277 + using namespace _connectivity_bits;
82.278 +
82.279 + typedef DfsVisitor<Digraph> Visitor;
82.280 + Visitor visitor;
82.281 +
82.282 + DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
82.283 + dfs.init();
82.284 + dfs.addSource(source);
82.285 + dfs.start();
82.286 +
82.287 + for (NodeIt it(digraph); it != INVALID; ++it) {
82.288 + if (!dfs.reached(it)) {
82.289 + return false;
82.290 + }
82.291 + }
82.292 +
82.293 + typedef ReverseDigraph<const Digraph> RDigraph;
82.294 + typedef typename RDigraph::NodeIt RNodeIt;
82.295 + RDigraph rdigraph(digraph);
82.296 +
82.297 + typedef DfsVisitor<RDigraph> RVisitor;
82.298 + RVisitor rvisitor;
82.299 +
82.300 + DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
82.301 + rdfs.init();
82.302 + rdfs.addSource(source);
82.303 + rdfs.start();
82.304 +
82.305 + for (RNodeIt it(rdigraph); it != INVALID; ++it) {
82.306 + if (!rdfs.reached(it)) {
82.307 + return false;
82.308 + }
82.309 + }
82.310 +
82.311 + return true;
82.312 + }
82.313 +
82.314 + /// \ingroup graph_properties
82.315 + ///
82.316 + /// \brief Count the number of strongly connected components of a
82.317 + /// directed graph
82.318 + ///
82.319 + /// This function counts the number of strongly connected components of
82.320 + /// the given directed graph.
82.321 + ///
82.322 + /// The strongly connected components are the classes of an
82.323 + /// equivalence relation on the nodes of a digraph. Two nodes are in
82.324 + /// the same class if they are connected with directed paths in both
82.325 + /// direction.
82.326 + ///
82.327 + /// \return The number of strongly connected components.
82.328 + /// \note By definition, the empty digraph has zero
82.329 + /// strongly connected components.
82.330 + ///
82.331 + /// \see stronglyConnected(), stronglyConnectedComponents()
82.332 + template <typename Digraph>
82.333 + int countStronglyConnectedComponents(const Digraph& digraph) {
82.334 + checkConcept<concepts::Digraph, Digraph>();
82.335 +
82.336 + using namespace _connectivity_bits;
82.337 +
82.338 + typedef typename Digraph::Node Node;
82.339 + typedef typename Digraph::Arc Arc;
82.340 + typedef typename Digraph::NodeIt NodeIt;
82.341 + typedef typename Digraph::ArcIt ArcIt;
82.342 +
82.343 + typedef std::vector<Node> Container;
82.344 + typedef typename Container::iterator Iterator;
82.345 +
82.346 + Container nodes(countNodes(digraph));
82.347 + typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
82.348 + Visitor visitor(nodes.begin());
82.349 +
82.350 + DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
82.351 + dfs.init();
82.352 + for (NodeIt it(digraph); it != INVALID; ++it) {
82.353 + if (!dfs.reached(it)) {
82.354 + dfs.addSource(it);
82.355 + dfs.start();
82.356 + }
82.357 + }
82.358 +
82.359 + typedef typename Container::reverse_iterator RIterator;
82.360 + typedef ReverseDigraph<const Digraph> RDigraph;
82.361 +
82.362 + RDigraph rdigraph(digraph);
82.363 +
82.364 + typedef DfsVisitor<Digraph> RVisitor;
82.365 + RVisitor rvisitor;
82.366 +
82.367 + DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
82.368 +
82.369 + int compNum = 0;
82.370 +
82.371 + rdfs.init();
82.372 + for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
82.373 + if (!rdfs.reached(*it)) {
82.374 + rdfs.addSource(*it);
82.375 + rdfs.start();
82.376 + ++compNum;
82.377 + }
82.378 + }
82.379 + return compNum;
82.380 + }
82.381 +
82.382 + /// \ingroup graph_properties
82.383 + ///
82.384 + /// \brief Find the strongly connected components of a directed graph
82.385 + ///
82.386 + /// This function finds the strongly connected components of the given
82.387 + /// directed graph. In addition, the numbering of the components will
82.388 + /// satisfy that there is no arc going from a higher numbered component
82.389 + /// to a lower one (i.e. it provides a topological order of the components).
82.390 + ///
82.391 + /// The strongly connected components are the classes of an
82.392 + /// equivalence relation on the nodes of a digraph. Two nodes are in
82.393 + /// the same class if they are connected with directed paths in both
82.394 + /// direction.
82.395 + ///
82.396 + /// \image html strongly_connected_components.png
82.397 + /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
82.398 + ///
82.399 + /// \param digraph The digraph.
82.400 + /// \retval compMap A writable node map. The values will be set from 0 to
82.401 + /// the number of the strongly connected components minus one. Each value
82.402 + /// of the map will be set exactly once, and the values of a certain
82.403 + /// component will be set continuously.
82.404 + /// \return The number of strongly connected components.
82.405 + /// \note By definition, the empty digraph has zero
82.406 + /// strongly connected components.
82.407 + ///
82.408 + /// \see stronglyConnected(), countStronglyConnectedComponents()
82.409 + template <typename Digraph, typename NodeMap>
82.410 + int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
82.411 + checkConcept<concepts::Digraph, Digraph>();
82.412 + typedef typename Digraph::Node Node;
82.413 + typedef typename Digraph::NodeIt NodeIt;
82.414 + checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
82.415 +
82.416 + using namespace _connectivity_bits;
82.417 +
82.418 + typedef std::vector<Node> Container;
82.419 + typedef typename Container::iterator Iterator;
82.420 +
82.421 + Container nodes(countNodes(digraph));
82.422 + typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
82.423 + Visitor visitor(nodes.begin());
82.424 +
82.425 + DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
82.426 + dfs.init();
82.427 + for (NodeIt it(digraph); it != INVALID; ++it) {
82.428 + if (!dfs.reached(it)) {
82.429 + dfs.addSource(it);
82.430 + dfs.start();
82.431 + }
82.432 + }
82.433 +
82.434 + typedef typename Container::reverse_iterator RIterator;
82.435 + typedef ReverseDigraph<const Digraph> RDigraph;
82.436 +
82.437 + RDigraph rdigraph(digraph);
82.438 +
82.439 + int compNum = 0;
82.440 +
82.441 + typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
82.442 + RVisitor rvisitor(compMap, compNum);
82.443 +
82.444 + DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
82.445 +
82.446 + rdfs.init();
82.447 + for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
82.448 + if (!rdfs.reached(*it)) {
82.449 + rdfs.addSource(*it);
82.450 + rdfs.start();
82.451 + ++compNum;
82.452 + }
82.453 + }
82.454 + return compNum;
82.455 + }
82.456 +
82.457 + /// \ingroup graph_properties
82.458 + ///
82.459 + /// \brief Find the cut arcs of the strongly connected components.
82.460 + ///
82.461 + /// This function finds the cut arcs of the strongly connected components
82.462 + /// of the given digraph.
82.463 + ///
82.464 + /// The strongly connected components are the classes of an
82.465 + /// equivalence relation on the nodes of a digraph. Two nodes are in
82.466 + /// the same class if they are connected with directed paths in both
82.467 + /// direction.
82.468 + /// The strongly connected components are separated by the cut arcs.
82.469 + ///
82.470 + /// \param digraph The digraph.
82.471 + /// \retval cutMap A writable arc map. The values will be set to \c true
82.472 + /// for the cut arcs (exactly once for each cut arc), and will not be
82.473 + /// changed for other arcs.
82.474 + /// \return The number of cut arcs.
82.475 + ///
82.476 + /// \see stronglyConnected(), stronglyConnectedComponents()
82.477 + template <typename Digraph, typename ArcMap>
82.478 + int stronglyConnectedCutArcs(const Digraph& digraph, ArcMap& cutMap) {
82.479 + checkConcept<concepts::Digraph, Digraph>();
82.480 + typedef typename Digraph::Node Node;
82.481 + typedef typename Digraph::Arc Arc;
82.482 + typedef typename Digraph::NodeIt NodeIt;
82.483 + checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
82.484 +
82.485 + using namespace _connectivity_bits;
82.486 +
82.487 + typedef std::vector<Node> Container;
82.488 + typedef typename Container::iterator Iterator;
82.489 +
82.490 + Container nodes(countNodes(digraph));
82.491 + typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
82.492 + Visitor visitor(nodes.begin());
82.493 +
82.494 + DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
82.495 + dfs.init();
82.496 + for (NodeIt it(digraph); it != INVALID; ++it) {
82.497 + if (!dfs.reached(it)) {
82.498 + dfs.addSource(it);
82.499 + dfs.start();
82.500 + }
82.501 + }
82.502 +
82.503 + typedef typename Container::reverse_iterator RIterator;
82.504 + typedef ReverseDigraph<const Digraph> RDigraph;
82.505 +
82.506 + RDigraph rdigraph(digraph);
82.507 +
82.508 + int cutNum = 0;
82.509 +
82.510 + typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
82.511 + RVisitor rvisitor(rdigraph, cutMap, cutNum);
82.512 +
82.513 + DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
82.514 +
82.515 + rdfs.init();
82.516 + for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
82.517 + if (!rdfs.reached(*it)) {
82.518 + rdfs.addSource(*it);
82.519 + rdfs.start();
82.520 + }
82.521 + }
82.522 + return cutNum;
82.523 + }
82.524 +
82.525 + namespace _connectivity_bits {
82.526 +
82.527 + template <typename Digraph>
82.528 + class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
82.529 + public:
82.530 + typedef typename Digraph::Node Node;
82.531 + typedef typename Digraph::Arc Arc;
82.532 + typedef typename Digraph::Edge Edge;
82.533 +
82.534 + CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
82.535 + : _graph(graph), _compNum(compNum),
82.536 + _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
82.537 +
82.538 + void start(const Node& node) {
82.539 + _predMap.set(node, INVALID);
82.540 + }
82.541 +
82.542 + void reach(const Node& node) {
82.543 + _numMap.set(node, _num);
82.544 + _retMap.set(node, _num);
82.545 + ++_num;
82.546 + }
82.547 +
82.548 + void discover(const Arc& edge) {
82.549 + _predMap.set(_graph.target(edge), _graph.source(edge));
82.550 + }
82.551 +
82.552 + void examine(const Arc& edge) {
82.553 + if (_graph.source(edge) == _graph.target(edge) &&
82.554 + _graph.direction(edge)) {
82.555 + ++_compNum;
82.556 + return;
82.557 + }
82.558 + if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
82.559 + return;
82.560 + }
82.561 + if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
82.562 + _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
82.563 + }
82.564 + }
82.565 +
82.566 + void backtrack(const Arc& edge) {
82.567 + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
82.568 + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
82.569 + }
82.570 + if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
82.571 + ++_compNum;
82.572 + }
82.573 + }
82.574 +
82.575 + private:
82.576 + const Digraph& _graph;
82.577 + int& _compNum;
82.578 +
82.579 + typename Digraph::template NodeMap<int> _numMap;
82.580 + typename Digraph::template NodeMap<int> _retMap;
82.581 + typename Digraph::template NodeMap<Node> _predMap;
82.582 + int _num;
82.583 + };
82.584 +
82.585 + template <typename Digraph, typename ArcMap>
82.586 + class BiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
82.587 + public:
82.588 + typedef typename Digraph::Node Node;
82.589 + typedef typename Digraph::Arc Arc;
82.590 + typedef typename Digraph::Edge Edge;
82.591 +
82.592 + BiNodeConnectedComponentsVisitor(const Digraph& graph,
82.593 + ArcMap& compMap, int &compNum)
82.594 + : _graph(graph), _compMap(compMap), _compNum(compNum),
82.595 + _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
82.596 +
82.597 + void start(const Node& node) {
82.598 + _predMap.set(node, INVALID);
82.599 + }
82.600 +
82.601 + void reach(const Node& node) {
82.602 + _numMap.set(node, _num);
82.603 + _retMap.set(node, _num);
82.604 + ++_num;
82.605 + }
82.606 +
82.607 + void discover(const Arc& edge) {
82.608 + Node target = _graph.target(edge);
82.609 + _predMap.set(target, edge);
82.610 + _edgeStack.push(edge);
82.611 + }
82.612 +
82.613 + void examine(const Arc& edge) {
82.614 + Node source = _graph.source(edge);
82.615 + Node target = _graph.target(edge);
82.616 + if (source == target && _graph.direction(edge)) {
82.617 + _compMap.set(edge, _compNum);
82.618 + ++_compNum;
82.619 + return;
82.620 + }
82.621 + if (_numMap[target] < _numMap[source]) {
82.622 + if (_predMap[source] != _graph.oppositeArc(edge)) {
82.623 + _edgeStack.push(edge);
82.624 + }
82.625 + }
82.626 + if (_predMap[source] != INVALID &&
82.627 + target == _graph.source(_predMap[source])) {
82.628 + return;
82.629 + }
82.630 + if (_retMap[source] > _numMap[target]) {
82.631 + _retMap.set(source, _numMap[target]);
82.632 + }
82.633 + }
82.634 +
82.635 + void backtrack(const Arc& edge) {
82.636 + Node source = _graph.source(edge);
82.637 + Node target = _graph.target(edge);
82.638 + if (_retMap[source] > _retMap[target]) {
82.639 + _retMap.set(source, _retMap[target]);
82.640 + }
82.641 + if (_numMap[source] <= _retMap[target]) {
82.642 + while (_edgeStack.top() != edge) {
82.643 + _compMap.set(_edgeStack.top(), _compNum);
82.644 + _edgeStack.pop();
82.645 + }
82.646 + _compMap.set(edge, _compNum);
82.647 + _edgeStack.pop();
82.648 + ++_compNum;
82.649 + }
82.650 + }
82.651 +
82.652 + private:
82.653 + const Digraph& _graph;
82.654 + ArcMap& _compMap;
82.655 + int& _compNum;
82.656 +
82.657 + typename Digraph::template NodeMap<int> _numMap;
82.658 + typename Digraph::template NodeMap<int> _retMap;
82.659 + typename Digraph::template NodeMap<Arc> _predMap;
82.660 + std::stack<Edge> _edgeStack;
82.661 + int _num;
82.662 + };
82.663 +
82.664 +
82.665 + template <typename Digraph, typename NodeMap>
82.666 + class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Digraph> {
82.667 + public:
82.668 + typedef typename Digraph::Node Node;
82.669 + typedef typename Digraph::Arc Arc;
82.670 + typedef typename Digraph::Edge Edge;
82.671 +
82.672 + BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap,
82.673 + int& cutNum)
82.674 + : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
82.675 + _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
82.676 +
82.677 + void start(const Node& node) {
82.678 + _predMap.set(node, INVALID);
82.679 + rootCut = false;
82.680 + }
82.681 +
82.682 + void reach(const Node& node) {
82.683 + _numMap.set(node, _num);
82.684 + _retMap.set(node, _num);
82.685 + ++_num;
82.686 + }
82.687 +
82.688 + void discover(const Arc& edge) {
82.689 + _predMap.set(_graph.target(edge), _graph.source(edge));
82.690 + }
82.691 +
82.692 + void examine(const Arc& edge) {
82.693 + if (_graph.source(edge) == _graph.target(edge) &&
82.694 + _graph.direction(edge)) {
82.695 + if (!_cutMap[_graph.source(edge)]) {
82.696 + _cutMap.set(_graph.source(edge), true);
82.697 + ++_cutNum;
82.698 + }
82.699 + return;
82.700 + }
82.701 + if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
82.702 + if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
82.703 + _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
82.704 + }
82.705 + }
82.706 +
82.707 + void backtrack(const Arc& edge) {
82.708 + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
82.709 + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
82.710 + }
82.711 + if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
82.712 + if (_predMap[_graph.source(edge)] != INVALID) {
82.713 + if (!_cutMap[_graph.source(edge)]) {
82.714 + _cutMap.set(_graph.source(edge), true);
82.715 + ++_cutNum;
82.716 + }
82.717 + } else if (rootCut) {
82.718 + if (!_cutMap[_graph.source(edge)]) {
82.719 + _cutMap.set(_graph.source(edge), true);
82.720 + ++_cutNum;
82.721 + }
82.722 + } else {
82.723 + rootCut = true;
82.724 + }
82.725 + }
82.726 + }
82.727 +
82.728 + private:
82.729 + const Digraph& _graph;
82.730 + NodeMap& _cutMap;
82.731 + int& _cutNum;
82.732 +
82.733 + typename Digraph::template NodeMap<int> _numMap;
82.734 + typename Digraph::template NodeMap<int> _retMap;
82.735 + typename Digraph::template NodeMap<Node> _predMap;
82.736 + std::stack<Edge> _edgeStack;
82.737 + int _num;
82.738 + bool rootCut;
82.739 + };
82.740 +
82.741 + }
82.742 +
82.743 + template <typename Graph>
82.744 + int countBiNodeConnectedComponents(const Graph& graph);
82.745 +
82.746 + /// \ingroup graph_properties
82.747 + ///
82.748 + /// \brief Check whether an undirected graph is bi-node-connected.
82.749 + ///
82.750 + /// This function checks whether the given undirected graph is
82.751 + /// bi-node-connected, i.e. any two edges are on same circle.
82.752 + ///
82.753 + /// \return \c true if the graph bi-node-connected.
82.754 + /// \note By definition, the empty graph is bi-node-connected.
82.755 + ///
82.756 + /// \see countBiNodeConnectedComponents(), biNodeConnectedComponents()
82.757 + template <typename Graph>
82.758 + bool biNodeConnected(const Graph& graph) {
82.759 + return countBiNodeConnectedComponents(graph) <= 1;
82.760 + }
82.761 +
82.762 + /// \ingroup graph_properties
82.763 + ///
82.764 + /// \brief Count the number of bi-node-connected components of an
82.765 + /// undirected graph.
82.766 + ///
82.767 + /// This function counts the number of bi-node-connected components of
82.768 + /// the given undirected graph.
82.769 + ///
82.770 + /// The bi-node-connected components are the classes of an equivalence
82.771 + /// relation on the edges of a undirected graph. Two edges are in the
82.772 + /// same class if they are on same circle.
82.773 + ///
82.774 + /// \return The number of bi-node-connected components.
82.775 + ///
82.776 + /// \see biNodeConnected(), biNodeConnectedComponents()
82.777 + template <typename Graph>
82.778 + int countBiNodeConnectedComponents(const Graph& graph) {
82.779 + checkConcept<concepts::Graph, Graph>();
82.780 + typedef typename Graph::NodeIt NodeIt;
82.781 +
82.782 + using namespace _connectivity_bits;
82.783 +
82.784 + typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
82.785 +
82.786 + int compNum = 0;
82.787 + Visitor visitor(graph, compNum);
82.788 +
82.789 + DfsVisit<Graph, Visitor> dfs(graph, visitor);
82.790 + dfs.init();
82.791 +
82.792 + for (NodeIt it(graph); it != INVALID; ++it) {
82.793 + if (!dfs.reached(it)) {
82.794 + dfs.addSource(it);
82.795 + dfs.start();
82.796 + }
82.797 + }
82.798 + return compNum;
82.799 + }
82.800 +
82.801 + /// \ingroup graph_properties
82.802 + ///
82.803 + /// \brief Find the bi-node-connected components of an undirected graph.
82.804 + ///
82.805 + /// This function finds the bi-node-connected components of the given
82.806 + /// undirected graph.
82.807 + ///
82.808 + /// The bi-node-connected components are the classes of an equivalence
82.809 + /// relation on the edges of a undirected graph. Two edges are in the
82.810 + /// same class if they are on same circle.
82.811 + ///
82.812 + /// \image html node_biconnected_components.png
82.813 + /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
82.814 + ///
82.815 + /// \param graph The undirected graph.
82.816 + /// \retval compMap A writable edge map. The values will be set from 0
82.817 + /// to the number of the bi-node-connected components minus one. Each
82.818 + /// value of the map will be set exactly once, and the values of a
82.819 + /// certain component will be set continuously.
82.820 + /// \return The number of bi-node-connected components.
82.821 + ///
82.822 + /// \see biNodeConnected(), countBiNodeConnectedComponents()
82.823 + template <typename Graph, typename EdgeMap>
82.824 + int biNodeConnectedComponents(const Graph& graph,
82.825 + EdgeMap& compMap) {
82.826 + checkConcept<concepts::Graph, Graph>();
82.827 + typedef typename Graph::NodeIt NodeIt;
82.828 + typedef typename Graph::Edge Edge;
82.829 + checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
82.830 +
82.831 + using namespace _connectivity_bits;
82.832 +
82.833 + typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
82.834 +
82.835 + int compNum = 0;
82.836 + Visitor visitor(graph, compMap, compNum);
82.837 +
82.838 + DfsVisit<Graph, Visitor> dfs(graph, visitor);
82.839 + dfs.init();
82.840 +
82.841 + for (NodeIt it(graph); it != INVALID; ++it) {
82.842 + if (!dfs.reached(it)) {
82.843 + dfs.addSource(it);
82.844 + dfs.start();
82.845 + }
82.846 + }
82.847 + return compNum;
82.848 + }
82.849 +
82.850 + /// \ingroup graph_properties
82.851 + ///
82.852 + /// \brief Find the bi-node-connected cut nodes in an undirected graph.
82.853 + ///
82.854 + /// This function finds the bi-node-connected cut nodes in the given
82.855 + /// undirected graph.
82.856 + ///
82.857 + /// The bi-node-connected components are the classes of an equivalence
82.858 + /// relation on the edges of a undirected graph. Two edges are in the
82.859 + /// same class if they are on same circle.
82.860 + /// The bi-node-connected components are separted by the cut nodes of
82.861 + /// the components.
82.862 + ///
82.863 + /// \param graph The undirected graph.
82.864 + /// \retval cutMap A writable node map. The values will be set to
82.865 + /// \c true for the nodes that separate two or more components
82.866 + /// (exactly once for each cut node), and will not be changed for
82.867 + /// other nodes.
82.868 + /// \return The number of the cut nodes.
82.869 + ///
82.870 + /// \see biNodeConnected(), biNodeConnectedComponents()
82.871 + template <typename Graph, typename NodeMap>
82.872 + int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
82.873 + checkConcept<concepts::Graph, Graph>();
82.874 + typedef typename Graph::Node Node;
82.875 + typedef typename Graph::NodeIt NodeIt;
82.876 + checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
82.877 +
82.878 + using namespace _connectivity_bits;
82.879 +
82.880 + typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
82.881 +
82.882 + int cutNum = 0;
82.883 + Visitor visitor(graph, cutMap, cutNum);
82.884 +
82.885 + DfsVisit<Graph, Visitor> dfs(graph, visitor);
82.886 + dfs.init();
82.887 +
82.888 + for (NodeIt it(graph); it != INVALID; ++it) {
82.889 + if (!dfs.reached(it)) {
82.890 + dfs.addSource(it);
82.891 + dfs.start();
82.892 + }
82.893 + }
82.894 + return cutNum;
82.895 + }
82.896 +
82.897 + namespace _connectivity_bits {
82.898 +
82.899 + template <typename Digraph>
82.900 + class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
82.901 + public:
82.902 + typedef typename Digraph::Node Node;
82.903 + typedef typename Digraph::Arc Arc;
82.904 + typedef typename Digraph::Edge Edge;
82.905 +
82.906 + CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
82.907 + : _graph(graph), _compNum(compNum),
82.908 + _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
82.909 +
82.910 + void start(const Node& node) {
82.911 + _predMap.set(node, INVALID);
82.912 + }
82.913 +
82.914 + void reach(const Node& node) {
82.915 + _numMap.set(node, _num);
82.916 + _retMap.set(node, _num);
82.917 + ++_num;
82.918 + }
82.919 +
82.920 + void leave(const Node& node) {
82.921 + if (_numMap[node] <= _retMap[node]) {
82.922 + ++_compNum;
82.923 + }
82.924 + }
82.925 +
82.926 + void discover(const Arc& edge) {
82.927 + _predMap.set(_graph.target(edge), edge);
82.928 + }
82.929 +
82.930 + void examine(const Arc& edge) {
82.931 + if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
82.932 + return;
82.933 + }
82.934 + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
82.935 + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
82.936 + }
82.937 + }
82.938 +
82.939 + void backtrack(const Arc& edge) {
82.940 + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
82.941 + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
82.942 + }
82.943 + }
82.944 +
82.945 + private:
82.946 + const Digraph& _graph;
82.947 + int& _compNum;
82.948 +
82.949 + typename Digraph::template NodeMap<int> _numMap;
82.950 + typename Digraph::template NodeMap<int> _retMap;
82.951 + typename Digraph::template NodeMap<Arc> _predMap;
82.952 + int _num;
82.953 + };
82.954 +
82.955 + template <typename Digraph, typename NodeMap>
82.956 + class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
82.957 + public:
82.958 + typedef typename Digraph::Node Node;
82.959 + typedef typename Digraph::Arc Arc;
82.960 + typedef typename Digraph::Edge Edge;
82.961 +
82.962 + BiEdgeConnectedComponentsVisitor(const Digraph& graph,
82.963 + NodeMap& compMap, int &compNum)
82.964 + : _graph(graph), _compMap(compMap), _compNum(compNum),
82.965 + _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
82.966 +
82.967 + void start(const Node& node) {
82.968 + _predMap.set(node, INVALID);
82.969 + }
82.970 +
82.971 + void reach(const Node& node) {
82.972 + _numMap.set(node, _num);
82.973 + _retMap.set(node, _num);
82.974 + _nodeStack.push(node);
82.975 + ++_num;
82.976 + }
82.977 +
82.978 + void leave(const Node& node) {
82.979 + if (_numMap[node] <= _retMap[node]) {
82.980 + while (_nodeStack.top() != node) {
82.981 + _compMap.set(_nodeStack.top(), _compNum);
82.982 + _nodeStack.pop();
82.983 + }
82.984 + _compMap.set(node, _compNum);
82.985 + _nodeStack.pop();
82.986 + ++_compNum;
82.987 + }
82.988 + }
82.989 +
82.990 + void discover(const Arc& edge) {
82.991 + _predMap.set(_graph.target(edge), edge);
82.992 + }
82.993 +
82.994 + void examine(const Arc& edge) {
82.995 + if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
82.996 + return;
82.997 + }
82.998 + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
82.999 + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
82.1000 + }
82.1001 + }
82.1002 +
82.1003 + void backtrack(const Arc& edge) {
82.1004 + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
82.1005 + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
82.1006 + }
82.1007 + }
82.1008 +
82.1009 + private:
82.1010 + const Digraph& _graph;
82.1011 + NodeMap& _compMap;
82.1012 + int& _compNum;
82.1013 +
82.1014 + typename Digraph::template NodeMap<int> _numMap;
82.1015 + typename Digraph::template NodeMap<int> _retMap;
82.1016 + typename Digraph::template NodeMap<Arc> _predMap;
82.1017 + std::stack<Node> _nodeStack;
82.1018 + int _num;
82.1019 + };
82.1020 +
82.1021 +
82.1022 + template <typename Digraph, typename ArcMap>
82.1023 + class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
82.1024 + public:
82.1025 + typedef typename Digraph::Node Node;
82.1026 + typedef typename Digraph::Arc Arc;
82.1027 + typedef typename Digraph::Edge Edge;
82.1028 +
82.1029 + BiEdgeConnectedCutEdgesVisitor(const Digraph& graph,
82.1030 + ArcMap& cutMap, int &cutNum)
82.1031 + : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
82.1032 + _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
82.1033 +
82.1034 + void start(const Node& node) {
82.1035 + _predMap[node] = INVALID;
82.1036 + }
82.1037 +
82.1038 + void reach(const Node& node) {
82.1039 + _numMap.set(node, _num);
82.1040 + _retMap.set(node, _num);
82.1041 + ++_num;
82.1042 + }
82.1043 +
82.1044 + void leave(const Node& node) {
82.1045 + if (_numMap[node] <= _retMap[node]) {
82.1046 + if (_predMap[node] != INVALID) {
82.1047 + _cutMap.set(_predMap[node], true);
82.1048 + ++_cutNum;
82.1049 + }
82.1050 + }
82.1051 + }
82.1052 +
82.1053 + void discover(const Arc& edge) {
82.1054 + _predMap.set(_graph.target(edge), edge);
82.1055 + }
82.1056 +
82.1057 + void examine(const Arc& edge) {
82.1058 + if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
82.1059 + return;
82.1060 + }
82.1061 + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
82.1062 + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
82.1063 + }
82.1064 + }
82.1065 +
82.1066 + void backtrack(const Arc& edge) {
82.1067 + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
82.1068 + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
82.1069 + }
82.1070 + }
82.1071 +
82.1072 + private:
82.1073 + const Digraph& _graph;
82.1074 + ArcMap& _cutMap;
82.1075 + int& _cutNum;
82.1076 +
82.1077 + typename Digraph::template NodeMap<int> _numMap;
82.1078 + typename Digraph::template NodeMap<int> _retMap;
82.1079 + typename Digraph::template NodeMap<Arc> _predMap;
82.1080 + int _num;
82.1081 + };
82.1082 + }
82.1083 +
82.1084 + template <typename Graph>
82.1085 + int countBiEdgeConnectedComponents(const Graph& graph);
82.1086 +
82.1087 + /// \ingroup graph_properties
82.1088 + ///
82.1089 + /// \brief Check whether an undirected graph is bi-edge-connected.
82.1090 + ///
82.1091 + /// This function checks whether the given undirected graph is
82.1092 + /// bi-edge-connected, i.e. any two nodes are connected with at least
82.1093 + /// two edge-disjoint paths.
82.1094 + ///
82.1095 + /// \return \c true if the graph is bi-edge-connected.
82.1096 + /// \note By definition, the empty graph is bi-edge-connected.
82.1097 + ///
82.1098 + /// \see countBiEdgeConnectedComponents(), biEdgeConnectedComponents()
82.1099 + template <typename Graph>
82.1100 + bool biEdgeConnected(const Graph& graph) {
82.1101 + return countBiEdgeConnectedComponents(graph) <= 1;
82.1102 + }
82.1103 +
82.1104 + /// \ingroup graph_properties
82.1105 + ///
82.1106 + /// \brief Count the number of bi-edge-connected components of an
82.1107 + /// undirected graph.
82.1108 + ///
82.1109 + /// This function counts the number of bi-edge-connected components of
82.1110 + /// the given undirected graph.
82.1111 + ///
82.1112 + /// The bi-edge-connected components are the classes of an equivalence
82.1113 + /// relation on the nodes of an undirected graph. Two nodes are in the
82.1114 + /// same class if they are connected with at least two edge-disjoint
82.1115 + /// paths.
82.1116 + ///
82.1117 + /// \return The number of bi-edge-connected components.
82.1118 + ///
82.1119 + /// \see biEdgeConnected(), biEdgeConnectedComponents()
82.1120 + template <typename Graph>
82.1121 + int countBiEdgeConnectedComponents(const Graph& graph) {
82.1122 + checkConcept<concepts::Graph, Graph>();
82.1123 + typedef typename Graph::NodeIt NodeIt;
82.1124 +
82.1125 + using namespace _connectivity_bits;
82.1126 +
82.1127 + typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
82.1128 +
82.1129 + int compNum = 0;
82.1130 + Visitor visitor(graph, compNum);
82.1131 +
82.1132 + DfsVisit<Graph, Visitor> dfs(graph, visitor);
82.1133 + dfs.init();
82.1134 +
82.1135 + for (NodeIt it(graph); it != INVALID; ++it) {
82.1136 + if (!dfs.reached(it)) {
82.1137 + dfs.addSource(it);
82.1138 + dfs.start();
82.1139 + }
82.1140 + }
82.1141 + return compNum;
82.1142 + }
82.1143 +
82.1144 + /// \ingroup graph_properties
82.1145 + ///
82.1146 + /// \brief Find the bi-edge-connected components of an undirected graph.
82.1147 + ///
82.1148 + /// This function finds the bi-edge-connected components of the given
82.1149 + /// undirected graph.
82.1150 + ///
82.1151 + /// The bi-edge-connected components are the classes of an equivalence
82.1152 + /// relation on the nodes of an undirected graph. Two nodes are in the
82.1153 + /// same class if they are connected with at least two edge-disjoint
82.1154 + /// paths.
82.1155 + ///
82.1156 + /// \image html edge_biconnected_components.png
82.1157 + /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
82.1158 + ///
82.1159 + /// \param graph The undirected graph.
82.1160 + /// \retval compMap A writable node map. The values will be set from 0 to
82.1161 + /// the number of the bi-edge-connected components minus one. Each value
82.1162 + /// of the map will be set exactly once, and the values of a certain
82.1163 + /// component will be set continuously.
82.1164 + /// \return The number of bi-edge-connected components.
82.1165 + ///
82.1166 + /// \see biEdgeConnected(), countBiEdgeConnectedComponents()
82.1167 + template <typename Graph, typename NodeMap>
82.1168 + int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
82.1169 + checkConcept<concepts::Graph, Graph>();
82.1170 + typedef typename Graph::NodeIt NodeIt;
82.1171 + typedef typename Graph::Node Node;
82.1172 + checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
82.1173 +
82.1174 + using namespace _connectivity_bits;
82.1175 +
82.1176 + typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
82.1177 +
82.1178 + int compNum = 0;
82.1179 + Visitor visitor(graph, compMap, compNum);
82.1180 +
82.1181 + DfsVisit<Graph, Visitor> dfs(graph, visitor);
82.1182 + dfs.init();
82.1183 +
82.1184 + for (NodeIt it(graph); it != INVALID; ++it) {
82.1185 + if (!dfs.reached(it)) {
82.1186 + dfs.addSource(it);
82.1187 + dfs.start();
82.1188 + }
82.1189 + }
82.1190 + return compNum;
82.1191 + }
82.1192 +
82.1193 + /// \ingroup graph_properties
82.1194 + ///
82.1195 + /// \brief Find the bi-edge-connected cut edges in an undirected graph.
82.1196 + ///
82.1197 + /// This function finds the bi-edge-connected cut edges in the given
82.1198 + /// undirected graph.
82.1199 + ///
82.1200 + /// The bi-edge-connected components are the classes of an equivalence
82.1201 + /// relation on the nodes of an undirected graph. Two nodes are in the
82.1202 + /// same class if they are connected with at least two edge-disjoint
82.1203 + /// paths.
82.1204 + /// The bi-edge-connected components are separted by the cut edges of
82.1205 + /// the components.
82.1206 + ///
82.1207 + /// \param graph The undirected graph.
82.1208 + /// \retval cutMap A writable edge map. The values will be set to \c true
82.1209 + /// for the cut edges (exactly once for each cut edge), and will not be
82.1210 + /// changed for other edges.
82.1211 + /// \return The number of cut edges.
82.1212 + ///
82.1213 + /// \see biEdgeConnected(), biEdgeConnectedComponents()
82.1214 + template <typename Graph, typename EdgeMap>
82.1215 + int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
82.1216 + checkConcept<concepts::Graph, Graph>();
82.1217 + typedef typename Graph::NodeIt NodeIt;
82.1218 + typedef typename Graph::Edge Edge;
82.1219 + checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
82.1220 +
82.1221 + using namespace _connectivity_bits;
82.1222 +
82.1223 + typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
82.1224 +
82.1225 + int cutNum = 0;
82.1226 + Visitor visitor(graph, cutMap, cutNum);
82.1227 +
82.1228 + DfsVisit<Graph, Visitor> dfs(graph, visitor);
82.1229 + dfs.init();
82.1230 +
82.1231 + for (NodeIt it(graph); it != INVALID; ++it) {
82.1232 + if (!dfs.reached(it)) {
82.1233 + dfs.addSource(it);
82.1234 + dfs.start();
82.1235 + }
82.1236 + }
82.1237 + return cutNum;
82.1238 + }
82.1239 +
82.1240 +
82.1241 + namespace _connectivity_bits {
82.1242 +
82.1243 + template <typename Digraph, typename IntNodeMap>
82.1244 + class TopologicalSortVisitor : public DfsVisitor<Digraph> {
82.1245 + public:
82.1246 + typedef typename Digraph::Node Node;
82.1247 + typedef typename Digraph::Arc edge;
82.1248 +
82.1249 + TopologicalSortVisitor(IntNodeMap& order, int num)
82.1250 + : _order(order), _num(num) {}
82.1251 +
82.1252 + void leave(const Node& node) {
82.1253 + _order.set(node, --_num);
82.1254 + }
82.1255 +
82.1256 + private:
82.1257 + IntNodeMap& _order;
82.1258 + int _num;
82.1259 + };
82.1260 +
82.1261 + }
82.1262 +
82.1263 + /// \ingroup graph_properties
82.1264 + ///
82.1265 + /// \brief Check whether a digraph is DAG.
82.1266 + ///
82.1267 + /// This function checks whether the given digraph is DAG, i.e.
82.1268 + /// \e Directed \e Acyclic \e Graph.
82.1269 + /// \return \c true if there is no directed cycle in the digraph.
82.1270 + /// \see acyclic()
82.1271 + template <typename Digraph>
82.1272 + bool dag(const Digraph& digraph) {
82.1273 +
82.1274 + checkConcept<concepts::Digraph, Digraph>();
82.1275 +
82.1276 + typedef typename Digraph::Node Node;
82.1277 + typedef typename Digraph::NodeIt NodeIt;
82.1278 + typedef typename Digraph::Arc Arc;
82.1279 +
82.1280 + typedef typename Digraph::template NodeMap<bool> ProcessedMap;
82.1281 +
82.1282 + typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
82.1283 + Create dfs(digraph);
82.1284 +
82.1285 + ProcessedMap processed(digraph);
82.1286 + dfs.processedMap(processed);
82.1287 +
82.1288 + dfs.init();
82.1289 + for (NodeIt it(digraph); it != INVALID; ++it) {
82.1290 + if (!dfs.reached(it)) {
82.1291 + dfs.addSource(it);
82.1292 + while (!dfs.emptyQueue()) {
82.1293 + Arc arc = dfs.nextArc();
82.1294 + Node target = digraph.target(arc);
82.1295 + if (dfs.reached(target) && !processed[target]) {
82.1296 + return false;
82.1297 + }
82.1298 + dfs.processNextArc();
82.1299 + }
82.1300 + }
82.1301 + }
82.1302 + return true;
82.1303 + }
82.1304 +
82.1305 + /// \ingroup graph_properties
82.1306 + ///
82.1307 + /// \brief Sort the nodes of a DAG into topolgical order.
82.1308 + ///
82.1309 + /// This function sorts the nodes of the given acyclic digraph (DAG)
82.1310 + /// into topolgical order.
82.1311 + ///
82.1312 + /// \param digraph The digraph, which must be DAG.
82.1313 + /// \retval order A writable node map. The values will be set from 0 to
82.1314 + /// the number of the nodes in the digraph minus one. Each value of the
82.1315 + /// map will be set exactly once, and the values will be set descending
82.1316 + /// order.
82.1317 + ///
82.1318 + /// \see dag(), checkedTopologicalSort()
82.1319 + template <typename Digraph, typename NodeMap>
82.1320 + void topologicalSort(const Digraph& digraph, NodeMap& order) {
82.1321 + using namespace _connectivity_bits;
82.1322 +
82.1323 + checkConcept<concepts::Digraph, Digraph>();
82.1324 + checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
82.1325 +
82.1326 + typedef typename Digraph::Node Node;
82.1327 + typedef typename Digraph::NodeIt NodeIt;
82.1328 + typedef typename Digraph::Arc Arc;
82.1329 +
82.1330 + TopologicalSortVisitor<Digraph, NodeMap>
82.1331 + visitor(order, countNodes(digraph));
82.1332 +
82.1333 + DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
82.1334 + dfs(digraph, visitor);
82.1335 +
82.1336 + dfs.init();
82.1337 + for (NodeIt it(digraph); it != INVALID; ++it) {
82.1338 + if (!dfs.reached(it)) {
82.1339 + dfs.addSource(it);
82.1340 + dfs.start();
82.1341 + }
82.1342 + }
82.1343 + }
82.1344 +
82.1345 + /// \ingroup graph_properties
82.1346 + ///
82.1347 + /// \brief Sort the nodes of a DAG into topolgical order.
82.1348 + ///
82.1349 + /// This function sorts the nodes of the given acyclic digraph (DAG)
82.1350 + /// into topolgical order and also checks whether the given digraph
82.1351 + /// is DAG.
82.1352 + ///
82.1353 + /// \param digraph The digraph.
82.1354 + /// \retval order A readable and writable node map. The values will be
82.1355 + /// set from 0 to the number of the nodes in the digraph minus one.
82.1356 + /// Each value of the map will be set exactly once, and the values will
82.1357 + /// be set descending order.
82.1358 + /// \return \c false if the digraph is not DAG.
82.1359 + ///
82.1360 + /// \see dag(), topologicalSort()
82.1361 + template <typename Digraph, typename NodeMap>
82.1362 + bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
82.1363 + using namespace _connectivity_bits;
82.1364 +
82.1365 + checkConcept<concepts::Digraph, Digraph>();
82.1366 + checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
82.1367 + NodeMap>();
82.1368 +
82.1369 + typedef typename Digraph::Node Node;
82.1370 + typedef typename Digraph::NodeIt NodeIt;
82.1371 + typedef typename Digraph::Arc Arc;
82.1372 +
82.1373 + for (NodeIt it(digraph); it != INVALID; ++it) {
82.1374 + order.set(it, -1);
82.1375 + }
82.1376 +
82.1377 + TopologicalSortVisitor<Digraph, NodeMap>
82.1378 + visitor(order, countNodes(digraph));
82.1379 +
82.1380 + DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
82.1381 + dfs(digraph, visitor);
82.1382 +
82.1383 + dfs.init();
82.1384 + for (NodeIt it(digraph); it != INVALID; ++it) {
82.1385 + if (!dfs.reached(it)) {
82.1386 + dfs.addSource(it);
82.1387 + while (!dfs.emptyQueue()) {
82.1388 + Arc arc = dfs.nextArc();
82.1389 + Node target = digraph.target(arc);
82.1390 + if (dfs.reached(target) && order[target] == -1) {
82.1391 + return false;
82.1392 + }
82.1393 + dfs.processNextArc();
82.1394 + }
82.1395 + }
82.1396 + }
82.1397 + return true;
82.1398 + }
82.1399 +
82.1400 + /// \ingroup graph_properties
82.1401 + ///
82.1402 + /// \brief Check whether an undirected graph is acyclic.
82.1403 + ///
82.1404 + /// This function checks whether the given undirected graph is acyclic.
82.1405 + /// \return \c true if there is no cycle in the graph.
82.1406 + /// \see dag()
82.1407 + template <typename Graph>
82.1408 + bool acyclic(const Graph& graph) {
82.1409 + checkConcept<concepts::Graph, Graph>();
82.1410 + typedef typename Graph::Node Node;
82.1411 + typedef typename Graph::NodeIt NodeIt;
82.1412 + typedef typename Graph::Arc Arc;
82.1413 + Dfs<Graph> dfs(graph);
82.1414 + dfs.init();
82.1415 + for (NodeIt it(graph); it != INVALID; ++it) {
82.1416 + if (!dfs.reached(it)) {
82.1417 + dfs.addSource(it);
82.1418 + while (!dfs.emptyQueue()) {
82.1419 + Arc arc = dfs.nextArc();
82.1420 + Node source = graph.source(arc);
82.1421 + Node target = graph.target(arc);
82.1422 + if (dfs.reached(target) &&
82.1423 + dfs.predArc(source) != graph.oppositeArc(arc)) {
82.1424 + return false;
82.1425 + }
82.1426 + dfs.processNextArc();
82.1427 + }
82.1428 + }
82.1429 + }
82.1430 + return true;
82.1431 + }
82.1432 +
82.1433 + /// \ingroup graph_properties
82.1434 + ///
82.1435 + /// \brief Check whether an undirected graph is tree.
82.1436 + ///
82.1437 + /// This function checks whether the given undirected graph is tree.
82.1438 + /// \return \c true if the graph is acyclic and connected.
82.1439 + /// \see acyclic(), connected()
82.1440 + template <typename Graph>
82.1441 + bool tree(const Graph& graph) {
82.1442 + checkConcept<concepts::Graph, Graph>();
82.1443 + typedef typename Graph::Node Node;
82.1444 + typedef typename Graph::NodeIt NodeIt;
82.1445 + typedef typename Graph::Arc Arc;
82.1446 + if (NodeIt(graph) == INVALID) return true;
82.1447 + Dfs<Graph> dfs(graph);
82.1448 + dfs.init();
82.1449 + dfs.addSource(NodeIt(graph));
82.1450 + while (!dfs.emptyQueue()) {
82.1451 + Arc arc = dfs.nextArc();
82.1452 + Node source = graph.source(arc);
82.1453 + Node target = graph.target(arc);
82.1454 + if (dfs.reached(target) &&
82.1455 + dfs.predArc(source) != graph.oppositeArc(arc)) {
82.1456 + return false;
82.1457 + }
82.1458 + dfs.processNextArc();
82.1459 + }
82.1460 + for (NodeIt it(graph); it != INVALID; ++it) {
82.1461 + if (!dfs.reached(it)) {
82.1462 + return false;
82.1463 + }
82.1464 + }
82.1465 + return true;
82.1466 + }
82.1467 +
82.1468 + namespace _connectivity_bits {
82.1469 +
82.1470 + template <typename Digraph>
82.1471 + class BipartiteVisitor : public BfsVisitor<Digraph> {
82.1472 + public:
82.1473 + typedef typename Digraph::Arc Arc;
82.1474 + typedef typename Digraph::Node Node;
82.1475 +
82.1476 + BipartiteVisitor(const Digraph& graph, bool& bipartite)
82.1477 + : _graph(graph), _part(graph), _bipartite(bipartite) {}
82.1478 +
82.1479 + void start(const Node& node) {
82.1480 + _part[node] = true;
82.1481 + }
82.1482 + void discover(const Arc& edge) {
82.1483 + _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
82.1484 + }
82.1485 + void examine(const Arc& edge) {
82.1486 + _bipartite = _bipartite &&
82.1487 + _part[_graph.target(edge)] != _part[_graph.source(edge)];
82.1488 + }
82.1489 +
82.1490 + private:
82.1491 +
82.1492 + const Digraph& _graph;
82.1493 + typename Digraph::template NodeMap<bool> _part;
82.1494 + bool& _bipartite;
82.1495 + };
82.1496 +
82.1497 + template <typename Digraph, typename PartMap>
82.1498 + class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
82.1499 + public:
82.1500 + typedef typename Digraph::Arc Arc;
82.1501 + typedef typename Digraph::Node Node;
82.1502 +
82.1503 + BipartitePartitionsVisitor(const Digraph& graph,
82.1504 + PartMap& part, bool& bipartite)
82.1505 + : _graph(graph), _part(part), _bipartite(bipartite) {}
82.1506 +
82.1507 + void start(const Node& node) {
82.1508 + _part.set(node, true);
82.1509 + }
82.1510 + void discover(const Arc& edge) {
82.1511 + _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
82.1512 + }
82.1513 + void examine(const Arc& edge) {
82.1514 + _bipartite = _bipartite &&
82.1515 + _part[_graph.target(edge)] != _part[_graph.source(edge)];
82.1516 + }
82.1517 +
82.1518 + private:
82.1519 +
82.1520 + const Digraph& _graph;
82.1521 + PartMap& _part;
82.1522 + bool& _bipartite;
82.1523 + };
82.1524 + }
82.1525 +
82.1526 + /// \ingroup graph_properties
82.1527 + ///
82.1528 + /// \brief Check whether an undirected graph is bipartite.
82.1529 + ///
82.1530 + /// The function checks whether the given undirected graph is bipartite.
82.1531 + /// \return \c true if the graph is bipartite.
82.1532 + ///
82.1533 + /// \see bipartitePartitions()
82.1534 + template<typename Graph>
82.1535 + bool bipartite(const Graph &graph){
82.1536 + using namespace _connectivity_bits;
82.1537 +
82.1538 + checkConcept<concepts::Graph, Graph>();
82.1539 +
82.1540 + typedef typename Graph::NodeIt NodeIt;
82.1541 + typedef typename Graph::ArcIt ArcIt;
82.1542 +
82.1543 + bool bipartite = true;
82.1544 +
82.1545 + BipartiteVisitor<Graph>
82.1546 + visitor(graph, bipartite);
82.1547 + BfsVisit<Graph, BipartiteVisitor<Graph> >
82.1548 + bfs(graph, visitor);
82.1549 + bfs.init();
82.1550 + for(NodeIt it(graph); it != INVALID; ++it) {
82.1551 + if(!bfs.reached(it)){
82.1552 + bfs.addSource(it);
82.1553 + while (!bfs.emptyQueue()) {
82.1554 + bfs.processNextNode();
82.1555 + if (!bipartite) return false;
82.1556 + }
82.1557 + }
82.1558 + }
82.1559 + return true;
82.1560 + }
82.1561 +
82.1562 + /// \ingroup graph_properties
82.1563 + ///
82.1564 + /// \brief Find the bipartite partitions of an undirected graph.
82.1565 + ///
82.1566 + /// This function checks whether the given undirected graph is bipartite
82.1567 + /// and gives back the bipartite partitions.
82.1568 + ///
82.1569 + /// \image html bipartite_partitions.png
82.1570 + /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
82.1571 + ///
82.1572 + /// \param graph The undirected graph.
82.1573 + /// \retval partMap A writable node map of \c bool (or convertible) value
82.1574 + /// type. The values will be set to \c true for one component and
82.1575 + /// \c false for the other one.
82.1576 + /// \return \c true if the graph is bipartite, \c false otherwise.
82.1577 + ///
82.1578 + /// \see bipartite()
82.1579 + template<typename Graph, typename NodeMap>
82.1580 + bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
82.1581 + using namespace _connectivity_bits;
82.1582 +
82.1583 + checkConcept<concepts::Graph, Graph>();
82.1584 + checkConcept<concepts::WriteMap<typename Graph::Node, bool>, NodeMap>();
82.1585 +
82.1586 + typedef typename Graph::Node Node;
82.1587 + typedef typename Graph::NodeIt NodeIt;
82.1588 + typedef typename Graph::ArcIt ArcIt;
82.1589 +
82.1590 + bool bipartite = true;
82.1591 +
82.1592 + BipartitePartitionsVisitor<Graph, NodeMap>
82.1593 + visitor(graph, partMap, bipartite);
82.1594 + BfsVisit<Graph, BipartitePartitionsVisitor<Graph, NodeMap> >
82.1595 + bfs(graph, visitor);
82.1596 + bfs.init();
82.1597 + for(NodeIt it(graph); it != INVALID; ++it) {
82.1598 + if(!bfs.reached(it)){
82.1599 + bfs.addSource(it);
82.1600 + while (!bfs.emptyQueue()) {
82.1601 + bfs.processNextNode();
82.1602 + if (!bipartite) return false;
82.1603 + }
82.1604 + }
82.1605 + }
82.1606 + return true;
82.1607 + }
82.1608 +
82.1609 + /// \ingroup graph_properties
82.1610 + ///
82.1611 + /// \brief Check whether the given graph contains no loop arcs/edges.
82.1612 + ///
82.1613 + /// This function returns \c true if there are no loop arcs/edges in
82.1614 + /// the given graph. It works for both directed and undirected graphs.
82.1615 + template <typename Graph>
82.1616 + bool loopFree(const Graph& graph) {
82.1617 + for (typename Graph::ArcIt it(graph); it != INVALID; ++it) {
82.1618 + if (graph.source(it) == graph.target(it)) return false;
82.1619 + }
82.1620 + return true;
82.1621 + }
82.1622 +
82.1623 + /// \ingroup graph_properties
82.1624 + ///
82.1625 + /// \brief Check whether the given graph contains no parallel arcs/edges.
82.1626 + ///
82.1627 + /// This function returns \c true if there are no parallel arcs/edges in
82.1628 + /// the given graph. It works for both directed and undirected graphs.
82.1629 + template <typename Graph>
82.1630 + bool parallelFree(const Graph& graph) {
82.1631 + typename Graph::template NodeMap<int> reached(graph, 0);
82.1632 + int cnt = 1;
82.1633 + for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
82.1634 + for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
82.1635 + if (reached[graph.target(a)] == cnt) return false;
82.1636 + reached[graph.target(a)] = cnt;
82.1637 + }
82.1638 + ++cnt;
82.1639 + }
82.1640 + return true;
82.1641 + }
82.1642 +
82.1643 + /// \ingroup graph_properties
82.1644 + ///
82.1645 + /// \brief Check whether the given graph is simple.
82.1646 + ///
82.1647 + /// This function returns \c true if the given graph is simple, i.e.
82.1648 + /// it contains no loop arcs/edges and no parallel arcs/edges.
82.1649 + /// The function works for both directed and undirected graphs.
82.1650 + /// \see loopFree(), parallelFree()
82.1651 + template <typename Graph>
82.1652 + bool simpleGraph(const Graph& graph) {
82.1653 + typename Graph::template NodeMap<int> reached(graph, 0);
82.1654 + int cnt = 1;
82.1655 + for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
82.1656 + reached[n] = cnt;
82.1657 + for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
82.1658 + if (reached[graph.target(a)] == cnt) return false;
82.1659 + reached[graph.target(a)] = cnt;
82.1660 + }
82.1661 + ++cnt;
82.1662 + }
82.1663 + return true;
82.1664 + }
82.1665 +
82.1666 +} //namespace lemon
82.1667 +
82.1668 +#endif //LEMON_CONNECTIVITY_H
83.1 --- a/lemon/core.h Fri Nov 13 12:33:33 2009 +0100
83.2 +++ b/lemon/core.h Thu Dec 10 17:05:35 2009 +0100
83.3 @@ -2,7 +2,7 @@
83.4 *
83.5 * This file is a part of LEMON, a generic C++ optimization library.
83.6 *
83.7 - * Copyright (C) 2003-2008
83.8 + * Copyright (C) 2003-2009
83.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
83.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
83.11 *
83.12 @@ -27,6 +27,16 @@
83.13 #include <lemon/bits/traits.h>
83.14 #include <lemon/assert.h>
83.15
83.16 +// Disable the following warnings when compiling with MSVC:
83.17 +// C4250: 'class1' : inherits 'class2::member' via dominance
83.18 +// C4355: 'this' : used in base member initializer list
83.19 +// C4503: 'function' : decorated name length exceeded, name was truncated
83.20 +// C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
83.21 +// C4996: 'function': was declared deprecated
83.22 +#ifdef _MSC_VER
83.23 +#pragma warning( disable : 4250 4355 4503 4800 4996 )
83.24 +#endif
83.25 +
83.26 ///\file
83.27 ///\brief LEMON core utilities.
83.28 ///
83.29 @@ -1034,28 +1044,27 @@
83.30 ///
83.31 ///\sa findArc()
83.32 ///\sa ArcLookUp, AllArcLookUp, DynArcLookUp
83.33 - template <typename _Graph>
83.34 - class ConArcIt : public _Graph::Arc {
83.35 + template <typename GR>
83.36 + class ConArcIt : public GR::Arc {
83.37 + typedef typename GR::Arc Parent;
83.38 +
83.39 public:
83.40
83.41 - typedef _Graph Graph;
83.42 - typedef typename Graph::Arc Parent;
83.43 -
83.44 - typedef typename Graph::Arc Arc;
83.45 - typedef typename Graph::Node Node;
83.46 + typedef typename GR::Arc Arc;
83.47 + typedef typename GR::Node Node;
83.48
83.49 /// \brief Constructor.
83.50 ///
83.51 /// Construct a new ConArcIt iterating on the arcs that
83.52 /// connects nodes \c u and \c v.
83.53 - ConArcIt(const Graph& g, Node u, Node v) : _graph(g) {
83.54 + ConArcIt(const GR& g, Node u, Node v) : _graph(g) {
83.55 Parent::operator=(findArc(_graph, u, v));
83.56 }
83.57
83.58 /// \brief Constructor.
83.59 ///
83.60 /// Construct a new ConArcIt that continues the iterating from arc \c a.
83.61 - ConArcIt(const Graph& g, Arc a) : Parent(a), _graph(g) {}
83.62 + ConArcIt(const GR& g, Arc a) : Parent(a), _graph(g) {}
83.63
83.64 /// \brief Increment operator.
83.65 ///
83.66 @@ -1066,7 +1075,7 @@
83.67 return *this;
83.68 }
83.69 private:
83.70 - const Graph& _graph;
83.71 + const GR& _graph;
83.72 };
83.73
83.74 namespace _core_bits {
83.75 @@ -1157,28 +1166,27 @@
83.76 ///\endcode
83.77 ///
83.78 ///\sa findEdge()
83.79 - template <typename _Graph>
83.80 - class ConEdgeIt : public _Graph::Edge {
83.81 + template <typename GR>
83.82 + class ConEdgeIt : public GR::Edge {
83.83 + typedef typename GR::Edge Parent;
83.84 +
83.85 public:
83.86
83.87 - typedef _Graph Graph;
83.88 - typedef typename Graph::Edge Parent;
83.89 -
83.90 - typedef typename Graph::Edge Edge;
83.91 - typedef typename Graph::Node Node;
83.92 + typedef typename GR::Edge Edge;
83.93 + typedef typename GR::Node Node;
83.94
83.95 /// \brief Constructor.
83.96 ///
83.97 /// Construct a new ConEdgeIt iterating on the edges that
83.98 /// connects nodes \c u and \c v.
83.99 - ConEdgeIt(const Graph& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
83.100 + ConEdgeIt(const GR& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
83.101 Parent::operator=(findEdge(_graph, _u, _v));
83.102 }
83.103
83.104 /// \brief Constructor.
83.105 ///
83.106 /// Construct a new ConEdgeIt that continues iterating from edge \c e.
83.107 - ConEdgeIt(const Graph& g, Edge e) : Parent(e), _graph(g) {}
83.108 + ConEdgeIt(const GR& g, Edge e) : Parent(e), _graph(g) {}
83.109
83.110 /// \brief Increment operator.
83.111 ///
83.112 @@ -1188,7 +1196,7 @@
83.113 return *this;
83.114 }
83.115 private:
83.116 - const Graph& _graph;
83.117 + const GR& _graph;
83.118 Node _u, _v;
83.119 };
83.120
83.121 @@ -1211,29 +1219,32 @@
83.122 ///optimal time bound in a constant factor for any distribution of
83.123 ///queries.
83.124 ///
83.125 - ///\tparam G The type of the underlying digraph.
83.126 + ///\tparam GR The type of the underlying digraph.
83.127 ///
83.128 ///\sa ArcLookUp
83.129 ///\sa AllArcLookUp
83.130 - template<class G>
83.131 + template <typename GR>
83.132 class DynArcLookUp
83.133 - : protected ItemSetTraits<G, typename G::Arc>::ItemNotifier::ObserverBase
83.134 + : protected ItemSetTraits<GR, typename GR::Arc>::ItemNotifier::ObserverBase
83.135 {
83.136 - public:
83.137 - typedef typename ItemSetTraits<G, typename G::Arc>
83.138 + typedef typename ItemSetTraits<GR, typename GR::Arc>
83.139 ::ItemNotifier::ObserverBase Parent;
83.140
83.141 - TEMPLATE_DIGRAPH_TYPEDEFS(G);
83.142 - typedef G Digraph;
83.143 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
83.144 +
83.145 + public:
83.146 +
83.147 + /// The Digraph type
83.148 + typedef GR Digraph;
83.149
83.150 protected:
83.151
83.152 - class AutoNodeMap : public ItemSetTraits<G, Node>::template Map<Arc>::Type {
83.153 + class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type {
83.154 + typedef typename ItemSetTraits<GR, Node>::template Map<Arc>::Type Parent;
83.155 +
83.156 public:
83.157
83.158 - typedef typename ItemSetTraits<G, Node>::template Map<Arc>::Type Parent;
83.159 -
83.160 - AutoNodeMap(const G& digraph) : Parent(digraph, INVALID) {}
83.161 + AutoNodeMap(const GR& digraph) : Parent(digraph, INVALID) {}
83.162
83.163 virtual void add(const Node& node) {
83.164 Parent::add(node);
83.165 @@ -1257,12 +1268,6 @@
83.166 }
83.167 };
83.168
83.169 - const Digraph &_g;
83.170 - AutoNodeMap _head;
83.171 - typename Digraph::template ArcMap<Arc> _parent;
83.172 - typename Digraph::template ArcMap<Arc> _left;
83.173 - typename Digraph::template ArcMap<Arc> _right;
83.174 -
83.175 class ArcLess {
83.176 const Digraph &g;
83.177 public:
83.178 @@ -1273,6 +1278,14 @@
83.179 }
83.180 };
83.181
83.182 + protected:
83.183 +
83.184 + const Digraph &_g;
83.185 + AutoNodeMap _head;
83.186 + typename Digraph::template ArcMap<Arc> _parent;
83.187 + typename Digraph::template ArcMap<Arc> _left;
83.188 + typename Digraph::template ArcMap<Arc> _right;
83.189 +
83.190 public:
83.191
83.192 ///Constructor
83.193 @@ -1315,27 +1328,27 @@
83.194
83.195 virtual void clear() {
83.196 for(NodeIt n(_g);n!=INVALID;++n) {
83.197 - _head.set(n, INVALID);
83.198 + _head[n] = INVALID;
83.199 }
83.200 }
83.201
83.202 void insert(Arc arc) {
83.203 Node s = _g.source(arc);
83.204 Node t = _g.target(arc);
83.205 - _left.set(arc, INVALID);
83.206 - _right.set(arc, INVALID);
83.207 + _left[arc] = INVALID;
83.208 + _right[arc] = INVALID;
83.209
83.210 Arc e = _head[s];
83.211 if (e == INVALID) {
83.212 - _head.set(s, arc);
83.213 - _parent.set(arc, INVALID);
83.214 + _head[s] = arc;
83.215 + _parent[arc] = INVALID;
83.216 return;
83.217 }
83.218 while (true) {
83.219 if (t < _g.target(e)) {
83.220 if (_left[e] == INVALID) {
83.221 - _left.set(e, arc);
83.222 - _parent.set(arc, e);
83.223 + _left[e] = arc;
83.224 + _parent[arc] = e;
83.225 splay(arc);
83.226 return;
83.227 } else {
83.228 @@ -1343,8 +1356,8 @@
83.229 }
83.230 } else {
83.231 if (_right[e] == INVALID) {
83.232 - _right.set(e, arc);
83.233 - _parent.set(arc, e);
83.234 + _right[e] = arc;
83.235 + _parent[arc] = e;
83.236 splay(arc);
83.237 return;
83.238 } else {
83.239 @@ -1357,27 +1370,27 @@
83.240 void remove(Arc arc) {
83.241 if (_left[arc] == INVALID) {
83.242 if (_right[arc] != INVALID) {
83.243 - _parent.set(_right[arc], _parent[arc]);
83.244 + _parent[_right[arc]] = _parent[arc];
83.245 }
83.246 if (_parent[arc] != INVALID) {
83.247 if (_left[_parent[arc]] == arc) {
83.248 - _left.set(_parent[arc], _right[arc]);
83.249 + _left[_parent[arc]] = _right[arc];
83.250 } else {
83.251 - _right.set(_parent[arc], _right[arc]);
83.252 + _right[_parent[arc]] = _right[arc];
83.253 }
83.254 } else {
83.255 - _head.set(_g.source(arc), _right[arc]);
83.256 + _head[_g.source(arc)] = _right[arc];
83.257 }
83.258 } else if (_right[arc] == INVALID) {
83.259 - _parent.set(_left[arc], _parent[arc]);
83.260 + _parent[_left[arc]] = _parent[arc];
83.261 if (_parent[arc] != INVALID) {
83.262 if (_left[_parent[arc]] == arc) {
83.263 - _left.set(_parent[arc], _left[arc]);
83.264 + _left[_parent[arc]] = _left[arc];
83.265 } else {
83.266 - _right.set(_parent[arc], _left[arc]);
83.267 + _right[_parent[arc]] = _left[arc];
83.268 }
83.269 } else {
83.270 - _head.set(_g.source(arc), _left[arc]);
83.271 + _head[_g.source(arc)] = _left[arc];
83.272 }
83.273 } else {
83.274 Arc e = _left[arc];
83.275 @@ -1387,38 +1400,38 @@
83.276 e = _right[e];
83.277 }
83.278 Arc s = _parent[e];
83.279 - _right.set(_parent[e], _left[e]);
83.280 + _right[_parent[e]] = _left[e];
83.281 if (_left[e] != INVALID) {
83.282 - _parent.set(_left[e], _parent[e]);
83.283 + _parent[_left[e]] = _parent[e];
83.284 }
83.285
83.286 - _left.set(e, _left[arc]);
83.287 - _parent.set(_left[arc], e);
83.288 - _right.set(e, _right[arc]);
83.289 - _parent.set(_right[arc], e);
83.290 + _left[e] = _left[arc];
83.291 + _parent[_left[arc]] = e;
83.292 + _right[e] = _right[arc];
83.293 + _parent[_right[arc]] = e;
83.294
83.295 - _parent.set(e, _parent[arc]);
83.296 + _parent[e] = _parent[arc];
83.297 if (_parent[arc] != INVALID) {
83.298 if (_left[_parent[arc]] == arc) {
83.299 - _left.set(_parent[arc], e);
83.300 + _left[_parent[arc]] = e;
83.301 } else {
83.302 - _right.set(_parent[arc], e);
83.303 + _right[_parent[arc]] = e;
83.304 }
83.305 }
83.306 splay(s);
83.307 } else {
83.308 - _right.set(e, _right[arc]);
83.309 - _parent.set(_right[arc], e);
83.310 - _parent.set(e, _parent[arc]);
83.311 + _right[e] = _right[arc];
83.312 + _parent[_right[arc]] = e;
83.313 + _parent[e] = _parent[arc];
83.314
83.315 if (_parent[arc] != INVALID) {
83.316 if (_left[_parent[arc]] == arc) {
83.317 - _left.set(_parent[arc], e);
83.318 + _left[_parent[arc]] = e;
83.319 } else {
83.320 - _right.set(_parent[arc], e);
83.321 + _right[_parent[arc]] = e;
83.322 }
83.323 } else {
83.324 - _head.set(_g.source(arc), e);
83.325 + _head[_g.source(arc)] = e;
83.326 }
83.327 }
83.328 }
83.329 @@ -1430,17 +1443,17 @@
83.330 Arc me=v[m];
83.331 if (a < m) {
83.332 Arc left = refreshRec(v,a,m-1);
83.333 - _left.set(me, left);
83.334 - _parent.set(left, me);
83.335 + _left[me] = left;
83.336 + _parent[left] = me;
83.337 } else {
83.338 - _left.set(me, INVALID);
83.339 + _left[me] = INVALID;
83.340 }
83.341 if (m < b) {
83.342 Arc right = refreshRec(v,m+1,b);
83.343 - _right.set(me, right);
83.344 - _parent.set(right, me);
83.345 + _right[me] = right;
83.346 + _parent[right] = me;
83.347 } else {
83.348 - _right.set(me, INVALID);
83.349 + _right[me] = INVALID;
83.350 }
83.351 return me;
83.352 }
83.353 @@ -1452,46 +1465,46 @@
83.354 if (!v.empty()) {
83.355 std::sort(v.begin(),v.end(),ArcLess(_g));
83.356 Arc head = refreshRec(v,0,v.size()-1);
83.357 - _head.set(n, head);
83.358 - _parent.set(head, INVALID);
83.359 + _head[n] = head;
83.360 + _parent[head] = INVALID;
83.361 }
83.362 - else _head.set(n, INVALID);
83.363 + else _head[n] = INVALID;
83.364 }
83.365 }
83.366
83.367 void zig(Arc v) {
83.368 Arc w = _parent[v];
83.369 - _parent.set(v, _parent[w]);
83.370 - _parent.set(w, v);
83.371 - _left.set(w, _right[v]);
83.372 - _right.set(v, w);
83.373 + _parent[v] = _parent[w];
83.374 + _parent[w] = v;
83.375 + _left[w] = _right[v];
83.376 + _right[v] = w;
83.377 if (_parent[v] != INVALID) {
83.378 if (_right[_parent[v]] == w) {
83.379 - _right.set(_parent[v], v);
83.380 + _right[_parent[v]] = v;
83.381 } else {
83.382 - _left.set(_parent[v], v);
83.383 + _left[_parent[v]] = v;
83.384 }
83.385 }
83.386 if (_left[w] != INVALID){
83.387 - _parent.set(_left[w], w);
83.388 + _parent[_left[w]] = w;
83.389 }
83.390 }
83.391
83.392 void zag(Arc v) {
83.393 Arc w = _parent[v];
83.394 - _parent.set(v, _parent[w]);
83.395 - _parent.set(w, v);
83.396 - _right.set(w, _left[v]);
83.397 - _left.set(v, w);
83.398 + _parent[v] = _parent[w];
83.399 + _parent[w] = v;
83.400 + _right[w] = _left[v];
83.401 + _left[v] = w;
83.402 if (_parent[v] != INVALID){
83.403 if (_left[_parent[v]] == w) {
83.404 - _left.set(_parent[v], v);
83.405 + _left[_parent[v]] = v;
83.406 } else {
83.407 - _right.set(_parent[v], v);
83.408 + _right[_parent[v]] = v;
83.409 }
83.410 }
83.411 if (_right[w] != INVALID){
83.412 - _parent.set(_right[w], w);
83.413 + _parent[_right[w]] = w;
83.414 }
83.415 }
83.416
83.417 @@ -1623,16 +1636,19 @@
83.418 ///digraph changes. This is a time consuming (superlinearly proportional
83.419 ///(<em>O</em>(<em>m</em> log<em>m</em>)) to the number of arcs).
83.420 ///
83.421 - ///\tparam G The type of the underlying digraph.
83.422 + ///\tparam GR The type of the underlying digraph.
83.423 ///
83.424 ///\sa DynArcLookUp
83.425 ///\sa AllArcLookUp
83.426 - template<class G>
83.427 + template<class GR>
83.428 class ArcLookUp
83.429 {
83.430 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
83.431 +
83.432 public:
83.433 - TEMPLATE_DIGRAPH_TYPEDEFS(G);
83.434 - typedef G Digraph;
83.435 +
83.436 + /// The Digraph type
83.437 + typedef GR Digraph;
83.438
83.439 protected:
83.440 const Digraph &_g;
83.441 @@ -1733,22 +1749,21 @@
83.442 ///digraph changes. This is a time consuming (superlinearly proportional
83.443 ///(<em>O</em>(<em>m</em> log<em>m</em>)) to the number of arcs).
83.444 ///
83.445 - ///\tparam G The type of the underlying digraph.
83.446 + ///\tparam GR The type of the underlying digraph.
83.447 ///
83.448 ///\sa DynArcLookUp
83.449 ///\sa ArcLookUp
83.450 - template<class G>
83.451 - class AllArcLookUp : public ArcLookUp<G>
83.452 + template<class GR>
83.453 + class AllArcLookUp : public ArcLookUp<GR>
83.454 {
83.455 - using ArcLookUp<G>::_g;
83.456 - using ArcLookUp<G>::_right;
83.457 - using ArcLookUp<G>::_left;
83.458 - using ArcLookUp<G>::_head;
83.459 + using ArcLookUp<GR>::_g;
83.460 + using ArcLookUp<GR>::_right;
83.461 + using ArcLookUp<GR>::_left;
83.462 + using ArcLookUp<GR>::_head;
83.463
83.464 - TEMPLATE_DIGRAPH_TYPEDEFS(G);
83.465 - typedef G Digraph;
83.466 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
83.467
83.468 - typename Digraph::template ArcMap<Arc> _next;
83.469 + typename GR::template ArcMap<Arc> _next;
83.470
83.471 Arc refreshNext(Arc head,Arc next=INVALID)
83.472 {
83.473 @@ -1767,13 +1782,17 @@
83.474 }
83.475
83.476 public:
83.477 +
83.478 + /// The Digraph type
83.479 + typedef GR Digraph;
83.480 +
83.481 ///Constructor
83.482
83.483 ///Constructor.
83.484 ///
83.485 ///It builds up the search database, which remains valid until the digraph
83.486 ///changes.
83.487 - AllArcLookUp(const Digraph &g) : ArcLookUp<G>(g), _next(g) {refreshNext();}
83.488 + AllArcLookUp(const Digraph &g) : ArcLookUp<GR>(g), _next(g) {refreshNext();}
83.489
83.490 ///Refresh the data structure at a node.
83.491
83.492 @@ -1783,7 +1802,7 @@
83.493 ///the number of the outgoing arcs of \c n.
83.494 void refresh(Node n)
83.495 {
83.496 - ArcLookUp<G>::refresh(n);
83.497 + ArcLookUp<GR>::refresh(n);
83.498 refreshNext(_head[n]);
83.499 }
83.500
83.501 @@ -1830,7 +1849,7 @@
83.502 #ifdef DOXYGEN
83.503 Arc operator()(Node s, Node t, Arc prev=INVALID) const {}
83.504 #else
83.505 - using ArcLookUp<G>::operator() ;
83.506 + using ArcLookUp<GR>::operator() ;
83.507 Arc operator()(Node s, Node t, Arc prev) const
83.508 {
83.509 return prev==INVALID?(*this)(s,t):_next[prev];
84.1 --- a/lemon/counter.h Fri Nov 13 12:33:33 2009 +0100
84.2 +++ b/lemon/counter.h Thu Dec 10 17:05:35 2009 +0100
84.3 @@ -2,7 +2,7 @@
84.4 *
84.5 * This file is a part of LEMON, a generic C++ optimization library.
84.6 *
84.7 - * Copyright (C) 2003-2008
84.8 + * Copyright (C) 2003-2009
84.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
84.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
84.11 *
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
85.2 +++ b/lemon/cplex.cc Thu Dec 10 17:05:35 2009 +0100
85.3 @@ -0,0 +1,951 @@
85.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
85.5 + *
85.6 + * This file is a part of LEMON, a generic C++ optimization library.
85.7 + *
85.8 + * Copyright (C) 2003-2009
85.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
85.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
85.11 + *
85.12 + * Permission to use, modify and distribute this software is granted
85.13 + * provided that this copyright notice appears in all copies. For
85.14 + * precise terms see the accompanying LICENSE file.
85.15 + *
85.16 + * This software is provided "AS IS" with no warranty of any kind,
85.17 + * express or implied, and with no claim as to its suitability for any
85.18 + * purpose.
85.19 + *
85.20 + */
85.21 +
85.22 +#include <iostream>
85.23 +#include <vector>
85.24 +#include <cstring>
85.25 +
85.26 +#include <lemon/cplex.h>
85.27 +
85.28 +extern "C" {
85.29 +#include <ilcplex/cplex.h>
85.30 +}
85.31 +
85.32 +
85.33 +///\file
85.34 +///\brief Implementation of the LEMON-CPLEX lp solver interface.
85.35 +namespace lemon {
85.36 +
85.37 + CplexEnv::LicenseError::LicenseError(int status) {
85.38 + if (!CPXgeterrorstring(0, status, _message)) {
85.39 + std::strcpy(_message, "Cplex unknown error");
85.40 + }
85.41 + }
85.42 +
85.43 + CplexEnv::CplexEnv() {
85.44 + int status;
85.45 + _cnt = new int;
85.46 + _env = CPXopenCPLEX(&status);
85.47 + if (_env == 0) {
85.48 + delete _cnt;
85.49 + _cnt = 0;
85.50 + throw LicenseError(status);
85.51 + }
85.52 + }
85.53 +
85.54 + CplexEnv::CplexEnv(const CplexEnv& other) {
85.55 + _env = other._env;
85.56 + _cnt = other._cnt;
85.57 + ++(*_cnt);
85.58 + }
85.59 +
85.60 + CplexEnv& CplexEnv::operator=(const CplexEnv& other) {
85.61 + _env = other._env;
85.62 + _cnt = other._cnt;
85.63 + ++(*_cnt);
85.64 + return *this;
85.65 + }
85.66 +
85.67 + CplexEnv::~CplexEnv() {
85.68 + --(*_cnt);
85.69 + if (*_cnt == 0) {
85.70 + delete _cnt;
85.71 + CPXcloseCPLEX(&_env);
85.72 + }
85.73 + }
85.74 +
85.75 + CplexBase::CplexBase() : LpBase() {
85.76 + int status;
85.77 + _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
85.78 + messageLevel(MESSAGE_NOTHING);
85.79 + }
85.80 +
85.81 + CplexBase::CplexBase(const CplexEnv& env)
85.82 + : LpBase(), _env(env) {
85.83 + int status;
85.84 + _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
85.85 + messageLevel(MESSAGE_NOTHING);
85.86 + }
85.87 +
85.88 + CplexBase::CplexBase(const CplexBase& cplex)
85.89 + : LpBase() {
85.90 + int status;
85.91 + _prob = CPXcloneprob(cplexEnv(), cplex._prob, &status);
85.92 + rows = cplex.rows;
85.93 + cols = cplex.cols;
85.94 + messageLevel(MESSAGE_NOTHING);
85.95 + }
85.96 +
85.97 + CplexBase::~CplexBase() {
85.98 + CPXfreeprob(cplexEnv(),&_prob);
85.99 + }
85.100 +
85.101 + int CplexBase::_addCol() {
85.102 + int i = CPXgetnumcols(cplexEnv(), _prob);
85.103 + double lb = -INF, ub = INF;
85.104 + CPXnewcols(cplexEnv(), _prob, 1, 0, &lb, &ub, 0, 0);
85.105 + return i;
85.106 + }
85.107 +
85.108 +
85.109 + int CplexBase::_addRow() {
85.110 + int i = CPXgetnumrows(cplexEnv(), _prob);
85.111 + const double ub = INF;
85.112 + const char s = 'L';
85.113 + CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
85.114 + return i;
85.115 + }
85.116 +
85.117 +
85.118 + void CplexBase::_eraseCol(int i) {
85.119 + CPXdelcols(cplexEnv(), _prob, i, i);
85.120 + }
85.121 +
85.122 + void CplexBase::_eraseRow(int i) {
85.123 + CPXdelrows(cplexEnv(), _prob, i, i);
85.124 + }
85.125 +
85.126 + void CplexBase::_eraseColId(int i) {
85.127 + cols.eraseIndex(i);
85.128 + cols.shiftIndices(i);
85.129 + }
85.130 + void CplexBase::_eraseRowId(int i) {
85.131 + rows.eraseIndex(i);
85.132 + rows.shiftIndices(i);
85.133 + }
85.134 +
85.135 + void CplexBase::_getColName(int col, std::string &name) const {
85.136 + int size;
85.137 + CPXgetcolname(cplexEnv(), _prob, 0, 0, 0, &size, col, col);
85.138 + if (size == 0) {
85.139 + name.clear();
85.140 + return;
85.141 + }
85.142 +
85.143 + size *= -1;
85.144 + std::vector<char> buf(size);
85.145 + char *cname;
85.146 + int tmp;
85.147 + CPXgetcolname(cplexEnv(), _prob, &cname, &buf.front(), size,
85.148 + &tmp, col, col);
85.149 + name = cname;
85.150 + }
85.151 +
85.152 + void CplexBase::_setColName(int col, const std::string &name) {
85.153 + char *cname;
85.154 + cname = const_cast<char*>(name.c_str());
85.155 + CPXchgcolname(cplexEnv(), _prob, 1, &col, &cname);
85.156 + }
85.157 +
85.158 + int CplexBase::_colByName(const std::string& name) const {
85.159 + int index;
85.160 + if (CPXgetcolindex(cplexEnv(), _prob,
85.161 + const_cast<char*>(name.c_str()), &index) == 0) {
85.162 + return index;
85.163 + }
85.164 + return -1;
85.165 + }
85.166 +
85.167 + void CplexBase::_getRowName(int row, std::string &name) const {
85.168 + int size;
85.169 + CPXgetrowname(cplexEnv(), _prob, 0, 0, 0, &size, row, row);
85.170 + if (size == 0) {
85.171 + name.clear();
85.172 + return;
85.173 + }
85.174 +
85.175 + size *= -1;
85.176 + std::vector<char> buf(size);
85.177 + char *cname;
85.178 + int tmp;
85.179 + CPXgetrowname(cplexEnv(), _prob, &cname, &buf.front(), size,
85.180 + &tmp, row, row);
85.181 + name = cname;
85.182 + }
85.183 +
85.184 + void CplexBase::_setRowName(int row, const std::string &name) {
85.185 + char *cname;
85.186 + cname = const_cast<char*>(name.c_str());
85.187 + CPXchgrowname(cplexEnv(), _prob, 1, &row, &cname);
85.188 + }
85.189 +
85.190 + int CplexBase::_rowByName(const std::string& name) const {
85.191 + int index;
85.192 + if (CPXgetrowindex(cplexEnv(), _prob,
85.193 + const_cast<char*>(name.c_str()), &index) == 0) {
85.194 + return index;
85.195 + }
85.196 + return -1;
85.197 + }
85.198 +
85.199 + void CplexBase::_setRowCoeffs(int i, ExprIterator b,
85.200 + ExprIterator e)
85.201 + {
85.202 + std::vector<int> indices;
85.203 + std::vector<int> rowlist;
85.204 + std::vector<Value> values;
85.205 +
85.206 + for(ExprIterator it=b; it!=e; ++it) {
85.207 + indices.push_back(it->first);
85.208 + values.push_back(it->second);
85.209 + rowlist.push_back(i);
85.210 + }
85.211 +
85.212 + CPXchgcoeflist(cplexEnv(), _prob, values.size(),
85.213 + &rowlist.front(), &indices.front(), &values.front());
85.214 + }
85.215 +
85.216 + void CplexBase::_getRowCoeffs(int i, InsertIterator b) const {
85.217 + int tmp1, tmp2, tmp3, length;
85.218 + CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
85.219 +
85.220 + length = -length;
85.221 + std::vector<int> indices(length);
85.222 + std::vector<double> values(length);
85.223 +
85.224 + CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2,
85.225 + &indices.front(), &values.front(),
85.226 + length, &tmp3, i, i);
85.227 +
85.228 + for (int i = 0; i < length; ++i) {
85.229 + *b = std::make_pair(indices[i], values[i]);
85.230 + ++b;
85.231 + }
85.232 + }
85.233 +
85.234 + void CplexBase::_setColCoeffs(int i, ExprIterator b, ExprIterator e) {
85.235 + std::vector<int> indices;
85.236 + std::vector<int> collist;
85.237 + std::vector<Value> values;
85.238 +
85.239 + for(ExprIterator it=b; it!=e; ++it) {
85.240 + indices.push_back(it->first);
85.241 + values.push_back(it->second);
85.242 + collist.push_back(i);
85.243 + }
85.244 +
85.245 + CPXchgcoeflist(cplexEnv(), _prob, values.size(),
85.246 + &indices.front(), &collist.front(), &values.front());
85.247 + }
85.248 +
85.249 + void CplexBase::_getColCoeffs(int i, InsertIterator b) const {
85.250 +
85.251 + int tmp1, tmp2, tmp3, length;
85.252 + CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
85.253 +
85.254 + length = -length;
85.255 + std::vector<int> indices(length);
85.256 + std::vector<double> values(length);
85.257 +
85.258 + CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2,
85.259 + &indices.front(), &values.front(),
85.260 + length, &tmp3, i, i);
85.261 +
85.262 + for (int i = 0; i < length; ++i) {
85.263 + *b = std::make_pair(indices[i], values[i]);
85.264 + ++b;
85.265 + }
85.266 +
85.267 + }
85.268 +
85.269 + void CplexBase::_setCoeff(int row, int col, Value value) {
85.270 + CPXchgcoef(cplexEnv(), _prob, row, col, value);
85.271 + }
85.272 +
85.273 + CplexBase::Value CplexBase::_getCoeff(int row, int col) const {
85.274 + CplexBase::Value value;
85.275 + CPXgetcoef(cplexEnv(), _prob, row, col, &value);
85.276 + return value;
85.277 + }
85.278 +
85.279 + void CplexBase::_setColLowerBound(int i, Value value) {
85.280 + const char s = 'L';
85.281 + CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
85.282 + }
85.283 +
85.284 + CplexBase::Value CplexBase::_getColLowerBound(int i) const {
85.285 + CplexBase::Value res;
85.286 + CPXgetlb(cplexEnv(), _prob, &res, i, i);
85.287 + return res <= -CPX_INFBOUND ? -INF : res;
85.288 + }
85.289 +
85.290 + void CplexBase::_setColUpperBound(int i, Value value)
85.291 + {
85.292 + const char s = 'U';
85.293 + CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
85.294 + }
85.295 +
85.296 + CplexBase::Value CplexBase::_getColUpperBound(int i) const {
85.297 + CplexBase::Value res;
85.298 + CPXgetub(cplexEnv(), _prob, &res, i, i);
85.299 + return res >= CPX_INFBOUND ? INF : res;
85.300 + }
85.301 +
85.302 + CplexBase::Value CplexBase::_getRowLowerBound(int i) const {
85.303 + char s;
85.304 + CPXgetsense(cplexEnv(), _prob, &s, i, i);
85.305 + CplexBase::Value res;
85.306 +
85.307 + switch (s) {
85.308 + case 'G':
85.309 + case 'R':
85.310 + case 'E':
85.311 + CPXgetrhs(cplexEnv(), _prob, &res, i, i);
85.312 + return res <= -CPX_INFBOUND ? -INF : res;
85.313 + default:
85.314 + return -INF;
85.315 + }
85.316 + }
85.317 +
85.318 + CplexBase::Value CplexBase::_getRowUpperBound(int i) const {
85.319 + char s;
85.320 + CPXgetsense(cplexEnv(), _prob, &s, i, i);
85.321 + CplexBase::Value res;
85.322 +
85.323 + switch (s) {
85.324 + case 'L':
85.325 + case 'E':
85.326 + CPXgetrhs(cplexEnv(), _prob, &res, i, i);
85.327 + return res >= CPX_INFBOUND ? INF : res;
85.328 + case 'R':
85.329 + CPXgetrhs(cplexEnv(), _prob, &res, i, i);
85.330 + {
85.331 + double rng;
85.332 + CPXgetrngval(cplexEnv(), _prob, &rng, i, i);
85.333 + res += rng;
85.334 + }
85.335 + return res >= CPX_INFBOUND ? INF : res;
85.336 + default:
85.337 + return INF;
85.338 + }
85.339 + }
85.340 +
85.341 + //This is easier to implement
85.342 + void CplexBase::_set_row_bounds(int i, Value lb, Value ub) {
85.343 + if (lb == -INF) {
85.344 + const char s = 'L';
85.345 + CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
85.346 + CPXchgrhs(cplexEnv(), _prob, 1, &i, &ub);
85.347 + } else if (ub == INF) {
85.348 + const char s = 'G';
85.349 + CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
85.350 + CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
85.351 + } else if (lb == ub){
85.352 + const char s = 'E';
85.353 + CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
85.354 + CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
85.355 + } else {
85.356 + const char s = 'R';
85.357 + CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
85.358 + CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
85.359 + double len = ub - lb;
85.360 + CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
85.361 + }
85.362 + }
85.363 +
85.364 + void CplexBase::_setRowLowerBound(int i, Value lb)
85.365 + {
85.366 + LEMON_ASSERT(lb != INF, "Invalid bound");
85.367 + _set_row_bounds(i, lb, CplexBase::_getRowUpperBound(i));
85.368 + }
85.369 +
85.370 + void CplexBase::_setRowUpperBound(int i, Value ub)
85.371 + {
85.372 +
85.373 + LEMON_ASSERT(ub != -INF, "Invalid bound");
85.374 + _set_row_bounds(i, CplexBase::_getRowLowerBound(i), ub);
85.375 + }
85.376 +
85.377 + void CplexBase::_setObjCoeffs(ExprIterator b, ExprIterator e)
85.378 + {
85.379 + std::vector<int> indices;
85.380 + std::vector<Value> values;
85.381 + for(ExprIterator it=b; it!=e; ++it) {
85.382 + indices.push_back(it->first);
85.383 + values.push_back(it->second);
85.384 + }
85.385 + CPXchgobj(cplexEnv(), _prob, values.size(),
85.386 + &indices.front(), &values.front());
85.387 +
85.388 + }
85.389 +
85.390 + void CplexBase::_getObjCoeffs(InsertIterator b) const
85.391 + {
85.392 + int num = CPXgetnumcols(cplexEnv(), _prob);
85.393 + std::vector<Value> x(num);
85.394 +
85.395 + CPXgetobj(cplexEnv(), _prob, &x.front(), 0, num - 1);
85.396 + for (int i = 0; i < num; ++i) {
85.397 + if (x[i] != 0.0) {
85.398 + *b = std::make_pair(i, x[i]);
85.399 + ++b;
85.400 + }
85.401 + }
85.402 + }
85.403 +
85.404 + void CplexBase::_setObjCoeff(int i, Value obj_coef)
85.405 + {
85.406 + CPXchgobj(cplexEnv(), _prob, 1, &i, &obj_coef);
85.407 + }
85.408 +
85.409 + CplexBase::Value CplexBase::_getObjCoeff(int i) const
85.410 + {
85.411 + Value x;
85.412 + CPXgetobj(cplexEnv(), _prob, &x, i, i);
85.413 + return x;
85.414 + }
85.415 +
85.416 + void CplexBase::_setSense(CplexBase::Sense sense) {
85.417 + switch (sense) {
85.418 + case MIN:
85.419 + CPXchgobjsen(cplexEnv(), _prob, CPX_MIN);
85.420 + break;
85.421 + case MAX:
85.422 + CPXchgobjsen(cplexEnv(), _prob, CPX_MAX);
85.423 + break;
85.424 + }
85.425 + }
85.426 +
85.427 + CplexBase::Sense CplexBase::_getSense() const {
85.428 + switch (CPXgetobjsen(cplexEnv(), _prob)) {
85.429 + case CPX_MIN:
85.430 + return MIN;
85.431 + case CPX_MAX:
85.432 + return MAX;
85.433 + default:
85.434 + LEMON_ASSERT(false, "Invalid sense");
85.435 + return CplexBase::Sense();
85.436 + }
85.437 + }
85.438 +
85.439 + void CplexBase::_clear() {
85.440 + CPXfreeprob(cplexEnv(),&_prob);
85.441 + int status;
85.442 + _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
85.443 + rows.clear();
85.444 + cols.clear();
85.445 + }
85.446 +
85.447 + void CplexBase::_messageLevel(MessageLevel level) {
85.448 + switch (level) {
85.449 + case MESSAGE_NOTHING:
85.450 + _message_enabled = false;
85.451 + break;
85.452 + case MESSAGE_ERROR:
85.453 + case MESSAGE_WARNING:
85.454 + case MESSAGE_NORMAL:
85.455 + case MESSAGE_VERBOSE:
85.456 + _message_enabled = true;
85.457 + break;
85.458 + }
85.459 + }
85.460 +
85.461 + void CplexBase::_applyMessageLevel() {
85.462 + CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND,
85.463 + _message_enabled ? CPX_ON : CPX_OFF);
85.464 + }
85.465 +
85.466 + // CplexLp members
85.467 +
85.468 + CplexLp::CplexLp()
85.469 + : LpBase(), LpSolver(), CplexBase() {}
85.470 +
85.471 + CplexLp::CplexLp(const CplexEnv& env)
85.472 + : LpBase(), LpSolver(), CplexBase(env) {}
85.473 +
85.474 + CplexLp::CplexLp(const CplexLp& other)
85.475 + : LpBase(), LpSolver(), CplexBase(other) {}
85.476 +
85.477 + CplexLp::~CplexLp() {}
85.478 +
85.479 + CplexLp* CplexLp::newSolver() const { return new CplexLp; }
85.480 + CplexLp* CplexLp::cloneSolver() const {return new CplexLp(*this); }
85.481 +
85.482 + const char* CplexLp::_solverName() const { return "CplexLp"; }
85.483 +
85.484 + void CplexLp::_clear_temporals() {
85.485 + _col_status.clear();
85.486 + _row_status.clear();
85.487 + _primal_ray.clear();
85.488 + _dual_ray.clear();
85.489 + }
85.490 +
85.491 + // The routine returns zero unless an error occurred during the
85.492 + // optimization. Examples of errors include exhausting available
85.493 + // memory (CPXERR_NO_MEMORY) or encountering invalid data in the
85.494 + // CPLEX problem object (CPXERR_NO_PROBLEM). Exceeding a
85.495 + // user-specified CPLEX limit, or proving the model infeasible or
85.496 + // unbounded, are not considered errors. Note that a zero return
85.497 + // value does not necessarily mean that a solution exists. Use query
85.498 + // routines CPXsolninfo, CPXgetstat, and CPXsolution to obtain
85.499 + // further information about the status of the optimization.
85.500 + CplexLp::SolveExitStatus CplexLp::convertStatus(int status) {
85.501 +#if CPX_VERSION >= 800
85.502 + if (status == 0) {
85.503 + switch (CPXgetstat(cplexEnv(), _prob)) {
85.504 + case CPX_STAT_OPTIMAL:
85.505 + case CPX_STAT_INFEASIBLE:
85.506 + case CPX_STAT_UNBOUNDED:
85.507 + return SOLVED;
85.508 + default:
85.509 + return UNSOLVED;
85.510 + }
85.511 + } else {
85.512 + return UNSOLVED;
85.513 + }
85.514 +#else
85.515 + if (status == 0) {
85.516 + //We want to exclude some cases
85.517 + switch (CPXgetstat(cplexEnv(), _prob)) {
85.518 + case CPX_OBJ_LIM:
85.519 + case CPX_IT_LIM_FEAS:
85.520 + case CPX_IT_LIM_INFEAS:
85.521 + case CPX_TIME_LIM_FEAS:
85.522 + case CPX_TIME_LIM_INFEAS:
85.523 + return UNSOLVED;
85.524 + default:
85.525 + return SOLVED;
85.526 + }
85.527 + } else {
85.528 + return UNSOLVED;
85.529 + }
85.530 +#endif
85.531 + }
85.532 +
85.533 + CplexLp::SolveExitStatus CplexLp::_solve() {
85.534 + _clear_temporals();
85.535 + _applyMessageLevel();
85.536 + return convertStatus(CPXlpopt(cplexEnv(), _prob));
85.537 + }
85.538 +
85.539 + CplexLp::SolveExitStatus CplexLp::solvePrimal() {
85.540 + _clear_temporals();
85.541 + _applyMessageLevel();
85.542 + return convertStatus(CPXprimopt(cplexEnv(), _prob));
85.543 + }
85.544 +
85.545 + CplexLp::SolveExitStatus CplexLp::solveDual() {
85.546 + _clear_temporals();
85.547 + _applyMessageLevel();
85.548 + return convertStatus(CPXdualopt(cplexEnv(), _prob));
85.549 + }
85.550 +
85.551 + CplexLp::SolveExitStatus CplexLp::solveBarrier() {
85.552 + _clear_temporals();
85.553 + _applyMessageLevel();
85.554 + return convertStatus(CPXbaropt(cplexEnv(), _prob));
85.555 + }
85.556 +
85.557 + CplexLp::Value CplexLp::_getPrimal(int i) const {
85.558 + Value x;
85.559 + CPXgetx(cplexEnv(), _prob, &x, i, i);
85.560 + return x;
85.561 + }
85.562 +
85.563 + CplexLp::Value CplexLp::_getDual(int i) const {
85.564 + Value y;
85.565 + CPXgetpi(cplexEnv(), _prob, &y, i, i);
85.566 + return y;
85.567 + }
85.568 +
85.569 + CplexLp::Value CplexLp::_getPrimalValue() const {
85.570 + Value objval;
85.571 + CPXgetobjval(cplexEnv(), _prob, &objval);
85.572 + return objval;
85.573 + }
85.574 +
85.575 + CplexLp::VarStatus CplexLp::_getColStatus(int i) const {
85.576 + if (_col_status.empty()) {
85.577 + _col_status.resize(CPXgetnumcols(cplexEnv(), _prob));
85.578 + CPXgetbase(cplexEnv(), _prob, &_col_status.front(), 0);
85.579 + }
85.580 + switch (_col_status[i]) {
85.581 + case CPX_BASIC:
85.582 + return BASIC;
85.583 + case CPX_FREE_SUPER:
85.584 + return FREE;
85.585 + case CPX_AT_LOWER:
85.586 + return LOWER;
85.587 + case CPX_AT_UPPER:
85.588 + return UPPER;
85.589 + default:
85.590 + LEMON_ASSERT(false, "Wrong column status");
85.591 + return CplexLp::VarStatus();
85.592 + }
85.593 + }
85.594 +
85.595 + CplexLp::VarStatus CplexLp::_getRowStatus(int i) const {
85.596 + if (_row_status.empty()) {
85.597 + _row_status.resize(CPXgetnumrows(cplexEnv(), _prob));
85.598 + CPXgetbase(cplexEnv(), _prob, 0, &_row_status.front());
85.599 + }
85.600 + switch (_row_status[i]) {
85.601 + case CPX_BASIC:
85.602 + return BASIC;
85.603 + case CPX_AT_LOWER:
85.604 + {
85.605 + char s;
85.606 + CPXgetsense(cplexEnv(), _prob, &s, i, i);
85.607 + return s != 'L' ? LOWER : UPPER;
85.608 + }
85.609 + case CPX_AT_UPPER:
85.610 + return UPPER;
85.611 + default:
85.612 + LEMON_ASSERT(false, "Wrong row status");
85.613 + return CplexLp::VarStatus();
85.614 + }
85.615 + }
85.616 +
85.617 + CplexLp::Value CplexLp::_getPrimalRay(int i) const {
85.618 + if (_primal_ray.empty()) {
85.619 + _primal_ray.resize(CPXgetnumcols(cplexEnv(), _prob));
85.620 + CPXgetray(cplexEnv(), _prob, &_primal_ray.front());
85.621 + }
85.622 + return _primal_ray[i];
85.623 + }
85.624 +
85.625 + CplexLp::Value CplexLp::_getDualRay(int i) const {
85.626 + if (_dual_ray.empty()) {
85.627 +
85.628 + }
85.629 + return _dual_ray[i];
85.630 + }
85.631 +
85.632 + // Cplex 7.0 status values
85.633 + // This table lists the statuses, returned by the CPXgetstat()
85.634 + // routine, for solutions to LP problems or mixed integer problems. If
85.635 + // no solution exists, the return value is zero.
85.636 +
85.637 + // For Simplex, Barrier
85.638 + // 1 CPX_OPTIMAL
85.639 + // Optimal solution found
85.640 + // 2 CPX_INFEASIBLE
85.641 + // Problem infeasible
85.642 + // 3 CPX_UNBOUNDED
85.643 + // Problem unbounded
85.644 + // 4 CPX_OBJ_LIM
85.645 + // Objective limit exceeded in Phase II
85.646 + // 5 CPX_IT_LIM_FEAS
85.647 + // Iteration limit exceeded in Phase II
85.648 + // 6 CPX_IT_LIM_INFEAS
85.649 + // Iteration limit exceeded in Phase I
85.650 + // 7 CPX_TIME_LIM_FEAS
85.651 + // Time limit exceeded in Phase II
85.652 + // 8 CPX_TIME_LIM_INFEAS
85.653 + // Time limit exceeded in Phase I
85.654 + // 9 CPX_NUM_BEST_FEAS
85.655 + // Problem non-optimal, singularities in Phase II
85.656 + // 10 CPX_NUM_BEST_INFEAS
85.657 + // Problem non-optimal, singularities in Phase I
85.658 + // 11 CPX_OPTIMAL_INFEAS
85.659 + // Optimal solution found, unscaled infeasibilities
85.660 + // 12 CPX_ABORT_FEAS
85.661 + // Aborted in Phase II
85.662 + // 13 CPX_ABORT_INFEAS
85.663 + // Aborted in Phase I
85.664 + // 14 CPX_ABORT_DUAL_INFEAS
85.665 + // Aborted in barrier, dual infeasible
85.666 + // 15 CPX_ABORT_PRIM_INFEAS
85.667 + // Aborted in barrier, primal infeasible
85.668 + // 16 CPX_ABORT_PRIM_DUAL_INFEAS
85.669 + // Aborted in barrier, primal and dual infeasible
85.670 + // 17 CPX_ABORT_PRIM_DUAL_FEAS
85.671 + // Aborted in barrier, primal and dual feasible
85.672 + // 18 CPX_ABORT_CROSSOVER
85.673 + // Aborted in crossover
85.674 + // 19 CPX_INForUNBD
85.675 + // Infeasible or unbounded
85.676 + // 20 CPX_PIVOT
85.677 + // User pivot used
85.678 + //
85.679 + // Pending return values
85.680 + // ??case CPX_ABORT_DUAL_INFEAS
85.681 + // ??case CPX_ABORT_CROSSOVER
85.682 + // ??case CPX_INForUNBD
85.683 + // ??case CPX_PIVOT
85.684 +
85.685 + //Some more interesting stuff:
85.686 +
85.687 + // CPX_PARAM_PROBMETHOD 1062 int LPMETHOD
85.688 + // 0 Automatic
85.689 + // 1 Primal Simplex
85.690 + // 2 Dual Simplex
85.691 + // 3 Network Simplex
85.692 + // 4 Standard Barrier
85.693 + // Default: 0
85.694 + // Description: Method for linear optimization.
85.695 + // Determines which algorithm is used when CPXlpopt() (or "optimize"
85.696 + // in the Interactive Optimizer) is called. Currently the behavior of
85.697 + // the "Automatic" setting is that CPLEX simply invokes the dual
85.698 + // simplex method, but this capability may be expanded in the future
85.699 + // so that CPLEX chooses the method based on problem characteristics
85.700 +#if CPX_VERSION < 900
85.701 + void statusSwitch(CPXENVptr cplexEnv(),int& stat){
85.702 + int lpmethod;
85.703 + CPXgetintparam (cplexEnv(),CPX_PARAM_PROBMETHOD,&lpmethod);
85.704 + if (lpmethod==2){
85.705 + if (stat==CPX_UNBOUNDED){
85.706 + stat=CPX_INFEASIBLE;
85.707 + }
85.708 + else{
85.709 + if (stat==CPX_INFEASIBLE)
85.710 + stat=CPX_UNBOUNDED;
85.711 + }
85.712 + }
85.713 + }
85.714 +#else
85.715 + void statusSwitch(CPXENVptr,int&){}
85.716 +#endif
85.717 +
85.718 + CplexLp::ProblemType CplexLp::_getPrimalType() const {
85.719 + // Unboundedness not treated well: the following is from cplex 9.0 doc
85.720 + // About Unboundedness
85.721 +
85.722 + // The treatment of models that are unbounded involves a few
85.723 + // subtleties. Specifically, a declaration of unboundedness means that
85.724 + // ILOG CPLEX has determined that the model has an unbounded
85.725 + // ray. Given any feasible solution x with objective z, a multiple of
85.726 + // the unbounded ray can be added to x to give a feasible solution
85.727 + // with objective z-1 (or z+1 for maximization models). Thus, if a
85.728 + // feasible solution exists, then the optimal objective is
85.729 + // unbounded. Note that ILOG CPLEX has not necessarily concluded that
85.730 + // a feasible solution exists. Users can call the routine CPXsolninfo
85.731 + // to determine whether ILOG CPLEX has also concluded that the model
85.732 + // has a feasible solution.
85.733 +
85.734 + int stat = CPXgetstat(cplexEnv(), _prob);
85.735 +#if CPX_VERSION >= 800
85.736 + switch (stat)
85.737 + {
85.738 + case CPX_STAT_OPTIMAL:
85.739 + return OPTIMAL;
85.740 + case CPX_STAT_UNBOUNDED:
85.741 + return UNBOUNDED;
85.742 + case CPX_STAT_INFEASIBLE:
85.743 + return INFEASIBLE;
85.744 + default:
85.745 + return UNDEFINED;
85.746 + }
85.747 +#else
85.748 + statusSwitch(cplexEnv(),stat);
85.749 + //CPXgetstat(cplexEnv(), _prob);
85.750 + switch (stat) {
85.751 + case 0:
85.752 + return UNDEFINED; //Undefined
85.753 + case CPX_OPTIMAL://Optimal
85.754 + return OPTIMAL;
85.755 + case CPX_UNBOUNDED://Unbounded
85.756 + return INFEASIBLE;//In case of dual simplex
85.757 + //return UNBOUNDED;
85.758 + case CPX_INFEASIBLE://Infeasible
85.759 + // case CPX_IT_LIM_INFEAS:
85.760 + // case CPX_TIME_LIM_INFEAS:
85.761 + // case CPX_NUM_BEST_INFEAS:
85.762 + // case CPX_OPTIMAL_INFEAS:
85.763 + // case CPX_ABORT_INFEAS:
85.764 + // case CPX_ABORT_PRIM_INFEAS:
85.765 + // case CPX_ABORT_PRIM_DUAL_INFEAS:
85.766 + return UNBOUNDED;//In case of dual simplex
85.767 + //return INFEASIBLE;
85.768 + // case CPX_OBJ_LIM:
85.769 + // case CPX_IT_LIM_FEAS:
85.770 + // case CPX_TIME_LIM_FEAS:
85.771 + // case CPX_NUM_BEST_FEAS:
85.772 + // case CPX_ABORT_FEAS:
85.773 + // case CPX_ABORT_PRIM_DUAL_FEAS:
85.774 + // return FEASIBLE;
85.775 + default:
85.776 + return UNDEFINED; //Everything else comes here
85.777 + //FIXME error
85.778 + }
85.779 +#endif
85.780 + }
85.781 +
85.782 + // Cplex 9.0 status values
85.783 + // CPX_STAT_ABORT_DUAL_OBJ_LIM
85.784 + // CPX_STAT_ABORT_IT_LIM
85.785 + // CPX_STAT_ABORT_OBJ_LIM
85.786 + // CPX_STAT_ABORT_PRIM_OBJ_LIM
85.787 + // CPX_STAT_ABORT_TIME_LIM
85.788 + // CPX_STAT_ABORT_USER
85.789 + // CPX_STAT_FEASIBLE_RELAXED
85.790 + // CPX_STAT_INFEASIBLE
85.791 + // CPX_STAT_INForUNBD
85.792 + // CPX_STAT_NUM_BEST
85.793 + // CPX_STAT_OPTIMAL
85.794 + // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
85.795 + // CPX_STAT_OPTIMAL_INFEAS
85.796 + // CPX_STAT_OPTIMAL_RELAXED
85.797 + // CPX_STAT_UNBOUNDED
85.798 +
85.799 + CplexLp::ProblemType CplexLp::_getDualType() const {
85.800 + int stat = CPXgetstat(cplexEnv(), _prob);
85.801 +#if CPX_VERSION >= 800
85.802 + switch (stat) {
85.803 + case CPX_STAT_OPTIMAL:
85.804 + return OPTIMAL;
85.805 + case CPX_STAT_UNBOUNDED:
85.806 + return INFEASIBLE;
85.807 + default:
85.808 + return UNDEFINED;
85.809 + }
85.810 +#else
85.811 + statusSwitch(cplexEnv(),stat);
85.812 + switch (stat) {
85.813 + case 0:
85.814 + return UNDEFINED; //Undefined
85.815 + case CPX_OPTIMAL://Optimal
85.816 + return OPTIMAL;
85.817 + case CPX_UNBOUNDED:
85.818 + return INFEASIBLE;
85.819 + default:
85.820 + return UNDEFINED; //Everything else comes here
85.821 + //FIXME error
85.822 + }
85.823 +#endif
85.824 + }
85.825 +
85.826 + // CplexMip members
85.827 +
85.828 + CplexMip::CplexMip()
85.829 + : LpBase(), MipSolver(), CplexBase() {
85.830 +
85.831 +#if CPX_VERSION < 800
85.832 + CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MIP);
85.833 +#else
85.834 + CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MILP);
85.835 +#endif
85.836 + }
85.837 +
85.838 + CplexMip::CplexMip(const CplexEnv& env)
85.839 + : LpBase(), MipSolver(), CplexBase(env) {
85.840 +
85.841 +#if CPX_VERSION < 800
85.842 + CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MIP);
85.843 +#else
85.844 + CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MILP);
85.845 +#endif
85.846 +
85.847 + }
85.848 +
85.849 + CplexMip::CplexMip(const CplexMip& other)
85.850 + : LpBase(), MipSolver(), CplexBase(other) {}
85.851 +
85.852 + CplexMip::~CplexMip() {}
85.853 +
85.854 + CplexMip* CplexMip::newSolver() const { return new CplexMip; }
85.855 + CplexMip* CplexMip::cloneSolver() const {return new CplexMip(*this); }
85.856 +
85.857 + const char* CplexMip::_solverName() const { return "CplexMip"; }
85.858 +
85.859 + void CplexMip::_setColType(int i, CplexMip::ColTypes col_type) {
85.860 +
85.861 + // Note If a variable is to be changed to binary, a call to CPXchgbds
85.862 + // should also be made to change the bounds to 0 and 1.
85.863 +
85.864 + switch (col_type){
85.865 + case INTEGER: {
85.866 + const char t = 'I';
85.867 + CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
85.868 + } break;
85.869 + case REAL: {
85.870 + const char t = 'C';
85.871 + CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
85.872 + } break;
85.873 + default:
85.874 + break;
85.875 + }
85.876 + }
85.877 +
85.878 + CplexMip::ColTypes CplexMip::_getColType(int i) const {
85.879 + char t;
85.880 + CPXgetctype (cplexEnv(), _prob, &t, i, i);
85.881 + switch (t) {
85.882 + case 'I':
85.883 + return INTEGER;
85.884 + case 'C':
85.885 + return REAL;
85.886 + default:
85.887 + LEMON_ASSERT(false, "Invalid column type");
85.888 + return ColTypes();
85.889 + }
85.890 +
85.891 + }
85.892 +
85.893 + CplexMip::SolveExitStatus CplexMip::_solve() {
85.894 + int status;
85.895 + _applyMessageLevel();
85.896 + status = CPXmipopt (cplexEnv(), _prob);
85.897 + if (status==0)
85.898 + return SOLVED;
85.899 + else
85.900 + return UNSOLVED;
85.901 +
85.902 + }
85.903 +
85.904 +
85.905 + CplexMip::ProblemType CplexMip::_getType() const {
85.906 +
85.907 + int stat = CPXgetstat(cplexEnv(), _prob);
85.908 +
85.909 + //Fortunately, MIP statuses did not change for cplex 8.0
85.910 + switch (stat) {
85.911 + case CPXMIP_OPTIMAL:
85.912 + // Optimal integer solution has been found.
85.913 + case CPXMIP_OPTIMAL_TOL:
85.914 + // Optimal soluton with the tolerance defined by epgap or epagap has
85.915 + // been found.
85.916 + return OPTIMAL;
85.917 + //This also exists in later issues
85.918 + // case CPXMIP_UNBOUNDED:
85.919 + //return UNBOUNDED;
85.920 + case CPXMIP_INFEASIBLE:
85.921 + return INFEASIBLE;
85.922 + default:
85.923 + return UNDEFINED;
85.924 + }
85.925 + //Unboundedness not treated well: the following is from cplex 9.0 doc
85.926 + // About Unboundedness
85.927 +
85.928 + // The treatment of models that are unbounded involves a few
85.929 + // subtleties. Specifically, a declaration of unboundedness means that
85.930 + // ILOG CPLEX has determined that the model has an unbounded
85.931 + // ray. Given any feasible solution x with objective z, a multiple of
85.932 + // the unbounded ray can be added to x to give a feasible solution
85.933 + // with objective z-1 (or z+1 for maximization models). Thus, if a
85.934 + // feasible solution exists, then the optimal objective is
85.935 + // unbounded. Note that ILOG CPLEX has not necessarily concluded that
85.936 + // a feasible solution exists. Users can call the routine CPXsolninfo
85.937 + // to determine whether ILOG CPLEX has also concluded that the model
85.938 + // has a feasible solution.
85.939 + }
85.940 +
85.941 + CplexMip::Value CplexMip::_getSol(int i) const {
85.942 + Value x;
85.943 + CPXgetmipx(cplexEnv(), _prob, &x, i, i);
85.944 + return x;
85.945 + }
85.946 +
85.947 + CplexMip::Value CplexMip::_getSolValue() const {
85.948 + Value objval;
85.949 + CPXgetmipobjval(cplexEnv(), _prob, &objval);
85.950 + return objval;
85.951 + }
85.952 +
85.953 +} //namespace lemon
85.954 +
86.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
86.2 +++ b/lemon/cplex.h Thu Dec 10 17:05:35 2009 +0100
86.3 @@ -0,0 +1,276 @@
86.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
86.5 + *
86.6 + * This file is a part of LEMON, a generic C++ optimization library.
86.7 + *
86.8 + * Copyright (C) 2003-2009
86.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
86.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
86.11 + *
86.12 + * Permission to use, modify and distribute this software is granted
86.13 + * provided that this copyright notice appears in all copies. For
86.14 + * precise terms see the accompanying LICENSE file.
86.15 + *
86.16 + * This software is provided "AS IS" with no warranty of any kind,
86.17 + * express or implied, and with no claim as to its suitability for any
86.18 + * purpose.
86.19 + *
86.20 + */
86.21 +
86.22 +#ifndef LEMON_CPLEX_H
86.23 +#define LEMON_CPLEX_H
86.24 +
86.25 +///\file
86.26 +///\brief Header of the LEMON-CPLEX lp solver interface.
86.27 +
86.28 +#include <lemon/lp_base.h>
86.29 +
86.30 +struct cpxenv;
86.31 +struct cpxlp;
86.32 +
86.33 +namespace lemon {
86.34 +
86.35 + /// \brief Reference counted wrapper around cpxenv pointer
86.36 + ///
86.37 + /// The cplex uses environment object which is responsible for
86.38 + /// checking the proper license usage. This class provides a simple
86.39 + /// interface for share the environment object between different
86.40 + /// problems.
86.41 + class CplexEnv {
86.42 + friend class CplexBase;
86.43 + private:
86.44 + cpxenv* _env;
86.45 + mutable int* _cnt;
86.46 +
86.47 + public:
86.48 +
86.49 + /// \brief This exception is thrown when the license check is not
86.50 + /// sufficient
86.51 + class LicenseError : public Exception {
86.52 + friend class CplexEnv;
86.53 + private:
86.54 +
86.55 + LicenseError(int status);
86.56 + char _message[510];
86.57 +
86.58 + public:
86.59 +
86.60 + /// The short error message
86.61 + virtual const char* what() const throw() {
86.62 + return _message;
86.63 + }
86.64 + };
86.65 +
86.66 + /// Constructor
86.67 + CplexEnv();
86.68 + /// Shallow copy constructor
86.69 + CplexEnv(const CplexEnv&);
86.70 + /// Shallow assignement
86.71 + CplexEnv& operator=(const CplexEnv&);
86.72 + /// Destructor
86.73 + virtual ~CplexEnv();
86.74 +
86.75 + protected:
86.76 +
86.77 + cpxenv* cplexEnv() { return _env; }
86.78 + const cpxenv* cplexEnv() const { return _env; }
86.79 + };
86.80 +
86.81 + /// \brief Base interface for the CPLEX LP and MIP solver
86.82 + ///
86.83 + /// This class implements the common interface of the CPLEX LP and
86.84 + /// MIP solvers.
86.85 + /// \ingroup lp_group
86.86 + class CplexBase : virtual public LpBase {
86.87 + protected:
86.88 +
86.89 + CplexEnv _env;
86.90 + cpxlp* _prob;
86.91 +
86.92 + CplexBase();
86.93 + CplexBase(const CplexEnv&);
86.94 + CplexBase(const CplexBase &);
86.95 + virtual ~CplexBase();
86.96 +
86.97 + virtual int _addCol();
86.98 + virtual int _addRow();
86.99 +
86.100 + virtual void _eraseCol(int i);
86.101 + virtual void _eraseRow(int i);
86.102 +
86.103 + virtual void _eraseColId(int i);
86.104 + virtual void _eraseRowId(int i);
86.105 +
86.106 + virtual void _getColName(int col, std::string& name) const;
86.107 + virtual void _setColName(int col, const std::string& name);
86.108 + virtual int _colByName(const std::string& name) const;
86.109 +
86.110 + virtual void _getRowName(int row, std::string& name) const;
86.111 + virtual void _setRowName(int row, const std::string& name);
86.112 + virtual int _rowByName(const std::string& name) const;
86.113 +
86.114 + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
86.115 + virtual void _getRowCoeffs(int i, InsertIterator b) const;
86.116 +
86.117 + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
86.118 + virtual void _getColCoeffs(int i, InsertIterator b) const;
86.119 +
86.120 + virtual void _setCoeff(int row, int col, Value value);
86.121 + virtual Value _getCoeff(int row, int col) const;
86.122 +
86.123 + virtual void _setColLowerBound(int i, Value value);
86.124 + virtual Value _getColLowerBound(int i) const;
86.125 +
86.126 + virtual void _setColUpperBound(int i, Value value);
86.127 + virtual Value _getColUpperBound(int i) const;
86.128 +
86.129 + private:
86.130 + void _set_row_bounds(int i, Value lb, Value ub);
86.131 + protected:
86.132 +
86.133 + virtual void _setRowLowerBound(int i, Value value);
86.134 + virtual Value _getRowLowerBound(int i) const;
86.135 +
86.136 + virtual void _setRowUpperBound(int i, Value value);
86.137 + virtual Value _getRowUpperBound(int i) const;
86.138 +
86.139 + virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
86.140 + virtual void _getObjCoeffs(InsertIterator b) const;
86.141 +
86.142 + virtual void _setObjCoeff(int i, Value obj_coef);
86.143 + virtual Value _getObjCoeff(int i) const;
86.144 +
86.145 + virtual void _setSense(Sense sense);
86.146 + virtual Sense _getSense() const;
86.147 +
86.148 + virtual void _clear();
86.149 +
86.150 + virtual void _messageLevel(MessageLevel level);
86.151 + void _applyMessageLevel();
86.152 +
86.153 + bool _message_enabled;
86.154 +
86.155 + public:
86.156 +
86.157 + /// Returns the used \c CplexEnv instance
86.158 + const CplexEnv& env() const { return _env; }
86.159 +
86.160 + /// \brief Returns the const cpxenv pointer
86.161 + ///
86.162 + /// \note The cpxenv might be destructed with the solver.
86.163 + const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
86.164 +
86.165 + /// \brief Returns the const cpxenv pointer
86.166 + ///
86.167 + /// \note The cpxenv might be destructed with the solver.
86.168 + cpxenv* cplexEnv() { return _env.cplexEnv(); }
86.169 +
86.170 + /// Returns the cplex problem object
86.171 + cpxlp* cplexLp() { return _prob; }
86.172 + /// Returns the cplex problem object
86.173 + const cpxlp* cplexLp() const { return _prob; }
86.174 +
86.175 + };
86.176 +
86.177 + /// \brief Interface for the CPLEX LP solver
86.178 + ///
86.179 + /// This class implements an interface for the CPLEX LP solver.
86.180 + ///\ingroup lp_group
86.181 + class CplexLp : public LpSolver, public CplexBase {
86.182 + public:
86.183 + /// \e
86.184 + CplexLp();
86.185 + /// \e
86.186 + CplexLp(const CplexEnv&);
86.187 + /// \e
86.188 + CplexLp(const CplexLp&);
86.189 + /// \e
86.190 + virtual ~CplexLp();
86.191 +
86.192 + /// \e
86.193 + virtual CplexLp* cloneSolver() const;
86.194 + /// \e
86.195 + virtual CplexLp* newSolver() const;
86.196 +
86.197 + private:
86.198 +
86.199 + // these values cannot retrieved element by element
86.200 + mutable std::vector<int> _col_status;
86.201 + mutable std::vector<int> _row_status;
86.202 +
86.203 + mutable std::vector<Value> _primal_ray;
86.204 + mutable std::vector<Value> _dual_ray;
86.205 +
86.206 + void _clear_temporals();
86.207 +
86.208 + SolveExitStatus convertStatus(int status);
86.209 +
86.210 + protected:
86.211 +
86.212 + virtual const char* _solverName() const;
86.213 +
86.214 + virtual SolveExitStatus _solve();
86.215 + virtual Value _getPrimal(int i) const;
86.216 + virtual Value _getDual(int i) const;
86.217 + virtual Value _getPrimalValue() const;
86.218 +
86.219 + virtual VarStatus _getColStatus(int i) const;
86.220 + virtual VarStatus _getRowStatus(int i) const;
86.221 +
86.222 + virtual Value _getPrimalRay(int i) const;
86.223 + virtual Value _getDualRay(int i) const;
86.224 +
86.225 + virtual ProblemType _getPrimalType() const;
86.226 + virtual ProblemType _getDualType() const;
86.227 +
86.228 + public:
86.229 +
86.230 + /// Solve with primal simplex method
86.231 + SolveExitStatus solvePrimal();
86.232 +
86.233 + /// Solve with dual simplex method
86.234 + SolveExitStatus solveDual();
86.235 +
86.236 + /// Solve with barrier method
86.237 + SolveExitStatus solveBarrier();
86.238 +
86.239 + };
86.240 +
86.241 + /// \brief Interface for the CPLEX MIP solver
86.242 + ///
86.243 + /// This class implements an interface for the CPLEX MIP solver.
86.244 + ///\ingroup lp_group
86.245 + class CplexMip : public MipSolver, public CplexBase {
86.246 + public:
86.247 + /// \e
86.248 + CplexMip();
86.249 + /// \e
86.250 + CplexMip(const CplexEnv&);
86.251 + /// \e
86.252 + CplexMip(const CplexMip&);
86.253 + /// \e
86.254 + virtual ~CplexMip();
86.255 +
86.256 + /// \e
86.257 + virtual CplexMip* cloneSolver() const;
86.258 + /// \e
86.259 + virtual CplexMip* newSolver() const;
86.260 +
86.261 + protected:
86.262 +
86.263 +
86.264 + virtual const char* _solverName() const;
86.265 +
86.266 + virtual ColTypes _getColType(int col) const;
86.267 + virtual void _setColType(int col, ColTypes col_type);
86.268 +
86.269 + virtual SolveExitStatus _solve();
86.270 + virtual ProblemType _getType() const;
86.271 + virtual Value _getSol(int i) const;
86.272 + virtual Value _getSolValue() const;
86.273 +
86.274 + };
86.275 +
86.276 +} //END OF NAMESPACE LEMON
86.277 +
86.278 +#endif //LEMON_CPLEX_H
86.279 +
87.1 --- a/lemon/dfs.h Fri Nov 13 12:33:33 2009 +0100
87.2 +++ b/lemon/dfs.h Thu Dec 10 17:05:35 2009 +0100
87.3 @@ -2,7 +2,7 @@
87.4 *
87.5 * This file is a part of LEMON, a generic C++ optimization library.
87.6 *
87.7 - * Copyright (C) 2003-2008
87.8 + * Copyright (C) 2003-2009
87.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
87.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
87.11 *
87.12 @@ -49,11 +49,11 @@
87.13 ///arcs of the %DFS paths.
87.14 ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
87.15 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
87.16 - ///Instantiates a PredMap.
87.17 + ///Instantiates a \c PredMap.
87.18
87.19 - ///This function instantiates a PredMap.
87.20 + ///This function instantiates a \ref PredMap.
87.21 ///\param g is the digraph, to which we would like to define the
87.22 - ///PredMap.
87.23 + ///\ref PredMap.
87.24 static PredMap *createPredMap(const Digraph &g)
87.25 {
87.26 return new PredMap(g);
87.27 @@ -64,11 +64,11 @@
87.28 ///The type of the map that indicates which nodes are processed.
87.29 ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
87.30 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
87.31 - ///Instantiates a ProcessedMap.
87.32 + ///Instantiates a \c ProcessedMap.
87.33
87.34 - ///This function instantiates a ProcessedMap.
87.35 + ///This function instantiates a \ref ProcessedMap.
87.36 ///\param g is the digraph, to which
87.37 - ///we would like to define the ProcessedMap
87.38 + ///we would like to define the \ref ProcessedMap.
87.39 #ifdef DOXYGEN
87.40 static ProcessedMap *createProcessedMap(const Digraph &g)
87.41 #else
87.42 @@ -83,11 +83,11 @@
87.43 ///The type of the map that indicates which nodes are reached.
87.44 ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
87.45 typedef typename Digraph::template NodeMap<bool> ReachedMap;
87.46 - ///Instantiates a ReachedMap.
87.47 + ///Instantiates a \c ReachedMap.
87.48
87.49 - ///This function instantiates a ReachedMap.
87.50 + ///This function instantiates a \ref ReachedMap.
87.51 ///\param g is the digraph, to which
87.52 - ///we would like to define the ReachedMap.
87.53 + ///we would like to define the \ref ReachedMap.
87.54 static ReachedMap *createReachedMap(const Digraph &g)
87.55 {
87.56 return new ReachedMap(g);
87.57 @@ -98,11 +98,11 @@
87.58 ///The type of the map that stores the distances of the nodes.
87.59 ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
87.60 typedef typename Digraph::template NodeMap<int> DistMap;
87.61 - ///Instantiates a DistMap.
87.62 + ///Instantiates a \c DistMap.
87.63
87.64 - ///This function instantiates a DistMap.
87.65 + ///This function instantiates a \ref DistMap.
87.66 ///\param g is the digraph, to which we would like to define the
87.67 - ///DistMap.
87.68 + ///\ref DistMap.
87.69 static DistMap *createDistMap(const Digraph &g)
87.70 {
87.71 return new DistMap(g);
87.72 @@ -119,13 +119,7 @@
87.73 ///used easier.
87.74 ///
87.75 ///\tparam GR The type of the digraph the algorithm runs on.
87.76 - ///The default value is \ref ListDigraph. The value of GR is not used
87.77 - ///directly by \ref Dfs, it is only passed to \ref DfsDefaultTraits.
87.78 - ///\tparam TR Traits class to set various data types used by the algorithm.
87.79 - ///The default traits class is
87.80 - ///\ref DfsDefaultTraits "DfsDefaultTraits<GR>".
87.81 - ///See \ref DfsDefaultTraits for the documentation of
87.82 - ///a Dfs traits class.
87.83 + ///The default type is \ref ListDigraph.
87.84 #ifdef DOXYGEN
87.85 template <typename GR,
87.86 typename TR>
87.87 @@ -151,7 +145,7 @@
87.88 ///The type of the paths.
87.89 typedef PredMapPath<Digraph, PredMap> Path;
87.90
87.91 - ///The traits class.
87.92 + ///The \ref DfsDefaultTraits "traits class" of the algorithm.
87.93 typedef TR Traits;
87.94
87.95 private:
87.96 @@ -212,7 +206,7 @@
87.97
87.98 typedef Dfs Create;
87.99
87.100 - ///\name Named template parameters
87.101 + ///\name Named Template Parameters
87.102
87.103 ///@{
87.104
87.105 @@ -226,10 +220,11 @@
87.106 }
87.107 };
87.108 ///\brief \ref named-templ-param "Named parameter" for setting
87.109 - ///PredMap type.
87.110 + ///\c PredMap type.
87.111 ///
87.112 ///\ref named-templ-param "Named parameter" for setting
87.113 - ///PredMap type.
87.114 + ///\c PredMap type.
87.115 + ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
87.116 template <class T>
87.117 struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
87.118 typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
87.119 @@ -245,10 +240,11 @@
87.120 }
87.121 };
87.122 ///\brief \ref named-templ-param "Named parameter" for setting
87.123 - ///DistMap type.
87.124 + ///\c DistMap type.
87.125 ///
87.126 ///\ref named-templ-param "Named parameter" for setting
87.127 - ///DistMap type.
87.128 + ///\c DistMap type.
87.129 + ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
87.130 template <class T>
87.131 struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
87.132 typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
87.133 @@ -264,10 +260,11 @@
87.134 }
87.135 };
87.136 ///\brief \ref named-templ-param "Named parameter" for setting
87.137 - ///ReachedMap type.
87.138 + ///\c ReachedMap type.
87.139 ///
87.140 ///\ref named-templ-param "Named parameter" for setting
87.141 - ///ReachedMap type.
87.142 + ///\c ReachedMap type.
87.143 + ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
87.144 template <class T>
87.145 struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
87.146 typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
87.147 @@ -283,10 +280,11 @@
87.148 }
87.149 };
87.150 ///\brief \ref named-templ-param "Named parameter" for setting
87.151 - ///ProcessedMap type.
87.152 + ///\c ProcessedMap type.
87.153 ///
87.154 ///\ref named-templ-param "Named parameter" for setting
87.155 - ///ProcessedMap type.
87.156 + ///\c ProcessedMap type.
87.157 + ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
87.158 template <class T>
87.159 struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
87.160 typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
87.161 @@ -300,10 +298,10 @@
87.162 }
87.163 };
87.164 ///\brief \ref named-templ-param "Named parameter" for setting
87.165 - ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
87.166 + ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
87.167 ///
87.168 ///\ref named-templ-param "Named parameter" for setting
87.169 - ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
87.170 + ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
87.171 ///If you don't set it explicitly, it will be automatically allocated.
87.172 struct SetStandardProcessedMap :
87.173 public Dfs< Digraph, SetStandardProcessedMapTraits > {
87.174 @@ -338,9 +336,10 @@
87.175 ///Sets the map that stores the predecessor arcs.
87.176
87.177 ///Sets the map that stores the predecessor arcs.
87.178 - ///If you don't use this function before calling \ref run(),
87.179 - ///it will allocate one. The destructor deallocates this
87.180 - ///automatically allocated map, of course.
87.181 + ///If you don't use this function before calling \ref run(Node) "run()"
87.182 + ///or \ref init(), an instance will be allocated automatically.
87.183 + ///The destructor deallocates this automatically allocated map,
87.184 + ///of course.
87.185 ///\return <tt> (*this) </tt>
87.186 Dfs &predMap(PredMap &m)
87.187 {
87.188 @@ -355,9 +354,10 @@
87.189 ///Sets the map that indicates which nodes are reached.
87.190
87.191 ///Sets the map that indicates which nodes are reached.
87.192 - ///If you don't use this function before calling \ref run(),
87.193 - ///it will allocate one. The destructor deallocates this
87.194 - ///automatically allocated map, of course.
87.195 + ///If you don't use this function before calling \ref run(Node) "run()"
87.196 + ///or \ref init(), an instance will be allocated automatically.
87.197 + ///The destructor deallocates this automatically allocated map,
87.198 + ///of course.
87.199 ///\return <tt> (*this) </tt>
87.200 Dfs &reachedMap(ReachedMap &m)
87.201 {
87.202 @@ -372,9 +372,10 @@
87.203 ///Sets the map that indicates which nodes are processed.
87.204
87.205 ///Sets the map that indicates which nodes are processed.
87.206 - ///If you don't use this function before calling \ref run(),
87.207 - ///it will allocate one. The destructor deallocates this
87.208 - ///automatically allocated map, of course.
87.209 + ///If you don't use this function before calling \ref run(Node) "run()"
87.210 + ///or \ref init(), an instance will be allocated automatically.
87.211 + ///The destructor deallocates this automatically allocated map,
87.212 + ///of course.
87.213 ///\return <tt> (*this) </tt>
87.214 Dfs &processedMap(ProcessedMap &m)
87.215 {
87.216 @@ -390,9 +391,10 @@
87.217
87.218 ///Sets the map that stores the distances of the nodes calculated by
87.219 ///the algorithm.
87.220 - ///If you don't use this function before calling \ref run(),
87.221 - ///it will allocate one. The destructor deallocates this
87.222 - ///automatically allocated map, of course.
87.223 + ///If you don't use this function before calling \ref run(Node) "run()"
87.224 + ///or \ref init(), an instance will be allocated automatically.
87.225 + ///The destructor deallocates this automatically allocated map,
87.226 + ///of course.
87.227 ///\return <tt> (*this) </tt>
87.228 Dfs &distMap(DistMap &m)
87.229 {
87.230 @@ -406,22 +408,20 @@
87.231
87.232 public:
87.233
87.234 - ///\name Execution control
87.235 - ///The simplest way to execute the algorithm is to use
87.236 - ///one of the member functions called \ref lemon::Dfs::run() "run()".
87.237 - ///\n
87.238 - ///If you need more control on the execution, first you must call
87.239 - ///\ref lemon::Dfs::init() "init()", then you can add a source node
87.240 - ///with \ref lemon::Dfs::addSource() "addSource()".
87.241 - ///Finally \ref lemon::Dfs::start() "start()" will perform the
87.242 - ///actual path computation.
87.243 + ///\name Execution Control
87.244 + ///The simplest way to execute the DFS algorithm is to use one of the
87.245 + ///member functions called \ref run(Node) "run()".\n
87.246 + ///If you need more control on the execution, first you have to call
87.247 + ///\ref init(), then you can add a source node with \ref addSource()
87.248 + ///and perform the actual computation with \ref start().
87.249 + ///This procedure can be repeated if there are nodes that have not
87.250 + ///been reached.
87.251
87.252 ///@{
87.253
87.254 + ///\brief Initializes the internal data structures.
87.255 + ///
87.256 ///Initializes the internal data structures.
87.257 -
87.258 - ///Initializes the internal data structures.
87.259 - ///
87.260 void init()
87.261 {
87.262 create_maps();
87.263 @@ -438,11 +438,10 @@
87.264
87.265 ///Adds a new source node to the set of nodes to be processed.
87.266 ///
87.267 - ///\pre The stack must be empty. (Otherwise the algorithm gives
87.268 - ///false results.)
87.269 - ///
87.270 - ///\warning Distances will be wrong (or at least strange) in case of
87.271 - ///multiple sources.
87.272 + ///\pre The stack must be empty. Otherwise the algorithm gives
87.273 + ///wrong results. (One of the outgoing arcs of all the source nodes
87.274 + ///except for the last one will not be visited and distances will
87.275 + ///also be wrong.)
87.276 void addSource(Node s)
87.277 {
87.278 LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
87.279 @@ -506,16 +505,16 @@
87.280 return _stack_head>=0?_stack[_stack_head]:INVALID;
87.281 }
87.282
87.283 - ///\brief Returns \c false if there are nodes
87.284 - ///to be processed.
87.285 - ///
87.286 - ///Returns \c false if there are nodes
87.287 - ///to be processed in the queue (stack).
87.288 + ///Returns \c false if there are nodes to be processed.
87.289 +
87.290 + ///Returns \c false if there are nodes to be processed
87.291 + ///in the queue (stack).
87.292 bool emptyQueue() const { return _stack_head<0; }
87.293
87.294 ///Returns the number of the nodes to be processed.
87.295
87.296 - ///Returns the number of the nodes to be processed in the queue (stack).
87.297 + ///Returns the number of the nodes to be processed
87.298 + ///in the queue (stack).
87.299 int queueSize() const { return _stack_head+1; }
87.300
87.301 ///Executes the algorithm.
87.302 @@ -637,8 +636,8 @@
87.303 ///%DFS path to each node.
87.304 ///
87.305 ///The algorithm computes
87.306 - ///- the %DFS tree,
87.307 - ///- the distance of each node from the root in the %DFS tree.
87.308 + ///- the %DFS tree (forest),
87.309 + ///- the distance of each node from the root(s) in the %DFS tree.
87.310 ///
87.311 ///\note <tt>d.run()</tt> is just a shortcut of the following code.
87.312 ///\code
87.313 @@ -663,10 +662,10 @@
87.314 ///@}
87.315
87.316 ///\name Query Functions
87.317 - ///The result of the %DFS algorithm can be obtained using these
87.318 + ///The results of the DFS algorithm can be obtained using these
87.319 ///functions.\n
87.320 - ///Either \ref lemon::Dfs::run() "run()" or \ref lemon::Dfs::start()
87.321 - ///"start()" must be called before using them.
87.322 + ///Either \ref run(Node) "run()" or \ref start() should be called
87.323 + ///before using them.
87.324
87.325 ///@{
87.326
87.327 @@ -674,49 +673,49 @@
87.328
87.329 ///Returns the DFS path to a node.
87.330 ///
87.331 - ///\warning \c t should be reachable from the root.
87.332 + ///\warning \c t should be reached from the root(s).
87.333 ///
87.334 - ///\pre Either \ref run() or \ref start() must be called before
87.335 - ///using this function.
87.336 + ///\pre Either \ref run(Node) "run()" or \ref init()
87.337 + ///must be called before using this function.
87.338 Path path(Node t) const { return Path(*G, *_pred, t); }
87.339
87.340 - ///The distance of a node from the root.
87.341 + ///The distance of a node from the root(s).
87.342
87.343 - ///Returns the distance of a node from the root.
87.344 + ///Returns the distance of a node from the root(s).
87.345 ///
87.346 - ///\warning If node \c v is not reachable from the root, then
87.347 + ///\warning If node \c v is not reached from the root(s), then
87.348 ///the return value of this function is undefined.
87.349 ///
87.350 - ///\pre Either \ref run() or \ref start() must be called before
87.351 - ///using this function.
87.352 + ///\pre Either \ref run(Node) "run()" or \ref init()
87.353 + ///must be called before using this function.
87.354 int dist(Node v) const { return (*_dist)[v]; }
87.355
87.356 ///Returns the 'previous arc' of the %DFS tree for a node.
87.357
87.358 ///This function returns the 'previous arc' of the %DFS tree for the
87.359 - ///node \c v, i.e. it returns the last arc of a %DFS path from the
87.360 - ///root to \c v. It is \c INVALID
87.361 - ///if \c v is not reachable from the root(s) or if \c v is a root.
87.362 + ///node \c v, i.e. it returns the last arc of a %DFS path from a
87.363 + ///root to \c v. It is \c INVALID if \c v is not reached from the
87.364 + ///root(s) or if \c v is a root.
87.365 ///
87.366 ///The %DFS tree used here is equal to the %DFS tree used in
87.367 ///\ref predNode().
87.368 ///
87.369 - ///\pre Either \ref run() or \ref start() must be called before using
87.370 - ///this function.
87.371 + ///\pre Either \ref run(Node) "run()" or \ref init()
87.372 + ///must be called before using this function.
87.373 Arc predArc(Node v) const { return (*_pred)[v];}
87.374
87.375 ///Returns the 'previous node' of the %DFS tree.
87.376
87.377 ///This function returns the 'previous node' of the %DFS
87.378 ///tree for the node \c v, i.e. it returns the last but one node
87.379 - ///from a %DFS path from the root to \c v. It is \c INVALID
87.380 - ///if \c v is not reachable from the root(s) or if \c v is a root.
87.381 + ///from a %DFS path from a root to \c v. It is \c INVALID
87.382 + ///if \c v is not reached from the root(s) or if \c v is a root.
87.383 ///
87.384 ///The %DFS tree used here is equal to the %DFS tree used in
87.385 ///\ref predArc().
87.386 ///
87.387 - ///\pre Either \ref run() or \ref start() must be called before
87.388 - ///using this function.
87.389 + ///\pre Either \ref run(Node) "run()" or \ref init()
87.390 + ///must be called before using this function.
87.391 Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
87.392 G->source((*_pred)[v]); }
87.393
87.394 @@ -726,7 +725,7 @@
87.395 ///Returns a const reference to the node map that stores the
87.396 ///distances of the nodes calculated by the algorithm.
87.397 ///
87.398 - ///\pre Either \ref run() or \ref init()
87.399 + ///\pre Either \ref run(Node) "run()" or \ref init()
87.400 ///must be called before using this function.
87.401 const DistMap &distMap() const { return *_dist;}
87.402
87.403 @@ -736,14 +735,15 @@
87.404 ///Returns a const reference to the node map that stores the predecessor
87.405 ///arcs, which form the DFS tree.
87.406 ///
87.407 - ///\pre Either \ref run() or \ref init()
87.408 + ///\pre Either \ref run(Node) "run()" or \ref init()
87.409 ///must be called before using this function.
87.410 const PredMap &predMap() const { return *_pred;}
87.411
87.412 - ///Checks if a node is reachable from the root(s).
87.413 + ///Checks if a node is reached from the root(s).
87.414
87.415 - ///Returns \c true if \c v is reachable from the root(s).
87.416 - ///\pre Either \ref run() or \ref start()
87.417 + ///Returns \c true if \c v is reached from the root(s).
87.418 + ///
87.419 + ///\pre Either \ref run(Node) "run()" or \ref init()
87.420 ///must be called before using this function.
87.421 bool reached(Node v) const { return (*_reached)[v]; }
87.422
87.423 @@ -889,8 +889,8 @@
87.424
87.425 /// This auxiliary class is created to implement the
87.426 /// \ref dfs() "function-type interface" of \ref Dfs algorithm.
87.427 - /// It does not have own \ref run() method, it uses the functions
87.428 - /// and features of the plain \ref Dfs.
87.429 + /// It does not have own \ref run(Node) "run()" method, it uses the
87.430 + /// functions and features of the plain \ref Dfs.
87.431 ///
87.432 /// This class should only be used through the \ref dfs() function,
87.433 /// which makes it easier to use the algorithm.
87.434 @@ -1110,8 +1110,7 @@
87.435 /// // Compute the DFS path from s to t
87.436 /// bool reached = dfs(g).path(p).dist(d).run(s,t);
87.437 ///\endcode
87.438 -
87.439 - ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
87.440 + ///\warning Don't forget to put the \ref DfsWizard::run(Node) "run()"
87.441 ///to the end of the parameter list.
87.442 ///\sa DfsWizard
87.443 ///\sa Dfs
87.444 @@ -1127,9 +1126,9 @@
87.445 ///
87.446 /// This class defines the interface of the DfsVisit events, and
87.447 /// it could be the base of a real visitor class.
87.448 - template <typename _Digraph>
87.449 + template <typename GR>
87.450 struct DfsVisitor {
87.451 - typedef _Digraph Digraph;
87.452 + typedef GR Digraph;
87.453 typedef typename Digraph::Arc Arc;
87.454 typedef typename Digraph::Node Node;
87.455 /// \brief Called for the source node of the DFS.
87.456 @@ -1165,9 +1164,9 @@
87.457 void backtrack(const Arc& arc) {}
87.458 };
87.459 #else
87.460 - template <typename _Digraph>
87.461 + template <typename GR>
87.462 struct DfsVisitor {
87.463 - typedef _Digraph Digraph;
87.464 + typedef GR Digraph;
87.465 typedef typename Digraph::Arc Arc;
87.466 typedef typename Digraph::Node Node;
87.467 void start(const Node&) {}
87.468 @@ -1200,11 +1199,11 @@
87.469 ///
87.470 /// Default traits class of DfsVisit class.
87.471 /// \tparam _Digraph The type of the digraph the algorithm runs on.
87.472 - template<class _Digraph>
87.473 + template<class GR>
87.474 struct DfsVisitDefaultTraits {
87.475
87.476 /// \brief The type of the digraph the algorithm runs on.
87.477 - typedef _Digraph Digraph;
87.478 + typedef GR Digraph;
87.479
87.480 /// \brief The type of the map that indicates which nodes are reached.
87.481 ///
87.482 @@ -1225,12 +1224,12 @@
87.483
87.484 /// \ingroup search
87.485 ///
87.486 - /// \brief %DFS algorithm class with visitor interface.
87.487 + /// \brief DFS algorithm class with visitor interface.
87.488 ///
87.489 - /// This class provides an efficient implementation of the %DFS algorithm
87.490 + /// This class provides an efficient implementation of the DFS algorithm
87.491 /// with visitor interface.
87.492 ///
87.493 - /// The %DfsVisit class provides an alternative interface to the Dfs
87.494 + /// The DfsVisit class provides an alternative interface to the Dfs
87.495 /// class. It works with callback mechanism, the DfsVisit object calls
87.496 /// the member functions of the \c Visitor class on every DFS event.
87.497 ///
87.498 @@ -1239,37 +1238,37 @@
87.499 /// events of the DFS algorithm. Otherwise consider to use Dfs or dfs()
87.500 /// instead.
87.501 ///
87.502 - /// \tparam _Digraph The type of the digraph the algorithm runs on.
87.503 - /// The default value is
87.504 - /// \ref ListDigraph. The value of _Digraph is not used directly by
87.505 - /// \ref DfsVisit, it is only passed to \ref DfsVisitDefaultTraits.
87.506 - /// \tparam _Visitor The Visitor type that is used by the algorithm.
87.507 - /// \ref DfsVisitor "DfsVisitor<_Digraph>" is an empty visitor, which
87.508 + /// \tparam GR The type of the digraph the algorithm runs on.
87.509 + /// The default type is \ref ListDigraph.
87.510 + /// The value of GR is not used directly by \ref DfsVisit,
87.511 + /// it is only passed to \ref DfsVisitDefaultTraits.
87.512 + /// \tparam VS The Visitor type that is used by the algorithm.
87.513 + /// \ref DfsVisitor "DfsVisitor<GR>" is an empty visitor, which
87.514 /// does not observe the DFS events. If you want to observe the DFS
87.515 /// events, you should implement your own visitor class.
87.516 - /// \tparam _Traits Traits class to set various data types used by the
87.517 + /// \tparam TR Traits class to set various data types used by the
87.518 /// algorithm. The default traits class is
87.519 - /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<_Digraph>".
87.520 + /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<GR>".
87.521 /// See \ref DfsVisitDefaultTraits for the documentation of
87.522 /// a DFS visit traits class.
87.523 #ifdef DOXYGEN
87.524 - template <typename _Digraph, typename _Visitor, typename _Traits>
87.525 + template <typename GR, typename VS, typename TR>
87.526 #else
87.527 - template <typename _Digraph = ListDigraph,
87.528 - typename _Visitor = DfsVisitor<_Digraph>,
87.529 - typename _Traits = DfsVisitDefaultTraits<_Digraph> >
87.530 + template <typename GR = ListDigraph,
87.531 + typename VS = DfsVisitor<GR>,
87.532 + typename TR = DfsVisitDefaultTraits<GR> >
87.533 #endif
87.534 class DfsVisit {
87.535 public:
87.536
87.537 ///The traits class.
87.538 - typedef _Traits Traits;
87.539 + typedef TR Traits;
87.540
87.541 ///The type of the digraph the algorithm runs on.
87.542 typedef typename Traits::Digraph Digraph;
87.543
87.544 ///The visitor type used by the algorithm.
87.545 - typedef _Visitor Visitor;
87.546 + typedef VS Visitor;
87.547
87.548 ///The type of the map that indicates which nodes are reached.
87.549 typedef typename Traits::ReachedMap ReachedMap;
87.550 @@ -1309,7 +1308,7 @@
87.551
87.552 typedef DfsVisit Create;
87.553
87.554 - /// \name Named template parameters
87.555 + /// \name Named Template Parameters
87.556
87.557 ///@{
87.558 template <class T>
87.559 @@ -1351,9 +1350,10 @@
87.560 /// \brief Sets the map that indicates which nodes are reached.
87.561 ///
87.562 /// Sets the map that indicates which nodes are reached.
87.563 - /// If you don't use this function before calling \ref run(),
87.564 - /// it will allocate one. The destructor deallocates this
87.565 - /// automatically allocated map, of course.
87.566 + /// If you don't use this function before calling \ref run(Node) "run()"
87.567 + /// or \ref init(), an instance will be allocated automatically.
87.568 + /// The destructor deallocates this automatically allocated map,
87.569 + /// of course.
87.570 /// \return <tt> (*this) </tt>
87.571 DfsVisit &reachedMap(ReachedMap &m) {
87.572 if(local_reached) {
87.573 @@ -1366,16 +1366,14 @@
87.574
87.575 public:
87.576
87.577 - /// \name Execution control
87.578 - /// The simplest way to execute the algorithm is to use
87.579 - /// one of the member functions called \ref lemon::DfsVisit::run()
87.580 - /// "run()".
87.581 - /// \n
87.582 - /// If you need more control on the execution, first you must call
87.583 - /// \ref lemon::DfsVisit::init() "init()", then you can add several
87.584 - /// source nodes with \ref lemon::DfsVisit::addSource() "addSource()".
87.585 - /// Finally \ref lemon::DfsVisit::start() "start()" will perform the
87.586 - /// actual path computation.
87.587 + /// \name Execution Control
87.588 + /// The simplest way to execute the DFS algorithm is to use one of the
87.589 + /// member functions called \ref run(Node) "run()".\n
87.590 + /// If you need more control on the execution, first you have to call
87.591 + /// \ref init(), then you can add a source node with \ref addSource()
87.592 + /// and perform the actual computation with \ref start().
87.593 + /// This procedure can be repeated if there are nodes that have not
87.594 + /// been reached.
87.595
87.596 /// @{
87.597
87.598 @@ -1391,15 +1389,14 @@
87.599 }
87.600 }
87.601
87.602 - ///Adds a new source node.
87.603 -
87.604 - ///Adds a new source node to the set of nodes to be processed.
87.605 + /// \brief Adds a new source node.
87.606 ///
87.607 - ///\pre The stack must be empty. (Otherwise the algorithm gives
87.608 - ///false results.)
87.609 + /// Adds a new source node to the set of nodes to be processed.
87.610 ///
87.611 - ///\warning Distances will be wrong (or at least strange) in case of
87.612 - ///multiple sources.
87.613 + /// \pre The stack must be empty. Otherwise the algorithm gives
87.614 + /// wrong results. (One of the outgoing arcs of all the source nodes
87.615 + /// except for the last one will not be visited and distances will
87.616 + /// also be wrong.)
87.617 void addSource(Node s)
87.618 {
87.619 LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
87.620 @@ -1413,6 +1410,7 @@
87.621 _stack[++_stack_head] = e;
87.622 } else {
87.623 _visitor->leave(s);
87.624 + _visitor->stop(s);
87.625 }
87.626 }
87.627 }
87.628 @@ -1589,8 +1587,8 @@
87.629 /// compute the %DFS path to each node.
87.630 ///
87.631 /// The algorithm computes
87.632 - /// - the %DFS tree,
87.633 - /// - the distance of each node from the root in the %DFS tree.
87.634 + /// - the %DFS tree (forest),
87.635 + /// - the distance of each node from the root(s) in the %DFS tree.
87.636 ///
87.637 /// \note <tt>d.run()</tt> is just a shortcut of the following code.
87.638 ///\code
87.639 @@ -1615,19 +1613,20 @@
87.640 ///@}
87.641
87.642 /// \name Query Functions
87.643 - /// The result of the %DFS algorithm can be obtained using these
87.644 + /// The results of the DFS algorithm can be obtained using these
87.645 /// functions.\n
87.646 - /// Either \ref lemon::DfsVisit::run() "run()" or
87.647 - /// \ref lemon::DfsVisit::start() "start()" must be called before
87.648 - /// using them.
87.649 + /// Either \ref run(Node) "run()" or \ref start() should be called
87.650 + /// before using them.
87.651 +
87.652 ///@{
87.653
87.654 - /// \brief Checks if a node is reachable from the root(s).
87.655 + /// \brief Checks if a node is reached from the root(s).
87.656 ///
87.657 - /// Returns \c true if \c v is reachable from the root(s).
87.658 - /// \pre Either \ref run() or \ref start()
87.659 + /// Returns \c true if \c v is reached from the root(s).
87.660 + ///
87.661 + /// \pre Either \ref run(Node) "run()" or \ref init()
87.662 /// must be called before using this function.
87.663 - bool reached(Node v) { return (*_reached)[v]; }
87.664 + bool reached(Node v) const { return (*_reached)[v]; }
87.665
87.666 ///@}
87.667
88.1 --- a/lemon/dijkstra.h Fri Nov 13 12:33:33 2009 +0100
88.2 +++ b/lemon/dijkstra.h Thu Dec 10 17:05:35 2009 +0100
88.3 @@ -2,7 +2,7 @@
88.4 *
88.5 * This file is a part of LEMON, a generic C++ optimization library.
88.6 *
88.7 - * Copyright (C) 2003-2008
88.8 + * Copyright (C) 2003-2009
88.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
88.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
88.11 *
88.12 @@ -38,8 +38,10 @@
88.13 ///
88.14 /// This operation traits class defines all computational operations and
88.15 /// constants which are used in the Dijkstra algorithm.
88.16 - template <typename Value>
88.17 + template <typename V>
88.18 struct DijkstraDefaultOperationTraits {
88.19 + /// \e
88.20 + typedef V Value;
88.21 /// \brief Gives back the zero value of the type.
88.22 static Value zero() {
88.23 return static_cast<Value>(0);
88.24 @@ -58,8 +60,8 @@
88.25
88.26 ///Default traits class of Dijkstra class.
88.27 ///\tparam GR The type of the digraph.
88.28 - ///\tparam LM The type of the length map.
88.29 - template<class GR, class LM>
88.30 + ///\tparam LEN The type of the length map.
88.31 + template<typename GR, typename LEN>
88.32 struct DijkstraDefaultTraits
88.33 {
88.34 ///The type of the digraph the algorithm runs on.
88.35 @@ -69,11 +71,11 @@
88.36
88.37 ///The type of the map that stores the arc lengths.
88.38 ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
88.39 - typedef LM LengthMap;
88.40 + typedef LEN LengthMap;
88.41 ///The type of the length of the arcs.
88.42 - typedef typename LM::Value Value;
88.43 + typedef typename LEN::Value Value;
88.44
88.45 - /// Operation traits for Dijkstra algorithm.
88.46 + /// Operation traits for %Dijkstra algorithm.
88.47
88.48 /// This class defines the operations that are used in the algorithm.
88.49 /// \see DijkstraDefaultOperationTraits
88.50 @@ -84,7 +86,7 @@
88.51 /// The cross reference type used by the heap.
88.52 /// Usually it is \c Digraph::NodeMap<int>.
88.53 typedef typename Digraph::template NodeMap<int> HeapCrossRef;
88.54 - ///Instantiates a \ref HeapCrossRef.
88.55 + ///Instantiates a \c HeapCrossRef.
88.56
88.57 ///This function instantiates a \ref HeapCrossRef.
88.58 /// \param g is the digraph, to which we would like to define the
88.59 @@ -94,14 +96,14 @@
88.60 return new HeapCrossRef(g);
88.61 }
88.62
88.63 - ///The heap type used by the Dijkstra algorithm.
88.64 + ///The heap type used by the %Dijkstra algorithm.
88.65
88.66 ///The heap type used by the Dijkstra algorithm.
88.67 ///
88.68 ///\sa BinHeap
88.69 ///\sa Dijkstra
88.70 - typedef BinHeap<typename LM::Value, HeapCrossRef, std::less<Value> > Heap;
88.71 - ///Instantiates a \ref Heap.
88.72 + typedef BinHeap<typename LEN::Value, HeapCrossRef, std::less<Value> > Heap;
88.73 + ///Instantiates a \c Heap.
88.74
88.75 ///This function instantiates a \ref Heap.
88.76 static Heap *createHeap(HeapCrossRef& r)
88.77 @@ -116,11 +118,11 @@
88.78 ///arcs of the shortest paths.
88.79 ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
88.80 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
88.81 - ///Instantiates a PredMap.
88.82 + ///Instantiates a \c PredMap.
88.83
88.84 - ///This function instantiates a PredMap.
88.85 + ///This function instantiates a \ref PredMap.
88.86 ///\param g is the digraph, to which we would like to define the
88.87 - ///PredMap.
88.88 + ///\ref PredMap.
88.89 static PredMap *createPredMap(const Digraph &g)
88.90 {
88.91 return new PredMap(g);
88.92 @@ -132,11 +134,11 @@
88.93 ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
88.94 ///By default it is a NullMap.
88.95 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
88.96 - ///Instantiates a ProcessedMap.
88.97 + ///Instantiates a \c ProcessedMap.
88.98
88.99 - ///This function instantiates a ProcessedMap.
88.100 + ///This function instantiates a \ref ProcessedMap.
88.101 ///\param g is the digraph, to which
88.102 - ///we would like to define the ProcessedMap
88.103 + ///we would like to define the \ref ProcessedMap.
88.104 #ifdef DOXYGEN
88.105 static ProcessedMap *createProcessedMap(const Digraph &g)
88.106 #else
88.107 @@ -150,12 +152,12 @@
88.108
88.109 ///The type of the map that stores the distances of the nodes.
88.110 ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
88.111 - typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
88.112 - ///Instantiates a DistMap.
88.113 + typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
88.114 + ///Instantiates a \c DistMap.
88.115
88.116 - ///This function instantiates a DistMap.
88.117 + ///This function instantiates a \ref DistMap.
88.118 ///\param g is the digraph, to which we would like to define
88.119 - ///the DistMap
88.120 + ///the \ref DistMap.
88.121 static DistMap *createDistMap(const Digraph &g)
88.122 {
88.123 return new DistMap(g);
88.124 @@ -179,26 +181,19 @@
88.125 ///it can be used easier.
88.126 ///
88.127 ///\tparam GR The type of the digraph the algorithm runs on.
88.128 - ///The default value is \ref ListDigraph.
88.129 - ///The value of GR is not used directly by \ref Dijkstra, it is only
88.130 - ///passed to \ref DijkstraDefaultTraits.
88.131 - ///\tparam LM A readable arc map that determines the lengths of the
88.132 - ///arcs. It is read once for each arc, so the map may involve in
88.133 + ///The default type is \ref ListDigraph.
88.134 + ///\tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
88.135 + ///the lengths of the arcs.
88.136 + ///It is read once for each arc, so the map may involve in
88.137 ///relatively time consuming process to compute the arc lengths if
88.138 ///it is necessary. The default map type is \ref
88.139 - ///concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
88.140 - ///The value of LM is not used directly by \ref Dijkstra, it is only
88.141 - ///passed to \ref DijkstraDefaultTraits.
88.142 - ///\tparam TR Traits class to set various data types used by the algorithm.
88.143 - ///The default traits class is \ref DijkstraDefaultTraits
88.144 - ///"DijkstraDefaultTraits<GR,LM>". See \ref DijkstraDefaultTraits
88.145 - ///for the documentation of a Dijkstra traits class.
88.146 + ///concepts::Digraph::ArcMap "GR::ArcMap<int>".
88.147 #ifdef DOXYGEN
88.148 - template <typename GR, typename LM, typename TR>
88.149 + template <typename GR, typename LEN, typename TR>
88.150 #else
88.151 template <typename GR=ListDigraph,
88.152 - typename LM=typename GR::template ArcMap<int>,
88.153 - typename TR=DijkstraDefaultTraits<GR,LM> >
88.154 + typename LEN=typename GR::template ArcMap<int>,
88.155 + typename TR=DijkstraDefaultTraits<GR,LEN> >
88.156 #endif
88.157 class Dijkstra {
88.158 public:
88.159 @@ -223,10 +218,11 @@
88.160 typedef typename TR::HeapCrossRef HeapCrossRef;
88.161 ///The heap type used by the algorithm.
88.162 typedef typename TR::Heap Heap;
88.163 - ///The operation traits class.
88.164 + ///\brief The \ref DijkstraDefaultOperationTraits "operation traits class"
88.165 + ///of the algorithm.
88.166 typedef typename TR::OperationTraits OperationTraits;
88.167
88.168 - ///The traits class.
88.169 + ///The \ref DijkstraDefaultTraits "traits class" of the algorithm.
88.170 typedef TR Traits;
88.171
88.172 private:
88.173 @@ -239,7 +235,7 @@
88.174 //Pointer to the underlying digraph.
88.175 const Digraph *G;
88.176 //Pointer to the length map.
88.177 - const LengthMap *length;
88.178 + const LengthMap *_length;
88.179 //Pointer to the map of predecessors arcs.
88.180 PredMap *_pred;
88.181 //Indicates if _pred is locally allocated (true) or not.
88.182 @@ -290,7 +286,7 @@
88.183
88.184 typedef Dijkstra Create;
88.185
88.186 - ///\name Named template parameters
88.187 + ///\name Named Template Parameters
88.188
88.189 ///@{
88.190
88.191 @@ -304,10 +300,11 @@
88.192 }
88.193 };
88.194 ///\brief \ref named-templ-param "Named parameter" for setting
88.195 - ///PredMap type.
88.196 + ///\c PredMap type.
88.197 ///
88.198 ///\ref named-templ-param "Named parameter" for setting
88.199 - ///PredMap type.
88.200 + ///\c PredMap type.
88.201 + ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
88.202 template <class T>
88.203 struct SetPredMap
88.204 : public Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > {
88.205 @@ -324,10 +321,11 @@
88.206 }
88.207 };
88.208 ///\brief \ref named-templ-param "Named parameter" for setting
88.209 - ///DistMap type.
88.210 + ///\c DistMap type.
88.211 ///
88.212 ///\ref named-templ-param "Named parameter" for setting
88.213 - ///DistMap type.
88.214 + ///\c DistMap type.
88.215 + ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
88.216 template <class T>
88.217 struct SetDistMap
88.218 : public Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > {
88.219 @@ -344,10 +342,11 @@
88.220 }
88.221 };
88.222 ///\brief \ref named-templ-param "Named parameter" for setting
88.223 - ///ProcessedMap type.
88.224 + ///\c ProcessedMap type.
88.225 ///
88.226 ///\ref named-templ-param "Named parameter" for setting
88.227 - ///ProcessedMap type.
88.228 + ///\c ProcessedMap type.
88.229 + ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
88.230 template <class T>
88.231 struct SetProcessedMap
88.232 : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > {
88.233 @@ -362,10 +361,10 @@
88.234 }
88.235 };
88.236 ///\brief \ref named-templ-param "Named parameter" for setting
88.237 - ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
88.238 + ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
88.239 ///
88.240 ///\ref named-templ-param "Named parameter" for setting
88.241 - ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
88.242 + ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
88.243 ///If you don't set it explicitly, it will be automatically allocated.
88.244 struct SetStandardProcessedMap
88.245 : public Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits > {
88.246 @@ -388,10 +387,14 @@
88.247 }
88.248 };
88.249 ///\brief \ref named-templ-param "Named parameter" for setting
88.250 - ///heap and cross reference type
88.251 + ///heap and cross reference types
88.252 ///
88.253 ///\ref named-templ-param "Named parameter" for setting heap and cross
88.254 - ///reference type.
88.255 + ///reference types. If this named parameter is used, then external
88.256 + ///heap and cross reference objects must be passed to the algorithm
88.257 + ///using the \ref heap() function before calling \ref run(Node) "run()"
88.258 + ///or \ref init().
88.259 + ///\sa SetStandardHeap
88.260 template <class H, class CR = typename Digraph::template NodeMap<int> >
88.261 struct SetHeap
88.262 : public Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > {
88.263 @@ -411,12 +414,18 @@
88.264 }
88.265 };
88.266 ///\brief \ref named-templ-param "Named parameter" for setting
88.267 - ///heap and cross reference type with automatic allocation
88.268 + ///heap and cross reference types with automatic allocation
88.269 ///
88.270 ///\ref named-templ-param "Named parameter" for setting heap and cross
88.271 - ///reference type. It can allocate the heap and the cross reference
88.272 - ///object if the cross reference's constructor waits for the digraph as
88.273 - ///parameter and the heap's constructor waits for the cross reference.
88.274 + ///reference types with automatic allocation.
88.275 + ///They should have standard constructor interfaces to be able to
88.276 + ///automatically created by the algorithm (i.e. the digraph should be
88.277 + ///passed to the constructor of the cross reference and the cross
88.278 + ///reference should be passed to the constructor of the heap).
88.279 + ///However external heap and cross reference objects could also be
88.280 + ///passed to the algorithm using the \ref heap() function before
88.281 + ///calling \ref run(Node) "run()" or \ref init().
88.282 + ///\sa SetHeap
88.283 template <class H, class CR = typename Digraph::template NodeMap<int> >
88.284 struct SetStandardHeap
88.285 : public Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> > {
88.286 @@ -433,7 +442,7 @@
88.287 ///\c OperationTraits type
88.288 ///
88.289 ///\ref named-templ-param "Named parameter" for setting
88.290 - ///\ref OperationTraits type.
88.291 + ///\c OperationTraits type.
88.292 template <class T>
88.293 struct SetOperationTraits
88.294 : public Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> > {
88.295 @@ -452,10 +461,10 @@
88.296 ///Constructor.
88.297
88.298 ///Constructor.
88.299 - ///\param _g The digraph the algorithm runs on.
88.300 - ///\param _length The length map used by the algorithm.
88.301 - Dijkstra(const Digraph& _g, const LengthMap& _length) :
88.302 - G(&_g), length(&_length),
88.303 + ///\param g The digraph the algorithm runs on.
88.304 + ///\param length The length map used by the algorithm.
88.305 + Dijkstra(const Digraph& g, const LengthMap& length) :
88.306 + G(&g), _length(&length),
88.307 _pred(NULL), local_pred(false),
88.308 _dist(NULL), local_dist(false),
88.309 _processed(NULL), local_processed(false),
88.310 @@ -479,16 +488,17 @@
88.311 ///\return <tt> (*this) </tt>
88.312 Dijkstra &lengthMap(const LengthMap &m)
88.313 {
88.314 - length = &m;
88.315 + _length = &m;
88.316 return *this;
88.317 }
88.318
88.319 ///Sets the map that stores the predecessor arcs.
88.320
88.321 ///Sets the map that stores the predecessor arcs.
88.322 - ///If you don't use this function before calling \ref run(),
88.323 - ///it will allocate one. The destructor deallocates this
88.324 - ///automatically allocated map, of course.
88.325 + ///If you don't use this function before calling \ref run(Node) "run()"
88.326 + ///or \ref init(), an instance will be allocated automatically.
88.327 + ///The destructor deallocates this automatically allocated map,
88.328 + ///of course.
88.329 ///\return <tt> (*this) </tt>
88.330 Dijkstra &predMap(PredMap &m)
88.331 {
88.332 @@ -503,9 +513,10 @@
88.333 ///Sets the map that indicates which nodes are processed.
88.334
88.335 ///Sets the map that indicates which nodes are processed.
88.336 - ///If you don't use this function before calling \ref run(),
88.337 - ///it will allocate one. The destructor deallocates this
88.338 - ///automatically allocated map, of course.
88.339 + ///If you don't use this function before calling \ref run(Node) "run()"
88.340 + ///or \ref init(), an instance will be allocated automatically.
88.341 + ///The destructor deallocates this automatically allocated map,
88.342 + ///of course.
88.343 ///\return <tt> (*this) </tt>
88.344 Dijkstra &processedMap(ProcessedMap &m)
88.345 {
88.346 @@ -521,9 +532,10 @@
88.347
88.348 ///Sets the map that stores the distances of the nodes calculated by the
88.349 ///algorithm.
88.350 - ///If you don't use this function before calling \ref run(),
88.351 - ///it will allocate one. The destructor deallocates this
88.352 - ///automatically allocated map, of course.
88.353 + ///If you don't use this function before calling \ref run(Node) "run()"
88.354 + ///or \ref init(), an instance will be allocated automatically.
88.355 + ///The destructor deallocates this automatically allocated map,
88.356 + ///of course.
88.357 ///\return <tt> (*this) </tt>
88.358 Dijkstra &distMap(DistMap &m)
88.359 {
88.360 @@ -538,9 +550,11 @@
88.361 ///Sets the heap and the cross reference used by algorithm.
88.362
88.363 ///Sets the heap and the cross reference used by algorithm.
88.364 - ///If you don't use this function before calling \ref run(),
88.365 - ///it will allocate one. The destructor deallocates this
88.366 - ///automatically allocated heap and cross reference, of course.
88.367 + ///If you don't use this function before calling \ref run(Node) "run()"
88.368 + ///or \ref init(), heap and cross reference instances will be
88.369 + ///allocated automatically.
88.370 + ///The destructor deallocates these automatically allocated objects,
88.371 + ///of course.
88.372 ///\return <tt> (*this) </tt>
88.373 Dijkstra &heap(Heap& hp, HeapCrossRef &cr)
88.374 {
88.375 @@ -567,22 +581,19 @@
88.376
88.377 public:
88.378
88.379 - ///\name Execution control
88.380 - ///The simplest way to execute the algorithm is to use one of the
88.381 - ///member functions called \ref lemon::Dijkstra::run() "run()".
88.382 - ///\n
88.383 - ///If you need more control on the execution, first you must call
88.384 - ///\ref lemon::Dijkstra::init() "init()", then you can add several
88.385 - ///source nodes with \ref lemon::Dijkstra::addSource() "addSource()".
88.386 - ///Finally \ref lemon::Dijkstra::start() "start()" will perform the
88.387 - ///actual path computation.
88.388 + ///\name Execution Control
88.389 + ///The simplest way to execute the %Dijkstra algorithm is to use
88.390 + ///one of the member functions called \ref run(Node) "run()".\n
88.391 + ///If you need more control on the execution, first you have to call
88.392 + ///\ref init(), then you can add several source nodes with
88.393 + ///\ref addSource(). Finally the actual path computation can be
88.394 + ///performed with one of the \ref start() functions.
88.395
88.396 ///@{
88.397
88.398 + ///\brief Initializes the internal data structures.
88.399 + ///
88.400 ///Initializes the internal data structures.
88.401 -
88.402 - ///Initializes the internal data structures.
88.403 - ///
88.404 void init()
88.405 {
88.406 create_maps();
88.407 @@ -630,12 +641,12 @@
88.408 Node w=G->target(e);
88.409 switch(_heap->state(w)) {
88.410 case Heap::PRE_HEAP:
88.411 - _heap->push(w,OperationTraits::plus(oldvalue, (*length)[e]));
88.412 + _heap->push(w,OperationTraits::plus(oldvalue, (*_length)[e]));
88.413 _pred->set(w,e);
88.414 break;
88.415 case Heap::IN_HEAP:
88.416 {
88.417 - Value newvalue = OperationTraits::plus(oldvalue, (*length)[e]);
88.418 + Value newvalue = OperationTraits::plus(oldvalue, (*_length)[e]);
88.419 if ( OperationTraits::less(newvalue, (*_heap)[w]) ) {
88.420 _heap->decrease(w, newvalue);
88.421 _pred->set(w,e);
88.422 @@ -658,17 +669,16 @@
88.423 return !_heap->empty()?_heap->top():INVALID;
88.424 }
88.425
88.426 - ///\brief Returns \c false if there are nodes
88.427 - ///to be processed.
88.428 - ///
88.429 - ///Returns \c false if there are nodes
88.430 - ///to be processed in the priority heap.
88.431 + ///Returns \c false if there are nodes to be processed.
88.432 +
88.433 + ///Returns \c false if there are nodes to be processed
88.434 + ///in the priority heap.
88.435 bool emptyQueue() const { return _heap->empty(); }
88.436
88.437 - ///Returns the number of the nodes to be processed in the priority heap
88.438 + ///Returns the number of the nodes to be processed.
88.439
88.440 - ///Returns the number of the nodes to be processed in the priority heap.
88.441 - ///
88.442 + ///Returns the number of the nodes to be processed
88.443 + ///in the priority heap.
88.444 int queueSize() const { return _heap->size(); }
88.445
88.446 ///Executes the algorithm.
88.447 @@ -789,11 +799,10 @@
88.448 ///@}
88.449
88.450 ///\name Query Functions
88.451 - ///The result of the %Dijkstra algorithm can be obtained using these
88.452 + ///The results of the %Dijkstra algorithm can be obtained using these
88.453 ///functions.\n
88.454 - ///Either \ref lemon::Dijkstra::run() "run()" or
88.455 - ///\ref lemon::Dijkstra::start() "start()" must be called before
88.456 - ///using them.
88.457 + ///Either \ref run(Node) "run()" or \ref start() should be called
88.458 + ///before using them.
88.459
88.460 ///@{
88.461
88.462 @@ -801,49 +810,49 @@
88.463
88.464 ///Returns the shortest path to a node.
88.465 ///
88.466 - ///\warning \c t should be reachable from the root(s).
88.467 + ///\warning \c t should be reached from the root(s).
88.468 ///
88.469 - ///\pre Either \ref run() or \ref start() must be called before
88.470 - ///using this function.
88.471 + ///\pre Either \ref run(Node) "run()" or \ref init()
88.472 + ///must be called before using this function.
88.473 Path path(Node t) const { return Path(*G, *_pred, t); }
88.474
88.475 ///The distance of a node from the root(s).
88.476
88.477 ///Returns the distance of a node from the root(s).
88.478 ///
88.479 - ///\warning If node \c v is not reachable from the root(s), then
88.480 + ///\warning If node \c v is not reached from the root(s), then
88.481 ///the return value of this function is undefined.
88.482 ///
88.483 - ///\pre Either \ref run() or \ref start() must be called before
88.484 - ///using this function.
88.485 + ///\pre Either \ref run(Node) "run()" or \ref init()
88.486 + ///must be called before using this function.
88.487 Value dist(Node v) const { return (*_dist)[v]; }
88.488
88.489 ///Returns the 'previous arc' of the shortest path tree for a node.
88.490
88.491 ///This function returns the 'previous arc' of the shortest path
88.492 ///tree for the node \c v, i.e. it returns the last arc of a
88.493 - ///shortest path from the root(s) to \c v. It is \c INVALID if \c v
88.494 - ///is not reachable from the root(s) or if \c v is a root.
88.495 + ///shortest path from a root to \c v. It is \c INVALID if \c v
88.496 + ///is not reached from the root(s) or if \c v is a root.
88.497 ///
88.498 ///The shortest path tree used here is equal to the shortest path
88.499 ///tree used in \ref predNode().
88.500 ///
88.501 - ///\pre Either \ref run() or \ref start() must be called before
88.502 - ///using this function.
88.503 + ///\pre Either \ref run(Node) "run()" or \ref init()
88.504 + ///must be called before using this function.
88.505 Arc predArc(Node v) const { return (*_pred)[v]; }
88.506
88.507 ///Returns the 'previous node' of the shortest path tree for a node.
88.508
88.509 ///This function returns the 'previous node' of the shortest path
88.510 ///tree for the node \c v, i.e. it returns the last but one node
88.511 - ///from a shortest path from the root(s) to \c v. It is \c INVALID
88.512 - ///if \c v is not reachable from the root(s) or if \c v is a root.
88.513 + ///from a shortest path from a root to \c v. It is \c INVALID
88.514 + ///if \c v is not reached from the root(s) or if \c v is a root.
88.515 ///
88.516 ///The shortest path tree used here is equal to the shortest path
88.517 ///tree used in \ref predArc().
88.518 ///
88.519 - ///\pre Either \ref run() or \ref start() must be called before
88.520 - ///using this function.
88.521 + ///\pre Either \ref run(Node) "run()" or \ref init()
88.522 + ///must be called before using this function.
88.523 Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
88.524 G->source((*_pred)[v]); }
88.525
88.526 @@ -853,7 +862,7 @@
88.527 ///Returns a const reference to the node map that stores the distances
88.528 ///of the nodes calculated by the algorithm.
88.529 ///
88.530 - ///\pre Either \ref run() or \ref init()
88.531 + ///\pre Either \ref run(Node) "run()" or \ref init()
88.532 ///must be called before using this function.
88.533 const DistMap &distMap() const { return *_dist;}
88.534
88.535 @@ -863,14 +872,15 @@
88.536 ///Returns a const reference to the node map that stores the predecessor
88.537 ///arcs, which form the shortest path tree.
88.538 ///
88.539 - ///\pre Either \ref run() or \ref init()
88.540 + ///\pre Either \ref run(Node) "run()" or \ref init()
88.541 ///must be called before using this function.
88.542 const PredMap &predMap() const { return *_pred;}
88.543
88.544 - ///Checks if a node is reachable from the root(s).
88.545 + ///Checks if a node is reached from the root(s).
88.546
88.547 - ///Returns \c true if \c v is reachable from the root(s).
88.548 - ///\pre Either \ref run() or \ref start()
88.549 + ///Returns \c true if \c v is reached from the root(s).
88.550 + ///
88.551 + ///\pre Either \ref run(Node) "run()" or \ref init()
88.552 ///must be called before using this function.
88.553 bool reached(Node v) const { return (*_heap_cross_ref)[v] !=
88.554 Heap::PRE_HEAP; }
88.555 @@ -879,7 +889,8 @@
88.556
88.557 ///Returns \c true if \c v is processed, i.e. the shortest
88.558 ///path to \c v has already found.
88.559 - ///\pre Either \ref run() or \ref init()
88.560 + ///
88.561 + ///\pre Either \ref run(Node) "run()" or \ref init()
88.562 ///must be called before using this function.
88.563 bool processed(Node v) const { return (*_heap_cross_ref)[v] ==
88.564 Heap::POST_HEAP; }
88.565 @@ -888,7 +899,8 @@
88.566
88.567 ///Returns the current distance of a node from the root(s).
88.568 ///It may be decreased in the following processes.
88.569 - ///\pre Either \ref run() or \ref init()
88.570 + ///
88.571 + ///\pre Either \ref run(Node) "run()" or \ref init()
88.572 ///must be called before using this function and
88.573 ///node \c v must be reached but not necessarily processed.
88.574 Value currentDist(Node v) const {
88.575 @@ -903,8 +915,8 @@
88.576
88.577 ///Default traits class of dijkstra() function.
88.578 ///\tparam GR The type of the digraph.
88.579 - ///\tparam LM The type of the length map.
88.580 - template<class GR, class LM>
88.581 + ///\tparam LEN The type of the length map.
88.582 + template<class GR, class LEN>
88.583 struct DijkstraWizardDefaultTraits
88.584 {
88.585 ///The type of the digraph the algorithm runs on.
88.586 @@ -913,9 +925,9 @@
88.587
88.588 ///The type of the map that stores the arc lengths.
88.589 ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
88.590 - typedef LM LengthMap;
88.591 + typedef LEN LengthMap;
88.592 ///The type of the length of the arcs.
88.593 - typedef typename LM::Value Value;
88.594 + typedef typename LEN::Value Value;
88.595
88.596 /// Operation traits for Dijkstra algorithm.
88.597
88.598 @@ -997,7 +1009,7 @@
88.599
88.600 ///The type of the map that stores the distances of the nodes.
88.601 ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
88.602 - typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
88.603 + typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
88.604 ///Instantiates a DistMap.
88.605
88.606 ///This function instantiates a DistMap.
88.607 @@ -1023,10 +1035,10 @@
88.608 /// as well as the \ref Dijkstra class.
88.609 /// The \ref DijkstraWizardBase is a class to be the default traits of the
88.610 /// \ref DijkstraWizard class.
88.611 - template<class GR,class LM>
88.612 - class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LM>
88.613 + template<typename GR, typename LEN>
88.614 + class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LEN>
88.615 {
88.616 - typedef DijkstraWizardDefaultTraits<GR,LM> Base;
88.617 + typedef DijkstraWizardDefaultTraits<GR,LEN> Base;
88.618 protected:
88.619 //The type of the nodes in the digraph.
88.620 typedef typename Base::Digraph::Node Node;
88.621 @@ -1060,9 +1072,9 @@
88.622 /// others are initiated to \c 0.
88.623 /// \param g The digraph the algorithm runs on.
88.624 /// \param l The length map.
88.625 - DijkstraWizardBase(const GR &g,const LM &l) :
88.626 + DijkstraWizardBase(const GR &g,const LEN &l) :
88.627 _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
88.628 - _length(reinterpret_cast<void*>(const_cast<LM*>(&l))),
88.629 + _length(reinterpret_cast<void*>(const_cast<LEN*>(&l))),
88.630 _processed(0), _pred(0), _dist(0), _path(0), _di(0) {}
88.631
88.632 };
88.633 @@ -1071,8 +1083,8 @@
88.634
88.635 /// This auxiliary class is created to implement the
88.636 /// \ref dijkstra() "function-type interface" of \ref Dijkstra algorithm.
88.637 - /// It does not have own \ref run() method, it uses the functions
88.638 - /// and features of the plain \ref Dijkstra.
88.639 + /// It does not have own \ref run(Node) "run()" method, it uses the
88.640 + /// functions and features of the plain \ref Dijkstra.
88.641 ///
88.642 /// This class should only be used through the \ref dijkstra() function,
88.643 /// which makes it easier to use the algorithm.
88.644 @@ -1267,15 +1279,15 @@
88.645 /// // Compute shortest path from s to t
88.646 /// bool reached = dijkstra(g,length).path(p).dist(d).run(s,t);
88.647 ///\endcode
88.648 - ///\warning Don't forget to put the \ref DijkstraWizard::run() "run()"
88.649 + ///\warning Don't forget to put the \ref DijkstraWizard::run(Node) "run()"
88.650 ///to the end of the parameter list.
88.651 ///\sa DijkstraWizard
88.652 ///\sa Dijkstra
88.653 - template<class GR, class LM>
88.654 - DijkstraWizard<DijkstraWizardBase<GR,LM> >
88.655 - dijkstra(const GR &digraph, const LM &length)
88.656 + template<typename GR, typename LEN>
88.657 + DijkstraWizard<DijkstraWizardBase<GR,LEN> >
88.658 + dijkstra(const GR &digraph, const LEN &length)
88.659 {
88.660 - return DijkstraWizard<DijkstraWizardBase<GR,LM> >(digraph,length);
88.661 + return DijkstraWizard<DijkstraWizardBase<GR,LEN> >(digraph,length);
88.662 }
88.663
88.664 } //END OF NAMESPACE LEMON
89.1 --- a/lemon/dim2.h Fri Nov 13 12:33:33 2009 +0100
89.2 +++ b/lemon/dim2.h Thu Dec 10 17:05:35 2009 +0100
89.3 @@ -2,7 +2,7 @@
89.4 *
89.5 * This file is a part of LEMON, a generic C++ optimization library.
89.6 *
89.7 - * Copyright (C) 2003-2008
89.8 + * Copyright (C) 2003-2009
89.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
89.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
89.11 *
90.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
90.2 +++ b/lemon/dimacs.h Thu Dec 10 17:05:35 2009 +0100
90.3 @@ -0,0 +1,448 @@
90.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
90.5 + *
90.6 + * This file is a part of LEMON, a generic C++ optimization library.
90.7 + *
90.8 + * Copyright (C) 2003-2009
90.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
90.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
90.11 + *
90.12 + * 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_DIMACS_H
90.23 +#define LEMON_DIMACS_H
90.24 +
90.25 +#include <iostream>
90.26 +#include <string>
90.27 +#include <vector>
90.28 +#include <limits>
90.29 +#include <lemon/maps.h>
90.30 +#include <lemon/error.h>
90.31 +/// \ingroup dimacs_group
90.32 +/// \file
90.33 +/// \brief DIMACS file format reader.
90.34 +
90.35 +namespace lemon {
90.36 +
90.37 + /// \addtogroup dimacs_group
90.38 + /// @{
90.39 +
90.40 + /// DIMACS file type descriptor.
90.41 + struct DimacsDescriptor
90.42 + {
90.43 + ///\brief DIMACS file type enum
90.44 + ///
90.45 + ///DIMACS file type enum.
90.46 + enum Type {
90.47 + NONE, ///< Undefined type.
90.48 + MIN, ///< DIMACS file type for minimum cost flow problems.
90.49 + MAX, ///< DIMACS file type for maximum flow problems.
90.50 + SP, ///< DIMACS file type for shostest path problems.
90.51 + MAT ///< DIMACS file type for plain graphs and matching problems.
90.52 + };
90.53 + ///The file type
90.54 + Type type;
90.55 + ///The number of nodes in the graph
90.56 + int nodeNum;
90.57 + ///The number of edges in the graph
90.58 + int edgeNum;
90.59 + int lineShift;
90.60 + ///Constructor. It sets the type to \c NONE.
90.61 + DimacsDescriptor() : type(NONE) {}
90.62 + };
90.63 +
90.64 + ///Discover the type of a DIMACS file
90.65 +
90.66 + ///This function starts seeking the beginning of the given file for the
90.67 + ///problem type and size info.
90.68 + ///The found data is returned in a special struct that can be evaluated
90.69 + ///and passed to the appropriate reader function.
90.70 + DimacsDescriptor dimacsType(std::istream& is)
90.71 + {
90.72 + DimacsDescriptor r;
90.73 + std::string problem,str;
90.74 + char c;
90.75 + r.lineShift=0;
90.76 + while (is >> c)
90.77 + switch(c)
90.78 + {
90.79 + case 'p':
90.80 + if(is >> problem >> r.nodeNum >> r.edgeNum)
90.81 + {
90.82 + getline(is, str);
90.83 + r.lineShift++;
90.84 + if(problem=="min") r.type=DimacsDescriptor::MIN;
90.85 + else if(problem=="max") r.type=DimacsDescriptor::MAX;
90.86 + else if(problem=="sp") r.type=DimacsDescriptor::SP;
90.87 + else if(problem=="mat") r.type=DimacsDescriptor::MAT;
90.88 + else throw FormatError("Unknown problem type");
90.89 + return r;
90.90 + }
90.91 + else
90.92 + {
90.93 + throw FormatError("Missing or wrong problem type declaration.");
90.94 + }
90.95 + break;
90.96 + case 'c':
90.97 + getline(is, str);
90.98 + r.lineShift++;
90.99 + break;
90.100 + default:
90.101 + throw FormatError("Unknown DIMACS declaration.");
90.102 + }
90.103 + throw FormatError("Missing problem type declaration.");
90.104 + }
90.105 +
90.106 +
90.107 + /// \brief DIMACS minimum cost flow reader function.
90.108 + ///
90.109 + /// This function reads a minimum cost flow instance from DIMACS format,
90.110 + /// i.e. from a DIMACS file having a line starting with
90.111 + /// \code
90.112 + /// p min
90.113 + /// \endcode
90.114 + /// At the beginning, \c g is cleared by \c g.clear(). The supply
90.115 + /// amount of the nodes are written to the \c supply node map
90.116 + /// (they are signed values). The lower bounds, capacities and costs
90.117 + /// of the arcs are written to the \c lower, \c capacity and \c cost
90.118 + /// arc maps.
90.119 + ///
90.120 + /// If the capacity of an arc is less than the lower bound, it will
90.121 + /// be set to "infinite" instead. The actual value of "infinite" is
90.122 + /// contolled by the \c infty parameter. If it is 0 (the default value),
90.123 + /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
90.124 + /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
90.125 + /// a non-zero value, that value will be used as "infinite".
90.126 + ///
90.127 + /// If the file type was previously evaluated by dimacsType(), then
90.128 + /// the descriptor struct should be given by the \c dest parameter.
90.129 + template <typename Digraph, typename LowerMap,
90.130 + typename CapacityMap, typename CostMap,
90.131 + typename SupplyMap>
90.132 + void readDimacsMin(std::istream& is,
90.133 + Digraph &g,
90.134 + LowerMap& lower,
90.135 + CapacityMap& capacity,
90.136 + CostMap& cost,
90.137 + SupplyMap& supply,
90.138 + typename CapacityMap::Value infty = 0,
90.139 + DimacsDescriptor desc=DimacsDescriptor())
90.140 + {
90.141 + g.clear();
90.142 + std::vector<typename Digraph::Node> nodes;
90.143 + typename Digraph::Arc e;
90.144 + std::string problem, str;
90.145 + char c;
90.146 + int i, j;
90.147 + if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
90.148 + if(desc.type!=DimacsDescriptor::MIN)
90.149 + throw FormatError("Problem type mismatch");
90.150 +
90.151 + nodes.resize(desc.nodeNum + 1);
90.152 + for (int k = 1; k <= desc.nodeNum; ++k) {
90.153 + nodes[k] = g.addNode();
90.154 + supply.set(nodes[k], 0);
90.155 + }
90.156 +
90.157 + typename SupplyMap::Value sup;
90.158 + typename CapacityMap::Value low;
90.159 + typename CapacityMap::Value cap;
90.160 + typename CostMap::Value co;
90.161 + typedef typename CapacityMap::Value Capacity;
90.162 + if(infty==0)
90.163 + infty = std::numeric_limits<Capacity>::has_infinity ?
90.164 + std::numeric_limits<Capacity>::infinity() :
90.165 + std::numeric_limits<Capacity>::max();
90.166 +
90.167 + while (is >> c) {
90.168 + switch (c) {
90.169 + case 'c': // comment line
90.170 + getline(is, str);
90.171 + break;
90.172 + case 'n': // node definition line
90.173 + is >> i >> sup;
90.174 + getline(is, str);
90.175 + supply.set(nodes[i], sup);
90.176 + break;
90.177 + case 'a': // arc definition line
90.178 + is >> i >> j >> low >> cap >> co;
90.179 + getline(is, str);
90.180 + e = g.addArc(nodes[i], nodes[j]);
90.181 + lower.set(e, low);
90.182 + if (cap >= low)
90.183 + capacity.set(e, cap);
90.184 + else
90.185 + capacity.set(e, infty);
90.186 + cost.set(e, co);
90.187 + break;
90.188 + }
90.189 + }
90.190 + }
90.191 +
90.192 + template<typename Digraph, typename CapacityMap>
90.193 + void _readDimacs(std::istream& is,
90.194 + Digraph &g,
90.195 + CapacityMap& capacity,
90.196 + typename Digraph::Node &s,
90.197 + typename Digraph::Node &t,
90.198 + typename CapacityMap::Value infty = 0,
90.199 + DimacsDescriptor desc=DimacsDescriptor()) {
90.200 + g.clear();
90.201 + s=t=INVALID;
90.202 + std::vector<typename Digraph::Node> nodes;
90.203 + typename Digraph::Arc e;
90.204 + char c, d;
90.205 + int i, j;
90.206 + typename CapacityMap::Value _cap;
90.207 + std::string str;
90.208 + nodes.resize(desc.nodeNum + 1);
90.209 + for (int k = 1; k <= desc.nodeNum; ++k) {
90.210 + nodes[k] = g.addNode();
90.211 + }
90.212 + typedef typename CapacityMap::Value Capacity;
90.213 +
90.214 + if(infty==0)
90.215 + infty = std::numeric_limits<Capacity>::has_infinity ?
90.216 + std::numeric_limits<Capacity>::infinity() :
90.217 + std::numeric_limits<Capacity>::max();
90.218 +
90.219 + while (is >> c) {
90.220 + switch (c) {
90.221 + case 'c': // comment line
90.222 + getline(is, str);
90.223 + break;
90.224 + case 'n': // node definition line
90.225 + if (desc.type==DimacsDescriptor::SP) { // shortest path problem
90.226 + is >> i;
90.227 + getline(is, str);
90.228 + s = nodes[i];
90.229 + }
90.230 + if (desc.type==DimacsDescriptor::MAX) { // max flow problem
90.231 + is >> i >> d;
90.232 + getline(is, str);
90.233 + if (d == 's') s = nodes[i];
90.234 + if (d == 't') t = nodes[i];
90.235 + }
90.236 + break;
90.237 + case 'a': // arc definition line
90.238 + if (desc.type==DimacsDescriptor::SP) {
90.239 + is >> i >> j >> _cap;
90.240 + getline(is, str);
90.241 + e = g.addArc(nodes[i], nodes[j]);
90.242 + capacity.set(e, _cap);
90.243 + }
90.244 + else if (desc.type==DimacsDescriptor::MAX) {
90.245 + is >> i >> j >> _cap;
90.246 + getline(is, str);
90.247 + e = g.addArc(nodes[i], nodes[j]);
90.248 + if (_cap >= 0)
90.249 + capacity.set(e, _cap);
90.250 + else
90.251 + capacity.set(e, infty);
90.252 + }
90.253 + else {
90.254 + is >> i >> j;
90.255 + getline(is, str);
90.256 + g.addArc(nodes[i], nodes[j]);
90.257 + }
90.258 + break;
90.259 + }
90.260 + }
90.261 + }
90.262 +
90.263 + /// \brief DIMACS maximum flow reader function.
90.264 + ///
90.265 + /// This function reads a maximum flow instance from DIMACS format,
90.266 + /// i.e. from a DIMACS file having a line starting with
90.267 + /// \code
90.268 + /// p max
90.269 + /// \endcode
90.270 + /// At the beginning, \c g is cleared by \c g.clear(). The arc
90.271 + /// capacities are written to the \c capacity arc map and \c s and
90.272 + /// \c t are set to the source and the target nodes.
90.273 + ///
90.274 + /// If the capacity of an arc is negative, it will
90.275 + /// be set to "infinite" instead. The actual value of "infinite" is
90.276 + /// contolled by the \c infty parameter. If it is 0 (the default value),
90.277 + /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
90.278 + /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
90.279 + /// a non-zero value, that value will be used as "infinite".
90.280 + ///
90.281 + /// If the file type was previously evaluated by dimacsType(), then
90.282 + /// the descriptor struct should be given by the \c dest parameter.
90.283 + template<typename Digraph, typename CapacityMap>
90.284 + void readDimacsMax(std::istream& is,
90.285 + Digraph &g,
90.286 + CapacityMap& capacity,
90.287 + typename Digraph::Node &s,
90.288 + typename Digraph::Node &t,
90.289 + typename CapacityMap::Value infty = 0,
90.290 + DimacsDescriptor desc=DimacsDescriptor()) {
90.291 + if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
90.292 + if(desc.type!=DimacsDescriptor::MAX)
90.293 + throw FormatError("Problem type mismatch");
90.294 + _readDimacs(is,g,capacity,s,t,infty,desc);
90.295 + }
90.296 +
90.297 + /// \brief DIMACS shortest path reader function.
90.298 + ///
90.299 + /// This function reads a shortest path instance from DIMACS format,
90.300 + /// i.e. from a DIMACS file having a line starting with
90.301 + /// \code
90.302 + /// p sp
90.303 + /// \endcode
90.304 + /// At the beginning, \c g is cleared by \c g.clear(). The arc
90.305 + /// lengths are written to the \c length arc map and \c s is set to the
90.306 + /// source node.
90.307 + ///
90.308 + /// If the file type was previously evaluated by dimacsType(), then
90.309 + /// the descriptor struct should be given by the \c dest parameter.
90.310 + template<typename Digraph, typename LengthMap>
90.311 + void readDimacsSp(std::istream& is,
90.312 + Digraph &g,
90.313 + LengthMap& length,
90.314 + typename Digraph::Node &s,
90.315 + DimacsDescriptor desc=DimacsDescriptor()) {
90.316 + typename Digraph::Node t;
90.317 + if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
90.318 + if(desc.type!=DimacsDescriptor::SP)
90.319 + throw FormatError("Problem type mismatch");
90.320 + _readDimacs(is, g, length, s, t, 0, desc);
90.321 + }
90.322 +
90.323 + /// \brief DIMACS capacitated digraph reader function.
90.324 + ///
90.325 + /// This function reads an arc capacitated digraph instance from
90.326 + /// DIMACS 'max' or 'sp' format.
90.327 + /// At the beginning, \c g is cleared by \c g.clear()
90.328 + /// and the arc capacities/lengths are written to the \c capacity
90.329 + /// arc map.
90.330 + ///
90.331 + /// In case of the 'max' format, if the capacity of an arc is negative,
90.332 + /// it will
90.333 + /// be set to "infinite" instead. The actual value of "infinite" is
90.334 + /// contolled by the \c infty parameter. If it is 0 (the default value),
90.335 + /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
90.336 + /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
90.337 + /// a non-zero value, that value will be used as "infinite".
90.338 + ///
90.339 + /// If the file type was previously evaluated by dimacsType(), then
90.340 + /// the descriptor struct should be given by the \c dest parameter.
90.341 + template<typename Digraph, typename CapacityMap>
90.342 + void readDimacsCap(std::istream& is,
90.343 + Digraph &g,
90.344 + CapacityMap& capacity,
90.345 + typename CapacityMap::Value infty = 0,
90.346 + DimacsDescriptor desc=DimacsDescriptor()) {
90.347 + typename Digraph::Node u,v;
90.348 + if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
90.349 + if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
90.350 + throw FormatError("Problem type mismatch");
90.351 + _readDimacs(is, g, capacity, u, v, infty, desc);
90.352 + }
90.353 +
90.354 + template<typename Graph>
90.355 + typename enable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
90.356 + _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
90.357 + dummy<0> = 0)
90.358 + {
90.359 + g.addEdge(s,t);
90.360 + }
90.361 + template<typename Graph>
90.362 + typename disable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
90.363 + _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
90.364 + dummy<1> = 1)
90.365 + {
90.366 + g.addArc(s,t);
90.367 + }
90.368 +
90.369 + /// \brief DIMACS plain (di)graph reader function.
90.370 + ///
90.371 + /// This function reads a plain (di)graph without any designated nodes
90.372 + /// and maps (e.g. a matching instance) from DIMACS format, i.e. from
90.373 + /// DIMACS files having a line starting with
90.374 + /// \code
90.375 + /// p mat
90.376 + /// \endcode
90.377 + /// At the beginning, \c g is cleared by \c g.clear().
90.378 + ///
90.379 + /// If the file type was previously evaluated by dimacsType(), then
90.380 + /// the descriptor struct should be given by the \c dest parameter.
90.381 + template<typename Graph>
90.382 + void readDimacsMat(std::istream& is, Graph &g,
90.383 + DimacsDescriptor desc=DimacsDescriptor())
90.384 + {
90.385 + if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
90.386 + if(desc.type!=DimacsDescriptor::MAT)
90.387 + throw FormatError("Problem type mismatch");
90.388 +
90.389 + g.clear();
90.390 + std::vector<typename Graph::Node> nodes;
90.391 + char c;
90.392 + int i, j;
90.393 + std::string str;
90.394 + nodes.resize(desc.nodeNum + 1);
90.395 + for (int k = 1; k <= desc.nodeNum; ++k) {
90.396 + nodes[k] = g.addNode();
90.397 + }
90.398 +
90.399 + while (is >> c) {
90.400 + switch (c) {
90.401 + case 'c': // comment line
90.402 + getline(is, str);
90.403 + break;
90.404 + case 'n': // node definition line
90.405 + break;
90.406 + case 'a': // arc definition line
90.407 + is >> i >> j;
90.408 + getline(is, str);
90.409 + _addArcEdge(g,nodes[i], nodes[j]);
90.410 + break;
90.411 + }
90.412 + }
90.413 + }
90.414 +
90.415 + /// DIMACS plain digraph writer function.
90.416 + ///
90.417 + /// This function writes a digraph without any designated nodes and
90.418 + /// maps into DIMACS format, i.e. into DIMACS file having a line
90.419 + /// starting with
90.420 + /// \code
90.421 + /// p mat
90.422 + /// \endcode
90.423 + /// If \c comment is not empty, then it will be printed in the first line
90.424 + /// prefixed by 'c'.
90.425 + template<typename Digraph>
90.426 + void writeDimacsMat(std::ostream& os, const Digraph &g,
90.427 + std::string comment="") {
90.428 + typedef typename Digraph::NodeIt NodeIt;
90.429 + typedef typename Digraph::ArcIt ArcIt;
90.430 +
90.431 + if(!comment.empty())
90.432 + os << "c " << comment << std::endl;
90.433 + os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
90.434 +
90.435 + typename Digraph::template NodeMap<int> nodes(g);
90.436 + int i = 1;
90.437 + for(NodeIt v(g); v != INVALID; ++v) {
90.438 + nodes.set(v, i);
90.439 + ++i;
90.440 + }
90.441 + for(ArcIt e(g); e != INVALID; ++e) {
90.442 + os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
90.443 + << std::endl;
90.444 + }
90.445 + }
90.446 +
90.447 + /// @}
90.448 +
90.449 +} //namespace lemon
90.450 +
90.451 +#endif //LEMON_DIMACS_H
91.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
91.2 +++ b/lemon/edge_set.h Thu Dec 10 17:05:35 2009 +0100
91.3 @@ -0,0 +1,1416 @@
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-2008
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_EDGE_SET_H
91.23 +#define LEMON_EDGE_SET_H
91.24 +
91.25 +#include <lemon/core.h>
91.26 +#include <lemon/bits/edge_set_extender.h>
91.27 +
91.28 +/// \ingroup graphs
91.29 +/// \file
91.30 +/// \brief ArcSet and EdgeSet classes.
91.31 +///
91.32 +/// Graphs which use another graph's node-set as own.
91.33 +namespace lemon {
91.34 +
91.35 + template <typename GR>
91.36 + class ListArcSetBase {
91.37 + public:
91.38 +
91.39 + typedef typename GR::Node Node;
91.40 + typedef typename GR::NodeIt NodeIt;
91.41 +
91.42 + protected:
91.43 +
91.44 + struct NodeT {
91.45 + int first_out, first_in;
91.46 + NodeT() : first_out(-1), first_in(-1) {}
91.47 + };
91.48 +
91.49 + typedef typename ItemSetTraits<GR, Node>::
91.50 + template Map<NodeT>::Type NodesImplBase;
91.51 +
91.52 + NodesImplBase* _nodes;
91.53 +
91.54 + struct ArcT {
91.55 + Node source, target;
91.56 + int next_out, next_in;
91.57 + int prev_out, prev_in;
91.58 + ArcT() : prev_out(-1), prev_in(-1) {}
91.59 + };
91.60 +
91.61 + std::vector<ArcT> arcs;
91.62 +
91.63 + int first_arc;
91.64 + int first_free_arc;
91.65 +
91.66 + const GR* _graph;
91.67 +
91.68 + void initalize(const GR& graph, NodesImplBase& nodes) {
91.69 + _graph = &graph;
91.70 + _nodes = &nodes;
91.71 + }
91.72 +
91.73 + public:
91.74 +
91.75 + class Arc {
91.76 + friend class ListArcSetBase<GR>;
91.77 + protected:
91.78 + Arc(int _id) : id(_id) {}
91.79 + int id;
91.80 + public:
91.81 + Arc() {}
91.82 + Arc(Invalid) : id(-1) {}
91.83 + bool operator==(const Arc& arc) const { return id == arc.id; }
91.84 + bool operator!=(const Arc& arc) const { return id != arc.id; }
91.85 + bool operator<(const Arc& arc) const { return id < arc.id; }
91.86 + };
91.87 +
91.88 + ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
91.89 +
91.90 + Node addNode() {
91.91 + LEMON_ASSERT(false,
91.92 + "This graph structure does not support node insertion");
91.93 + return INVALID; // avoid warning
91.94 + }
91.95 +
91.96 + Arc addArc(const Node& u, const Node& v) {
91.97 + int n;
91.98 + if (first_free_arc == -1) {
91.99 + n = arcs.size();
91.100 + arcs.push_back(ArcT());
91.101 + } else {
91.102 + n = first_free_arc;
91.103 + first_free_arc = arcs[first_free_arc].next_in;
91.104 + }
91.105 + arcs[n].next_in = (*_nodes)[v].first_in;
91.106 + if ((*_nodes)[v].first_in != -1) {
91.107 + arcs[(*_nodes)[v].first_in].prev_in = n;
91.108 + }
91.109 + (*_nodes)[v].first_in = n;
91.110 + arcs[n].next_out = (*_nodes)[u].first_out;
91.111 + if ((*_nodes)[u].first_out != -1) {
91.112 + arcs[(*_nodes)[u].first_out].prev_out = n;
91.113 + }
91.114 + (*_nodes)[u].first_out = n;
91.115 + arcs[n].source = u;
91.116 + arcs[n].target = v;
91.117 + return Arc(n);
91.118 + }
91.119 +
91.120 + void erase(const Arc& arc) {
91.121 + int n = arc.id;
91.122 + if (arcs[n].prev_in != -1) {
91.123 + arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
91.124 + } else {
91.125 + (*_nodes)[arcs[n].target].first_in = arcs[n].next_in;
91.126 + }
91.127 + if (arcs[n].next_in != -1) {
91.128 + arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
91.129 + }
91.130 +
91.131 + if (arcs[n].prev_out != -1) {
91.132 + arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
91.133 + } else {
91.134 + (*_nodes)[arcs[n].source].first_out = arcs[n].next_out;
91.135 + }
91.136 + if (arcs[n].next_out != -1) {
91.137 + arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
91.138 + }
91.139 +
91.140 + }
91.141 +
91.142 + void clear() {
91.143 + Node node;
91.144 + for (first(node); node != INVALID; next(node)) {
91.145 + (*_nodes)[node].first_in = -1;
91.146 + (*_nodes)[node].first_out = -1;
91.147 + }
91.148 + arcs.clear();
91.149 + first_arc = -1;
91.150 + first_free_arc = -1;
91.151 + }
91.152 +
91.153 + void first(Node& node) const {
91.154 + _graph->first(node);
91.155 + }
91.156 +
91.157 + void next(Node& node) const {
91.158 + _graph->next(node);
91.159 + }
91.160 +
91.161 + void first(Arc& arc) const {
91.162 + Node node;
91.163 + first(node);
91.164 + while (node != INVALID && (*_nodes)[node].first_in == -1) {
91.165 + next(node);
91.166 + }
91.167 + arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
91.168 + }
91.169 +
91.170 + void next(Arc& arc) const {
91.171 + if (arcs[arc.id].next_in != -1) {
91.172 + arc.id = arcs[arc.id].next_in;
91.173 + } else {
91.174 + Node node = arcs[arc.id].target;
91.175 + next(node);
91.176 + while (node != INVALID && (*_nodes)[node].first_in == -1) {
91.177 + next(node);
91.178 + }
91.179 + arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
91.180 + }
91.181 + }
91.182 +
91.183 + void firstOut(Arc& arc, const Node& node) const {
91.184 + arc.id = (*_nodes)[node].first_out;
91.185 + }
91.186 +
91.187 + void nextOut(Arc& arc) const {
91.188 + arc.id = arcs[arc.id].next_out;
91.189 + }
91.190 +
91.191 + void firstIn(Arc& arc, const Node& node) const {
91.192 + arc.id = (*_nodes)[node].first_in;
91.193 + }
91.194 +
91.195 + void nextIn(Arc& arc) const {
91.196 + arc.id = arcs[arc.id].next_in;
91.197 + }
91.198 +
91.199 + int id(const Node& node) const { return _graph->id(node); }
91.200 + int id(const Arc& arc) const { return arc.id; }
91.201 +
91.202 + Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
91.203 + Arc arcFromId(int ix) const { return Arc(ix); }
91.204 +
91.205 + int maxNodeId() const { return _graph->maxNodeId(); };
91.206 + int maxArcId() const { return arcs.size() - 1; }
91.207 +
91.208 + Node source(const Arc& arc) const { return arcs[arc.id].source;}
91.209 + Node target(const Arc& arc) const { return arcs[arc.id].target;}
91.210 +
91.211 + typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
91.212 +
91.213 + NodeNotifier& notifier(Node) const {
91.214 + return _graph->notifier(Node());
91.215 + }
91.216 +
91.217 + template <typename V>
91.218 + class NodeMap : public GR::template NodeMap<V> {
91.219 + typedef typename GR::template NodeMap<V> Parent;
91.220 +
91.221 + public:
91.222 +
91.223 + explicit NodeMap(const ListArcSetBase<GR>& arcset)
91.224 + : Parent(*arcset._graph) {}
91.225 +
91.226 + NodeMap(const ListArcSetBase<GR>& arcset, const V& value)
91.227 + : Parent(*arcset._graph, value) {}
91.228 +
91.229 + NodeMap& operator=(const NodeMap& cmap) {
91.230 + return operator=<NodeMap>(cmap);
91.231 + }
91.232 +
91.233 + template <typename CMap>
91.234 + NodeMap& operator=(const CMap& cmap) {
91.235 + Parent::operator=(cmap);
91.236 + return *this;
91.237 + }
91.238 + };
91.239 +
91.240 + };
91.241 +
91.242 + /// \ingroup graphs
91.243 + ///
91.244 + /// \brief Digraph using a node set of another digraph or graph and
91.245 + /// an own arc set.
91.246 + ///
91.247 + /// This structure can be used to establish another directed graph
91.248 + /// over a node set of an existing one. This class uses the same
91.249 + /// Node type as the underlying graph, and each valid node of the
91.250 + /// original graph is valid in this arc set, therefore the node
91.251 + /// objects of the original graph can be used directly with this
91.252 + /// class. The node handling functions (id handling, observing, and
91.253 + /// iterators) works equivalently as in the original graph.
91.254 + ///
91.255 + /// This implementation is based on doubly-linked lists, from each
91.256 + /// node the outgoing and the incoming arcs make up lists, therefore
91.257 + /// one arc can be erased in constant time. It also makes possible,
91.258 + /// that node can be removed from the underlying graph, in this case
91.259 + /// all arcs incident to the given node is erased from the arc set.
91.260 + ///
91.261 + /// \param GR The type of the graph which shares its node set with
91.262 + /// this class. Its interface must conform to the
91.263 + /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
91.264 + /// concept.
91.265 + ///
91.266 + /// This class fully conforms to the \ref concepts::Digraph
91.267 + /// "Digraph" concept.
91.268 + template <typename GR>
91.269 + class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
91.270 + typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
91.271 +
91.272 + public:
91.273 +
91.274 + typedef typename Parent::Node Node;
91.275 + typedef typename Parent::Arc Arc;
91.276 +
91.277 + typedef typename Parent::NodesImplBase NodesImplBase;
91.278 +
91.279 + void eraseNode(const Node& node) {
91.280 + Arc arc;
91.281 + Parent::firstOut(arc, node);
91.282 + while (arc != INVALID ) {
91.283 + erase(arc);
91.284 + Parent::firstOut(arc, node);
91.285 + }
91.286 +
91.287 + Parent::firstIn(arc, node);
91.288 + while (arc != INVALID ) {
91.289 + erase(arc);
91.290 + Parent::firstIn(arc, node);
91.291 + }
91.292 + }
91.293 +
91.294 + void clearNodes() {
91.295 + Parent::clear();
91.296 + }
91.297 +
91.298 + class NodesImpl : public NodesImplBase {
91.299 + typedef NodesImplBase Parent;
91.300 +
91.301 + public:
91.302 + NodesImpl(const GR& graph, ListArcSet& arcset)
91.303 + : Parent(graph), _arcset(arcset) {}
91.304 +
91.305 + virtual ~NodesImpl() {}
91.306 +
91.307 + protected:
91.308 +
91.309 + virtual void erase(const Node& node) {
91.310 + _arcset.eraseNode(node);
91.311 + Parent::erase(node);
91.312 + }
91.313 + virtual void erase(const std::vector<Node>& nodes) {
91.314 + for (int i = 0; i < int(nodes.size()); ++i) {
91.315 + _arcset.eraseNode(nodes[i]);
91.316 + }
91.317 + Parent::erase(nodes);
91.318 + }
91.319 + virtual void clear() {
91.320 + _arcset.clearNodes();
91.321 + Parent::clear();
91.322 + }
91.323 +
91.324 + private:
91.325 + ListArcSet& _arcset;
91.326 + };
91.327 +
91.328 + NodesImpl _nodes;
91.329 +
91.330 + public:
91.331 +
91.332 + /// \brief Constructor of the ArcSet.
91.333 + ///
91.334 + /// Constructor of the ArcSet.
91.335 + ListArcSet(const GR& graph) : _nodes(graph, *this) {
91.336 + Parent::initalize(graph, _nodes);
91.337 + }
91.338 +
91.339 + /// \brief Add a new arc to the digraph.
91.340 + ///
91.341 + /// Add a new arc to the digraph with source node \c s
91.342 + /// and target node \c t.
91.343 + /// \return The new arc.
91.344 + Arc addArc(const Node& s, const Node& t) {
91.345 + return Parent::addArc(s, t);
91.346 + }
91.347 +
91.348 + /// \brief Erase an arc from the digraph.
91.349 + ///
91.350 + /// Erase an arc \c a from the digraph.
91.351 + void erase(const Arc& a) {
91.352 + return Parent::erase(a);
91.353 + }
91.354 +
91.355 + };
91.356 +
91.357 + template <typename GR>
91.358 + class ListEdgeSetBase {
91.359 + public:
91.360 +
91.361 + typedef typename GR::Node Node;
91.362 + typedef typename GR::NodeIt NodeIt;
91.363 +
91.364 + protected:
91.365 +
91.366 + struct NodeT {
91.367 + int first_out;
91.368 + NodeT() : first_out(-1) {}
91.369 + };
91.370 +
91.371 + typedef typename ItemSetTraits<GR, Node>::
91.372 + template Map<NodeT>::Type NodesImplBase;
91.373 +
91.374 + NodesImplBase* _nodes;
91.375 +
91.376 + struct ArcT {
91.377 + Node target;
91.378 + int prev_out, next_out;
91.379 + ArcT() : prev_out(-1), next_out(-1) {}
91.380 + };
91.381 +
91.382 + std::vector<ArcT> arcs;
91.383 +
91.384 + int first_arc;
91.385 + int first_free_arc;
91.386 +
91.387 + const GR* _graph;
91.388 +
91.389 + void initalize(const GR& graph, NodesImplBase& nodes) {
91.390 + _graph = &graph;
91.391 + _nodes = &nodes;
91.392 + }
91.393 +
91.394 + public:
91.395 +
91.396 + class Edge {
91.397 + friend class ListEdgeSetBase;
91.398 + protected:
91.399 +
91.400 + int id;
91.401 + explicit Edge(int _id) { id = _id;}
91.402 +
91.403 + public:
91.404 + Edge() {}
91.405 + Edge (Invalid) { id = -1; }
91.406 + bool operator==(const Edge& arc) const {return id == arc.id;}
91.407 + bool operator!=(const Edge& arc) const {return id != arc.id;}
91.408 + bool operator<(const Edge& arc) const {return id < arc.id;}
91.409 + };
91.410 +
91.411 + class Arc {
91.412 + friend class ListEdgeSetBase;
91.413 + protected:
91.414 + Arc(int _id) : id(_id) {}
91.415 + int id;
91.416 + public:
91.417 + operator Edge() const { return edgeFromId(id / 2); }
91.418 +
91.419 + Arc() {}
91.420 + Arc(Invalid) : id(-1) {}
91.421 + bool operator==(const Arc& arc) const { return id == arc.id; }
91.422 + bool operator!=(const Arc& arc) const { return id != arc.id; }
91.423 + bool operator<(const Arc& arc) const { return id < arc.id; }
91.424 + };
91.425 +
91.426 + ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
91.427 +
91.428 + Node addNode() {
91.429 + LEMON_ASSERT(false,
91.430 + "This graph structure does not support node insertion");
91.431 + return INVALID; // avoid warning
91.432 + }
91.433 +
91.434 + Edge addEdge(const Node& u, const Node& v) {
91.435 + int n;
91.436 +
91.437 + if (first_free_arc == -1) {
91.438 + n = arcs.size();
91.439 + arcs.push_back(ArcT());
91.440 + arcs.push_back(ArcT());
91.441 + } else {
91.442 + n = first_free_arc;
91.443 + first_free_arc = arcs[n].next_out;
91.444 + }
91.445 +
91.446 + arcs[n].target = u;
91.447 + arcs[n | 1].target = v;
91.448 +
91.449 + arcs[n].next_out = (*_nodes)[v].first_out;
91.450 + if ((*_nodes)[v].first_out != -1) {
91.451 + arcs[(*_nodes)[v].first_out].prev_out = n;
91.452 + }
91.453 + (*_nodes)[v].first_out = n;
91.454 + arcs[n].prev_out = -1;
91.455 +
91.456 + if ((*_nodes)[u].first_out != -1) {
91.457 + arcs[(*_nodes)[u].first_out].prev_out = (n | 1);
91.458 + }
91.459 + arcs[n | 1].next_out = (*_nodes)[u].first_out;
91.460 + (*_nodes)[u].first_out = (n | 1);
91.461 + arcs[n | 1].prev_out = -1;
91.462 +
91.463 + return Edge(n / 2);
91.464 + }
91.465 +
91.466 + void erase(const Edge& arc) {
91.467 + int n = arc.id * 2;
91.468 +
91.469 + if (arcs[n].next_out != -1) {
91.470 + arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
91.471 + }
91.472 +
91.473 + if (arcs[n].prev_out != -1) {
91.474 + arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
91.475 + } else {
91.476 + (*_nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
91.477 + }
91.478 +
91.479 + if (arcs[n | 1].next_out != -1) {
91.480 + arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
91.481 + }
91.482 +
91.483 + if (arcs[n | 1].prev_out != -1) {
91.484 + arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
91.485 + } else {
91.486 + (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
91.487 + }
91.488 +
91.489 + arcs[n].next_out = first_free_arc;
91.490 + first_free_arc = n;
91.491 +
91.492 + }
91.493 +
91.494 + void clear() {
91.495 + Node node;
91.496 + for (first(node); node != INVALID; next(node)) {
91.497 + (*_nodes)[node].first_out = -1;
91.498 + }
91.499 + arcs.clear();
91.500 + first_arc = -1;
91.501 + first_free_arc = -1;
91.502 + }
91.503 +
91.504 + void first(Node& node) const {
91.505 + _graph->first(node);
91.506 + }
91.507 +
91.508 + void next(Node& node) const {
91.509 + _graph->next(node);
91.510 + }
91.511 +
91.512 + void first(Arc& arc) const {
91.513 + Node node;
91.514 + first(node);
91.515 + while (node != INVALID && (*_nodes)[node].first_out == -1) {
91.516 + next(node);
91.517 + }
91.518 + arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
91.519 + }
91.520 +
91.521 + void next(Arc& arc) const {
91.522 + if (arcs[arc.id].next_out != -1) {
91.523 + arc.id = arcs[arc.id].next_out;
91.524 + } else {
91.525 + Node node = arcs[arc.id ^ 1].target;
91.526 + next(node);
91.527 + while(node != INVALID && (*_nodes)[node].first_out == -1) {
91.528 + next(node);
91.529 + }
91.530 + arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
91.531 + }
91.532 + }
91.533 +
91.534 + void first(Edge& edge) const {
91.535 + Node node;
91.536 + first(node);
91.537 + while (node != INVALID) {
91.538 + edge.id = (*_nodes)[node].first_out;
91.539 + while ((edge.id & 1) != 1) {
91.540 + edge.id = arcs[edge.id].next_out;
91.541 + }
91.542 + if (edge.id != -1) {
91.543 + edge.id /= 2;
91.544 + return;
91.545 + }
91.546 + next(node);
91.547 + }
91.548 + edge.id = -1;
91.549 + }
91.550 +
91.551 + void next(Edge& edge) const {
91.552 + Node node = arcs[edge.id * 2].target;
91.553 + edge.id = arcs[(edge.id * 2) | 1].next_out;
91.554 + while ((edge.id & 1) != 1) {
91.555 + edge.id = arcs[edge.id].next_out;
91.556 + }
91.557 + if (edge.id != -1) {
91.558 + edge.id /= 2;
91.559 + return;
91.560 + }
91.561 + next(node);
91.562 + while (node != INVALID) {
91.563 + edge.id = (*_nodes)[node].first_out;
91.564 + while ((edge.id & 1) != 1) {
91.565 + edge.id = arcs[edge.id].next_out;
91.566 + }
91.567 + if (edge.id != -1) {
91.568 + edge.id /= 2;
91.569 + return;
91.570 + }
91.571 + next(node);
91.572 + }
91.573 + edge.id = -1;
91.574 + }
91.575 +
91.576 + void firstOut(Arc& arc, const Node& node) const {
91.577 + arc.id = (*_nodes)[node].first_out;
91.578 + }
91.579 +
91.580 + void nextOut(Arc& arc) const {
91.581 + arc.id = arcs[arc.id].next_out;
91.582 + }
91.583 +
91.584 + void firstIn(Arc& arc, const Node& node) const {
91.585 + arc.id = (((*_nodes)[node].first_out) ^ 1);
91.586 + if (arc.id == -2) arc.id = -1;
91.587 + }
91.588 +
91.589 + void nextIn(Arc& arc) const {
91.590 + arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
91.591 + if (arc.id == -2) arc.id = -1;
91.592 + }
91.593 +
91.594 + void firstInc(Edge &arc, bool& dir, const Node& node) const {
91.595 + int de = (*_nodes)[node].first_out;
91.596 + if (de != -1 ) {
91.597 + arc.id = de / 2;
91.598 + dir = ((de & 1) == 1);
91.599 + } else {
91.600 + arc.id = -1;
91.601 + dir = true;
91.602 + }
91.603 + }
91.604 + void nextInc(Edge &arc, bool& dir) const {
91.605 + int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
91.606 + if (de != -1 ) {
91.607 + arc.id = de / 2;
91.608 + dir = ((de & 1) == 1);
91.609 + } else {
91.610 + arc.id = -1;
91.611 + dir = true;
91.612 + }
91.613 + }
91.614 +
91.615 + static bool direction(Arc arc) {
91.616 + return (arc.id & 1) == 1;
91.617 + }
91.618 +
91.619 + static Arc direct(Edge edge, bool dir) {
91.620 + return Arc(edge.id * 2 + (dir ? 1 : 0));
91.621 + }
91.622 +
91.623 + int id(const Node& node) const { return _graph->id(node); }
91.624 + static int id(Arc e) { return e.id; }
91.625 + static int id(Edge e) { return e.id; }
91.626 +
91.627 + Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
91.628 + static Arc arcFromId(int id) { return Arc(id);}
91.629 + static Edge edgeFromId(int id) { return Edge(id);}
91.630 +
91.631 + int maxNodeId() const { return _graph->maxNodeId(); };
91.632 + int maxEdgeId() const { return arcs.size() / 2 - 1; }
91.633 + int maxArcId() const { return arcs.size()-1; }
91.634 +
91.635 + Node source(Arc e) const { return arcs[e.id ^ 1].target; }
91.636 + Node target(Arc e) const { return arcs[e.id].target; }
91.637 +
91.638 + Node u(Edge e) const { return arcs[2 * e.id].target; }
91.639 + Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
91.640 +
91.641 + typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
91.642 +
91.643 + NodeNotifier& notifier(Node) const {
91.644 + return _graph->notifier(Node());
91.645 + }
91.646 +
91.647 + template <typename V>
91.648 + class NodeMap : public GR::template NodeMap<V> {
91.649 + typedef typename GR::template NodeMap<V> Parent;
91.650 +
91.651 + public:
91.652 +
91.653 + explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
91.654 + : Parent(*arcset._graph) {}
91.655 +
91.656 + NodeMap(const ListEdgeSetBase<GR>& arcset, const V& value)
91.657 + : Parent(*arcset._graph, value) {}
91.658 +
91.659 + NodeMap& operator=(const NodeMap& cmap) {
91.660 + return operator=<NodeMap>(cmap);
91.661 + }
91.662 +
91.663 + template <typename CMap>
91.664 + NodeMap& operator=(const CMap& cmap) {
91.665 + Parent::operator=(cmap);
91.666 + return *this;
91.667 + }
91.668 + };
91.669 +
91.670 + };
91.671 +
91.672 + /// \ingroup graphs
91.673 + ///
91.674 + /// \brief Graph using a node set of another digraph or graph and an
91.675 + /// own edge set.
91.676 + ///
91.677 + /// This structure can be used to establish another graph over a
91.678 + /// node set of an existing one. This class uses the same Node type
91.679 + /// as the underlying graph, and each valid node of the original
91.680 + /// graph is valid in this arc set, therefore the node objects of
91.681 + /// the original graph can be used directly with this class. The
91.682 + /// node handling functions (id handling, observing, and iterators)
91.683 + /// works equivalently as in the original graph.
91.684 + ///
91.685 + /// This implementation is based on doubly-linked lists, from each
91.686 + /// node the incident edges make up lists, therefore one edge can be
91.687 + /// erased in constant time. It also makes possible, that node can
91.688 + /// be removed from the underlying graph, in this case all edges
91.689 + /// incident to the given node is erased from the arc set.
91.690 + ///
91.691 + /// \param GR The type of the graph which shares its node set
91.692 + /// with this class. Its interface must conform to the
91.693 + /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
91.694 + /// concept.
91.695 + ///
91.696 + /// This class fully conforms to the \ref concepts::Graph "Graph"
91.697 + /// concept.
91.698 + template <typename GR>
91.699 + class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
91.700 + typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
91.701 +
91.702 + public:
91.703 +
91.704 + typedef typename Parent::Node Node;
91.705 + typedef typename Parent::Arc Arc;
91.706 + typedef typename Parent::Edge Edge;
91.707 +
91.708 + typedef typename Parent::NodesImplBase NodesImplBase;
91.709 +
91.710 + void eraseNode(const Node& node) {
91.711 + Arc arc;
91.712 + Parent::firstOut(arc, node);
91.713 + while (arc != INVALID ) {
91.714 + erase(arc);
91.715 + Parent::firstOut(arc, node);
91.716 + }
91.717 +
91.718 + }
91.719 +
91.720 + void clearNodes() {
91.721 + Parent::clear();
91.722 + }
91.723 +
91.724 + class NodesImpl : public NodesImplBase {
91.725 + typedef NodesImplBase Parent;
91.726 +
91.727 + public:
91.728 + NodesImpl(const GR& graph, ListEdgeSet& arcset)
91.729 + : Parent(graph), _arcset(arcset) {}
91.730 +
91.731 + virtual ~NodesImpl() {}
91.732 +
91.733 + protected:
91.734 +
91.735 + virtual void erase(const Node& node) {
91.736 + _arcset.eraseNode(node);
91.737 + Parent::erase(node);
91.738 + }
91.739 + virtual void erase(const std::vector<Node>& nodes) {
91.740 + for (int i = 0; i < int(nodes.size()); ++i) {
91.741 + _arcset.eraseNode(nodes[i]);
91.742 + }
91.743 + Parent::erase(nodes);
91.744 + }
91.745 + virtual void clear() {
91.746 + _arcset.clearNodes();
91.747 + Parent::clear();
91.748 + }
91.749 +
91.750 + private:
91.751 + ListEdgeSet& _arcset;
91.752 + };
91.753 +
91.754 + NodesImpl _nodes;
91.755 +
91.756 + public:
91.757 +
91.758 + /// \brief Constructor of the EdgeSet.
91.759 + ///
91.760 + /// Constructor of the EdgeSet.
91.761 + ListEdgeSet(const GR& graph) : _nodes(graph, *this) {
91.762 + Parent::initalize(graph, _nodes);
91.763 + }
91.764 +
91.765 + /// \brief Add a new edge to the graph.
91.766 + ///
91.767 + /// Add a new edge to the graph with node \c u
91.768 + /// and node \c v endpoints.
91.769 + /// \return The new edge.
91.770 + Edge addEdge(const Node& u, const Node& v) {
91.771 + return Parent::addEdge(u, v);
91.772 + }
91.773 +
91.774 + /// \brief Erase an edge from the graph.
91.775 + ///
91.776 + /// Erase the edge \c e from the graph.
91.777 + void erase(const Edge& e) {
91.778 + return Parent::erase(e);
91.779 + }
91.780 +
91.781 + };
91.782 +
91.783 + template <typename GR>
91.784 + class SmartArcSetBase {
91.785 + public:
91.786 +
91.787 + typedef typename GR::Node Node;
91.788 + typedef typename GR::NodeIt NodeIt;
91.789 +
91.790 + protected:
91.791 +
91.792 + struct NodeT {
91.793 + int first_out, first_in;
91.794 + NodeT() : first_out(-1), first_in(-1) {}
91.795 + };
91.796 +
91.797 + typedef typename ItemSetTraits<GR, Node>::
91.798 + template Map<NodeT>::Type NodesImplBase;
91.799 +
91.800 + NodesImplBase* _nodes;
91.801 +
91.802 + struct ArcT {
91.803 + Node source, target;
91.804 + int next_out, next_in;
91.805 + ArcT() {}
91.806 + };
91.807 +
91.808 + std::vector<ArcT> arcs;
91.809 +
91.810 + const GR* _graph;
91.811 +
91.812 + void initalize(const GR& graph, NodesImplBase& nodes) {
91.813 + _graph = &graph;
91.814 + _nodes = &nodes;
91.815 + }
91.816 +
91.817 + public:
91.818 +
91.819 + class Arc {
91.820 + friend class SmartArcSetBase<GR>;
91.821 + protected:
91.822 + Arc(int _id) : id(_id) {}
91.823 + int id;
91.824 + public:
91.825 + Arc() {}
91.826 + Arc(Invalid) : id(-1) {}
91.827 + bool operator==(const Arc& arc) const { return id == arc.id; }
91.828 + bool operator!=(const Arc& arc) const { return id != arc.id; }
91.829 + bool operator<(const Arc& arc) const { return id < arc.id; }
91.830 + };
91.831 +
91.832 + SmartArcSetBase() {}
91.833 +
91.834 + Node addNode() {
91.835 + LEMON_ASSERT(false,
91.836 + "This graph structure does not support node insertion");
91.837 + return INVALID; // avoid warning
91.838 + }
91.839 +
91.840 + Arc addArc(const Node& u, const Node& v) {
91.841 + int n = arcs.size();
91.842 + arcs.push_back(ArcT());
91.843 + arcs[n].next_in = (*_nodes)[v].first_in;
91.844 + (*_nodes)[v].first_in = n;
91.845 + arcs[n].next_out = (*_nodes)[u].first_out;
91.846 + (*_nodes)[u].first_out = n;
91.847 + arcs[n].source = u;
91.848 + arcs[n].target = v;
91.849 + return Arc(n);
91.850 + }
91.851 +
91.852 + void clear() {
91.853 + Node node;
91.854 + for (first(node); node != INVALID; next(node)) {
91.855 + (*_nodes)[node].first_in = -1;
91.856 + (*_nodes)[node].first_out = -1;
91.857 + }
91.858 + arcs.clear();
91.859 + }
91.860 +
91.861 + void first(Node& node) const {
91.862 + _graph->first(node);
91.863 + }
91.864 +
91.865 + void next(Node& node) const {
91.866 + _graph->next(node);
91.867 + }
91.868 +
91.869 + void first(Arc& arc) const {
91.870 + arc.id = arcs.size() - 1;
91.871 + }
91.872 +
91.873 + void next(Arc& arc) const {
91.874 + --arc.id;
91.875 + }
91.876 +
91.877 + void firstOut(Arc& arc, const Node& node) const {
91.878 + arc.id = (*_nodes)[node].first_out;
91.879 + }
91.880 +
91.881 + void nextOut(Arc& arc) const {
91.882 + arc.id = arcs[arc.id].next_out;
91.883 + }
91.884 +
91.885 + void firstIn(Arc& arc, const Node& node) const {
91.886 + arc.id = (*_nodes)[node].first_in;
91.887 + }
91.888 +
91.889 + void nextIn(Arc& arc) const {
91.890 + arc.id = arcs[arc.id].next_in;
91.891 + }
91.892 +
91.893 + int id(const Node& node) const { return _graph->id(node); }
91.894 + int id(const Arc& arc) const { return arc.id; }
91.895 +
91.896 + Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
91.897 + Arc arcFromId(int ix) const { return Arc(ix); }
91.898 +
91.899 + int maxNodeId() const { return _graph->maxNodeId(); };
91.900 + int maxArcId() const { return arcs.size() - 1; }
91.901 +
91.902 + Node source(const Arc& arc) const { return arcs[arc.id].source;}
91.903 + Node target(const Arc& arc) const { return arcs[arc.id].target;}
91.904 +
91.905 + typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
91.906 +
91.907 + NodeNotifier& notifier(Node) const {
91.908 + return _graph->notifier(Node());
91.909 + }
91.910 +
91.911 + template <typename V>
91.912 + class NodeMap : public GR::template NodeMap<V> {
91.913 + typedef typename GR::template NodeMap<V> Parent;
91.914 +
91.915 + public:
91.916 +
91.917 + explicit NodeMap(const SmartArcSetBase<GR>& arcset)
91.918 + : Parent(*arcset._graph) { }
91.919 +
91.920 + NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
91.921 + : Parent(*arcset._graph, value) { }
91.922 +
91.923 + NodeMap& operator=(const NodeMap& cmap) {
91.924 + return operator=<NodeMap>(cmap);
91.925 + }
91.926 +
91.927 + template <typename CMap>
91.928 + NodeMap& operator=(const CMap& cmap) {
91.929 + Parent::operator=(cmap);
91.930 + return *this;
91.931 + }
91.932 + };
91.933 +
91.934 + };
91.935 +
91.936 +
91.937 + /// \ingroup graphs
91.938 + ///
91.939 + /// \brief Digraph using a node set of another digraph or graph and
91.940 + /// an own arc set.
91.941 + ///
91.942 + /// This structure can be used to establish another directed graph
91.943 + /// over a node set of an existing one. This class uses the same
91.944 + /// Node type as the underlying graph, and each valid node of the
91.945 + /// original graph is valid in this arc set, therefore the node
91.946 + /// objects of the original graph can be used directly with this
91.947 + /// class. The node handling functions (id handling, observing, and
91.948 + /// iterators) works equivalently as in the original graph.
91.949 + ///
91.950 + /// \param GR The type of the graph which shares its node set with
91.951 + /// this class. Its interface must conform to the
91.952 + /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
91.953 + /// concept.
91.954 + ///
91.955 + /// This implementation is slightly faster than the \c ListArcSet,
91.956 + /// because it uses continuous storage for arcs and it uses just
91.957 + /// single-linked lists for enumerate outgoing and incoming
91.958 + /// arcs. Therefore the arcs cannot be erased from the arc sets.
91.959 + ///
91.960 + /// \warning If a node is erased from the underlying graph and this
91.961 + /// node is the source or target of one arc in the arc set, then
91.962 + /// the arc set is invalidated, and it cannot be used anymore. The
91.963 + /// validity can be checked with the \c valid() member function.
91.964 + ///
91.965 + /// This class fully conforms to the \ref concepts::Digraph
91.966 + /// "Digraph" concept.
91.967 + template <typename GR>
91.968 + class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
91.969 + typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
91.970 +
91.971 + public:
91.972 +
91.973 + typedef typename Parent::Node Node;
91.974 + typedef typename Parent::Arc Arc;
91.975 +
91.976 + protected:
91.977 +
91.978 + typedef typename Parent::NodesImplBase NodesImplBase;
91.979 +
91.980 + void eraseNode(const Node& node) {
91.981 + if (typename Parent::InArcIt(*this, node) == INVALID &&
91.982 + typename Parent::OutArcIt(*this, node) == INVALID) {
91.983 + return;
91.984 + }
91.985 + throw typename NodesImplBase::Notifier::ImmediateDetach();
91.986 + }
91.987 +
91.988 + void clearNodes() {
91.989 + Parent::clear();
91.990 + }
91.991 +
91.992 + class NodesImpl : public NodesImplBase {
91.993 + typedef NodesImplBase Parent;
91.994 +
91.995 + public:
91.996 + NodesImpl(const GR& graph, SmartArcSet& arcset)
91.997 + : Parent(graph), _arcset(arcset) {}
91.998 +
91.999 + virtual ~NodesImpl() {}
91.1000 +
91.1001 + bool attached() const {
91.1002 + return Parent::attached();
91.1003 + }
91.1004 +
91.1005 + protected:
91.1006 +
91.1007 + virtual void erase(const Node& node) {
91.1008 + try {
91.1009 + _arcset.eraseNode(node);
91.1010 + Parent::erase(node);
91.1011 + } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
91.1012 + Parent::clear();
91.1013 + throw;
91.1014 + }
91.1015 + }
91.1016 + virtual void erase(const std::vector<Node>& nodes) {
91.1017 + try {
91.1018 + for (int i = 0; i < int(nodes.size()); ++i) {
91.1019 + _arcset.eraseNode(nodes[i]);
91.1020 + }
91.1021 + Parent::erase(nodes);
91.1022 + } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
91.1023 + Parent::clear();
91.1024 + throw;
91.1025 + }
91.1026 + }
91.1027 + virtual void clear() {
91.1028 + _arcset.clearNodes();
91.1029 + Parent::clear();
91.1030 + }
91.1031 +
91.1032 + private:
91.1033 + SmartArcSet& _arcset;
91.1034 + };
91.1035 +
91.1036 + NodesImpl _nodes;
91.1037 +
91.1038 + public:
91.1039 +
91.1040 + /// \brief Constructor of the ArcSet.
91.1041 + ///
91.1042 + /// Constructor of the ArcSet.
91.1043 + SmartArcSet(const GR& graph) : _nodes(graph, *this) {
91.1044 + Parent::initalize(graph, _nodes);
91.1045 + }
91.1046 +
91.1047 + /// \brief Add a new arc to the digraph.
91.1048 + ///
91.1049 + /// Add a new arc to the digraph with source node \c s
91.1050 + /// and target node \c t.
91.1051 + /// \return The new arc.
91.1052 + Arc addArc(const Node& s, const Node& t) {
91.1053 + return Parent::addArc(s, t);
91.1054 + }
91.1055 +
91.1056 + /// \brief Validity check
91.1057 + ///
91.1058 + /// This functions gives back false if the ArcSet is
91.1059 + /// invalidated. It occurs when a node in the underlying graph is
91.1060 + /// erased and it is not isolated in the ArcSet.
91.1061 + bool valid() const {
91.1062 + return _nodes.attached();
91.1063 + }
91.1064 +
91.1065 + };
91.1066 +
91.1067 +
91.1068 + template <typename GR>
91.1069 + class SmartEdgeSetBase {
91.1070 + public:
91.1071 +
91.1072 + typedef typename GR::Node Node;
91.1073 + typedef typename GR::NodeIt NodeIt;
91.1074 +
91.1075 + protected:
91.1076 +
91.1077 + struct NodeT {
91.1078 + int first_out;
91.1079 + NodeT() : first_out(-1) {}
91.1080 + };
91.1081 +
91.1082 + typedef typename ItemSetTraits<GR, Node>::
91.1083 + template Map<NodeT>::Type NodesImplBase;
91.1084 +
91.1085 + NodesImplBase* _nodes;
91.1086 +
91.1087 + struct ArcT {
91.1088 + Node target;
91.1089 + int next_out;
91.1090 + ArcT() {}
91.1091 + };
91.1092 +
91.1093 + std::vector<ArcT> arcs;
91.1094 +
91.1095 + const GR* _graph;
91.1096 +
91.1097 + void initalize(const GR& graph, NodesImplBase& nodes) {
91.1098 + _graph = &graph;
91.1099 + _nodes = &nodes;
91.1100 + }
91.1101 +
91.1102 + public:
91.1103 +
91.1104 + class Edge {
91.1105 + friend class SmartEdgeSetBase;
91.1106 + protected:
91.1107 +
91.1108 + int id;
91.1109 + explicit Edge(int _id) { id = _id;}
91.1110 +
91.1111 + public:
91.1112 + Edge() {}
91.1113 + Edge (Invalid) { id = -1; }
91.1114 + bool operator==(const Edge& arc) const {return id == arc.id;}
91.1115 + bool operator!=(const Edge& arc) const {return id != arc.id;}
91.1116 + bool operator<(const Edge& arc) const {return id < arc.id;}
91.1117 + };
91.1118 +
91.1119 + class Arc {
91.1120 + friend class SmartEdgeSetBase;
91.1121 + protected:
91.1122 + Arc(int _id) : id(_id) {}
91.1123 + int id;
91.1124 + public:
91.1125 + operator Edge() const { return edgeFromId(id / 2); }
91.1126 +
91.1127 + Arc() {}
91.1128 + Arc(Invalid) : id(-1) {}
91.1129 + bool operator==(const Arc& arc) const { return id == arc.id; }
91.1130 + bool operator!=(const Arc& arc) const { return id != arc.id; }
91.1131 + bool operator<(const Arc& arc) const { return id < arc.id; }
91.1132 + };
91.1133 +
91.1134 + SmartEdgeSetBase() {}
91.1135 +
91.1136 + Node addNode() {
91.1137 + LEMON_ASSERT(false,
91.1138 + "This graph structure does not support node insertion");
91.1139 + return INVALID; // avoid warning
91.1140 + }
91.1141 +
91.1142 + Edge addEdge(const Node& u, const Node& v) {
91.1143 + int n = arcs.size();
91.1144 + arcs.push_back(ArcT());
91.1145 + arcs.push_back(ArcT());
91.1146 +
91.1147 + arcs[n].target = u;
91.1148 + arcs[n | 1].target = v;
91.1149 +
91.1150 + arcs[n].next_out = (*_nodes)[v].first_out;
91.1151 + (*_nodes)[v].first_out = n;
91.1152 +
91.1153 + arcs[n | 1].next_out = (*_nodes)[u].first_out;
91.1154 + (*_nodes)[u].first_out = (n | 1);
91.1155 +
91.1156 + return Edge(n / 2);
91.1157 + }
91.1158 +
91.1159 + void clear() {
91.1160 + Node node;
91.1161 + for (first(node); node != INVALID; next(node)) {
91.1162 + (*_nodes)[node].first_out = -1;
91.1163 + }
91.1164 + arcs.clear();
91.1165 + }
91.1166 +
91.1167 + void first(Node& node) const {
91.1168 + _graph->first(node);
91.1169 + }
91.1170 +
91.1171 + void next(Node& node) const {
91.1172 + _graph->next(node);
91.1173 + }
91.1174 +
91.1175 + void first(Arc& arc) const {
91.1176 + arc.id = arcs.size() - 1;
91.1177 + }
91.1178 +
91.1179 + void next(Arc& arc) const {
91.1180 + --arc.id;
91.1181 + }
91.1182 +
91.1183 + void first(Edge& arc) const {
91.1184 + arc.id = arcs.size() / 2 - 1;
91.1185 + }
91.1186 +
91.1187 + void next(Edge& arc) const {
91.1188 + --arc.id;
91.1189 + }
91.1190 +
91.1191 + void firstOut(Arc& arc, const Node& node) const {
91.1192 + arc.id = (*_nodes)[node].first_out;
91.1193 + }
91.1194 +
91.1195 + void nextOut(Arc& arc) const {
91.1196 + arc.id = arcs[arc.id].next_out;
91.1197 + }
91.1198 +
91.1199 + void firstIn(Arc& arc, const Node& node) const {
91.1200 + arc.id = (((*_nodes)[node].first_out) ^ 1);
91.1201 + if (arc.id == -2) arc.id = -1;
91.1202 + }
91.1203 +
91.1204 + void nextIn(Arc& arc) const {
91.1205 + arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
91.1206 + if (arc.id == -2) arc.id = -1;
91.1207 + }
91.1208 +
91.1209 + void firstInc(Edge &arc, bool& dir, const Node& node) const {
91.1210 + int de = (*_nodes)[node].first_out;
91.1211 + if (de != -1 ) {
91.1212 + arc.id = de / 2;
91.1213 + dir = ((de & 1) == 1);
91.1214 + } else {
91.1215 + arc.id = -1;
91.1216 + dir = true;
91.1217 + }
91.1218 + }
91.1219 + void nextInc(Edge &arc, bool& dir) const {
91.1220 + int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
91.1221 + if (de != -1 ) {
91.1222 + arc.id = de / 2;
91.1223 + dir = ((de & 1) == 1);
91.1224 + } else {
91.1225 + arc.id = -1;
91.1226 + dir = true;
91.1227 + }
91.1228 + }
91.1229 +
91.1230 + static bool direction(Arc arc) {
91.1231 + return (arc.id & 1) == 1;
91.1232 + }
91.1233 +
91.1234 + static Arc direct(Edge edge, bool dir) {
91.1235 + return Arc(edge.id * 2 + (dir ? 1 : 0));
91.1236 + }
91.1237 +
91.1238 + int id(Node node) const { return _graph->id(node); }
91.1239 + static int id(Arc arc) { return arc.id; }
91.1240 + static int id(Edge arc) { return arc.id; }
91.1241 +
91.1242 + Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
91.1243 + static Arc arcFromId(int id) { return Arc(id); }
91.1244 + static Edge edgeFromId(int id) { return Edge(id);}
91.1245 +
91.1246 + int maxNodeId() const { return _graph->maxNodeId(); };
91.1247 + int maxArcId() const { return arcs.size() - 1; }
91.1248 + int maxEdgeId() const { return arcs.size() / 2 - 1; }
91.1249 +
91.1250 + Node source(Arc e) const { return arcs[e.id ^ 1].target; }
91.1251 + Node target(Arc e) const { return arcs[e.id].target; }
91.1252 +
91.1253 + Node u(Edge e) const { return arcs[2 * e.id].target; }
91.1254 + Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
91.1255 +
91.1256 + typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
91.1257 +
91.1258 + NodeNotifier& notifier(Node) const {
91.1259 + return _graph->notifier(Node());
91.1260 + }
91.1261 +
91.1262 + template <typename V>
91.1263 + class NodeMap : public GR::template NodeMap<V> {
91.1264 + typedef typename GR::template NodeMap<V> Parent;
91.1265 +
91.1266 + public:
91.1267 +
91.1268 + explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
91.1269 + : Parent(*arcset._graph) { }
91.1270 +
91.1271 + NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& value)
91.1272 + : Parent(*arcset._graph, value) { }
91.1273 +
91.1274 + NodeMap& operator=(const NodeMap& cmap) {
91.1275 + return operator=<NodeMap>(cmap);
91.1276 + }
91.1277 +
91.1278 + template <typename CMap>
91.1279 + NodeMap& operator=(const CMap& cmap) {
91.1280 + Parent::operator=(cmap);
91.1281 + return *this;
91.1282 + }
91.1283 + };
91.1284 +
91.1285 + };
91.1286 +
91.1287 + /// \ingroup graphs
91.1288 + ///
91.1289 + /// \brief Graph using a node set of another digraph or graph and an
91.1290 + /// own edge set.
91.1291 + ///
91.1292 + /// This structure can be used to establish another graph over a
91.1293 + /// node set of an existing one. This class uses the same Node type
91.1294 + /// as the underlying graph, and each valid node of the original
91.1295 + /// graph is valid in this arc set, therefore the node objects of
91.1296 + /// the original graph can be used directly with this class. The
91.1297 + /// node handling functions (id handling, observing, and iterators)
91.1298 + /// works equivalently as in the original graph.
91.1299 + ///
91.1300 + /// \param GR The type of the graph which shares its node set
91.1301 + /// with this class. Its interface must conform to the
91.1302 + /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
91.1303 + /// concept.
91.1304 + ///
91.1305 + /// This implementation is slightly faster than the \c ListEdgeSet,
91.1306 + /// because it uses continuous storage for edges and it uses just
91.1307 + /// single-linked lists for enumerate incident edges. Therefore the
91.1308 + /// edges cannot be erased from the edge sets.
91.1309 + ///
91.1310 + /// \warning If a node is erased from the underlying graph and this
91.1311 + /// node is incident to one edge in the edge set, then the edge set
91.1312 + /// is invalidated, and it cannot be used anymore. The validity can
91.1313 + /// be checked with the \c valid() member function.
91.1314 + ///
91.1315 + /// This class fully conforms to the \ref concepts::Graph
91.1316 + /// "Graph" concept.
91.1317 + template <typename GR>
91.1318 + class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
91.1319 + typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
91.1320 +
91.1321 + public:
91.1322 +
91.1323 + typedef typename Parent::Node Node;
91.1324 + typedef typename Parent::Arc Arc;
91.1325 + typedef typename Parent::Edge Edge;
91.1326 +
91.1327 + protected:
91.1328 +
91.1329 + typedef typename Parent::NodesImplBase NodesImplBase;
91.1330 +
91.1331 + void eraseNode(const Node& node) {
91.1332 + if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
91.1333 + return;
91.1334 + }
91.1335 + throw typename NodesImplBase::Notifier::ImmediateDetach();
91.1336 + }
91.1337 +
91.1338 + void clearNodes() {
91.1339 + Parent::clear();
91.1340 + }
91.1341 +
91.1342 + class NodesImpl : public NodesImplBase {
91.1343 + typedef NodesImplBase Parent;
91.1344 +
91.1345 + public:
91.1346 + NodesImpl(const GR& graph, SmartEdgeSet& arcset)
91.1347 + : Parent(graph), _arcset(arcset) {}
91.1348 +
91.1349 + virtual ~NodesImpl() {}
91.1350 +
91.1351 + bool attached() const {
91.1352 + return Parent::attached();
91.1353 + }
91.1354 +
91.1355 + protected:
91.1356 +
91.1357 + virtual void erase(const Node& node) {
91.1358 + try {
91.1359 + _arcset.eraseNode(node);
91.1360 + Parent::erase(node);
91.1361 + } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
91.1362 + Parent::clear();
91.1363 + throw;
91.1364 + }
91.1365 + }
91.1366 + virtual void erase(const std::vector<Node>& nodes) {
91.1367 + try {
91.1368 + for (int i = 0; i < int(nodes.size()); ++i) {
91.1369 + _arcset.eraseNode(nodes[i]);
91.1370 + }
91.1371 + Parent::erase(nodes);
91.1372 + } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
91.1373 + Parent::clear();
91.1374 + throw;
91.1375 + }
91.1376 + }
91.1377 + virtual void clear() {
91.1378 + _arcset.clearNodes();
91.1379 + Parent::clear();
91.1380 + }
91.1381 +
91.1382 + private:
91.1383 + SmartEdgeSet& _arcset;
91.1384 + };
91.1385 +
91.1386 + NodesImpl _nodes;
91.1387 +
91.1388 + public:
91.1389 +
91.1390 + /// \brief Constructor of the EdgeSet.
91.1391 + ///
91.1392 + /// Constructor of the EdgeSet.
91.1393 + SmartEdgeSet(const GR& graph) : _nodes(graph, *this) {
91.1394 + Parent::initalize(graph, _nodes);
91.1395 + }
91.1396 +
91.1397 + /// \brief Add a new edge to the graph.
91.1398 + ///
91.1399 + /// Add a new edge to the graph with node \c u
91.1400 + /// and node \c v endpoints.
91.1401 + /// \return The new edge.
91.1402 + Edge addEdge(const Node& u, const Node& v) {
91.1403 + return Parent::addEdge(u, v);
91.1404 + }
91.1405 +
91.1406 + /// \brief Validity check
91.1407 + ///
91.1408 + /// This functions gives back false if the EdgeSet is
91.1409 + /// invalidated. It occurs when a node in the underlying graph is
91.1410 + /// erased and it is not isolated in the EdgeSet.
91.1411 + bool valid() const {
91.1412 + return _nodes.attached();
91.1413 + }
91.1414 +
91.1415 + };
91.1416 +
91.1417 +}
91.1418 +
91.1419 +#endif
92.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
92.2 +++ b/lemon/elevator.h Thu Dec 10 17:05:35 2009 +0100
92.3 @@ -0,0 +1,982 @@
92.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
92.5 + *
92.6 + * This file is a part of LEMON, a generic C++ optimization library.
92.7 + *
92.8 + * Copyright (C) 2003-2009
92.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
92.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
92.11 + *
92.12 + * Permission to use, modify and distribute this software is granted
92.13 + * provided that this copyright notice appears in all copies. For
92.14 + * precise terms see the accompanying LICENSE file.
92.15 + *
92.16 + * This software is provided "AS IS" with no warranty of any kind,
92.17 + * express or implied, and with no claim as to its suitability for any
92.18 + * purpose.
92.19 + *
92.20 + */
92.21 +
92.22 +#ifndef LEMON_ELEVATOR_H
92.23 +#define LEMON_ELEVATOR_H
92.24 +
92.25 +///\ingroup auxdat
92.26 +///\file
92.27 +///\brief Elevator class
92.28 +///
92.29 +///Elevator class implements an efficient data structure
92.30 +///for labeling items in push-relabel type algorithms.
92.31 +///
92.32 +
92.33 +#include <lemon/core.h>
92.34 +#include <lemon/bits/traits.h>
92.35 +
92.36 +namespace lemon {
92.37 +
92.38 + ///Class for handling "labels" in push-relabel type algorithms.
92.39 +
92.40 + ///A class for handling "labels" in push-relabel type algorithms.
92.41 + ///
92.42 + ///\ingroup auxdat
92.43 + ///Using this class you can assign "labels" (nonnegative integer numbers)
92.44 + ///to the edges or nodes of a graph, manipulate and query them through
92.45 + ///operations typically arising in "push-relabel" type algorithms.
92.46 + ///
92.47 + ///Each item is either \em active or not, and you can also choose a
92.48 + ///highest level active item.
92.49 + ///
92.50 + ///\sa LinkedElevator
92.51 + ///
92.52 + ///\param GR Type of the underlying graph.
92.53 + ///\param Item Type of the items the data is assigned to (\c GR::Node,
92.54 + ///\c GR::Arc or \c GR::Edge).
92.55 + template<class GR, class Item>
92.56 + class Elevator
92.57 + {
92.58 + public:
92.59 +
92.60 + typedef Item Key;
92.61 + typedef int Value;
92.62 +
92.63 + private:
92.64 +
92.65 + typedef Item *Vit;
92.66 + typedef typename ItemSetTraits<GR,Item>::template Map<Vit>::Type VitMap;
92.67 + typedef typename ItemSetTraits<GR,Item>::template Map<int>::Type IntMap;
92.68 +
92.69 + const GR &_g;
92.70 + int _max_level;
92.71 + int _item_num;
92.72 + VitMap _where;
92.73 + IntMap _level;
92.74 + std::vector<Item> _items;
92.75 + std::vector<Vit> _first;
92.76 + std::vector<Vit> _last_active;
92.77 +
92.78 + int _highest_active;
92.79 +
92.80 + void copy(Item i, Vit p)
92.81 + {
92.82 + _where[*p=i] = p;
92.83 + }
92.84 + void copy(Vit s, Vit p)
92.85 + {
92.86 + if(s!=p)
92.87 + {
92.88 + Item i=*s;
92.89 + *p=i;
92.90 + _where[i] = p;
92.91 + }
92.92 + }
92.93 + void swap(Vit i, Vit j)
92.94 + {
92.95 + Item ti=*i;
92.96 + Vit ct = _where[ti];
92.97 + _where[ti] = _where[*i=*j];
92.98 + _where[*j] = ct;
92.99 + *j=ti;
92.100 + }
92.101 +
92.102 + public:
92.103 +
92.104 + ///Constructor with given maximum level.
92.105 +
92.106 + ///Constructor with given maximum level.
92.107 + ///
92.108 + ///\param graph The underlying graph.
92.109 + ///\param max_level The maximum allowed level.
92.110 + ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
92.111 + Elevator(const GR &graph,int max_level) :
92.112 + _g(graph),
92.113 + _max_level(max_level),
92.114 + _item_num(_max_level),
92.115 + _where(graph),
92.116 + _level(graph,0),
92.117 + _items(_max_level),
92.118 + _first(_max_level+2),
92.119 + _last_active(_max_level+2),
92.120 + _highest_active(-1) {}
92.121 + ///Constructor.
92.122 +
92.123 + ///Constructor.
92.124 + ///
92.125 + ///\param graph The underlying graph.
92.126 + ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
92.127 + ///where \c max_level is equal to the number of labeled items in the graph.
92.128 + Elevator(const GR &graph) :
92.129 + _g(graph),
92.130 + _max_level(countItems<GR, Item>(graph)),
92.131 + _item_num(_max_level),
92.132 + _where(graph),
92.133 + _level(graph,0),
92.134 + _items(_max_level),
92.135 + _first(_max_level+2),
92.136 + _last_active(_max_level+2),
92.137 + _highest_active(-1)
92.138 + {
92.139 + }
92.140 +
92.141 + ///Activate item \c i.
92.142 +
92.143 + ///Activate item \c i.
92.144 + ///\pre Item \c i shouldn't be active before.
92.145 + void activate(Item i)
92.146 + {
92.147 + const int l=_level[i];
92.148 + swap(_where[i],++_last_active[l]);
92.149 + if(l>_highest_active) _highest_active=l;
92.150 + }
92.151 +
92.152 + ///Deactivate item \c i.
92.153 +
92.154 + ///Deactivate item \c i.
92.155 + ///\pre Item \c i must be active before.
92.156 + void deactivate(Item i)
92.157 + {
92.158 + swap(_where[i],_last_active[_level[i]]--);
92.159 + while(_highest_active>=0 &&
92.160 + _last_active[_highest_active]<_first[_highest_active])
92.161 + _highest_active--;
92.162 + }
92.163 +
92.164 + ///Query whether item \c i is active
92.165 + bool active(Item i) const { return _where[i]<=_last_active[_level[i]]; }
92.166 +
92.167 + ///Return the level of item \c i.
92.168 + int operator[](Item i) const { return _level[i]; }
92.169 +
92.170 + ///Return the number of items on level \c l.
92.171 + int onLevel(int l) const
92.172 + {
92.173 + return _first[l+1]-_first[l];
92.174 + }
92.175 + ///Return true if level \c l is empty.
92.176 + bool emptyLevel(int l) const
92.177 + {
92.178 + return _first[l+1]-_first[l]==0;
92.179 + }
92.180 + ///Return the number of items above level \c l.
92.181 + int aboveLevel(int l) const
92.182 + {
92.183 + return _first[_max_level+1]-_first[l+1];
92.184 + }
92.185 + ///Return the number of active items on level \c l.
92.186 + int activesOnLevel(int l) const
92.187 + {
92.188 + return _last_active[l]-_first[l]+1;
92.189 + }
92.190 + ///Return true if there is no active item on level \c l.
92.191 + bool activeFree(int l) const
92.192 + {
92.193 + return _last_active[l]<_first[l];
92.194 + }
92.195 + ///Return the maximum allowed level.
92.196 + int maxLevel() const
92.197 + {
92.198 + return _max_level;
92.199 + }
92.200 +
92.201 + ///\name Highest Active Item
92.202 + ///Functions for working with the highest level
92.203 + ///active item.
92.204 +
92.205 + ///@{
92.206 +
92.207 + ///Return a highest level active item.
92.208 +
92.209 + ///Return a highest level active item or INVALID if there is no active
92.210 + ///item.
92.211 + Item highestActive() const
92.212 + {
92.213 + return _highest_active>=0?*_last_active[_highest_active]:INVALID;
92.214 + }
92.215 +
92.216 + ///Return the highest active level.
92.217 +
92.218 + ///Return the level of the highest active item or -1 if there is no active
92.219 + ///item.
92.220 + int highestActiveLevel() const
92.221 + {
92.222 + return _highest_active;
92.223 + }
92.224 +
92.225 + ///Lift the highest active item by one.
92.226 +
92.227 + ///Lift the item returned by highestActive() by one.
92.228 + ///
92.229 + void liftHighestActive()
92.230 + {
92.231 + Item it = *_last_active[_highest_active];
92.232 + ++_level[it];
92.233 + swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
92.234 + --_first[++_highest_active];
92.235 + }
92.236 +
92.237 + ///Lift the highest active item to the given level.
92.238 +
92.239 + ///Lift the item returned by highestActive() to level \c new_level.
92.240 + ///
92.241 + ///\warning \c new_level must be strictly higher
92.242 + ///than the current level.
92.243 + ///
92.244 + void liftHighestActive(int new_level)
92.245 + {
92.246 + const Item li = *_last_active[_highest_active];
92.247 +
92.248 + copy(--_first[_highest_active+1],_last_active[_highest_active]--);
92.249 + for(int l=_highest_active+1;l<new_level;l++)
92.250 + {
92.251 + copy(--_first[l+1],_first[l]);
92.252 + --_last_active[l];
92.253 + }
92.254 + copy(li,_first[new_level]);
92.255 + _level[li] = new_level;
92.256 + _highest_active=new_level;
92.257 + }
92.258 +
92.259 + ///Lift the highest active item to the top level.
92.260 +
92.261 + ///Lift the item returned by highestActive() to the top level and
92.262 + ///deactivate it.
92.263 + void liftHighestActiveToTop()
92.264 + {
92.265 + const Item li = *_last_active[_highest_active];
92.266 +
92.267 + copy(--_first[_highest_active+1],_last_active[_highest_active]--);
92.268 + for(int l=_highest_active+1;l<_max_level;l++)
92.269 + {
92.270 + copy(--_first[l+1],_first[l]);
92.271 + --_last_active[l];
92.272 + }
92.273 + copy(li,_first[_max_level]);
92.274 + --_last_active[_max_level];
92.275 + _level[li] = _max_level;
92.276 +
92.277 + while(_highest_active>=0 &&
92.278 + _last_active[_highest_active]<_first[_highest_active])
92.279 + _highest_active--;
92.280 + }
92.281 +
92.282 + ///@}
92.283 +
92.284 + ///\name Active Item on Certain Level
92.285 + ///Functions for working with the active items.
92.286 +
92.287 + ///@{
92.288 +
92.289 + ///Return an active item on level \c l.
92.290 +
92.291 + ///Return an active item on level \c l or \ref INVALID if there is no such
92.292 + ///an item. (\c l must be from the range [0...\c max_level].
92.293 + Item activeOn(int l) const
92.294 + {
92.295 + return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
92.296 + }
92.297 +
92.298 + ///Lift the active item returned by \c activeOn(level) by one.
92.299 +
92.300 + ///Lift the active item returned by \ref activeOn() "activeOn(level)"
92.301 + ///by one.
92.302 + Item liftActiveOn(int level)
92.303 + {
92.304 + Item it =*_last_active[level];
92.305 + ++_level[it];
92.306 + swap(_last_active[level]--, --_first[level+1]);
92.307 + if (level+1>_highest_active) ++_highest_active;
92.308 + }
92.309 +
92.310 + ///Lift the active item returned by \c activeOn(level) to the given level.
92.311 +
92.312 + ///Lift the active item returned by \ref activeOn() "activeOn(level)"
92.313 + ///to the given level.
92.314 + void liftActiveOn(int level, int new_level)
92.315 + {
92.316 + const Item ai = *_last_active[level];
92.317 +
92.318 + copy(--_first[level+1], _last_active[level]--);
92.319 + for(int l=level+1;l<new_level;l++)
92.320 + {
92.321 + copy(_last_active[l],_first[l]);
92.322 + copy(--_first[l+1], _last_active[l]--);
92.323 + }
92.324 + copy(ai,_first[new_level]);
92.325 + _level[ai] = new_level;
92.326 + if (new_level>_highest_active) _highest_active=new_level;
92.327 + }
92.328 +
92.329 + ///Lift the active item returned by \c activeOn(level) to the top level.
92.330 +
92.331 + ///Lift the active item returned by \ref activeOn() "activeOn(level)"
92.332 + ///to the top level and deactivate it.
92.333 + void liftActiveToTop(int level)
92.334 + {
92.335 + const Item ai = *_last_active[level];
92.336 +
92.337 + copy(--_first[level+1],_last_active[level]--);
92.338 + for(int l=level+1;l<_max_level;l++)
92.339 + {
92.340 + copy(_last_active[l],_first[l]);
92.341 + copy(--_first[l+1], _last_active[l]--);
92.342 + }
92.343 + copy(ai,_first[_max_level]);
92.344 + --_last_active[_max_level];
92.345 + _level[ai] = _max_level;
92.346 +
92.347 + if (_highest_active==level) {
92.348 + while(_highest_active>=0 &&
92.349 + _last_active[_highest_active]<_first[_highest_active])
92.350 + _highest_active--;
92.351 + }
92.352 + }
92.353 +
92.354 + ///@}
92.355 +
92.356 + ///Lift an active item to a higher level.
92.357 +
92.358 + ///Lift an active item to a higher level.
92.359 + ///\param i The item to be lifted. It must be active.
92.360 + ///\param new_level The new level of \c i. It must be strictly higher
92.361 + ///than the current level.
92.362 + ///
92.363 + void lift(Item i, int new_level)
92.364 + {
92.365 + const int lo = _level[i];
92.366 + const Vit w = _where[i];
92.367 +
92.368 + copy(_last_active[lo],w);
92.369 + copy(--_first[lo+1],_last_active[lo]--);
92.370 + for(int l=lo+1;l<new_level;l++)
92.371 + {
92.372 + copy(_last_active[l],_first[l]);
92.373 + copy(--_first[l+1],_last_active[l]--);
92.374 + }
92.375 + copy(i,_first[new_level]);
92.376 + _level[i] = new_level;
92.377 + if(new_level>_highest_active) _highest_active=new_level;
92.378 + }
92.379 +
92.380 + ///Move an inactive item to the top but one level (in a dirty way).
92.381 +
92.382 + ///This function moves an inactive item from the top level to the top
92.383 + ///but one level (in a dirty way).
92.384 + ///\warning It makes the underlying datastructure corrupt, so use it
92.385 + ///only if you really know what it is for.
92.386 + ///\pre The item is on the top level.
92.387 + void dirtyTopButOne(Item i) {
92.388 + _level[i] = _max_level - 1;
92.389 + }
92.390 +
92.391 + ///Lift all items on and above the given level to the top level.
92.392 +
92.393 + ///This function lifts all items on and above level \c l to the top
92.394 + ///level and deactivates them.
92.395 + void liftToTop(int l)
92.396 + {
92.397 + const Vit f=_first[l];
92.398 + const Vit tl=_first[_max_level];
92.399 + for(Vit i=f;i!=tl;++i)
92.400 + _level[*i] = _max_level;
92.401 + for(int i=l;i<=_max_level;i++)
92.402 + {
92.403 + _first[i]=f;
92.404 + _last_active[i]=f-1;
92.405 + }
92.406 + for(_highest_active=l-1;
92.407 + _highest_active>=0 &&
92.408 + _last_active[_highest_active]<_first[_highest_active];
92.409 + _highest_active--) ;
92.410 + }
92.411 +
92.412 + private:
92.413 + int _init_lev;
92.414 + Vit _init_num;
92.415 +
92.416 + public:
92.417 +
92.418 + ///\name Initialization
92.419 + ///Using these functions you can initialize the levels of the items.
92.420 + ///\n
92.421 + ///The initialization must be started with calling \c initStart().
92.422 + ///Then the items should be listed level by level starting with the
92.423 + ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
92.424 + ///Finally \c initFinish() must be called.
92.425 + ///The items not listed are put on the highest level.
92.426 + ///@{
92.427 +
92.428 + ///Start the initialization process.
92.429 + void initStart()
92.430 + {
92.431 + _init_lev=0;
92.432 + _init_num=&_items[0];
92.433 + _first[0]=&_items[0];
92.434 + _last_active[0]=&_items[0]-1;
92.435 + Vit n=&_items[0];
92.436 + for(typename ItemSetTraits<GR,Item>::ItemIt i(_g);i!=INVALID;++i)
92.437 + {
92.438 + *n=i;
92.439 + _where[i] = n;
92.440 + _level[i] = _max_level;
92.441 + ++n;
92.442 + }
92.443 + }
92.444 +
92.445 + ///Add an item to the current level.
92.446 + void initAddItem(Item i)
92.447 + {
92.448 + swap(_where[i],_init_num);
92.449 + _level[i] = _init_lev;
92.450 + ++_init_num;
92.451 + }
92.452 +
92.453 + ///Start a new level.
92.454 +
92.455 + ///Start a new level.
92.456 + ///It shouldn't be used before the items on level 0 are listed.
92.457 + void initNewLevel()
92.458 + {
92.459 + _init_lev++;
92.460 + _first[_init_lev]=_init_num;
92.461 + _last_active[_init_lev]=_init_num-1;
92.462 + }
92.463 +
92.464 + ///Finalize the initialization process.
92.465 + void initFinish()
92.466 + {
92.467 + for(_init_lev++;_init_lev<=_max_level;_init_lev++)
92.468 + {
92.469 + _first[_init_lev]=_init_num;
92.470 + _last_active[_init_lev]=_init_num-1;
92.471 + }
92.472 + _first[_max_level+1]=&_items[0]+_item_num;
92.473 + _last_active[_max_level+1]=&_items[0]+_item_num-1;
92.474 + _highest_active = -1;
92.475 + }
92.476 +
92.477 + ///@}
92.478 +
92.479 + };
92.480 +
92.481 + ///Class for handling "labels" in push-relabel type algorithms.
92.482 +
92.483 + ///A class for handling "labels" in push-relabel type algorithms.
92.484 + ///
92.485 + ///\ingroup auxdat
92.486 + ///Using this class you can assign "labels" (nonnegative integer numbers)
92.487 + ///to the edges or nodes of a graph, manipulate and query them through
92.488 + ///operations typically arising in "push-relabel" type algorithms.
92.489 + ///
92.490 + ///Each item is either \em active or not, and you can also choose a
92.491 + ///highest level active item.
92.492 + ///
92.493 + ///\sa Elevator
92.494 + ///
92.495 + ///\param GR Type of the underlying graph.
92.496 + ///\param Item Type of the items the data is assigned to (\c GR::Node,
92.497 + ///\c GR::Arc or \c GR::Edge).
92.498 + template <class GR, class Item>
92.499 + class LinkedElevator {
92.500 + public:
92.501 +
92.502 + typedef Item Key;
92.503 + typedef int Value;
92.504 +
92.505 + private:
92.506 +
92.507 + typedef typename ItemSetTraits<GR,Item>::
92.508 + template Map<Item>::Type ItemMap;
92.509 + typedef typename ItemSetTraits<GR,Item>::
92.510 + template Map<int>::Type IntMap;
92.511 + typedef typename ItemSetTraits<GR,Item>::
92.512 + template Map<bool>::Type BoolMap;
92.513 +
92.514 + const GR &_graph;
92.515 + int _max_level;
92.516 + int _item_num;
92.517 + std::vector<Item> _first, _last;
92.518 + ItemMap _prev, _next;
92.519 + int _highest_active;
92.520 + IntMap _level;
92.521 + BoolMap _active;
92.522 +
92.523 + public:
92.524 + ///Constructor with given maximum level.
92.525 +
92.526 + ///Constructor with given maximum level.
92.527 + ///
92.528 + ///\param graph The underlying graph.
92.529 + ///\param max_level The maximum allowed level.
92.530 + ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
92.531 + LinkedElevator(const GR& graph, int max_level)
92.532 + : _graph(graph), _max_level(max_level), _item_num(_max_level),
92.533 + _first(_max_level + 1), _last(_max_level + 1),
92.534 + _prev(graph), _next(graph),
92.535 + _highest_active(-1), _level(graph), _active(graph) {}
92.536 +
92.537 + ///Constructor.
92.538 +
92.539 + ///Constructor.
92.540 + ///
92.541 + ///\param graph The underlying graph.
92.542 + ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
92.543 + ///where \c max_level is equal to the number of labeled items in the graph.
92.544 + LinkedElevator(const GR& graph)
92.545 + : _graph(graph), _max_level(countItems<GR, Item>(graph)),
92.546 + _item_num(_max_level),
92.547 + _first(_max_level + 1), _last(_max_level + 1),
92.548 + _prev(graph, INVALID), _next(graph, INVALID),
92.549 + _highest_active(-1), _level(graph), _active(graph) {}
92.550 +
92.551 +
92.552 + ///Activate item \c i.
92.553 +
92.554 + ///Activate item \c i.
92.555 + ///\pre Item \c i shouldn't be active before.
92.556 + void activate(Item i) {
92.557 + _active[i] = true;
92.558 +
92.559 + int level = _level[i];
92.560 + if (level > _highest_active) {
92.561 + _highest_active = level;
92.562 + }
92.563 +
92.564 + if (_prev[i] == INVALID || _active[_prev[i]]) return;
92.565 + //unlace
92.566 + _next[_prev[i]] = _next[i];
92.567 + if (_next[i] != INVALID) {
92.568 + _prev[_next[i]] = _prev[i];
92.569 + } else {
92.570 + _last[level] = _prev[i];
92.571 + }
92.572 + //lace
92.573 + _next[i] = _first[level];
92.574 + _prev[_first[level]] = i;
92.575 + _prev[i] = INVALID;
92.576 + _first[level] = i;
92.577 +
92.578 + }
92.579 +
92.580 + ///Deactivate item \c i.
92.581 +
92.582 + ///Deactivate item \c i.
92.583 + ///\pre Item \c i must be active before.
92.584 + void deactivate(Item i) {
92.585 + _active[i] = false;
92.586 + int level = _level[i];
92.587 +
92.588 + if (_next[i] == INVALID || !_active[_next[i]])
92.589 + goto find_highest_level;
92.590 +
92.591 + //unlace
92.592 + _prev[_next[i]] = _prev[i];
92.593 + if (_prev[i] != INVALID) {
92.594 + _next[_prev[i]] = _next[i];
92.595 + } else {
92.596 + _first[_level[i]] = _next[i];
92.597 + }
92.598 + //lace
92.599 + _prev[i] = _last[level];
92.600 + _next[_last[level]] = i;
92.601 + _next[i] = INVALID;
92.602 + _last[level] = i;
92.603 +
92.604 + find_highest_level:
92.605 + if (level == _highest_active) {
92.606 + while (_highest_active >= 0 && activeFree(_highest_active))
92.607 + --_highest_active;
92.608 + }
92.609 + }
92.610 +
92.611 + ///Query whether item \c i is active
92.612 + bool active(Item i) const { return _active[i]; }
92.613 +
92.614 + ///Return the level of item \c i.
92.615 + int operator[](Item i) const { return _level[i]; }
92.616 +
92.617 + ///Return the number of items on level \c l.
92.618 + int onLevel(int l) const {
92.619 + int num = 0;
92.620 + Item n = _first[l];
92.621 + while (n != INVALID) {
92.622 + ++num;
92.623 + n = _next[n];
92.624 + }
92.625 + return num;
92.626 + }
92.627 +
92.628 + ///Return true if the level is empty.
92.629 + bool emptyLevel(int l) const {
92.630 + return _first[l] == INVALID;
92.631 + }
92.632 +
92.633 + ///Return the number of items above level \c l.
92.634 + int aboveLevel(int l) const {
92.635 + int num = 0;
92.636 + for (int level = l + 1; level < _max_level; ++level)
92.637 + num += onLevel(level);
92.638 + return num;
92.639 + }
92.640 +
92.641 + ///Return the number of active items on level \c l.
92.642 + int activesOnLevel(int l) const {
92.643 + int num = 0;
92.644 + Item n = _first[l];
92.645 + while (n != INVALID && _active[n]) {
92.646 + ++num;
92.647 + n = _next[n];
92.648 + }
92.649 + return num;
92.650 + }
92.651 +
92.652 + ///Return true if there is no active item on level \c l.
92.653 + bool activeFree(int l) const {
92.654 + return _first[l] == INVALID || !_active[_first[l]];
92.655 + }
92.656 +
92.657 + ///Return the maximum allowed level.
92.658 + int maxLevel() const {
92.659 + return _max_level;
92.660 + }
92.661 +
92.662 + ///\name Highest Active Item
92.663 + ///Functions for working with the highest level
92.664 + ///active item.
92.665 +
92.666 + ///@{
92.667 +
92.668 + ///Return a highest level active item.
92.669 +
92.670 + ///Return a highest level active item or INVALID if there is no active
92.671 + ///item.
92.672 + Item highestActive() const {
92.673 + return _highest_active >= 0 ? _first[_highest_active] : INVALID;
92.674 + }
92.675 +
92.676 + ///Return the highest active level.
92.677 +
92.678 + ///Return the level of the highest active item or -1 if there is no active
92.679 + ///item.
92.680 + int highestActiveLevel() const {
92.681 + return _highest_active;
92.682 + }
92.683 +
92.684 + ///Lift the highest active item by one.
92.685 +
92.686 + ///Lift the item returned by highestActive() by one.
92.687 + ///
92.688 + void liftHighestActive() {
92.689 + Item i = _first[_highest_active];
92.690 + if (_next[i] != INVALID) {
92.691 + _prev[_next[i]] = INVALID;
92.692 + _first[_highest_active] = _next[i];
92.693 + } else {
92.694 + _first[_highest_active] = INVALID;
92.695 + _last[_highest_active] = INVALID;
92.696 + }
92.697 + _level[i] = ++_highest_active;
92.698 + if (_first[_highest_active] == INVALID) {
92.699 + _first[_highest_active] = i;
92.700 + _last[_highest_active] = i;
92.701 + _prev[i] = INVALID;
92.702 + _next[i] = INVALID;
92.703 + } else {
92.704 + _prev[_first[_highest_active]] = i;
92.705 + _next[i] = _first[_highest_active];
92.706 + _first[_highest_active] = i;
92.707 + }
92.708 + }
92.709 +
92.710 + ///Lift the highest active item to the given level.
92.711 +
92.712 + ///Lift the item returned by highestActive() to level \c new_level.
92.713 + ///
92.714 + ///\warning \c new_level must be strictly higher
92.715 + ///than the current level.
92.716 + ///
92.717 + void liftHighestActive(int new_level) {
92.718 + Item i = _first[_highest_active];
92.719 + if (_next[i] != INVALID) {
92.720 + _prev[_next[i]] = INVALID;
92.721 + _first[_highest_active] = _next[i];
92.722 + } else {
92.723 + _first[_highest_active] = INVALID;
92.724 + _last[_highest_active] = INVALID;
92.725 + }
92.726 + _level[i] = _highest_active = new_level;
92.727 + if (_first[_highest_active] == INVALID) {
92.728 + _first[_highest_active] = _last[_highest_active] = i;
92.729 + _prev[i] = INVALID;
92.730 + _next[i] = INVALID;
92.731 + } else {
92.732 + _prev[_first[_highest_active]] = i;
92.733 + _next[i] = _first[_highest_active];
92.734 + _first[_highest_active] = i;
92.735 + }
92.736 + }
92.737 +
92.738 + ///Lift the highest active item to the top level.
92.739 +
92.740 + ///Lift the item returned by highestActive() to the top level and
92.741 + ///deactivate it.
92.742 + void liftHighestActiveToTop() {
92.743 + Item i = _first[_highest_active];
92.744 + _level[i] = _max_level;
92.745 + if (_next[i] != INVALID) {
92.746 + _prev[_next[i]] = INVALID;
92.747 + _first[_highest_active] = _next[i];
92.748 + } else {
92.749 + _first[_highest_active] = INVALID;
92.750 + _last[_highest_active] = INVALID;
92.751 + }
92.752 + while (_highest_active >= 0 && activeFree(_highest_active))
92.753 + --_highest_active;
92.754 + }
92.755 +
92.756 + ///@}
92.757 +
92.758 + ///\name Active Item on Certain Level
92.759 + ///Functions for working with the active items.
92.760 +
92.761 + ///@{
92.762 +
92.763 + ///Return an active item on level \c l.
92.764 +
92.765 + ///Return an active item on level \c l or \ref INVALID if there is no such
92.766 + ///an item. (\c l must be from the range [0...\c max_level].
92.767 + Item activeOn(int l) const
92.768 + {
92.769 + return _active[_first[l]] ? _first[l] : INVALID;
92.770 + }
92.771 +
92.772 + ///Lift the active item returned by \c activeOn(l) by one.
92.773 +
92.774 + ///Lift the active item returned by \ref activeOn() "activeOn(l)"
92.775 + ///by one.
92.776 + Item liftActiveOn(int l)
92.777 + {
92.778 + Item i = _first[l];
92.779 + if (_next[i] != INVALID) {
92.780 + _prev[_next[i]] = INVALID;
92.781 + _first[l] = _next[i];
92.782 + } else {
92.783 + _first[l] = INVALID;
92.784 + _last[l] = INVALID;
92.785 + }
92.786 + _level[i] = ++l;
92.787 + if (_first[l] == INVALID) {
92.788 + _first[l] = _last[l] = i;
92.789 + _prev[i] = INVALID;
92.790 + _next[i] = INVALID;
92.791 + } else {
92.792 + _prev[_first[l]] = i;
92.793 + _next[i] = _first[l];
92.794 + _first[l] = i;
92.795 + }
92.796 + if (_highest_active < l) {
92.797 + _highest_active = l;
92.798 + }
92.799 + }
92.800 +
92.801 + ///Lift the active item returned by \c activeOn(l) to the given level.
92.802 +
92.803 + ///Lift the active item returned by \ref activeOn() "activeOn(l)"
92.804 + ///to the given level.
92.805 + void liftActiveOn(int l, int new_level)
92.806 + {
92.807 + Item i = _first[l];
92.808 + if (_next[i] != INVALID) {
92.809 + _prev[_next[i]] = INVALID;
92.810 + _first[l] = _next[i];
92.811 + } else {
92.812 + _first[l] = INVALID;
92.813 + _last[l] = INVALID;
92.814 + }
92.815 + _level[i] = l = new_level;
92.816 + if (_first[l] == INVALID) {
92.817 + _first[l] = _last[l] = i;
92.818 + _prev[i] = INVALID;
92.819 + _next[i] = INVALID;
92.820 + } else {
92.821 + _prev[_first[l]] = i;
92.822 + _next[i] = _first[l];
92.823 + _first[l] = i;
92.824 + }
92.825 + if (_highest_active < l) {
92.826 + _highest_active = l;
92.827 + }
92.828 + }
92.829 +
92.830 + ///Lift the active item returned by \c activeOn(l) to the top level.
92.831 +
92.832 + ///Lift the active item returned by \ref activeOn() "activeOn(l)"
92.833 + ///to the top level and deactivate it.
92.834 + void liftActiveToTop(int l)
92.835 + {
92.836 + Item i = _first[l];
92.837 + if (_next[i] != INVALID) {
92.838 + _prev[_next[i]] = INVALID;
92.839 + _first[l] = _next[i];
92.840 + } else {
92.841 + _first[l] = INVALID;
92.842 + _last[l] = INVALID;
92.843 + }
92.844 + _level[i] = _max_level;
92.845 + if (l == _highest_active) {
92.846 + while (_highest_active >= 0 && activeFree(_highest_active))
92.847 + --_highest_active;
92.848 + }
92.849 + }
92.850 +
92.851 + ///@}
92.852 +
92.853 + /// \brief Lift an active item to a higher level.
92.854 + ///
92.855 + /// Lift an active item to a higher level.
92.856 + /// \param i The item to be lifted. It must be active.
92.857 + /// \param new_level The new level of \c i. It must be strictly higher
92.858 + /// than the current level.
92.859 + ///
92.860 + void lift(Item i, int new_level) {
92.861 + if (_next[i] != INVALID) {
92.862 + _prev[_next[i]] = _prev[i];
92.863 + } else {
92.864 + _last[new_level] = _prev[i];
92.865 + }
92.866 + if (_prev[i] != INVALID) {
92.867 + _next[_prev[i]] = _next[i];
92.868 + } else {
92.869 + _first[new_level] = _next[i];
92.870 + }
92.871 + _level[i] = new_level;
92.872 + if (_first[new_level] == INVALID) {
92.873 + _first[new_level] = _last[new_level] = i;
92.874 + _prev[i] = INVALID;
92.875 + _next[i] = INVALID;
92.876 + } else {
92.877 + _prev[_first[new_level]] = i;
92.878 + _next[i] = _first[new_level];
92.879 + _first[new_level] = i;
92.880 + }
92.881 + if (_highest_active < new_level) {
92.882 + _highest_active = new_level;
92.883 + }
92.884 + }
92.885 +
92.886 + ///Move an inactive item to the top but one level (in a dirty way).
92.887 +
92.888 + ///This function moves an inactive item from the top level to the top
92.889 + ///but one level (in a dirty way).
92.890 + ///\warning It makes the underlying datastructure corrupt, so use it
92.891 + ///only if you really know what it is for.
92.892 + ///\pre The item is on the top level.
92.893 + void dirtyTopButOne(Item i) {
92.894 + _level[i] = _max_level - 1;
92.895 + }
92.896 +
92.897 + ///Lift all items on and above the given level to the top level.
92.898 +
92.899 + ///This function lifts all items on and above level \c l to the top
92.900 + ///level and deactivates them.
92.901 + void liftToTop(int l) {
92.902 + for (int i = l + 1; _first[i] != INVALID; ++i) {
92.903 + Item n = _first[i];
92.904 + while (n != INVALID) {
92.905 + _level[n] = _max_level;
92.906 + n = _next[n];
92.907 + }
92.908 + _first[i] = INVALID;
92.909 + _last[i] = INVALID;
92.910 + }
92.911 + if (_highest_active > l - 1) {
92.912 + _highest_active = l - 1;
92.913 + while (_highest_active >= 0 && activeFree(_highest_active))
92.914 + --_highest_active;
92.915 + }
92.916 + }
92.917 +
92.918 + private:
92.919 +
92.920 + int _init_level;
92.921 +
92.922 + public:
92.923 +
92.924 + ///\name Initialization
92.925 + ///Using these functions you can initialize the levels of the items.
92.926 + ///\n
92.927 + ///The initialization must be started with calling \c initStart().
92.928 + ///Then the items should be listed level by level starting with the
92.929 + ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
92.930 + ///Finally \c initFinish() must be called.
92.931 + ///The items not listed are put on the highest level.
92.932 + ///@{
92.933 +
92.934 + ///Start the initialization process.
92.935 + void initStart() {
92.936 +
92.937 + for (int i = 0; i <= _max_level; ++i) {
92.938 + _first[i] = _last[i] = INVALID;
92.939 + }
92.940 + _init_level = 0;
92.941 + for(typename ItemSetTraits<GR,Item>::ItemIt i(_graph);
92.942 + i != INVALID; ++i) {
92.943 + _level[i] = _max_level;
92.944 + _active[i] = false;
92.945 + }
92.946 + }
92.947 +
92.948 + ///Add an item to the current level.
92.949 + void initAddItem(Item i) {
92.950 + _level[i] = _init_level;
92.951 + if (_last[_init_level] == INVALID) {
92.952 + _first[_init_level] = i;
92.953 + _last[_init_level] = i;
92.954 + _prev[i] = INVALID;
92.955 + _next[i] = INVALID;
92.956 + } else {
92.957 + _prev[i] = _last[_init_level];
92.958 + _next[i] = INVALID;
92.959 + _next[_last[_init_level]] = i;
92.960 + _last[_init_level] = i;
92.961 + }
92.962 + }
92.963 +
92.964 + ///Start a new level.
92.965 +
92.966 + ///Start a new level.
92.967 + ///It shouldn't be used before the items on level 0 are listed.
92.968 + void initNewLevel() {
92.969 + ++_init_level;
92.970 + }
92.971 +
92.972 + ///Finalize the initialization process.
92.973 + void initFinish() {
92.974 + _highest_active = -1;
92.975 + }
92.976 +
92.977 + ///@}
92.978 +
92.979 + };
92.980 +
92.981 +
92.982 +} //END OF NAMESPACE LEMON
92.983 +
92.984 +#endif
92.985 +
93.1 --- a/lemon/error.h Fri Nov 13 12:33:33 2009 +0100
93.2 +++ b/lemon/error.h Thu Dec 10 17:05:35 2009 +0100
93.3 @@ -2,7 +2,7 @@
93.4 *
93.5 * This file is a part of LEMON, a generic C++ optimization library.
93.6 *
93.7 - * Copyright (C) 2003-2008
93.8 + * Copyright (C) 2003-2009
93.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
93.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
93.11 *
94.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
94.2 +++ b/lemon/euler.h Thu Dec 10 17:05:35 2009 +0100
94.3 @@ -0,0 +1,287 @@
94.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
94.5 + *
94.6 + * This file is a part of LEMON, a generic C++ optimization library.
94.7 + *
94.8 + * Copyright (C) 2003-2009
94.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
94.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
94.11 + *
94.12 + * Permission to use, modify and distribute this software is granted
94.13 + * provided that this copyright notice appears in all copies. For
94.14 + * precise terms see the accompanying LICENSE file.
94.15 + *
94.16 + * This software is provided "AS IS" with no warranty of any kind,
94.17 + * express or implied, and with no claim as to its suitability for any
94.18 + * purpose.
94.19 + *
94.20 + */
94.21 +
94.22 +#ifndef LEMON_EULER_H
94.23 +#define LEMON_EULER_H
94.24 +
94.25 +#include<lemon/core.h>
94.26 +#include<lemon/adaptors.h>
94.27 +#include<lemon/connectivity.h>
94.28 +#include <list>
94.29 +
94.30 +/// \ingroup graph_properties
94.31 +/// \file
94.32 +/// \brief Euler tour iterators and a function for checking the \e Eulerian
94.33 +/// property.
94.34 +///
94.35 +///This file provides Euler tour iterators and a function to check
94.36 +///if a (di)graph is \e Eulerian.
94.37 +
94.38 +namespace lemon {
94.39 +
94.40 + ///Euler tour iterator for digraphs.
94.41 +
94.42 + /// \ingroup graph_prop
94.43 + ///This iterator provides an Euler tour (Eulerian circuit) of a \e directed
94.44 + ///graph (if there exists) and it converts to the \c Arc type of the digraph.
94.45 + ///
94.46 + ///For example, if the given digraph has an Euler tour (i.e it has only one
94.47 + ///non-trivial component and the in-degree is equal to the out-degree
94.48 + ///for all nodes), then the following code will put the arcs of \c g
94.49 + ///to the vector \c et according to an Euler tour of \c g.
94.50 + ///\code
94.51 + /// std::vector<ListDigraph::Arc> et;
94.52 + /// for(DiEulerIt<ListDigraph> e(g); e!=INVALID; ++e)
94.53 + /// et.push_back(e);
94.54 + ///\endcode
94.55 + ///If \c g has no Euler tour, then the resulted walk will not be closed
94.56 + ///or not contain all arcs.
94.57 + ///\sa EulerIt
94.58 + template<typename GR>
94.59 + class DiEulerIt
94.60 + {
94.61 + typedef typename GR::Node Node;
94.62 + typedef typename GR::NodeIt NodeIt;
94.63 + typedef typename GR::Arc Arc;
94.64 + typedef typename GR::ArcIt ArcIt;
94.65 + typedef typename GR::OutArcIt OutArcIt;
94.66 + typedef typename GR::InArcIt InArcIt;
94.67 +
94.68 + const GR &g;
94.69 + typename GR::template NodeMap<OutArcIt> narc;
94.70 + std::list<Arc> euler;
94.71 +
94.72 + public:
94.73 +
94.74 + ///Constructor
94.75 +
94.76 + ///Constructor.
94.77 + ///\param gr A digraph.
94.78 + ///\param start The starting point of the tour. If it is not given,
94.79 + ///the tour will start from the first node that has an outgoing arc.
94.80 + DiEulerIt(const GR &gr, typename GR::Node start = INVALID)
94.81 + : g(gr), narc(g)
94.82 + {
94.83 + if (start==INVALID) {
94.84 + NodeIt n(g);
94.85 + while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
94.86 + start=n;
94.87 + }
94.88 + if (start!=INVALID) {
94.89 + for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
94.90 + while (narc[start]!=INVALID) {
94.91 + euler.push_back(narc[start]);
94.92 + Node next=g.target(narc[start]);
94.93 + ++narc[start];
94.94 + start=next;
94.95 + }
94.96 + }
94.97 + }
94.98 +
94.99 + ///Arc conversion
94.100 + operator Arc() { return euler.empty()?INVALID:euler.front(); }
94.101 + ///Compare with \c INVALID
94.102 + bool operator==(Invalid) { return euler.empty(); }
94.103 + ///Compare with \c INVALID
94.104 + bool operator!=(Invalid) { return !euler.empty(); }
94.105 +
94.106 + ///Next arc of the tour
94.107 +
94.108 + ///Next arc of the tour
94.109 + ///
94.110 + DiEulerIt &operator++() {
94.111 + Node s=g.target(euler.front());
94.112 + euler.pop_front();
94.113 + typename std::list<Arc>::iterator next=euler.begin();
94.114 + while(narc[s]!=INVALID) {
94.115 + euler.insert(next,narc[s]);
94.116 + Node n=g.target(narc[s]);
94.117 + ++narc[s];
94.118 + s=n;
94.119 + }
94.120 + return *this;
94.121 + }
94.122 + ///Postfix incrementation
94.123 +
94.124 + /// Postfix incrementation.
94.125 + ///
94.126 + ///\warning This incrementation
94.127 + ///returns an \c Arc, not a \ref DiEulerIt, as one may
94.128 + ///expect.
94.129 + Arc operator++(int)
94.130 + {
94.131 + Arc e=*this;
94.132 + ++(*this);
94.133 + return e;
94.134 + }
94.135 + };
94.136 +
94.137 + ///Euler tour iterator for graphs.
94.138 +
94.139 + /// \ingroup graph_properties
94.140 + ///This iterator provides an Euler tour (Eulerian circuit) of an
94.141 + ///\e undirected graph (if there exists) and it converts to the \c Arc
94.142 + ///and \c Edge types of the graph.
94.143 + ///
94.144 + ///For example, if the given graph has an Euler tour (i.e it has only one
94.145 + ///non-trivial component and the degree of each node is even),
94.146 + ///the following code will print the arc IDs according to an
94.147 + ///Euler tour of \c g.
94.148 + ///\code
94.149 + /// for(EulerIt<ListGraph> e(g); e!=INVALID; ++e) {
94.150 + /// std::cout << g.id(Edge(e)) << std::eol;
94.151 + /// }
94.152 + ///\endcode
94.153 + ///Although this iterator is for undirected graphs, it still returns
94.154 + ///arcs in order to indicate the direction of the tour.
94.155 + ///(But arcs convert to edges, of course.)
94.156 + ///
94.157 + ///If \c g has no Euler tour, then the resulted walk will not be closed
94.158 + ///or not contain all edges.
94.159 + template<typename GR>
94.160 + class EulerIt
94.161 + {
94.162 + typedef typename GR::Node Node;
94.163 + typedef typename GR::NodeIt NodeIt;
94.164 + typedef typename GR::Arc Arc;
94.165 + typedef typename GR::Edge Edge;
94.166 + typedef typename GR::ArcIt ArcIt;
94.167 + typedef typename GR::OutArcIt OutArcIt;
94.168 + typedef typename GR::InArcIt InArcIt;
94.169 +
94.170 + const GR &g;
94.171 + typename GR::template NodeMap<OutArcIt> narc;
94.172 + typename GR::template EdgeMap<bool> visited;
94.173 + std::list<Arc> euler;
94.174 +
94.175 + public:
94.176 +
94.177 + ///Constructor
94.178 +
94.179 + ///Constructor.
94.180 + ///\param gr A graph.
94.181 + ///\param start The starting point of the tour. If it is not given,
94.182 + ///the tour will start from the first node that has an incident edge.
94.183 + EulerIt(const GR &gr, typename GR::Node start = INVALID)
94.184 + : g(gr), narc(g), visited(g, false)
94.185 + {
94.186 + if (start==INVALID) {
94.187 + NodeIt n(g);
94.188 + while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
94.189 + start=n;
94.190 + }
94.191 + if (start!=INVALID) {
94.192 + for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
94.193 + while(narc[start]!=INVALID) {
94.194 + euler.push_back(narc[start]);
94.195 + visited[narc[start]]=true;
94.196 + Node next=g.target(narc[start]);
94.197 + ++narc[start];
94.198 + start=next;
94.199 + while(narc[start]!=INVALID && visited[narc[start]]) ++narc[start];
94.200 + }
94.201 + }
94.202 + }
94.203 +
94.204 + ///Arc conversion
94.205 + operator Arc() const { return euler.empty()?INVALID:euler.front(); }
94.206 + ///Edge conversion
94.207 + operator Edge() const { return euler.empty()?INVALID:euler.front(); }
94.208 + ///Compare with \c INVALID
94.209 + bool operator==(Invalid) const { return euler.empty(); }
94.210 + ///Compare with \c INVALID
94.211 + bool operator!=(Invalid) const { return !euler.empty(); }
94.212 +
94.213 + ///Next arc of the tour
94.214 +
94.215 + ///Next arc of the tour
94.216 + ///
94.217 + EulerIt &operator++() {
94.218 + Node s=g.target(euler.front());
94.219 + euler.pop_front();
94.220 + typename std::list<Arc>::iterator next=euler.begin();
94.221 + while(narc[s]!=INVALID) {
94.222 + while(narc[s]!=INVALID && visited[narc[s]]) ++narc[s];
94.223 + if(narc[s]==INVALID) break;
94.224 + else {
94.225 + euler.insert(next,narc[s]);
94.226 + visited[narc[s]]=true;
94.227 + Node n=g.target(narc[s]);
94.228 + ++narc[s];
94.229 + s=n;
94.230 + }
94.231 + }
94.232 + return *this;
94.233 + }
94.234 +
94.235 + ///Postfix incrementation
94.236 +
94.237 + /// Postfix incrementation.
94.238 + ///
94.239 + ///\warning This incrementation returns an \c Arc (which converts to
94.240 + ///an \c Edge), not an \ref EulerIt, as one may expect.
94.241 + Arc operator++(int)
94.242 + {
94.243 + Arc e=*this;
94.244 + ++(*this);
94.245 + return e;
94.246 + }
94.247 + };
94.248 +
94.249 +
94.250 + ///Check if the given graph is Eulerian
94.251 +
94.252 + /// \ingroup graph_properties
94.253 + ///This function checks if the given graph is Eulerian.
94.254 + ///It works for both directed and undirected graphs.
94.255 + ///
94.256 + ///By definition, a digraph is called \e Eulerian if
94.257 + ///and only if it is connected and the number of incoming and outgoing
94.258 + ///arcs are the same for each node.
94.259 + ///Similarly, an undirected graph is called \e Eulerian if
94.260 + ///and only if it is connected and the number of incident edges is even
94.261 + ///for each node.
94.262 + ///
94.263 + ///\note There are (di)graphs that are not Eulerian, but still have an
94.264 + /// Euler tour, since they may contain isolated nodes.
94.265 + ///
94.266 + ///\sa DiEulerIt, EulerIt
94.267 + template<typename GR>
94.268 +#ifdef DOXYGEN
94.269 + bool
94.270 +#else
94.271 + typename enable_if<UndirectedTagIndicator<GR>,bool>::type
94.272 + eulerian(const GR &g)
94.273 + {
94.274 + for(typename GR::NodeIt n(g);n!=INVALID;++n)
94.275 + if(countIncEdges(g,n)%2) return false;
94.276 + return connected(g);
94.277 + }
94.278 + template<class GR>
94.279 + typename disable_if<UndirectedTagIndicator<GR>,bool>::type
94.280 +#endif
94.281 + eulerian(const GR &g)
94.282 + {
94.283 + for(typename GR::NodeIt n(g);n!=INVALID;++n)
94.284 + if(countInArcs(g,n)!=countOutArcs(g,n)) return false;
94.285 + return connected(undirector(g));
94.286 + }
94.287 +
94.288 +}
94.289 +
94.290 +#endif
95.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
95.2 +++ b/lemon/fib_heap.h Thu Dec 10 17:05:35 2009 +0100
95.3 @@ -0,0 +1,468 @@
95.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
95.5 + *
95.6 + * This file is a part of LEMON, a generic C++ optimization library.
95.7 + *
95.8 + * Copyright (C) 2003-2009
95.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
95.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
95.11 + *
95.12 + * Permission to use, modify and distribute this software is granted
95.13 + * provided that this copyright notice appears in all copies. For
95.14 + * precise terms see the accompanying LICENSE file.
95.15 + *
95.16 + * This software is provided "AS IS" with no warranty of any kind,
95.17 + * express or implied, and with no claim as to its suitability for any
95.18 + * purpose.
95.19 + *
95.20 + */
95.21 +
95.22 +#ifndef LEMON_FIB_HEAP_H
95.23 +#define LEMON_FIB_HEAP_H
95.24 +
95.25 +///\file
95.26 +///\ingroup auxdat
95.27 +///\brief Fibonacci Heap implementation.
95.28 +
95.29 +#include <vector>
95.30 +#include <functional>
95.31 +#include <lemon/math.h>
95.32 +
95.33 +namespace lemon {
95.34 +
95.35 + /// \ingroup auxdat
95.36 + ///
95.37 + ///\brief Fibonacci Heap.
95.38 + ///
95.39 + ///This class implements the \e Fibonacci \e heap data structure. A \e heap
95.40 + ///is a data structure for storing items with specified values called \e
95.41 + ///priorities in such a way that finding the item with minimum priority is
95.42 + ///efficient. \c CMP specifies the ordering of the priorities. In a heap
95.43 + ///one can change the priority of an item, add or erase an item, etc.
95.44 + ///
95.45 + ///The methods \ref increase and \ref erase are not efficient in a Fibonacci
95.46 + ///heap. In case of many calls to these operations, it is better to use a
95.47 + ///\ref BinHeap "binary heap".
95.48 + ///
95.49 + ///\param PRIO Type of the priority of the items.
95.50 + ///\param IM A read and writable Item int map, used internally
95.51 + ///to handle the cross references.
95.52 + ///\param CMP A class for the ordering of the priorities. The
95.53 + ///default is \c std::less<PRIO>.
95.54 + ///
95.55 + ///\sa BinHeap
95.56 + ///\sa Dijkstra
95.57 +#ifdef DOXYGEN
95.58 + template <typename PRIO, typename IM, typename CMP>
95.59 +#else
95.60 + template <typename PRIO, typename IM, typename CMP = std::less<PRIO> >
95.61 +#endif
95.62 + class FibHeap {
95.63 + public:
95.64 + ///\e
95.65 + typedef IM ItemIntMap;
95.66 + ///\e
95.67 + typedef PRIO Prio;
95.68 + ///\e
95.69 + typedef typename ItemIntMap::Key Item;
95.70 + ///\e
95.71 + typedef std::pair<Item,Prio> Pair;
95.72 + ///\e
95.73 + typedef CMP Compare;
95.74 +
95.75 + private:
95.76 + class Store;
95.77 +
95.78 + std::vector<Store> _data;
95.79 + int _minimum;
95.80 + ItemIntMap &_iim;
95.81 + Compare _comp;
95.82 + int _num;
95.83 +
95.84 + public:
95.85 +
95.86 + /// \brief Type to represent the items states.
95.87 + ///
95.88 + /// Each Item element have a state associated to it. It may be "in heap",
95.89 + /// "pre heap" or "post heap". The latter two are indifferent from the
95.90 + /// heap's point of view, but may be useful to the user.
95.91 + ///
95.92 + /// The item-int map must be initialized in such way that it assigns
95.93 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
95.94 + enum State {
95.95 + IN_HEAP = 0, ///< = 0.
95.96 + PRE_HEAP = -1, ///< = -1.
95.97 + POST_HEAP = -2 ///< = -2.
95.98 + };
95.99 +
95.100 + /// \brief The constructor
95.101 + ///
95.102 + /// \c map should be given to the constructor, since it is
95.103 + /// used internally to handle the cross references.
95.104 + explicit FibHeap(ItemIntMap &map)
95.105 + : _minimum(0), _iim(map), _num() {}
95.106 +
95.107 + /// \brief The constructor
95.108 + ///
95.109 + /// \c map should be given to the constructor, since it is used
95.110 + /// internally to handle the cross references. \c comp is an
95.111 + /// object for ordering of the priorities.
95.112 + FibHeap(ItemIntMap &map, const Compare &comp)
95.113 + : _minimum(0), _iim(map), _comp(comp), _num() {}
95.114 +
95.115 + /// \brief The number of items stored in the heap.
95.116 + ///
95.117 + /// Returns the number of items stored in the heap.
95.118 + int size() const { return _num; }
95.119 +
95.120 + /// \brief Checks if the heap stores no items.
95.121 + ///
95.122 + /// Returns \c true if and only if the heap stores no items.
95.123 + bool empty() const { return _num==0; }
95.124 +
95.125 + /// \brief Make empty this heap.
95.126 + ///
95.127 + /// Make empty this heap. It does not change the cross reference
95.128 + /// map. If you want to reuse a heap what is not surely empty you
95.129 + /// should first clear the heap and after that you should set the
95.130 + /// cross reference map for each item to \c PRE_HEAP.
95.131 + void clear() {
95.132 + _data.clear(); _minimum = 0; _num = 0;
95.133 + }
95.134 +
95.135 + /// \brief \c item gets to the heap with priority \c value independently
95.136 + /// if \c item was already there.
95.137 + ///
95.138 + /// This method calls \ref push(\c item, \c value) if \c item is not
95.139 + /// stored in the heap and it calls \ref decrease(\c item, \c value) or
95.140 + /// \ref increase(\c item, \c value) otherwise.
95.141 + void set (const Item& item, const Prio& value) {
95.142 + int i=_iim[item];
95.143 + if ( i >= 0 && _data[i].in ) {
95.144 + if ( _comp(value, _data[i].prio) ) decrease(item, value);
95.145 + if ( _comp(_data[i].prio, value) ) increase(item, value);
95.146 + } else push(item, value);
95.147 + }
95.148 +
95.149 + /// \brief Adds \c item to the heap with priority \c value.
95.150 + ///
95.151 + /// Adds \c item to the heap with priority \c value.
95.152 + /// \pre \c item must not be stored in the heap.
95.153 + void push (const Item& item, const Prio& value) {
95.154 + int i=_iim[item];
95.155 + if ( i < 0 ) {
95.156 + int s=_data.size();
95.157 + _iim.set( item, s );
95.158 + Store st;
95.159 + st.name=item;
95.160 + _data.push_back(st);
95.161 + i=s;
95.162 + } else {
95.163 + _data[i].parent=_data[i].child=-1;
95.164 + _data[i].degree=0;
95.165 + _data[i].in=true;
95.166 + _data[i].marked=false;
95.167 + }
95.168 +
95.169 + if ( _num ) {
95.170 + _data[_data[_minimum].right_neighbor].left_neighbor=i;
95.171 + _data[i].right_neighbor=_data[_minimum].right_neighbor;
95.172 + _data[_minimum].right_neighbor=i;
95.173 + _data[i].left_neighbor=_minimum;
95.174 + if ( _comp( value, _data[_minimum].prio) ) _minimum=i;
95.175 + } else {
95.176 + _data[i].right_neighbor=_data[i].left_neighbor=i;
95.177 + _minimum=i;
95.178 + }
95.179 + _data[i].prio=value;
95.180 + ++_num;
95.181 + }
95.182 +
95.183 + /// \brief Returns the item with minimum priority relative to \c Compare.
95.184 + ///
95.185 + /// This method returns the item with minimum priority relative to \c
95.186 + /// Compare.
95.187 + /// \pre The heap must be nonempty.
95.188 + Item top() const { return _data[_minimum].name; }
95.189 +
95.190 + /// \brief Returns the minimum priority relative to \c Compare.
95.191 + ///
95.192 + /// It returns the minimum priority relative to \c Compare.
95.193 + /// \pre The heap must be nonempty.
95.194 + const Prio& prio() const { return _data[_minimum].prio; }
95.195 +
95.196 + /// \brief Returns the priority of \c item.
95.197 + ///
95.198 + /// It returns the priority of \c item.
95.199 + /// \pre \c item must be in the heap.
95.200 + const Prio& operator[](const Item& item) const {
95.201 + return _data[_iim[item]].prio;
95.202 + }
95.203 +
95.204 + /// \brief Deletes the item with minimum priority relative to \c Compare.
95.205 + ///
95.206 + /// This method deletes the item with minimum priority relative to \c
95.207 + /// Compare from the heap.
95.208 + /// \pre The heap must be non-empty.
95.209 + void pop() {
95.210 + /*The first case is that there are only one root.*/
95.211 + if ( _data[_minimum].left_neighbor==_minimum ) {
95.212 + _data[_minimum].in=false;
95.213 + if ( _data[_minimum].degree!=0 ) {
95.214 + makeroot(_data[_minimum].child);
95.215 + _minimum=_data[_minimum].child;
95.216 + balance();
95.217 + }
95.218 + } else {
95.219 + int right=_data[_minimum].right_neighbor;
95.220 + unlace(_minimum);
95.221 + _data[_minimum].in=false;
95.222 + if ( _data[_minimum].degree > 0 ) {
95.223 + int left=_data[_minimum].left_neighbor;
95.224 + int child=_data[_minimum].child;
95.225 + int last_child=_data[child].left_neighbor;
95.226 +
95.227 + makeroot(child);
95.228 +
95.229 + _data[left].right_neighbor=child;
95.230 + _data[child].left_neighbor=left;
95.231 + _data[right].left_neighbor=last_child;
95.232 + _data[last_child].right_neighbor=right;
95.233 + }
95.234 + _minimum=right;
95.235 + balance();
95.236 + } // the case where there are more roots
95.237 + --_num;
95.238 + }
95.239 +
95.240 + /// \brief Deletes \c item from the heap.
95.241 + ///
95.242 + /// This method deletes \c item from the heap, if \c item was already
95.243 + /// stored in the heap. It is quite inefficient in Fibonacci heaps.
95.244 + void erase (const Item& item) {
95.245 + int i=_iim[item];
95.246 +
95.247 + if ( i >= 0 && _data[i].in ) {
95.248 + if ( _data[i].parent!=-1 ) {
95.249 + int p=_data[i].parent;
95.250 + cut(i,p);
95.251 + cascade(p);
95.252 + }
95.253 + _minimum=i; //As if its prio would be -infinity
95.254 + pop();
95.255 + }
95.256 + }
95.257 +
95.258 + /// \brief Decreases the priority of \c item to \c value.
95.259 + ///
95.260 + /// This method decreases the priority of \c item to \c value.
95.261 + /// \pre \c item must be stored in the heap with priority at least \c
95.262 + /// value relative to \c Compare.
95.263 + void decrease (Item item, const Prio& value) {
95.264 + int i=_iim[item];
95.265 + _data[i].prio=value;
95.266 + int p=_data[i].parent;
95.267 +
95.268 + if ( p!=-1 && _comp(value, _data[p].prio) ) {
95.269 + cut(i,p);
95.270 + cascade(p);
95.271 + }
95.272 + if ( _comp(value, _data[_minimum].prio) ) _minimum=i;
95.273 + }
95.274 +
95.275 + /// \brief Increases the priority of \c item to \c value.
95.276 + ///
95.277 + /// This method sets the priority of \c item to \c value. Though
95.278 + /// there is no precondition on the priority of \c item, this
95.279 + /// method should be used only if it is indeed necessary to increase
95.280 + /// (relative to \c Compare) the priority of \c item, because this
95.281 + /// method is inefficient.
95.282 + void increase (Item item, const Prio& value) {
95.283 + erase(item);
95.284 + push(item, value);
95.285 + }
95.286 +
95.287 +
95.288 + /// \brief Returns if \c item is in, has already been in, or has never
95.289 + /// been in the heap.
95.290 + ///
95.291 + /// This method returns PRE_HEAP if \c item has never been in the
95.292 + /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
95.293 + /// otherwise. In the latter case it is possible that \c item will
95.294 + /// get back to the heap again.
95.295 + State state(const Item &item) const {
95.296 + int i=_iim[item];
95.297 + if( i>=0 ) {
95.298 + if ( _data[i].in ) i=0;
95.299 + else i=-2;
95.300 + }
95.301 + return State(i);
95.302 + }
95.303 +
95.304 + /// \brief Sets the state of the \c item in the heap.
95.305 + ///
95.306 + /// Sets the state of the \c item in the heap. It can be used to
95.307 + /// manually clear the heap when it is important to achive the
95.308 + /// better time _complexity.
95.309 + /// \param i The item.
95.310 + /// \param st The state. It should not be \c IN_HEAP.
95.311 + void state(const Item& i, State st) {
95.312 + switch (st) {
95.313 + case POST_HEAP:
95.314 + case PRE_HEAP:
95.315 + if (state(i) == IN_HEAP) {
95.316 + erase(i);
95.317 + }
95.318 + _iim[i] = st;
95.319 + break;
95.320 + case IN_HEAP:
95.321 + break;
95.322 + }
95.323 + }
95.324 +
95.325 + private:
95.326 +
95.327 + void balance() {
95.328 +
95.329 + int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;
95.330 +
95.331 + std::vector<int> A(maxdeg,-1);
95.332 +
95.333 + /*
95.334 + *Recall that now minimum does not point to the minimum prio element.
95.335 + *We set minimum to this during balance().
95.336 + */
95.337 + int anchor=_data[_minimum].left_neighbor;
95.338 + int next=_minimum;
95.339 + bool end=false;
95.340 +
95.341 + do {
95.342 + int active=next;
95.343 + if ( anchor==active ) end=true;
95.344 + int d=_data[active].degree;
95.345 + next=_data[active].right_neighbor;
95.346 +
95.347 + while (A[d]!=-1) {
95.348 + if( _comp(_data[active].prio, _data[A[d]].prio) ) {
95.349 + fuse(active,A[d]);
95.350 + } else {
95.351 + fuse(A[d],active);
95.352 + active=A[d];
95.353 + }
95.354 + A[d]=-1;
95.355 + ++d;
95.356 + }
95.357 + A[d]=active;
95.358 + } while ( !end );
95.359 +
95.360 +
95.361 + while ( _data[_minimum].parent >=0 )
95.362 + _minimum=_data[_minimum].parent;
95.363 + int s=_minimum;
95.364 + int m=_minimum;
95.365 + do {
95.366 + if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
95.367 + s=_data[s].right_neighbor;
95.368 + } while ( s != m );
95.369 + }
95.370 +
95.371 + void makeroot(int c) {
95.372 + int s=c;
95.373 + do {
95.374 + _data[s].parent=-1;
95.375 + s=_data[s].right_neighbor;
95.376 + } while ( s != c );
95.377 + }
95.378 +
95.379 + void cut(int a, int b) {
95.380 + /*
95.381 + *Replacing a from the children of b.
95.382 + */
95.383 + --_data[b].degree;
95.384 +
95.385 + if ( _data[b].degree !=0 ) {
95.386 + int child=_data[b].child;
95.387 + if ( child==a )
95.388 + _data[b].child=_data[child].right_neighbor;
95.389 + unlace(a);
95.390 + }
95.391 +
95.392 +
95.393 + /*Lacing a to the roots.*/
95.394 + int right=_data[_minimum].right_neighbor;
95.395 + _data[_minimum].right_neighbor=a;
95.396 + _data[a].left_neighbor=_minimum;
95.397 + _data[a].right_neighbor=right;
95.398 + _data[right].left_neighbor=a;
95.399 +
95.400 + _data[a].parent=-1;
95.401 + _data[a].marked=false;
95.402 + }
95.403 +
95.404 + void cascade(int a) {
95.405 + if ( _data[a].parent!=-1 ) {
95.406 + int p=_data[a].parent;
95.407 +
95.408 + if ( _data[a].marked==false ) _data[a].marked=true;
95.409 + else {
95.410 + cut(a,p);
95.411 + cascade(p);
95.412 + }
95.413 + }
95.414 + }
95.415 +
95.416 + void fuse(int a, int b) {
95.417 + unlace(b);
95.418 +
95.419 + /*Lacing b under a.*/
95.420 + _data[b].parent=a;
95.421 +
95.422 + if (_data[a].degree==0) {
95.423 + _data[b].left_neighbor=b;
95.424 + _data[b].right_neighbor=b;
95.425 + _data[a].child=b;
95.426 + } else {
95.427 + int child=_data[a].child;
95.428 + int last_child=_data[child].left_neighbor;
95.429 + _data[child].left_neighbor=b;
95.430 + _data[b].right_neighbor=child;
95.431 + _data[last_child].right_neighbor=b;
95.432 + _data[b].left_neighbor=last_child;
95.433 + }
95.434 +
95.435 + ++_data[a].degree;
95.436 +
95.437 + _data[b].marked=false;
95.438 + }
95.439 +
95.440 + /*
95.441 + *It is invoked only if a has siblings.
95.442 + */
95.443 + void unlace(int a) {
95.444 + int leftn=_data[a].left_neighbor;
95.445 + int rightn=_data[a].right_neighbor;
95.446 + _data[leftn].right_neighbor=rightn;
95.447 + _data[rightn].left_neighbor=leftn;
95.448 + }
95.449 +
95.450 +
95.451 + class Store {
95.452 + friend class FibHeap;
95.453 +
95.454 + Item name;
95.455 + int parent;
95.456 + int left_neighbor;
95.457 + int right_neighbor;
95.458 + int child;
95.459 + int degree;
95.460 + bool marked;
95.461 + bool in;
95.462 + Prio prio;
95.463 +
95.464 + Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
95.465 + };
95.466 + };
95.467 +
95.468 +} //namespace lemon
95.469 +
95.470 +#endif //LEMON_FIB_HEAP_H
95.471 +
96.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
96.2 +++ b/lemon/full_graph.h Thu Dec 10 17:05:35 2009 +0100
96.3 @@ -0,0 +1,612 @@
96.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
96.5 + *
96.6 + * This file is a part of LEMON, a generic C++ optimization library.
96.7 + *
96.8 + * Copyright (C) 2003-2009
96.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
96.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
96.11 + *
96.12 + * Permission to use, modify and distribute this software is granted
96.13 + * provided that this copyright notice appears in all copies. For
96.14 + * precise terms see the accompanying LICENSE file.
96.15 + *
96.16 + * This software is provided "AS IS" with no warranty of any kind,
96.17 + * express or implied, and with no claim as to its suitability for any
96.18 + * purpose.
96.19 + *
96.20 + */
96.21 +
96.22 +#ifndef LEMON_FULL_GRAPH_H
96.23 +#define LEMON_FULL_GRAPH_H
96.24 +
96.25 +#include <lemon/core.h>
96.26 +#include <lemon/bits/graph_extender.h>
96.27 +
96.28 +///\ingroup graphs
96.29 +///\file
96.30 +///\brief FullGraph and FullDigraph classes.
96.31 +
96.32 +namespace lemon {
96.33 +
96.34 + class FullDigraphBase {
96.35 + public:
96.36 +
96.37 + typedef FullDigraphBase Digraph;
96.38 +
96.39 + class Node;
96.40 + class Arc;
96.41 +
96.42 + protected:
96.43 +
96.44 + int _node_num;
96.45 + int _arc_num;
96.46 +
96.47 + FullDigraphBase() {}
96.48 +
96.49 + void construct(int n) { _node_num = n; _arc_num = n * n; }
96.50 +
96.51 + public:
96.52 +
96.53 + typedef True NodeNumTag;
96.54 + typedef True ArcNumTag;
96.55 +
96.56 + Node operator()(int ix) const { return Node(ix); }
96.57 + int index(const Node& node) const { return node._id; }
96.58 +
96.59 + Arc arc(const Node& s, const Node& t) const {
96.60 + return Arc(s._id * _node_num + t._id);
96.61 + }
96.62 +
96.63 + int nodeNum() const { return _node_num; }
96.64 + int arcNum() const { return _arc_num; }
96.65 +
96.66 + int maxNodeId() const { return _node_num - 1; }
96.67 + int maxArcId() const { return _arc_num - 1; }
96.68 +
96.69 + Node source(Arc arc) const { return arc._id / _node_num; }
96.70 + Node target(Arc arc) const { return arc._id % _node_num; }
96.71 +
96.72 + static int id(Node node) { return node._id; }
96.73 + static int id(Arc arc) { return arc._id; }
96.74 +
96.75 + static Node nodeFromId(int id) { return Node(id);}
96.76 + static Arc arcFromId(int id) { return Arc(id);}
96.77 +
96.78 + typedef True FindArcTag;
96.79 +
96.80 + Arc findArc(Node s, Node t, Arc prev = INVALID) const {
96.81 + return prev == INVALID ? arc(s, t) : INVALID;
96.82 + }
96.83 +
96.84 + class Node {
96.85 + friend class FullDigraphBase;
96.86 +
96.87 + protected:
96.88 + int _id;
96.89 + Node(int id) : _id(id) {}
96.90 + public:
96.91 + Node() {}
96.92 + Node (Invalid) : _id(-1) {}
96.93 + bool operator==(const Node node) const {return _id == node._id;}
96.94 + bool operator!=(const Node node) const {return _id != node._id;}
96.95 + bool operator<(const Node node) const {return _id < node._id;}
96.96 + };
96.97 +
96.98 + class Arc {
96.99 + friend class FullDigraphBase;
96.100 +
96.101 + protected:
96.102 + int _id; // _node_num * source + target;
96.103 +
96.104 + Arc(int id) : _id(id) {}
96.105 +
96.106 + public:
96.107 + Arc() { }
96.108 + Arc (Invalid) { _id = -1; }
96.109 + bool operator==(const Arc arc) const {return _id == arc._id;}
96.110 + bool operator!=(const Arc arc) const {return _id != arc._id;}
96.111 + bool operator<(const Arc arc) const {return _id < arc._id;}
96.112 + };
96.113 +
96.114 + void first(Node& node) const {
96.115 + node._id = _node_num - 1;
96.116 + }
96.117 +
96.118 + static void next(Node& node) {
96.119 + --node._id;
96.120 + }
96.121 +
96.122 + void first(Arc& arc) const {
96.123 + arc._id = _arc_num - 1;
96.124 + }
96.125 +
96.126 + static void next(Arc& arc) {
96.127 + --arc._id;
96.128 + }
96.129 +
96.130 + void firstOut(Arc& arc, const Node& node) const {
96.131 + arc._id = (node._id + 1) * _node_num - 1;
96.132 + }
96.133 +
96.134 + void nextOut(Arc& arc) const {
96.135 + if (arc._id % _node_num == 0) arc._id = 0;
96.136 + --arc._id;
96.137 + }
96.138 +
96.139 + void firstIn(Arc& arc, const Node& node) const {
96.140 + arc._id = _arc_num + node._id - _node_num;
96.141 + }
96.142 +
96.143 + void nextIn(Arc& arc) const {
96.144 + arc._id -= _node_num;
96.145 + if (arc._id < 0) arc._id = -1;
96.146 + }
96.147 +
96.148 + };
96.149 +
96.150 + typedef DigraphExtender<FullDigraphBase> ExtendedFullDigraphBase;
96.151 +
96.152 + /// \ingroup graphs
96.153 + ///
96.154 + /// \brief A full digraph class.
96.155 + ///
96.156 + /// This is a simple and fast directed full graph implementation.
96.157 + /// From each node go arcs to each node (including the source node),
96.158 + /// therefore the number of the arcs in the digraph is the square of
96.159 + /// the node number. This digraph type is completely static, so you
96.160 + /// can neither add nor delete either arcs or nodes, and it needs
96.161 + /// constant space in memory.
96.162 + ///
96.163 + /// This class fully conforms to the \ref concepts::Digraph
96.164 + /// "Digraph concept".
96.165 + ///
96.166 + /// The \c FullDigraph and \c FullGraph classes are very similar,
96.167 + /// but there are two differences. While this class conforms only
96.168 + /// to the \ref concepts::Digraph "Digraph" concept, the \c FullGraph
96.169 + /// class conforms to the \ref concepts::Graph "Graph" concept,
96.170 + /// moreover \c FullGraph does not contain a loop arc for each
96.171 + /// node as \c FullDigraph does.
96.172 + ///
96.173 + /// \sa FullGraph
96.174 + class FullDigraph : public ExtendedFullDigraphBase {
96.175 + typedef ExtendedFullDigraphBase Parent;
96.176 +
96.177 + public:
96.178 +
96.179 + /// \brief Constructor
96.180 + FullDigraph() { construct(0); }
96.181 +
96.182 + /// \brief Constructor
96.183 + ///
96.184 + /// Constructor.
96.185 + /// \param n The number of the nodes.
96.186 + FullDigraph(int n) { construct(n); }
96.187 +
96.188 + /// \brief Resizes the digraph
96.189 + ///
96.190 + /// Resizes the digraph. The function will fully destroy and
96.191 + /// rebuild the digraph. This cause that the maps of the digraph will
96.192 + /// reallocated automatically and the previous values will be lost.
96.193 + void resize(int n) {
96.194 + Parent::notifier(Arc()).clear();
96.195 + Parent::notifier(Node()).clear();
96.196 + construct(n);
96.197 + Parent::notifier(Node()).build();
96.198 + Parent::notifier(Arc()).build();
96.199 + }
96.200 +
96.201 + /// \brief Returns the node with the given index.
96.202 + ///
96.203 + /// Returns the node with the given index. Since it is a static
96.204 + /// digraph its nodes can be indexed with integers from the range
96.205 + /// <tt>[0..nodeNum()-1]</tt>.
96.206 + /// \sa index()
96.207 + Node operator()(int ix) const { return Parent::operator()(ix); }
96.208 +
96.209 + /// \brief Returns the index of the given node.
96.210 + ///
96.211 + /// Returns the index of the given node. Since it is a static
96.212 + /// digraph its nodes can be indexed with integers from the range
96.213 + /// <tt>[0..nodeNum()-1]</tt>.
96.214 + /// \sa operator()
96.215 + int index(const Node& node) const { return Parent::index(node); }
96.216 +
96.217 + /// \brief Returns the arc connecting the given nodes.
96.218 + ///
96.219 + /// Returns the arc connecting the given nodes.
96.220 + Arc arc(const Node& u, const Node& v) const {
96.221 + return Parent::arc(u, v);
96.222 + }
96.223 +
96.224 + /// \brief Number of nodes.
96.225 + int nodeNum() const { return Parent::nodeNum(); }
96.226 + /// \brief Number of arcs.
96.227 + int arcNum() const { return Parent::arcNum(); }
96.228 + };
96.229 +
96.230 +
96.231 + class FullGraphBase {
96.232 + public:
96.233 +
96.234 + typedef FullGraphBase Graph;
96.235 +
96.236 + class Node;
96.237 + class Arc;
96.238 + class Edge;
96.239 +
96.240 + protected:
96.241 +
96.242 + int _node_num;
96.243 + int _edge_num;
96.244 +
96.245 + FullGraphBase() {}
96.246 +
96.247 + void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; }
96.248 +
96.249 + int _uid(int e) const {
96.250 + int u = e / _node_num;
96.251 + int v = e % _node_num;
96.252 + return u < v ? u : _node_num - 2 - u;
96.253 + }
96.254 +
96.255 + int _vid(int e) const {
96.256 + int u = e / _node_num;
96.257 + int v = e % _node_num;
96.258 + return u < v ? v : _node_num - 1 - v;
96.259 + }
96.260 +
96.261 + void _uvid(int e, int& u, int& v) const {
96.262 + u = e / _node_num;
96.263 + v = e % _node_num;
96.264 + if (u >= v) {
96.265 + u = _node_num - 2 - u;
96.266 + v = _node_num - 1 - v;
96.267 + }
96.268 + }
96.269 +
96.270 + void _stid(int a, int& s, int& t) const {
96.271 + if ((a & 1) == 1) {
96.272 + _uvid(a >> 1, s, t);
96.273 + } else {
96.274 + _uvid(a >> 1, t, s);
96.275 + }
96.276 + }
96.277 +
96.278 + int _eid(int u, int v) const {
96.279 + if (u < (_node_num - 1) / 2) {
96.280 + return u * _node_num + v;
96.281 + } else {
96.282 + return (_node_num - 1 - u) * _node_num - v - 1;
96.283 + }
96.284 + }
96.285 +
96.286 + public:
96.287 +
96.288 + Node operator()(int ix) const { return Node(ix); }
96.289 + int index(const Node& node) const { return node._id; }
96.290 +
96.291 + Edge edge(const Node& u, const Node& v) const {
96.292 + if (u._id < v._id) {
96.293 + return Edge(_eid(u._id, v._id));
96.294 + } else if (u._id != v._id) {
96.295 + return Edge(_eid(v._id, u._id));
96.296 + } else {
96.297 + return INVALID;
96.298 + }
96.299 + }
96.300 +
96.301 + Arc arc(const Node& s, const Node& t) const {
96.302 + if (s._id < t._id) {
96.303 + return Arc((_eid(s._id, t._id) << 1) | 1);
96.304 + } else if (s._id != t._id) {
96.305 + return Arc(_eid(t._id, s._id) << 1);
96.306 + } else {
96.307 + return INVALID;
96.308 + }
96.309 + }
96.310 +
96.311 + typedef True NodeNumTag;
96.312 + typedef True ArcNumTag;
96.313 + typedef True EdgeNumTag;
96.314 +
96.315 + int nodeNum() const { return _node_num; }
96.316 + int arcNum() const { return 2 * _edge_num; }
96.317 + int edgeNum() const { return _edge_num; }
96.318 +
96.319 + static int id(Node node) { return node._id; }
96.320 + static int id(Arc arc) { return arc._id; }
96.321 + static int id(Edge edge) { return edge._id; }
96.322 +
96.323 + int maxNodeId() const { return _node_num-1; }
96.324 + int maxArcId() const { return 2 * _edge_num-1; }
96.325 + int maxEdgeId() const { return _edge_num-1; }
96.326 +
96.327 + static Node nodeFromId(int id) { return Node(id);}
96.328 + static Arc arcFromId(int id) { return Arc(id);}
96.329 + static Edge edgeFromId(int id) { return Edge(id);}
96.330 +
96.331 + Node u(Edge edge) const {
96.332 + return Node(_uid(edge._id));
96.333 + }
96.334 +
96.335 + Node v(Edge edge) const {
96.336 + return Node(_vid(edge._id));
96.337 + }
96.338 +
96.339 + Node source(Arc arc) const {
96.340 + return Node((arc._id & 1) == 1 ?
96.341 + _uid(arc._id >> 1) : _vid(arc._id >> 1));
96.342 + }
96.343 +
96.344 + Node target(Arc arc) const {
96.345 + return Node((arc._id & 1) == 1 ?
96.346 + _vid(arc._id >> 1) : _uid(arc._id >> 1));
96.347 + }
96.348 +
96.349 + typedef True FindEdgeTag;
96.350 + typedef True FindArcTag;
96.351 +
96.352 + Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
96.353 + return prev != INVALID ? INVALID : edge(u, v);
96.354 + }
96.355 +
96.356 + Arc findArc(Node s, Node t, Arc prev = INVALID) const {
96.357 + return prev != INVALID ? INVALID : arc(s, t);
96.358 + }
96.359 +
96.360 + class Node {
96.361 + friend class FullGraphBase;
96.362 +
96.363 + protected:
96.364 + int _id;
96.365 + Node(int id) : _id(id) {}
96.366 + public:
96.367 + Node() {}
96.368 + Node (Invalid) { _id = -1; }
96.369 + bool operator==(const Node node) const {return _id == node._id;}
96.370 + bool operator!=(const Node node) const {return _id != node._id;}
96.371 + bool operator<(const Node node) const {return _id < node._id;}
96.372 + };
96.373 +
96.374 + class Edge {
96.375 + friend class FullGraphBase;
96.376 + friend class Arc;
96.377 +
96.378 + protected:
96.379 + int _id;
96.380 +
96.381 + Edge(int id) : _id(id) {}
96.382 +
96.383 + public:
96.384 + Edge() { }
96.385 + Edge (Invalid) { _id = -1; }
96.386 +
96.387 + bool operator==(const Edge edge) const {return _id == edge._id;}
96.388 + bool operator!=(const Edge edge) const {return _id != edge._id;}
96.389 + bool operator<(const Edge edge) const {return _id < edge._id;}
96.390 + };
96.391 +
96.392 + class Arc {
96.393 + friend class FullGraphBase;
96.394 +
96.395 + protected:
96.396 + int _id;
96.397 +
96.398 + Arc(int id) : _id(id) {}
96.399 +
96.400 + public:
96.401 + Arc() { }
96.402 + Arc (Invalid) { _id = -1; }
96.403 +
96.404 + operator Edge() const { return Edge(_id != -1 ? (_id >> 1) : -1); }
96.405 +
96.406 + bool operator==(const Arc arc) const {return _id == arc._id;}
96.407 + bool operator!=(const Arc arc) const {return _id != arc._id;}
96.408 + bool operator<(const Arc arc) const {return _id < arc._id;}
96.409 + };
96.410 +
96.411 + static bool direction(Arc arc) {
96.412 + return (arc._id & 1) == 1;
96.413 + }
96.414 +
96.415 + static Arc direct(Edge edge, bool dir) {
96.416 + return Arc((edge._id << 1) | (dir ? 1 : 0));
96.417 + }
96.418 +
96.419 + void first(Node& node) const {
96.420 + node._id = _node_num - 1;
96.421 + }
96.422 +
96.423 + static void next(Node& node) {
96.424 + --node._id;
96.425 + }
96.426 +
96.427 + void first(Arc& arc) const {
96.428 + arc._id = (_edge_num << 1) - 1;
96.429 + }
96.430 +
96.431 + static void next(Arc& arc) {
96.432 + --arc._id;
96.433 + }
96.434 +
96.435 + void first(Edge& edge) const {
96.436 + edge._id = _edge_num - 1;
96.437 + }
96.438 +
96.439 + static void next(Edge& edge) {
96.440 + --edge._id;
96.441 + }
96.442 +
96.443 + void firstOut(Arc& arc, const Node& node) const {
96.444 + int s = node._id, t = _node_num - 1;
96.445 + if (s < t) {
96.446 + arc._id = (_eid(s, t) << 1) | 1;
96.447 + } else {
96.448 + --t;
96.449 + arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
96.450 + }
96.451 + }
96.452 +
96.453 + void nextOut(Arc& arc) const {
96.454 + int s, t;
96.455 + _stid(arc._id, s, t);
96.456 + --t;
96.457 + if (s < t) {
96.458 + arc._id = (_eid(s, t) << 1) | 1;
96.459 + } else {
96.460 + if (s == t) --t;
96.461 + arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
96.462 + }
96.463 + }
96.464 +
96.465 + void firstIn(Arc& arc, const Node& node) const {
96.466 + int s = _node_num - 1, t = node._id;
96.467 + if (s > t) {
96.468 + arc._id = (_eid(t, s) << 1);
96.469 + } else {
96.470 + --s;
96.471 + arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
96.472 + }
96.473 + }
96.474 +
96.475 + void nextIn(Arc& arc) const {
96.476 + int s, t;
96.477 + _stid(arc._id, s, t);
96.478 + --s;
96.479 + if (s > t) {
96.480 + arc._id = (_eid(t, s) << 1);
96.481 + } else {
96.482 + if (s == t) --s;
96.483 + arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
96.484 + }
96.485 + }
96.486 +
96.487 + void firstInc(Edge& edge, bool& dir, const Node& node) const {
96.488 + int u = node._id, v = _node_num - 1;
96.489 + if (u < v) {
96.490 + edge._id = _eid(u, v);
96.491 + dir = true;
96.492 + } else {
96.493 + --v;
96.494 + edge._id = (v != -1 ? _eid(v, u) : -1);
96.495 + dir = false;
96.496 + }
96.497 + }
96.498 +
96.499 + void nextInc(Edge& edge, bool& dir) const {
96.500 + int u, v;
96.501 + if (dir) {
96.502 + _uvid(edge._id, u, v);
96.503 + --v;
96.504 + if (u < v) {
96.505 + edge._id = _eid(u, v);
96.506 + } else {
96.507 + --v;
96.508 + edge._id = (v != -1 ? _eid(v, u) : -1);
96.509 + dir = false;
96.510 + }
96.511 + } else {
96.512 + _uvid(edge._id, v, u);
96.513 + --v;
96.514 + edge._id = (v != -1 ? _eid(v, u) : -1);
96.515 + }
96.516 + }
96.517 +
96.518 + };
96.519 +
96.520 + typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
96.521 +
96.522 + /// \ingroup graphs
96.523 + ///
96.524 + /// \brief An undirected full graph class.
96.525 + ///
96.526 + /// This is a simple and fast undirected full graph
96.527 + /// implementation. From each node go edge to each other node,
96.528 + /// therefore the number of edges in the graph is \f$n(n-1)/2\f$.
96.529 + /// This graph type is completely static, so you can neither
96.530 + /// add nor delete either edges or nodes, and it needs constant
96.531 + /// space in memory.
96.532 + ///
96.533 + /// This class fully conforms to the \ref concepts::Graph "Graph concept".
96.534 + ///
96.535 + /// The \c FullGraph and \c FullDigraph classes are very similar,
96.536 + /// but there are two differences. While the \c FullDigraph class
96.537 + /// conforms only to the \ref concepts::Digraph "Digraph" concept,
96.538 + /// this class conforms to the \ref concepts::Graph "Graph" concept,
96.539 + /// moreover \c FullGraph does not contain a loop arc for each
96.540 + /// node as \c FullDigraph does.
96.541 + ///
96.542 + /// \sa FullDigraph
96.543 + class FullGraph : public ExtendedFullGraphBase {
96.544 + typedef ExtendedFullGraphBase Parent;
96.545 +
96.546 + public:
96.547 +
96.548 + /// \brief Constructor
96.549 + FullGraph() { construct(0); }
96.550 +
96.551 + /// \brief Constructor
96.552 + ///
96.553 + /// Constructor.
96.554 + /// \param n The number of the nodes.
96.555 + FullGraph(int n) { construct(n); }
96.556 +
96.557 + /// \brief Resizes the graph
96.558 + ///
96.559 + /// Resizes the graph. The function will fully destroy and
96.560 + /// rebuild the graph. This cause that the maps of the graph will
96.561 + /// reallocated automatically and the previous values will be lost.
96.562 + void resize(int n) {
96.563 + Parent::notifier(Arc()).clear();
96.564 + Parent::notifier(Edge()).clear();
96.565 + Parent::notifier(Node()).clear();
96.566 + construct(n);
96.567 + Parent::notifier(Node()).build();
96.568 + Parent::notifier(Edge()).build();
96.569 + Parent::notifier(Arc()).build();
96.570 + }
96.571 +
96.572 + /// \brief Returns the node with the given index.
96.573 + ///
96.574 + /// Returns the node with the given index. Since it is a static
96.575 + /// graph its nodes can be indexed with integers from the range
96.576 + /// <tt>[0..nodeNum()-1]</tt>.
96.577 + /// \sa index()
96.578 + Node operator()(int ix) const { return Parent::operator()(ix); }
96.579 +
96.580 + /// \brief Returns the index of the given node.
96.581 + ///
96.582 + /// Returns the index of the given node. Since it is a static
96.583 + /// graph its nodes can be indexed with integers from the range
96.584 + /// <tt>[0..nodeNum()-1]</tt>.
96.585 + /// \sa operator()
96.586 + int index(const Node& node) const { return Parent::index(node); }
96.587 +
96.588 + /// \brief Returns the arc connecting the given nodes.
96.589 + ///
96.590 + /// Returns the arc connecting the given nodes.
96.591 + Arc arc(const Node& s, const Node& t) const {
96.592 + return Parent::arc(s, t);
96.593 + }
96.594 +
96.595 + /// \brief Returns the edge connects the given nodes.
96.596 + ///
96.597 + /// Returns the edge connects the given nodes.
96.598 + Edge edge(const Node& u, const Node& v) const {
96.599 + return Parent::edge(u, v);
96.600 + }
96.601 +
96.602 + /// \brief Number of nodes.
96.603 + int nodeNum() const { return Parent::nodeNum(); }
96.604 + /// \brief Number of arcs.
96.605 + int arcNum() const { return Parent::arcNum(); }
96.606 + /// \brief Number of edges.
96.607 + int edgeNum() const { return Parent::edgeNum(); }
96.608 +
96.609 + };
96.610 +
96.611 +
96.612 +} //namespace lemon
96.613 +
96.614 +
96.615 +#endif //LEMON_FULL_GRAPH_H
97.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
97.2 +++ b/lemon/glpk.cc Thu Dec 10 17:05:35 2009 +0100
97.3 @@ -0,0 +1,967 @@
97.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
97.5 + *
97.6 + * This file is a part of LEMON, a generic C++ optimization library.
97.7 + *
97.8 + * Copyright (C) 2003-2009
97.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
97.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
97.11 + *
97.12 + * Permission to use, modify and distribute this software is granted
97.13 + * provided that this copyright notice appears in all copies. For
97.14 + * precise terms see the accompanying LICENSE file.
97.15 + *
97.16 + * This software is provided "AS IS" with no warranty of any kind,
97.17 + * express or implied, and with no claim as to its suitability for any
97.18 + * purpose.
97.19 + *
97.20 + */
97.21 +
97.22 +///\file
97.23 +///\brief Implementation of the LEMON GLPK LP and MIP solver interface.
97.24 +
97.25 +#include <lemon/glpk.h>
97.26 +#include <glpk.h>
97.27 +
97.28 +#include <lemon/assert.h>
97.29 +
97.30 +namespace lemon {
97.31 +
97.32 + // GlpkBase members
97.33 +
97.34 + GlpkBase::GlpkBase() : LpBase() {
97.35 + lp = glp_create_prob();
97.36 + glp_create_index(lp);
97.37 + messageLevel(MESSAGE_NOTHING);
97.38 + }
97.39 +
97.40 + GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() {
97.41 + lp = glp_create_prob();
97.42 + glp_copy_prob(lp, other.lp, GLP_ON);
97.43 + glp_create_index(lp);
97.44 + rows = other.rows;
97.45 + cols = other.cols;
97.46 + messageLevel(MESSAGE_NOTHING);
97.47 + }
97.48 +
97.49 + GlpkBase::~GlpkBase() {
97.50 + glp_delete_prob(lp);
97.51 + }
97.52 +
97.53 + int GlpkBase::_addCol() {
97.54 + int i = glp_add_cols(lp, 1);
97.55 + glp_set_col_bnds(lp, i, GLP_FR, 0.0, 0.0);
97.56 + return i;
97.57 + }
97.58 +
97.59 + int GlpkBase::_addRow() {
97.60 + int i = glp_add_rows(lp, 1);
97.61 + glp_set_row_bnds(lp, i, GLP_FR, 0.0, 0.0);
97.62 + return i;
97.63 + }
97.64 +
97.65 + void GlpkBase::_eraseCol(int i) {
97.66 + int ca[2];
97.67 + ca[1] = i;
97.68 + glp_del_cols(lp, 1, ca);
97.69 + }
97.70 +
97.71 + void GlpkBase::_eraseRow(int i) {
97.72 + int ra[2];
97.73 + ra[1] = i;
97.74 + glp_del_rows(lp, 1, ra);
97.75 + }
97.76 +
97.77 + void GlpkBase::_eraseColId(int i) {
97.78 + cols.eraseIndex(i);
97.79 + cols.shiftIndices(i);
97.80 + }
97.81 +
97.82 + void GlpkBase::_eraseRowId(int i) {
97.83 + rows.eraseIndex(i);
97.84 + rows.shiftIndices(i);
97.85 + }
97.86 +
97.87 + void GlpkBase::_getColName(int c, std::string& name) const {
97.88 + const char *str = glp_get_col_name(lp, c);
97.89 + if (str) name = str;
97.90 + else name.clear();
97.91 + }
97.92 +
97.93 + void GlpkBase::_setColName(int c, const std::string & name) {
97.94 + glp_set_col_name(lp, c, const_cast<char*>(name.c_str()));
97.95 +
97.96 + }
97.97 +
97.98 + int GlpkBase::_colByName(const std::string& name) const {
97.99 + int k = glp_find_col(lp, const_cast<char*>(name.c_str()));
97.100 + return k > 0 ? k : -1;
97.101 + }
97.102 +
97.103 + void GlpkBase::_getRowName(int r, std::string& name) const {
97.104 + const char *str = glp_get_row_name(lp, r);
97.105 + if (str) name = str;
97.106 + else name.clear();
97.107 + }
97.108 +
97.109 + void GlpkBase::_setRowName(int r, const std::string & name) {
97.110 + glp_set_row_name(lp, r, const_cast<char*>(name.c_str()));
97.111 +
97.112 + }
97.113 +
97.114 + int GlpkBase::_rowByName(const std::string& name) const {
97.115 + int k = glp_find_row(lp, const_cast<char*>(name.c_str()));
97.116 + return k > 0 ? k : -1;
97.117 + }
97.118 +
97.119 + void GlpkBase::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
97.120 + std::vector<int> indexes;
97.121 + std::vector<Value> values;
97.122 +
97.123 + indexes.push_back(0);
97.124 + values.push_back(0);
97.125 +
97.126 + for(ExprIterator it = b; it != e; ++it) {
97.127 + indexes.push_back(it->first);
97.128 + values.push_back(it->second);
97.129 + }
97.130 +
97.131 + glp_set_mat_row(lp, i, values.size() - 1,
97.132 + &indexes.front(), &values.front());
97.133 + }
97.134 +
97.135 + void GlpkBase::_getRowCoeffs(int ix, InsertIterator b) const {
97.136 + int length = glp_get_mat_row(lp, ix, 0, 0);
97.137 +
97.138 + std::vector<int> indexes(length + 1);
97.139 + std::vector<Value> values(length + 1);
97.140 +
97.141 + glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
97.142 +
97.143 + for (int i = 1; i <= length; ++i) {
97.144 + *b = std::make_pair(indexes[i], values[i]);
97.145 + ++b;
97.146 + }
97.147 + }
97.148 +
97.149 + void GlpkBase::_setColCoeffs(int ix, ExprIterator b,
97.150 + ExprIterator e) {
97.151 +
97.152 + std::vector<int> indexes;
97.153 + std::vector<Value> values;
97.154 +
97.155 + indexes.push_back(0);
97.156 + values.push_back(0);
97.157 +
97.158 + for(ExprIterator it = b; it != e; ++it) {
97.159 + indexes.push_back(it->first);
97.160 + values.push_back(it->second);
97.161 + }
97.162 +
97.163 + glp_set_mat_col(lp, ix, values.size() - 1,
97.164 + &indexes.front(), &values.front());
97.165 + }
97.166 +
97.167 + void GlpkBase::_getColCoeffs(int ix, InsertIterator b) const {
97.168 + int length = glp_get_mat_col(lp, ix, 0, 0);
97.169 +
97.170 + std::vector<int> indexes(length + 1);
97.171 + std::vector<Value> values(length + 1);
97.172 +
97.173 + glp_get_mat_col(lp, ix, &indexes.front(), &values.front());
97.174 +
97.175 + for (int i = 1; i <= length; ++i) {
97.176 + *b = std::make_pair(indexes[i], values[i]);
97.177 + ++b;
97.178 + }
97.179 + }
97.180 +
97.181 + void GlpkBase::_setCoeff(int ix, int jx, Value value) {
97.182 +
97.183 + if (glp_get_num_cols(lp) < glp_get_num_rows(lp)) {
97.184 +
97.185 + int length = glp_get_mat_row(lp, ix, 0, 0);
97.186 +
97.187 + std::vector<int> indexes(length + 2);
97.188 + std::vector<Value> values(length + 2);
97.189 +
97.190 + glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
97.191 +
97.192 + //The following code does not suppose that the elements of the
97.193 + //array indexes are sorted
97.194 + bool found = false;
97.195 + for (int i = 1; i <= length; ++i) {
97.196 + if (indexes[i] == jx) {
97.197 + found = true;
97.198 + values[i] = value;
97.199 + break;
97.200 + }
97.201 + }
97.202 + if (!found) {
97.203 + ++length;
97.204 + indexes[length] = jx;
97.205 + values[length] = value;
97.206 + }
97.207 +
97.208 + glp_set_mat_row(lp, ix, length, &indexes.front(), &values.front());
97.209 +
97.210 + } else {
97.211 +
97.212 + int length = glp_get_mat_col(lp, jx, 0, 0);
97.213 +
97.214 + std::vector<int> indexes(length + 2);
97.215 + std::vector<Value> values(length + 2);
97.216 +
97.217 + glp_get_mat_col(lp, jx, &indexes.front(), &values.front());
97.218 +
97.219 + //The following code does not suppose that the elements of the
97.220 + //array indexes are sorted
97.221 + bool found = false;
97.222 + for (int i = 1; i <= length; ++i) {
97.223 + if (indexes[i] == ix) {
97.224 + found = true;
97.225 + values[i] = value;
97.226 + break;
97.227 + }
97.228 + }
97.229 + if (!found) {
97.230 + ++length;
97.231 + indexes[length] = ix;
97.232 + values[length] = value;
97.233 + }
97.234 +
97.235 + glp_set_mat_col(lp, jx, length, &indexes.front(), &values.front());
97.236 + }
97.237 +
97.238 + }
97.239 +
97.240 + GlpkBase::Value GlpkBase::_getCoeff(int ix, int jx) const {
97.241 +
97.242 + int length = glp_get_mat_row(lp, ix, 0, 0);
97.243 +
97.244 + std::vector<int> indexes(length + 1);
97.245 + std::vector<Value> values(length + 1);
97.246 +
97.247 + glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
97.248 +
97.249 + for (int i = 1; i <= length; ++i) {
97.250 + if (indexes[i] == jx) {
97.251 + return values[i];
97.252 + }
97.253 + }
97.254 +
97.255 + return 0;
97.256 + }
97.257 +
97.258 + void GlpkBase::_setColLowerBound(int i, Value lo) {
97.259 + LEMON_ASSERT(lo != INF, "Invalid bound");
97.260 +
97.261 + int b = glp_get_col_type(lp, i);
97.262 + double up = glp_get_col_ub(lp, i);
97.263 + if (lo == -INF) {
97.264 + switch (b) {
97.265 + case GLP_FR:
97.266 + case GLP_LO:
97.267 + glp_set_col_bnds(lp, i, GLP_FR, lo, up);
97.268 + break;
97.269 + case GLP_UP:
97.270 + break;
97.271 + case GLP_DB:
97.272 + case GLP_FX:
97.273 + glp_set_col_bnds(lp, i, GLP_UP, lo, up);
97.274 + break;
97.275 + default:
97.276 + break;
97.277 + }
97.278 + } else {
97.279 + switch (b) {
97.280 + case GLP_FR:
97.281 + case GLP_LO:
97.282 + glp_set_col_bnds(lp, i, GLP_LO, lo, up);
97.283 + break;
97.284 + case GLP_UP:
97.285 + case GLP_DB:
97.286 + case GLP_FX:
97.287 + if (lo == up)
97.288 + glp_set_col_bnds(lp, i, GLP_FX, lo, up);
97.289 + else
97.290 + glp_set_col_bnds(lp, i, GLP_DB, lo, up);
97.291 + break;
97.292 + default:
97.293 + break;
97.294 + }
97.295 + }
97.296 + }
97.297 +
97.298 + GlpkBase::Value GlpkBase::_getColLowerBound(int i) const {
97.299 + int b = glp_get_col_type(lp, i);
97.300 + switch (b) {
97.301 + case GLP_LO:
97.302 + case GLP_DB:
97.303 + case GLP_FX:
97.304 + return glp_get_col_lb(lp, i);
97.305 + default:
97.306 + return -INF;
97.307 + }
97.308 + }
97.309 +
97.310 + void GlpkBase::_setColUpperBound(int i, Value up) {
97.311 + LEMON_ASSERT(up != -INF, "Invalid bound");
97.312 +
97.313 + int b = glp_get_col_type(lp, i);
97.314 + double lo = glp_get_col_lb(lp, i);
97.315 + if (up == INF) {
97.316 + switch (b) {
97.317 + case GLP_FR:
97.318 + case GLP_LO:
97.319 + break;
97.320 + case GLP_UP:
97.321 + glp_set_col_bnds(lp, i, GLP_FR, lo, up);
97.322 + break;
97.323 + case GLP_DB:
97.324 + case GLP_FX:
97.325 + glp_set_col_bnds(lp, i, GLP_LO, lo, up);
97.326 + break;
97.327 + default:
97.328 + break;
97.329 + }
97.330 + } else {
97.331 + switch (b) {
97.332 + case GLP_FR:
97.333 + glp_set_col_bnds(lp, i, GLP_UP, lo, up);
97.334 + break;
97.335 + case GLP_UP:
97.336 + glp_set_col_bnds(lp, i, GLP_UP, lo, up);
97.337 + break;
97.338 + case GLP_LO:
97.339 + case GLP_DB:
97.340 + case GLP_FX:
97.341 + if (lo == up)
97.342 + glp_set_col_bnds(lp, i, GLP_FX, lo, up);
97.343 + else
97.344 + glp_set_col_bnds(lp, i, GLP_DB, lo, up);
97.345 + break;
97.346 + default:
97.347 + break;
97.348 + }
97.349 + }
97.350 +
97.351 + }
97.352 +
97.353 + GlpkBase::Value GlpkBase::_getColUpperBound(int i) const {
97.354 + int b = glp_get_col_type(lp, i);
97.355 + switch (b) {
97.356 + case GLP_UP:
97.357 + case GLP_DB:
97.358 + case GLP_FX:
97.359 + return glp_get_col_ub(lp, i);
97.360 + default:
97.361 + return INF;
97.362 + }
97.363 + }
97.364 +
97.365 + void GlpkBase::_setRowLowerBound(int i, Value lo) {
97.366 + LEMON_ASSERT(lo != INF, "Invalid bound");
97.367 +
97.368 + int b = glp_get_row_type(lp, i);
97.369 + double up = glp_get_row_ub(lp, i);
97.370 + if (lo == -INF) {
97.371 + switch (b) {
97.372 + case GLP_FR:
97.373 + case GLP_LO:
97.374 + glp_set_row_bnds(lp, i, GLP_FR, lo, up);
97.375 + break;
97.376 + case GLP_UP:
97.377 + break;
97.378 + case GLP_DB:
97.379 + case GLP_FX:
97.380 + glp_set_row_bnds(lp, i, GLP_UP, lo, up);
97.381 + break;
97.382 + default:
97.383 + break;
97.384 + }
97.385 + } else {
97.386 + switch (b) {
97.387 + case GLP_FR:
97.388 + case GLP_LO:
97.389 + glp_set_row_bnds(lp, i, GLP_LO, lo, up);
97.390 + break;
97.391 + case GLP_UP:
97.392 + case GLP_DB:
97.393 + case GLP_FX:
97.394 + if (lo == up)
97.395 + glp_set_row_bnds(lp, i, GLP_FX, lo, up);
97.396 + else
97.397 + glp_set_row_bnds(lp, i, GLP_DB, lo, up);
97.398 + break;
97.399 + default:
97.400 + break;
97.401 + }
97.402 + }
97.403 +
97.404 + }
97.405 +
97.406 + GlpkBase::Value GlpkBase::_getRowLowerBound(int i) const {
97.407 + int b = glp_get_row_type(lp, i);
97.408 + switch (b) {
97.409 + case GLP_LO:
97.410 + case GLP_DB:
97.411 + case GLP_FX:
97.412 + return glp_get_row_lb(lp, i);
97.413 + default:
97.414 + return -INF;
97.415 + }
97.416 + }
97.417 +
97.418 + void GlpkBase::_setRowUpperBound(int i, Value up) {
97.419 + LEMON_ASSERT(up != -INF, "Invalid bound");
97.420 +
97.421 + int b = glp_get_row_type(lp, i);
97.422 + double lo = glp_get_row_lb(lp, i);
97.423 + if (up == INF) {
97.424 + switch (b) {
97.425 + case GLP_FR:
97.426 + case GLP_LO:
97.427 + break;
97.428 + case GLP_UP:
97.429 + glp_set_row_bnds(lp, i, GLP_FR, lo, up);
97.430 + break;
97.431 + case GLP_DB:
97.432 + case GLP_FX:
97.433 + glp_set_row_bnds(lp, i, GLP_LO, lo, up);
97.434 + break;
97.435 + default:
97.436 + break;
97.437 + }
97.438 + } else {
97.439 + switch (b) {
97.440 + case GLP_FR:
97.441 + glp_set_row_bnds(lp, i, GLP_UP, lo, up);
97.442 + break;
97.443 + case GLP_UP:
97.444 + glp_set_row_bnds(lp, i, GLP_UP, lo, up);
97.445 + break;
97.446 + case GLP_LO:
97.447 + case GLP_DB:
97.448 + case GLP_FX:
97.449 + if (lo == up)
97.450 + glp_set_row_bnds(lp, i, GLP_FX, lo, up);
97.451 + else
97.452 + glp_set_row_bnds(lp, i, GLP_DB, lo, up);
97.453 + break;
97.454 + default:
97.455 + break;
97.456 + }
97.457 + }
97.458 + }
97.459 +
97.460 + GlpkBase::Value GlpkBase::_getRowUpperBound(int i) const {
97.461 + int b = glp_get_row_type(lp, i);
97.462 + switch (b) {
97.463 + case GLP_UP:
97.464 + case GLP_DB:
97.465 + case GLP_FX:
97.466 + return glp_get_row_ub(lp, i);
97.467 + default:
97.468 + return INF;
97.469 + }
97.470 + }
97.471 +
97.472 + void GlpkBase::_setObjCoeffs(ExprIterator b, ExprIterator e) {
97.473 + for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
97.474 + glp_set_obj_coef(lp, i, 0.0);
97.475 + }
97.476 + for (ExprIterator it = b; it != e; ++it) {
97.477 + glp_set_obj_coef(lp, it->first, it->second);
97.478 + }
97.479 + }
97.480 +
97.481 + void GlpkBase::_getObjCoeffs(InsertIterator b) const {
97.482 + for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
97.483 + Value val = glp_get_obj_coef(lp, i);
97.484 + if (val != 0.0) {
97.485 + *b = std::make_pair(i, val);
97.486 + ++b;
97.487 + }
97.488 + }
97.489 + }
97.490 +
97.491 + void GlpkBase::_setObjCoeff(int i, Value obj_coef) {
97.492 + //i = 0 means the constant term (shift)
97.493 + glp_set_obj_coef(lp, i, obj_coef);
97.494 + }
97.495 +
97.496 + GlpkBase::Value GlpkBase::_getObjCoeff(int i) const {
97.497 + //i = 0 means the constant term (shift)
97.498 + return glp_get_obj_coef(lp, i);
97.499 + }
97.500 +
97.501 + void GlpkBase::_setSense(GlpkBase::Sense sense) {
97.502 + switch (sense) {
97.503 + case MIN:
97.504 + glp_set_obj_dir(lp, GLP_MIN);
97.505 + break;
97.506 + case MAX:
97.507 + glp_set_obj_dir(lp, GLP_MAX);
97.508 + break;
97.509 + }
97.510 + }
97.511 +
97.512 + GlpkBase::Sense GlpkBase::_getSense() const {
97.513 + switch(glp_get_obj_dir(lp)) {
97.514 + case GLP_MIN:
97.515 + return MIN;
97.516 + case GLP_MAX:
97.517 + return MAX;
97.518 + default:
97.519 + LEMON_ASSERT(false, "Wrong sense");
97.520 + return GlpkBase::Sense();
97.521 + }
97.522 + }
97.523 +
97.524 + void GlpkBase::_clear() {
97.525 + glp_erase_prob(lp);
97.526 + rows.clear();
97.527 + cols.clear();
97.528 + }
97.529 +
97.530 + void GlpkBase::freeEnv() {
97.531 + glp_free_env();
97.532 + }
97.533 +
97.534 + void GlpkBase::_messageLevel(MessageLevel level) {
97.535 + switch (level) {
97.536 + case MESSAGE_NOTHING:
97.537 + _message_level = GLP_MSG_OFF;
97.538 + break;
97.539 + case MESSAGE_ERROR:
97.540 + _message_level = GLP_MSG_ERR;
97.541 + break;
97.542 + case MESSAGE_WARNING:
97.543 + _message_level = GLP_MSG_ERR;
97.544 + break;
97.545 + case MESSAGE_NORMAL:
97.546 + _message_level = GLP_MSG_ON;
97.547 + break;
97.548 + case MESSAGE_VERBOSE:
97.549 + _message_level = GLP_MSG_ALL;
97.550 + break;
97.551 + }
97.552 + }
97.553 +
97.554 + GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
97.555 +
97.556 + // GlpkLp members
97.557 +
97.558 + GlpkLp::GlpkLp()
97.559 + : LpBase(), LpSolver(), GlpkBase() {
97.560 + presolver(false);
97.561 + }
97.562 +
97.563 + GlpkLp::GlpkLp(const GlpkLp& other)
97.564 + : LpBase(other), LpSolver(other), GlpkBase(other) {
97.565 + presolver(false);
97.566 + }
97.567 +
97.568 + GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
97.569 + GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); }
97.570 +
97.571 + const char* GlpkLp::_solverName() const { return "GlpkLp"; }
97.572 +
97.573 + void GlpkLp::_clear_temporals() {
97.574 + _primal_ray.clear();
97.575 + _dual_ray.clear();
97.576 + }
97.577 +
97.578 + GlpkLp::SolveExitStatus GlpkLp::_solve() {
97.579 + return solvePrimal();
97.580 + }
97.581 +
97.582 + GlpkLp::SolveExitStatus GlpkLp::solvePrimal() {
97.583 + _clear_temporals();
97.584 +
97.585 + glp_smcp smcp;
97.586 + glp_init_smcp(&smcp);
97.587 +
97.588 + smcp.msg_lev = _message_level;
97.589 + smcp.presolve = _presolve;
97.590 +
97.591 + // If the basis is not valid we get an error return value.
97.592 + // In this case we can try to create a new basis.
97.593 + switch (glp_simplex(lp, &smcp)) {
97.594 + case 0:
97.595 + break;
97.596 + case GLP_EBADB:
97.597 + case GLP_ESING:
97.598 + case GLP_ECOND:
97.599 + glp_term_out(false);
97.600 + glp_adv_basis(lp, 0);
97.601 + glp_term_out(true);
97.602 + if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
97.603 + break;
97.604 + default:
97.605 + return UNSOLVED;
97.606 + }
97.607 +
97.608 + return SOLVED;
97.609 + }
97.610 +
97.611 + GlpkLp::SolveExitStatus GlpkLp::solveDual() {
97.612 + _clear_temporals();
97.613 +
97.614 + glp_smcp smcp;
97.615 + glp_init_smcp(&smcp);
97.616 +
97.617 + smcp.msg_lev = _message_level;
97.618 + smcp.meth = GLP_DUAL;
97.619 + smcp.presolve = _presolve;
97.620 +
97.621 + // If the basis is not valid we get an error return value.
97.622 + // In this case we can try to create a new basis.
97.623 + switch (glp_simplex(lp, &smcp)) {
97.624 + case 0:
97.625 + break;
97.626 + case GLP_EBADB:
97.627 + case GLP_ESING:
97.628 + case GLP_ECOND:
97.629 + glp_term_out(false);
97.630 + glp_adv_basis(lp, 0);
97.631 + glp_term_out(true);
97.632 + if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
97.633 + break;
97.634 + default:
97.635 + return UNSOLVED;
97.636 + }
97.637 + return SOLVED;
97.638 + }
97.639 +
97.640 + GlpkLp::Value GlpkLp::_getPrimal(int i) const {
97.641 + return glp_get_col_prim(lp, i);
97.642 + }
97.643 +
97.644 + GlpkLp::Value GlpkLp::_getDual(int i) const {
97.645 + return glp_get_row_dual(lp, i);
97.646 + }
97.647 +
97.648 + GlpkLp::Value GlpkLp::_getPrimalValue() const {
97.649 + return glp_get_obj_val(lp);
97.650 + }
97.651 +
97.652 + GlpkLp::VarStatus GlpkLp::_getColStatus(int i) const {
97.653 + switch (glp_get_col_stat(lp, i)) {
97.654 + case GLP_BS:
97.655 + return BASIC;
97.656 + case GLP_UP:
97.657 + return UPPER;
97.658 + case GLP_LO:
97.659 + return LOWER;
97.660 + case GLP_NF:
97.661 + return FREE;
97.662 + case GLP_NS:
97.663 + return FIXED;
97.664 + default:
97.665 + LEMON_ASSERT(false, "Wrong column status");
97.666 + return GlpkLp::VarStatus();
97.667 + }
97.668 + }
97.669 +
97.670 + GlpkLp::VarStatus GlpkLp::_getRowStatus(int i) const {
97.671 + switch (glp_get_row_stat(lp, i)) {
97.672 + case GLP_BS:
97.673 + return BASIC;
97.674 + case GLP_UP:
97.675 + return UPPER;
97.676 + case GLP_LO:
97.677 + return LOWER;
97.678 + case GLP_NF:
97.679 + return FREE;
97.680 + case GLP_NS:
97.681 + return FIXED;
97.682 + default:
97.683 + LEMON_ASSERT(false, "Wrong row status");
97.684 + return GlpkLp::VarStatus();
97.685 + }
97.686 + }
97.687 +
97.688 + GlpkLp::Value GlpkLp::_getPrimalRay(int i) const {
97.689 + if (_primal_ray.empty()) {
97.690 + int row_num = glp_get_num_rows(lp);
97.691 + int col_num = glp_get_num_cols(lp);
97.692 +
97.693 + _primal_ray.resize(col_num + 1, 0.0);
97.694 +
97.695 + int index = glp_get_unbnd_ray(lp);
97.696 + if (index != 0) {
97.697 + // The primal ray is found in primal simplex second phase
97.698 + LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
97.699 + glp_get_col_stat(lp, index - row_num)) != GLP_BS,
97.700 + "Wrong primal ray");
97.701 +
97.702 + bool negate = glp_get_obj_dir(lp) == GLP_MAX;
97.703 +
97.704 + if (index > row_num) {
97.705 + _primal_ray[index - row_num] = 1.0;
97.706 + if (glp_get_col_dual(lp, index - row_num) > 0) {
97.707 + negate = !negate;
97.708 + }
97.709 + } else {
97.710 + if (glp_get_row_dual(lp, index) > 0) {
97.711 + negate = !negate;
97.712 + }
97.713 + }
97.714 +
97.715 + std::vector<int> ray_indexes(row_num + 1);
97.716 + std::vector<Value> ray_values(row_num + 1);
97.717 + int ray_length = glp_eval_tab_col(lp, index, &ray_indexes.front(),
97.718 + &ray_values.front());
97.719 +
97.720 + for (int i = 1; i <= ray_length; ++i) {
97.721 + if (ray_indexes[i] > row_num) {
97.722 + _primal_ray[ray_indexes[i] - row_num] = ray_values[i];
97.723 + }
97.724 + }
97.725 +
97.726 + if (negate) {
97.727 + for (int i = 1; i <= col_num; ++i) {
97.728 + _primal_ray[i] = - _primal_ray[i];
97.729 + }
97.730 + }
97.731 + } else {
97.732 + for (int i = 1; i <= col_num; ++i) {
97.733 + _primal_ray[i] = glp_get_col_prim(lp, i);
97.734 + }
97.735 + }
97.736 + }
97.737 + return _primal_ray[i];
97.738 + }
97.739 +
97.740 + GlpkLp::Value GlpkLp::_getDualRay(int i) const {
97.741 + if (_dual_ray.empty()) {
97.742 + int row_num = glp_get_num_rows(lp);
97.743 +
97.744 + _dual_ray.resize(row_num + 1, 0.0);
97.745 +
97.746 + int index = glp_get_unbnd_ray(lp);
97.747 + if (index != 0) {
97.748 + // The dual ray is found in dual simplex second phase
97.749 + LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
97.750 + glp_get_col_stat(lp, index - row_num)) == GLP_BS,
97.751 +
97.752 + "Wrong dual ray");
97.753 +
97.754 + int idx;
97.755 + bool negate = false;
97.756 +
97.757 + if (index > row_num) {
97.758 + idx = glp_get_col_bind(lp, index - row_num);
97.759 + if (glp_get_col_prim(lp, index - row_num) >
97.760 + glp_get_col_ub(lp, index - row_num)) {
97.761 + negate = true;
97.762 + }
97.763 + } else {
97.764 + idx = glp_get_row_bind(lp, index);
97.765 + if (glp_get_row_prim(lp, index) > glp_get_row_ub(lp, index)) {
97.766 + negate = true;
97.767 + }
97.768 + }
97.769 +
97.770 + _dual_ray[idx] = negate ? - 1.0 : 1.0;
97.771 +
97.772 + glp_btran(lp, &_dual_ray.front());
97.773 + } else {
97.774 + double eps = 1e-7;
97.775 + // The dual ray is found in primal simplex first phase
97.776 + // We assume that the glpk minimizes the slack to get feasible solution
97.777 + for (int i = 1; i <= row_num; ++i) {
97.778 + int index = glp_get_bhead(lp, i);
97.779 + if (index <= row_num) {
97.780 + double res = glp_get_row_prim(lp, index);
97.781 + if (res > glp_get_row_ub(lp, index) + eps) {
97.782 + _dual_ray[i] = -1;
97.783 + } else if (res < glp_get_row_lb(lp, index) - eps) {
97.784 + _dual_ray[i] = 1;
97.785 + } else {
97.786 + _dual_ray[i] = 0;
97.787 + }
97.788 + _dual_ray[i] *= glp_get_rii(lp, index);
97.789 + } else {
97.790 + double res = glp_get_col_prim(lp, index - row_num);
97.791 + if (res > glp_get_col_ub(lp, index - row_num) + eps) {
97.792 + _dual_ray[i] = -1;
97.793 + } else if (res < glp_get_col_lb(lp, index - row_num) - eps) {
97.794 + _dual_ray[i] = 1;
97.795 + } else {
97.796 + _dual_ray[i] = 0;
97.797 + }
97.798 + _dual_ray[i] /= glp_get_sjj(lp, index - row_num);
97.799 + }
97.800 + }
97.801 +
97.802 + glp_btran(lp, &_dual_ray.front());
97.803 +
97.804 + for (int i = 1; i <= row_num; ++i) {
97.805 + _dual_ray[i] /= glp_get_rii(lp, i);
97.806 + }
97.807 + }
97.808 + }
97.809 + return _dual_ray[i];
97.810 + }
97.811 +
97.812 + GlpkLp::ProblemType GlpkLp::_getPrimalType() const {
97.813 + if (glp_get_status(lp) == GLP_OPT)
97.814 + return OPTIMAL;
97.815 + switch (glp_get_prim_stat(lp)) {
97.816 + case GLP_UNDEF:
97.817 + return UNDEFINED;
97.818 + case GLP_FEAS:
97.819 + case GLP_INFEAS:
97.820 + if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
97.821 + return UNBOUNDED;
97.822 + } else {
97.823 + return UNDEFINED;
97.824 + }
97.825 + case GLP_NOFEAS:
97.826 + return INFEASIBLE;
97.827 + default:
97.828 + LEMON_ASSERT(false, "Wrong primal type");
97.829 + return GlpkLp::ProblemType();
97.830 + }
97.831 + }
97.832 +
97.833 + GlpkLp::ProblemType GlpkLp::_getDualType() const {
97.834 + if (glp_get_status(lp) == GLP_OPT)
97.835 + return OPTIMAL;
97.836 + switch (glp_get_dual_stat(lp)) {
97.837 + case GLP_UNDEF:
97.838 + return UNDEFINED;
97.839 + case GLP_FEAS:
97.840 + case GLP_INFEAS:
97.841 + if (glp_get_prim_stat(lp) == GLP_NOFEAS) {
97.842 + return UNBOUNDED;
97.843 + } else {
97.844 + return UNDEFINED;
97.845 + }
97.846 + case GLP_NOFEAS:
97.847 + return INFEASIBLE;
97.848 + default:
97.849 + LEMON_ASSERT(false, "Wrong primal type");
97.850 + return GlpkLp::ProblemType();
97.851 + }
97.852 + }
97.853 +
97.854 + void GlpkLp::presolver(bool presolve) {
97.855 + _presolve = presolve;
97.856 + }
97.857 +
97.858 + // GlpkMip members
97.859 +
97.860 + GlpkMip::GlpkMip()
97.861 + : LpBase(), MipSolver(), GlpkBase() {
97.862 + }
97.863 +
97.864 + GlpkMip::GlpkMip(const GlpkMip& other)
97.865 + : LpBase(), MipSolver(), GlpkBase(other) {
97.866 + }
97.867 +
97.868 + void GlpkMip::_setColType(int i, GlpkMip::ColTypes col_type) {
97.869 + switch (col_type) {
97.870 + case INTEGER:
97.871 + glp_set_col_kind(lp, i, GLP_IV);
97.872 + break;
97.873 + case REAL:
97.874 + glp_set_col_kind(lp, i, GLP_CV);
97.875 + break;
97.876 + }
97.877 + }
97.878 +
97.879 + GlpkMip::ColTypes GlpkMip::_getColType(int i) const {
97.880 + switch (glp_get_col_kind(lp, i)) {
97.881 + case GLP_IV:
97.882 + case GLP_BV:
97.883 + return INTEGER;
97.884 + default:
97.885 + return REAL;
97.886 + }
97.887 +
97.888 + }
97.889 +
97.890 + GlpkMip::SolveExitStatus GlpkMip::_solve() {
97.891 + glp_smcp smcp;
97.892 + glp_init_smcp(&smcp);
97.893 +
97.894 + smcp.msg_lev = _message_level;
97.895 + smcp.meth = GLP_DUAL;
97.896 +
97.897 + // If the basis is not valid we get an error return value.
97.898 + // In this case we can try to create a new basis.
97.899 + switch (glp_simplex(lp, &smcp)) {
97.900 + case 0:
97.901 + break;
97.902 + case GLP_EBADB:
97.903 + case GLP_ESING:
97.904 + case GLP_ECOND:
97.905 + glp_term_out(false);
97.906 + glp_adv_basis(lp, 0);
97.907 + glp_term_out(true);
97.908 + if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
97.909 + break;
97.910 + default:
97.911 + return UNSOLVED;
97.912 + }
97.913 +
97.914 + if (glp_get_status(lp) != GLP_OPT) return SOLVED;
97.915 +
97.916 + glp_iocp iocp;
97.917 + glp_init_iocp(&iocp);
97.918 +
97.919 + iocp.msg_lev = _message_level;
97.920 +
97.921 + if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
97.922 + return SOLVED;
97.923 + }
97.924 +
97.925 +
97.926 + GlpkMip::ProblemType GlpkMip::_getType() const {
97.927 + switch (glp_get_status(lp)) {
97.928 + case GLP_OPT:
97.929 + switch (glp_mip_status(lp)) {
97.930 + case GLP_UNDEF:
97.931 + return UNDEFINED;
97.932 + case GLP_NOFEAS:
97.933 + return INFEASIBLE;
97.934 + case GLP_FEAS:
97.935 + return FEASIBLE;
97.936 + case GLP_OPT:
97.937 + return OPTIMAL;
97.938 + default:
97.939 + LEMON_ASSERT(false, "Wrong problem type.");
97.940 + return GlpkMip::ProblemType();
97.941 + }
97.942 + case GLP_NOFEAS:
97.943 + return INFEASIBLE;
97.944 + case GLP_INFEAS:
97.945 + case GLP_FEAS:
97.946 + if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
97.947 + return UNBOUNDED;
97.948 + } else {
97.949 + return UNDEFINED;
97.950 + }
97.951 + default:
97.952 + LEMON_ASSERT(false, "Wrong problem type.");
97.953 + return GlpkMip::ProblemType();
97.954 + }
97.955 + }
97.956 +
97.957 + GlpkMip::Value GlpkMip::_getSol(int i) const {
97.958 + return glp_mip_col_val(lp, i);
97.959 + }
97.960 +
97.961 + GlpkMip::Value GlpkMip::_getSolValue() const {
97.962 + return glp_mip_obj_val(lp);
97.963 + }
97.964 +
97.965 + GlpkMip* GlpkMip::newSolver() const { return new GlpkMip; }
97.966 + GlpkMip* GlpkMip::cloneSolver() const {return new GlpkMip(*this); }
97.967 +
97.968 + const char* GlpkMip::_solverName() const { return "GlpkMip"; }
97.969 +
97.970 +} //END OF NAMESPACE LEMON
98.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
98.2 +++ b/lemon/glpk.h Thu Dec 10 17:05:35 2009 +0100
98.3 @@ -0,0 +1,236 @@
98.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
98.5 + *
98.6 + * This file is a part of LEMON, a generic C++ optimization library.
98.7 + *
98.8 + * Copyright (C) 2003-2008
98.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
98.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
98.11 + *
98.12 + * Permission to use, modify and distribute this software is granted
98.13 + * provided that this copyright notice appears in all copies. For
98.14 + * precise terms see the accompanying LICENSE file.
98.15 + *
98.16 + * This software is provided "AS IS" with no warranty of any kind,
98.17 + * express or implied, and with no claim as to its suitability for any
98.18 + * purpose.
98.19 + *
98.20 + */
98.21 +
98.22 +#ifndef LEMON_GLPK_H
98.23 +#define LEMON_GLPK_H
98.24 +
98.25 +///\file
98.26 +///\brief Header of the LEMON-GLPK lp solver interface.
98.27 +///\ingroup lp_group
98.28 +
98.29 +#include <lemon/lp_base.h>
98.30 +
98.31 +// forward declaration
98.32 +#if !defined _GLP_PROB && !defined GLP_PROB
98.33 +#define _GLP_PROB
98.34 +#define GLP_PROB
98.35 +typedef struct { double _opaque_prob; } glp_prob;
98.36 +/* LP/MIP problem object */
98.37 +#endif
98.38 +
98.39 +namespace lemon {
98.40 +
98.41 +
98.42 + /// \brief Base interface for the GLPK LP and MIP solver
98.43 + ///
98.44 + /// This class implements the common interface of the GLPK LP and MIP solver.
98.45 + /// \ingroup lp_group
98.46 + class GlpkBase : virtual public LpBase {
98.47 + protected:
98.48 +
98.49 + typedef glp_prob LPX;
98.50 + glp_prob* lp;
98.51 +
98.52 + GlpkBase();
98.53 + GlpkBase(const GlpkBase&);
98.54 + virtual ~GlpkBase();
98.55 +
98.56 + protected:
98.57 +
98.58 + virtual int _addCol();
98.59 + virtual int _addRow();
98.60 +
98.61 + virtual void _eraseCol(int i);
98.62 + virtual void _eraseRow(int i);
98.63 +
98.64 + virtual void _eraseColId(int i);
98.65 + virtual void _eraseRowId(int i);
98.66 +
98.67 + virtual void _getColName(int col, std::string& name) const;
98.68 + virtual void _setColName(int col, const std::string& name);
98.69 + virtual int _colByName(const std::string& name) const;
98.70 +
98.71 + virtual void _getRowName(int row, std::string& name) const;
98.72 + virtual void _setRowName(int row, const std::string& name);
98.73 + virtual int _rowByName(const std::string& name) const;
98.74 +
98.75 + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
98.76 + virtual void _getRowCoeffs(int i, InsertIterator b) const;
98.77 +
98.78 + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
98.79 + virtual void _getColCoeffs(int i, InsertIterator b) const;
98.80 +
98.81 + virtual void _setCoeff(int row, int col, Value value);
98.82 + virtual Value _getCoeff(int row, int col) const;
98.83 +
98.84 + virtual void _setColLowerBound(int i, Value value);
98.85 + virtual Value _getColLowerBound(int i) const;
98.86 +
98.87 + virtual void _setColUpperBound(int i, Value value);
98.88 + virtual Value _getColUpperBound(int i) const;
98.89 +
98.90 + virtual void _setRowLowerBound(int i, Value value);
98.91 + virtual Value _getRowLowerBound(int i) const;
98.92 +
98.93 + virtual void _setRowUpperBound(int i, Value value);
98.94 + virtual Value _getRowUpperBound(int i) const;
98.95 +
98.96 + virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
98.97 + virtual void _getObjCoeffs(InsertIterator b) const;
98.98 +
98.99 + virtual void _setObjCoeff(int i, Value obj_coef);
98.100 + virtual Value _getObjCoeff(int i) const;
98.101 +
98.102 + virtual void _setSense(Sense);
98.103 + virtual Sense _getSense() const;
98.104 +
98.105 + virtual void _clear();
98.106 +
98.107 + virtual void _messageLevel(MessageLevel level);
98.108 +
98.109 + private:
98.110 +
98.111 + static void freeEnv();
98.112 +
98.113 + struct FreeEnvHelper {
98.114 + ~FreeEnvHelper() {
98.115 + freeEnv();
98.116 + }
98.117 + };
98.118 +
98.119 + static FreeEnvHelper freeEnvHelper;
98.120 +
98.121 + protected:
98.122 +
98.123 + int _message_level;
98.124 +
98.125 + public:
98.126 +
98.127 + ///Pointer to the underlying GLPK data structure.
98.128 + LPX *lpx() {return lp;}
98.129 + ///Const pointer to the underlying GLPK data structure.
98.130 + const LPX *lpx() const {return lp;}
98.131 +
98.132 + ///Returns the constraint identifier understood by GLPK.
98.133 + int lpxRow(Row r) const { return rows(id(r)); }
98.134 +
98.135 + ///Returns the variable identifier understood by GLPK.
98.136 + int lpxCol(Col c) const { return cols(id(c)); }
98.137 +
98.138 + };
98.139 +
98.140 + /// \brief Interface for the GLPK LP solver
98.141 + ///
98.142 + /// This class implements an interface for the GLPK LP solver.
98.143 + ///\ingroup lp_group
98.144 + class GlpkLp : public LpSolver, public GlpkBase {
98.145 + public:
98.146 +
98.147 + ///\e
98.148 + GlpkLp();
98.149 + ///\e
98.150 + GlpkLp(const GlpkLp&);
98.151 +
98.152 + ///\e
98.153 + virtual GlpkLp* cloneSolver() const;
98.154 + ///\e
98.155 + virtual GlpkLp* newSolver() const;
98.156 +
98.157 + private:
98.158 +
98.159 + mutable std::vector<double> _primal_ray;
98.160 + mutable std::vector<double> _dual_ray;
98.161 +
98.162 + void _clear_temporals();
98.163 +
98.164 + protected:
98.165 +
98.166 + virtual const char* _solverName() const;
98.167 +
98.168 + virtual SolveExitStatus _solve();
98.169 + virtual Value _getPrimal(int i) const;
98.170 + virtual Value _getDual(int i) const;
98.171 +
98.172 + virtual Value _getPrimalValue() const;
98.173 +
98.174 + virtual VarStatus _getColStatus(int i) const;
98.175 + virtual VarStatus _getRowStatus(int i) const;
98.176 +
98.177 + virtual Value _getPrimalRay(int i) const;
98.178 + virtual Value _getDualRay(int i) const;
98.179 +
98.180 + virtual ProblemType _getPrimalType() const;
98.181 + virtual ProblemType _getDualType() const;
98.182 +
98.183 + public:
98.184 +
98.185 + ///Solve with primal simplex
98.186 + SolveExitStatus solvePrimal();
98.187 +
98.188 + ///Solve with dual simplex
98.189 + SolveExitStatus solveDual();
98.190 +
98.191 + private:
98.192 +
98.193 + bool _presolve;
98.194 +
98.195 + public:
98.196 +
98.197 + ///Turns on or off the presolver
98.198 +
98.199 + ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
98.200 + ///
98.201 + ///The presolver is off by default.
98.202 + void presolver(bool presolve);
98.203 +
98.204 + };
98.205 +
98.206 + /// \brief Interface for the GLPK MIP solver
98.207 + ///
98.208 + /// This class implements an interface for the GLPK MIP solver.
98.209 + ///\ingroup lp_group
98.210 + class GlpkMip : public MipSolver, public GlpkBase {
98.211 + public:
98.212 +
98.213 + ///\e
98.214 + GlpkMip();
98.215 + ///\e
98.216 + GlpkMip(const GlpkMip&);
98.217 +
98.218 + virtual GlpkMip* cloneSolver() const;
98.219 + virtual GlpkMip* newSolver() const;
98.220 +
98.221 + protected:
98.222 +
98.223 + virtual const char* _solverName() const;
98.224 +
98.225 + virtual ColTypes _getColType(int col) const;
98.226 + virtual void _setColType(int col, ColTypes col_type);
98.227 +
98.228 + virtual SolveExitStatus _solve();
98.229 + virtual ProblemType _getType() const;
98.230 + virtual Value _getSol(int i) const;
98.231 + virtual Value _getSolValue() const;
98.232 +
98.233 + };
98.234 +
98.235 +
98.236 +} //END OF NAMESPACE LEMON
98.237 +
98.238 +#endif //LEMON_GLPK_H
98.239 +
99.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
99.2 +++ b/lemon/gomory_hu.h Thu Dec 10 17:05:35 2009 +0100
99.3 @@ -0,0 +1,570 @@
99.4 +/* -*- C++ -*-
99.5 + *
99.6 + * This file is a part of LEMON, a generic C++ optimization library
99.7 + *
99.8 + * Copyright (C) 2003-2008
99.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
99.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
99.11 + *
99.12 + * Permission to use, modify and distribute this software is granted
99.13 + * provided that this copyright notice appears in all copies. For
99.14 + * precise terms see the accompanying LICENSE file.
99.15 + *
99.16 + * This software is provided "AS IS" with no warranty of any kind,
99.17 + * express or implied, and with no claim as to its suitability for any
99.18 + * purpose.
99.19 + *
99.20 + */
99.21 +
99.22 +#ifndef LEMON_GOMORY_HU_TREE_H
99.23 +#define LEMON_GOMORY_HU_TREE_H
99.24 +
99.25 +#include <limits>
99.26 +
99.27 +#include <lemon/core.h>
99.28 +#include <lemon/preflow.h>
99.29 +#include <lemon/concept_check.h>
99.30 +#include <lemon/concepts/maps.h>
99.31 +
99.32 +/// \ingroup min_cut
99.33 +/// \file
99.34 +/// \brief Gomory-Hu cut tree in graphs.
99.35 +
99.36 +namespace lemon {
99.37 +
99.38 + /// \ingroup min_cut
99.39 + ///
99.40 + /// \brief Gomory-Hu cut tree algorithm
99.41 + ///
99.42 + /// The Gomory-Hu tree is a tree on the node set of a given graph, but it
99.43 + /// may contain edges which are not in the original graph. It has the
99.44 + /// property that the minimum capacity edge of the path between two nodes
99.45 + /// in this tree has the same weight as the minimum cut in the graph
99.46 + /// between these nodes. Moreover the components obtained by removing
99.47 + /// this edge from the tree determine the corresponding minimum cut.
99.48 + /// Therefore once this tree is computed, the minimum cut between any pair
99.49 + /// of nodes can easily be obtained.
99.50 + ///
99.51 + /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
99.52 + /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{e})\f$ overall
99.53 + /// time complexity. It calculates a rooted Gomory-Hu tree.
99.54 + /// The structure of the tree and the edge weights can be
99.55 + /// obtained using \c predNode(), \c predValue() and \c rootDist().
99.56 + /// The functions \c minCutMap() and \c minCutValue() calculate
99.57 + /// the minimum cut and the minimum cut value between any two nodes
99.58 + /// in the graph. You can also list (iterate on) the nodes and the
99.59 + /// edges of the cuts using \c MinCutNodeIt and \c MinCutEdgeIt.
99.60 + ///
99.61 + /// \tparam GR The type of the undirected graph the algorithm runs on.
99.62 + /// \tparam CAP The type of the edge map containing the capacities.
99.63 + /// The default map type is \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
99.64 +#ifdef DOXYGEN
99.65 + template <typename GR,
99.66 + typename CAP>
99.67 +#else
99.68 + template <typename GR,
99.69 + typename CAP = typename GR::template EdgeMap<int> >
99.70 +#endif
99.71 + class GomoryHu {
99.72 + public:
99.73 +
99.74 + /// The graph type of the algorithm
99.75 + typedef GR Graph;
99.76 + /// The capacity map type of the algorithm
99.77 + typedef CAP Capacity;
99.78 + /// The value type of capacities
99.79 + typedef typename Capacity::Value Value;
99.80 +
99.81 + private:
99.82 +
99.83 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
99.84 +
99.85 + const Graph& _graph;
99.86 + const Capacity& _capacity;
99.87 +
99.88 + Node _root;
99.89 + typename Graph::template NodeMap<Node>* _pred;
99.90 + typename Graph::template NodeMap<Value>* _weight;
99.91 + typename Graph::template NodeMap<int>* _order;
99.92 +
99.93 + void createStructures() {
99.94 + if (!_pred) {
99.95 + _pred = new typename Graph::template NodeMap<Node>(_graph);
99.96 + }
99.97 + if (!_weight) {
99.98 + _weight = new typename Graph::template NodeMap<Value>(_graph);
99.99 + }
99.100 + if (!_order) {
99.101 + _order = new typename Graph::template NodeMap<int>(_graph);
99.102 + }
99.103 + }
99.104 +
99.105 + void destroyStructures() {
99.106 + if (_pred) {
99.107 + delete _pred;
99.108 + }
99.109 + if (_weight) {
99.110 + delete _weight;
99.111 + }
99.112 + if (_order) {
99.113 + delete _order;
99.114 + }
99.115 + }
99.116 +
99.117 + public:
99.118 +
99.119 + /// \brief Constructor
99.120 + ///
99.121 + /// Constructor.
99.122 + /// \param graph The undirected graph the algorithm runs on.
99.123 + /// \param capacity The edge capacity map.
99.124 + GomoryHu(const Graph& graph, const Capacity& capacity)
99.125 + : _graph(graph), _capacity(capacity),
99.126 + _pred(0), _weight(0), _order(0)
99.127 + {
99.128 + checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
99.129 + }
99.130 +
99.131 +
99.132 + /// \brief Destructor
99.133 + ///
99.134 + /// Destructor.
99.135 + ~GomoryHu() {
99.136 + destroyStructures();
99.137 + }
99.138 +
99.139 + private:
99.140 +
99.141 + // Initialize the internal data structures
99.142 + void init() {
99.143 + createStructures();
99.144 +
99.145 + _root = NodeIt(_graph);
99.146 + for (NodeIt n(_graph); n != INVALID; ++n) {
99.147 + (*_pred)[n] = _root;
99.148 + (*_order)[n] = -1;
99.149 + }
99.150 + (*_pred)[_root] = INVALID;
99.151 + (*_weight)[_root] = std::numeric_limits<Value>::max();
99.152 + }
99.153 +
99.154 +
99.155 + // Start the algorithm
99.156 + void start() {
99.157 + Preflow<Graph, Capacity> fa(_graph, _capacity, _root, INVALID);
99.158 +
99.159 + for (NodeIt n(_graph); n != INVALID; ++n) {
99.160 + if (n == _root) continue;
99.161 +
99.162 + Node pn = (*_pred)[n];
99.163 + fa.source(n);
99.164 + fa.target(pn);
99.165 +
99.166 + fa.runMinCut();
99.167 +
99.168 + (*_weight)[n] = fa.flowValue();
99.169 +
99.170 + for (NodeIt nn(_graph); nn != INVALID; ++nn) {
99.171 + if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
99.172 + (*_pred)[nn] = n;
99.173 + }
99.174 + }
99.175 + if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
99.176 + (*_pred)[n] = (*_pred)[pn];
99.177 + (*_pred)[pn] = n;
99.178 + (*_weight)[n] = (*_weight)[pn];
99.179 + (*_weight)[pn] = fa.flowValue();
99.180 + }
99.181 + }
99.182 +
99.183 + (*_order)[_root] = 0;
99.184 + int index = 1;
99.185 +
99.186 + for (NodeIt n(_graph); n != INVALID; ++n) {
99.187 + std::vector<Node> st;
99.188 + Node nn = n;
99.189 + while ((*_order)[nn] == -1) {
99.190 + st.push_back(nn);
99.191 + nn = (*_pred)[nn];
99.192 + }
99.193 + while (!st.empty()) {
99.194 + (*_order)[st.back()] = index++;
99.195 + st.pop_back();
99.196 + }
99.197 + }
99.198 + }
99.199 +
99.200 + public:
99.201 +
99.202 + ///\name Execution Control
99.203 +
99.204 + ///@{
99.205 +
99.206 + /// \brief Run the Gomory-Hu algorithm.
99.207 + ///
99.208 + /// This function runs the Gomory-Hu algorithm.
99.209 + void run() {
99.210 + init();
99.211 + start();
99.212 + }
99.213 +
99.214 + /// @}
99.215 +
99.216 + ///\name Query Functions
99.217 + ///The results of the algorithm can be obtained using these
99.218 + ///functions.\n
99.219 + ///\ref run() should be called before using them.\n
99.220 + ///See also \ref MinCutNodeIt and \ref MinCutEdgeIt.
99.221 +
99.222 + ///@{
99.223 +
99.224 + /// \brief Return the predecessor node in the Gomory-Hu tree.
99.225 + ///
99.226 + /// This function returns the predecessor node of the given node
99.227 + /// in the Gomory-Hu tree.
99.228 + /// If \c node is the root of the tree, then it returns \c INVALID.
99.229 + ///
99.230 + /// \pre \ref run() must be called before using this function.
99.231 + Node predNode(const Node& node) const {
99.232 + return (*_pred)[node];
99.233 + }
99.234 +
99.235 + /// \brief Return the weight of the predecessor edge in the
99.236 + /// Gomory-Hu tree.
99.237 + ///
99.238 + /// This function returns the weight of the predecessor edge of the
99.239 + /// given node in the Gomory-Hu tree.
99.240 + /// If \c node is the root of the tree, the result is undefined.
99.241 + ///
99.242 + /// \pre \ref run() must be called before using this function.
99.243 + Value predValue(const Node& node) const {
99.244 + return (*_weight)[node];
99.245 + }
99.246 +
99.247 + /// \brief Return the distance from the root node in the Gomory-Hu tree.
99.248 + ///
99.249 + /// This function returns the distance of the given node from the root
99.250 + /// node in the Gomory-Hu tree.
99.251 + ///
99.252 + /// \pre \ref run() must be called before using this function.
99.253 + int rootDist(const Node& node) const {
99.254 + return (*_order)[node];
99.255 + }
99.256 +
99.257 + /// \brief Return the minimum cut value between two nodes
99.258 + ///
99.259 + /// This function returns the minimum cut value between the nodes
99.260 + /// \c s and \c t.
99.261 + /// It finds the nearest common ancestor of the given nodes in the
99.262 + /// Gomory-Hu tree and calculates the minimum weight edge on the
99.263 + /// paths to the ancestor.
99.264 + ///
99.265 + /// \pre \ref run() must be called before using this function.
99.266 + Value minCutValue(const Node& s, const Node& t) const {
99.267 + Node sn = s, tn = t;
99.268 + Value value = std::numeric_limits<Value>::max();
99.269 +
99.270 + while (sn != tn) {
99.271 + if ((*_order)[sn] < (*_order)[tn]) {
99.272 + if ((*_weight)[tn] <= value) value = (*_weight)[tn];
99.273 + tn = (*_pred)[tn];
99.274 + } else {
99.275 + if ((*_weight)[sn] <= value) value = (*_weight)[sn];
99.276 + sn = (*_pred)[sn];
99.277 + }
99.278 + }
99.279 + return value;
99.280 + }
99.281 +
99.282 + /// \brief Return the minimum cut between two nodes
99.283 + ///
99.284 + /// This function returns the minimum cut between the nodes \c s and \c t
99.285 + /// in the \c cutMap parameter by setting the nodes in the component of
99.286 + /// \c s to \c true and the other nodes to \c false.
99.287 + ///
99.288 + /// For higher level interfaces see MinCutNodeIt and MinCutEdgeIt.
99.289 + ///
99.290 + /// \param s The base node.
99.291 + /// \param t The node you want to separate from node \c s.
99.292 + /// \param cutMap The cut will be returned in this map.
99.293 + /// It must be a \c bool (or convertible) \ref concepts::ReadWriteMap
99.294 + /// "ReadWriteMap" on the graph nodes.
99.295 + ///
99.296 + /// \return The value of the minimum cut between \c s and \c t.
99.297 + ///
99.298 + /// \pre \ref run() must be called before using this function.
99.299 + template <typename CutMap>
99.300 + Value minCutMap(const Node& s, ///<
99.301 + const Node& t,
99.302 + ///<
99.303 + CutMap& cutMap
99.304 + ///<
99.305 + ) const {
99.306 + Node sn = s, tn = t;
99.307 + bool s_root=false;
99.308 + Node rn = INVALID;
99.309 + Value value = std::numeric_limits<Value>::max();
99.310 +
99.311 + while (sn != tn) {
99.312 + if ((*_order)[sn] < (*_order)[tn]) {
99.313 + if ((*_weight)[tn] <= value) {
99.314 + rn = tn;
99.315 + s_root = false;
99.316 + value = (*_weight)[tn];
99.317 + }
99.318 + tn = (*_pred)[tn];
99.319 + } else {
99.320 + if ((*_weight)[sn] <= value) {
99.321 + rn = sn;
99.322 + s_root = true;
99.323 + value = (*_weight)[sn];
99.324 + }
99.325 + sn = (*_pred)[sn];
99.326 + }
99.327 + }
99.328 +
99.329 + typename Graph::template NodeMap<bool> reached(_graph, false);
99.330 + reached[_root] = true;
99.331 + cutMap.set(_root, !s_root);
99.332 + reached[rn] = true;
99.333 + cutMap.set(rn, s_root);
99.334 +
99.335 + std::vector<Node> st;
99.336 + for (NodeIt n(_graph); n != INVALID; ++n) {
99.337 + st.clear();
99.338 + Node nn = n;
99.339 + while (!reached[nn]) {
99.340 + st.push_back(nn);
99.341 + nn = (*_pred)[nn];
99.342 + }
99.343 + while (!st.empty()) {
99.344 + cutMap.set(st.back(), cutMap[nn]);
99.345 + st.pop_back();
99.346 + }
99.347 + }
99.348 +
99.349 + return value;
99.350 + }
99.351 +
99.352 + ///@}
99.353 +
99.354 + friend class MinCutNodeIt;
99.355 +
99.356 + /// Iterate on the nodes of a minimum cut
99.357 +
99.358 + /// This iterator class lists the nodes of a minimum cut found by
99.359 + /// GomoryHu. Before using it, you must allocate a GomoryHu class
99.360 + /// and call its \ref GomoryHu::run() "run()" method.
99.361 + ///
99.362 + /// This example counts the nodes in the minimum cut separating \c s from
99.363 + /// \c t.
99.364 + /// \code
99.365 + /// GomoruHu<Graph> gom(g, capacities);
99.366 + /// gom.run();
99.367 + /// int cnt=0;
99.368 + /// for(GomoruHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
99.369 + /// \endcode
99.370 + class MinCutNodeIt
99.371 + {
99.372 + bool _side;
99.373 + typename Graph::NodeIt _node_it;
99.374 + typename Graph::template NodeMap<bool> _cut;
99.375 + public:
99.376 + /// Constructor
99.377 +
99.378 + /// Constructor.
99.379 + ///
99.380 + MinCutNodeIt(GomoryHu const &gomory,
99.381 + ///< The GomoryHu class. You must call its
99.382 + /// run() method
99.383 + /// before initializing this iterator.
99.384 + const Node& s, ///< The base node.
99.385 + const Node& t,
99.386 + ///< The node you want to separate from node \c s.
99.387 + bool side=true
99.388 + ///< If it is \c true (default) then the iterator lists
99.389 + /// the nodes of the component containing \c s,
99.390 + /// otherwise it lists the other component.
99.391 + /// \note As the minimum cut is not always unique,
99.392 + /// \code
99.393 + /// MinCutNodeIt(gomory, s, t, true);
99.394 + /// \endcode
99.395 + /// and
99.396 + /// \code
99.397 + /// MinCutNodeIt(gomory, t, s, false);
99.398 + /// \endcode
99.399 + /// does not necessarily give the same set of nodes.
99.400 + /// However it is ensured that
99.401 + /// \code
99.402 + /// MinCutNodeIt(gomory, s, t, true);
99.403 + /// \endcode
99.404 + /// and
99.405 + /// \code
99.406 + /// MinCutNodeIt(gomory, s, t, false);
99.407 + /// \endcode
99.408 + /// together list each node exactly once.
99.409 + )
99.410 + : _side(side), _cut(gomory._graph)
99.411 + {
99.412 + gomory.minCutMap(s,t,_cut);
99.413 + for(_node_it=typename Graph::NodeIt(gomory._graph);
99.414 + _node_it!=INVALID && _cut[_node_it]!=_side;
99.415 + ++_node_it) {}
99.416 + }
99.417 + /// Conversion to \c Node
99.418 +
99.419 + /// Conversion to \c Node.
99.420 + ///
99.421 + operator typename Graph::Node() const
99.422 + {
99.423 + return _node_it;
99.424 + }
99.425 + bool operator==(Invalid) { return _node_it==INVALID; }
99.426 + bool operator!=(Invalid) { return _node_it!=INVALID; }
99.427 + /// Next node
99.428 +
99.429 + /// Next node.
99.430 + ///
99.431 + MinCutNodeIt &operator++()
99.432 + {
99.433 + for(++_node_it;_node_it!=INVALID&&_cut[_node_it]!=_side;++_node_it) {}
99.434 + return *this;
99.435 + }
99.436 + /// Postfix incrementation
99.437 +
99.438 + /// Postfix incrementation.
99.439 + ///
99.440 + /// \warning This incrementation
99.441 + /// returns a \c Node, not a \c MinCutNodeIt, as one may
99.442 + /// expect.
99.443 + typename Graph::Node operator++(int)
99.444 + {
99.445 + typename Graph::Node n=*this;
99.446 + ++(*this);
99.447 + return n;
99.448 + }
99.449 + };
99.450 +
99.451 + friend class MinCutEdgeIt;
99.452 +
99.453 + /// Iterate on the edges of a minimum cut
99.454 +
99.455 + /// This iterator class lists the edges of a minimum cut found by
99.456 + /// GomoryHu. Before using it, you must allocate a GomoryHu class
99.457 + /// and call its \ref GomoryHu::run() "run()" method.
99.458 + ///
99.459 + /// This example computes the value of the minimum cut separating \c s from
99.460 + /// \c t.
99.461 + /// \code
99.462 + /// GomoruHu<Graph> gom(g, capacities);
99.463 + /// gom.run();
99.464 + /// int value=0;
99.465 + /// for(GomoruHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
99.466 + /// value+=capacities[e];
99.467 + /// \endcode
99.468 + /// The result will be the same as the value returned by
99.469 + /// \ref GomoryHu::minCutValue() "gom.minCutValue(s,t)".
99.470 + class MinCutEdgeIt
99.471 + {
99.472 + bool _side;
99.473 + const Graph &_graph;
99.474 + typename Graph::NodeIt _node_it;
99.475 + typename Graph::OutArcIt _arc_it;
99.476 + typename Graph::template NodeMap<bool> _cut;
99.477 + void step()
99.478 + {
99.479 + ++_arc_it;
99.480 + while(_node_it!=INVALID && _arc_it==INVALID)
99.481 + {
99.482 + for(++_node_it;_node_it!=INVALID&&!_cut[_node_it];++_node_it) {}
99.483 + if(_node_it!=INVALID)
99.484 + _arc_it=typename Graph::OutArcIt(_graph,_node_it);
99.485 + }
99.486 + }
99.487 +
99.488 + public:
99.489 + /// Constructor
99.490 +
99.491 + /// Constructor.
99.492 + ///
99.493 + MinCutEdgeIt(GomoryHu const &gomory,
99.494 + ///< The GomoryHu class. You must call its
99.495 + /// run() method
99.496 + /// before initializing this iterator.
99.497 + const Node& s, ///< The base node.
99.498 + const Node& t,
99.499 + ///< The node you want to separate from node \c s.
99.500 + bool side=true
99.501 + ///< If it is \c true (default) then the listed arcs
99.502 + /// will be oriented from the
99.503 + /// nodes of the component containing \c s,
99.504 + /// otherwise they will be oriented in the opposite
99.505 + /// direction.
99.506 + )
99.507 + : _graph(gomory._graph), _cut(_graph)
99.508 + {
99.509 + gomory.minCutMap(s,t,_cut);
99.510 + if(!side)
99.511 + for(typename Graph::NodeIt n(_graph);n!=INVALID;++n)
99.512 + _cut[n]=!_cut[n];
99.513 +
99.514 + for(_node_it=typename Graph::NodeIt(_graph);
99.515 + _node_it!=INVALID && !_cut[_node_it];
99.516 + ++_node_it) {}
99.517 + _arc_it = _node_it!=INVALID ?
99.518 + typename Graph::OutArcIt(_graph,_node_it) : INVALID;
99.519 + while(_node_it!=INVALID && _arc_it == INVALID)
99.520 + {
99.521 + for(++_node_it; _node_it!=INVALID&&!_cut[_node_it]; ++_node_it) {}
99.522 + if(_node_it!=INVALID)
99.523 + _arc_it= typename Graph::OutArcIt(_graph,_node_it);
99.524 + }
99.525 + while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
99.526 + }
99.527 + /// Conversion to \c Arc
99.528 +
99.529 + /// Conversion to \c Arc.
99.530 + ///
99.531 + operator typename Graph::Arc() const
99.532 + {
99.533 + return _arc_it;
99.534 + }
99.535 + /// Conversion to \c Edge
99.536 +
99.537 + /// Conversion to \c Edge.
99.538 + ///
99.539 + operator typename Graph::Edge() const
99.540 + {
99.541 + return _arc_it;
99.542 + }
99.543 + bool operator==(Invalid) { return _node_it==INVALID; }
99.544 + bool operator!=(Invalid) { return _node_it!=INVALID; }
99.545 + /// Next edge
99.546 +
99.547 + /// Next edge.
99.548 + ///
99.549 + MinCutEdgeIt &operator++()
99.550 + {
99.551 + step();
99.552 + while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
99.553 + return *this;
99.554 + }
99.555 + /// Postfix incrementation
99.556 +
99.557 + /// Postfix incrementation.
99.558 + ///
99.559 + /// \warning This incrementation
99.560 + /// returns an \c Arc, not a \c MinCutEdgeIt, as one may expect.
99.561 + typename Graph::Arc operator++(int)
99.562 + {
99.563 + typename Graph::Arc e=*this;
99.564 + ++(*this);
99.565 + return e;
99.566 + }
99.567 + };
99.568 +
99.569 + };
99.570 +
99.571 +}
99.572 +
99.573 +#endif
100.1 --- a/lemon/graph_to_eps.h Fri Nov 13 12:33:33 2009 +0100
100.2 +++ b/lemon/graph_to_eps.h Thu Dec 10 17:05:35 2009 +0100
100.3 @@ -2,7 +2,7 @@
100.4 *
100.5 * This file is a part of LEMON, a generic C++ optimization library.
100.6 *
100.7 - * Copyright (C) 2003-2008
100.8 + * Copyright (C) 2003-2009
100.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
100.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
100.11 *
100.12 @@ -64,11 +64,12 @@
100.13
100.14 ///Default traits class of \ref GraphToEps.
100.15 ///
100.16 -///\c G is the type of the underlying graph.
100.17 -template<class G>
100.18 +///\param GR is the type of the underlying graph.
100.19 +template<class GR>
100.20 struct DefaultGraphToEpsTraits
100.21 {
100.22 - typedef G Graph;
100.23 + typedef GR Graph;
100.24 + typedef GR Digraph;
100.25 typedef typename Graph::Node Node;
100.26 typedef typename Graph::NodeIt NodeIt;
100.27 typedef typename Graph::Arc Arc;
100.28 @@ -139,15 +140,14 @@
100.29 ///Constructor
100.30
100.31 ///Constructor
100.32 - ///\param _g Reference to the graph to be printed.
100.33 - ///\param _os Reference to the output stream.
100.34 - ///\param _os Reference to the output stream.
100.35 + ///\param gr Reference to the graph to be printed.
100.36 + ///\param ost Reference to the output stream.
100.37 ///By default it is <tt>std::cout</tt>.
100.38 - ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
100.39 + ///\param pros If it is \c true, then the \c ostream referenced by \c os
100.40 ///will be explicitly deallocated by the destructor.
100.41 - DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
100.42 - bool _pros=false) :
100.43 - g(_g), os(_os),
100.44 + DefaultGraphToEpsTraits(const GR &gr, std::ostream& ost = std::cout,
100.45 + bool pros = false) :
100.46 + g(gr), os(ost),
100.47 _coords(dim2::Point<double>(1,1)), _nodeSizes(1), _nodeShapes(0),
100.48 _nodeColors(WHITE), _arcColors(BLACK),
100.49 _arcWidths(1.0), _arcWidthScale(0.003),
100.50 @@ -158,8 +158,8 @@
100.51 _enableParallel(false), _parArcDist(1),
100.52 _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
100.53 _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
100.54 - _undirected(lemon::UndirectedTagIndicator<G>::value),
100.55 - _pleaseRemoveOsStream(_pros), _scaleToA4(false),
100.56 + _undirected(lemon::UndirectedTagIndicator<GR>::value),
100.57 + _pleaseRemoveOsStream(pros), _scaleToA4(false),
100.58 _nodeTextColorType(SAME_COL), _nodeTextColors(BLACK),
100.59 _autoNodeScale(false),
100.60 _autoArcWidthScale(false),
100.61 @@ -242,6 +242,7 @@
100.62 // dradnats ++C eht yb deriuqer si ti eveileb t'naC
100.63
100.64 typedef typename T::Graph Graph;
100.65 + typedef typename T::Digraph Digraph;
100.66 typedef typename Graph::Node Node;
100.67 typedef typename Graph::NodeIt NodeIt;
100.68 typedef typename Graph::Arc Arc;
100.69 @@ -269,22 +270,18 @@
100.70 /// = 1
100.71 ///\image html nodeshape_1.png
100.72 ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm
100.73 - ///
100.74 SQUARE=1,
100.75 /// = 2
100.76 ///\image html nodeshape_2.png
100.77 ///\image latex nodeshape_2.eps "DIAMOND shape (2)" width=2cm
100.78 - ///
100.79 DIAMOND=2,
100.80 /// = 3
100.81 ///\image html nodeshape_3.png
100.82 - ///\image latex nodeshape_2.eps "MALE shape (4)" width=2cm
100.83 - ///
100.84 + ///\image latex nodeshape_3.eps "MALE shape (3)" width=2cm
100.85 MALE=3,
100.86 /// = 4
100.87 ///\image html nodeshape_4.png
100.88 - ///\image latex nodeshape_2.eps "FEMALE shape (4)" width=2cm
100.89 - ///
100.90 + ///\image latex nodeshape_4.eps "FEMALE shape (4)" width=2cm
100.91 FEMALE=4
100.92 };
100.93
100.94 @@ -1134,55 +1131,55 @@
100.95 ///\warning Don't forget to put the \ref GraphToEps::run() "run()"
100.96 ///to the end of the parameter list.
100.97 ///\sa GraphToEps
100.98 -///\sa graphToEps(G &g, const char *file_name)
100.99 -template<class G>
100.100 -GraphToEps<DefaultGraphToEpsTraits<G> >
100.101 -graphToEps(G &g, std::ostream& os=std::cout)
100.102 +///\sa graphToEps(GR &g, const char *file_name)
100.103 +template<class GR>
100.104 +GraphToEps<DefaultGraphToEpsTraits<GR> >
100.105 +graphToEps(GR &g, std::ostream& os=std::cout)
100.106 {
100.107 return
100.108 - GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
100.109 + GraphToEps<DefaultGraphToEpsTraits<GR> >(DefaultGraphToEpsTraits<GR>(g,os));
100.110 }
100.111
100.112 ///Generates an EPS file from a graph
100.113
100.114 ///\ingroup eps_io
100.115 ///This function does the same as
100.116 -///\ref graphToEps(G &g,std::ostream& os)
100.117 +///\ref graphToEps(GR &g,std::ostream& os)
100.118 ///but it writes its output into the file \c file_name
100.119 ///instead of a stream.
100.120 -///\sa graphToEps(G &g, std::ostream& os)
100.121 -template<class G>
100.122 -GraphToEps<DefaultGraphToEpsTraits<G> >
100.123 -graphToEps(G &g,const char *file_name)
100.124 +///\sa graphToEps(GR &g, std::ostream& os)
100.125 +template<class GR>
100.126 +GraphToEps<DefaultGraphToEpsTraits<GR> >
100.127 +graphToEps(GR &g,const char *file_name)
100.128 {
100.129 std::ostream* os = new std::ofstream(file_name);
100.130 if (!(*os)) {
100.131 delete os;
100.132 throw IoError("Cannot write file", file_name);
100.133 }
100.134 - return GraphToEps<DefaultGraphToEpsTraits<G> >
100.135 - (DefaultGraphToEpsTraits<G>(g,*os,true));
100.136 + return GraphToEps<DefaultGraphToEpsTraits<GR> >
100.137 + (DefaultGraphToEpsTraits<GR>(g,*os,true));
100.138 }
100.139
100.140 ///Generates an EPS file from a graph
100.141
100.142 ///\ingroup eps_io
100.143 ///This function does the same as
100.144 -///\ref graphToEps(G &g,std::ostream& os)
100.145 +///\ref graphToEps(GR &g,std::ostream& os)
100.146 ///but it writes its output into the file \c file_name
100.147 ///instead of a stream.
100.148 -///\sa graphToEps(G &g, std::ostream& os)
100.149 -template<class G>
100.150 -GraphToEps<DefaultGraphToEpsTraits<G> >
100.151 -graphToEps(G &g,const std::string& file_name)
100.152 +///\sa graphToEps(GR &g, std::ostream& os)
100.153 +template<class GR>
100.154 +GraphToEps<DefaultGraphToEpsTraits<GR> >
100.155 +graphToEps(GR &g,const std::string& file_name)
100.156 {
100.157 std::ostream* os = new std::ofstream(file_name.c_str());
100.158 if (!(*os)) {
100.159 delete os;
100.160 throw IoError("Cannot write file", file_name);
100.161 }
100.162 - return GraphToEps<DefaultGraphToEpsTraits<G> >
100.163 - (DefaultGraphToEpsTraits<G>(g,*os,true));
100.164 + return GraphToEps<DefaultGraphToEpsTraits<GR> >
100.165 + (DefaultGraphToEpsTraits<GR>(g,*os,true));
100.166 }
100.167
100.168 } //END OF NAMESPACE LEMON
101.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
101.2 +++ b/lemon/grid_graph.h Thu Dec 10 17:05:35 2009 +0100
101.3 @@ -0,0 +1,703 @@
101.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
101.5 + *
101.6 + * This file is a part of LEMON, a generic C++ optimization library.
101.7 + *
101.8 + * Copyright (C) 2003-2009
101.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
101.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
101.11 + *
101.12 + * Permission to use, modify and distribute this software is granted
101.13 + * provided that this copyright notice appears in all copies. For
101.14 + * precise terms see the accompanying LICENSE file.
101.15 + *
101.16 + * This software is provided "AS IS" with no warranty of any kind,
101.17 + * express or implied, and with no claim as to its suitability for any
101.18 + * purpose.
101.19 + *
101.20 + */
101.21 +
101.22 +#ifndef GRID_GRAPH_H
101.23 +#define GRID_GRAPH_H
101.24 +
101.25 +#include <lemon/core.h>
101.26 +#include <lemon/bits/graph_extender.h>
101.27 +#include <lemon/dim2.h>
101.28 +#include <lemon/assert.h>
101.29 +
101.30 +///\ingroup graphs
101.31 +///\file
101.32 +///\brief GridGraph class.
101.33 +
101.34 +namespace lemon {
101.35 +
101.36 + class GridGraphBase {
101.37 +
101.38 + public:
101.39 +
101.40 + typedef GridGraphBase Graph;
101.41 +
101.42 + class Node;
101.43 + class Edge;
101.44 + class Arc;
101.45 +
101.46 + public:
101.47 +
101.48 + GridGraphBase() {}
101.49 +
101.50 + protected:
101.51 +
101.52 + void construct(int width, int height) {
101.53 + _width = width; _height = height;
101.54 + _node_num = width * height;
101.55 + _edge_num = 2 * _node_num - width - height;
101.56 + _edge_limit = _node_num - _width;
101.57 + }
101.58 +
101.59 + public:
101.60 +
101.61 + Node operator()(int i, int j) const {
101.62 + LEMON_DEBUG(0 <= i && i < _width &&
101.63 + 0 <= j && j < _height, "Index out of range");
101.64 + return Node(i + j * _width);
101.65 + }
101.66 +
101.67 + int col(Node n) const {
101.68 + return n._id % _width;
101.69 + }
101.70 +
101.71 + int row(Node n) const {
101.72 + return n._id / _width;
101.73 + }
101.74 +
101.75 + dim2::Point<int> pos(Node n) const {
101.76 + return dim2::Point<int>(col(n), row(n));
101.77 + }
101.78 +
101.79 + int width() const {
101.80 + return _width;
101.81 + }
101.82 +
101.83 + int height() const {
101.84 + return _height;
101.85 + }
101.86 +
101.87 + typedef True NodeNumTag;
101.88 + typedef True EdgeNumTag;
101.89 + typedef True ArcNumTag;
101.90 +
101.91 + int nodeNum() const { return _node_num; }
101.92 + int edgeNum() const { return _edge_num; }
101.93 + int arcNum() const { return 2 * _edge_num; }
101.94 +
101.95 + Node u(Edge edge) const {
101.96 + if (edge._id < _edge_limit) {
101.97 + return edge._id;
101.98 + } else {
101.99 + return (edge._id - _edge_limit) % (_width - 1) +
101.100 + (edge._id - _edge_limit) / (_width - 1) * _width;
101.101 + }
101.102 + }
101.103 +
101.104 + Node v(Edge edge) const {
101.105 + if (edge._id < _edge_limit) {
101.106 + return edge._id + _width;
101.107 + } else {
101.108 + return (edge._id - _edge_limit) % (_width - 1) +
101.109 + (edge._id - _edge_limit) / (_width - 1) * _width + 1;
101.110 + }
101.111 + }
101.112 +
101.113 + Node source(Arc arc) const {
101.114 + return (arc._id & 1) == 1 ? u(arc) : v(arc);
101.115 + }
101.116 +
101.117 + Node target(Arc arc) const {
101.118 + return (arc._id & 1) == 1 ? v(arc) : u(arc);
101.119 + }
101.120 +
101.121 + static int id(Node node) { return node._id; }
101.122 + static int id(Edge edge) { return edge._id; }
101.123 + static int id(Arc arc) { return arc._id; }
101.124 +
101.125 + int maxNodeId() const { return _node_num - 1; }
101.126 + int maxEdgeId() const { return _edge_num - 1; }
101.127 + int maxArcId() const { return 2 * _edge_num - 1; }
101.128 +
101.129 + static Node nodeFromId(int id) { return Node(id);}
101.130 + static Edge edgeFromId(int id) { return Edge(id);}
101.131 + static Arc arcFromId(int id) { return Arc(id);}
101.132 +
101.133 + typedef True FindEdgeTag;
101.134 + typedef True FindArcTag;
101.135 +
101.136 + Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
101.137 + if (prev != INVALID) return INVALID;
101.138 + if (v._id > u._id) {
101.139 + if (v._id - u._id == _width)
101.140 + return Edge(u._id);
101.141 + if (v._id - u._id == 1 && u._id % _width < _width - 1) {
101.142 + return Edge(u._id / _width * (_width - 1) +
101.143 + u._id % _width + _edge_limit);
101.144 + }
101.145 + } else {
101.146 + if (u._id - v._id == _width)
101.147 + return Edge(v._id);
101.148 + if (u._id - v._id == 1 && v._id % _width < _width - 1) {
101.149 + return Edge(v._id / _width * (_width - 1) +
101.150 + v._id % _width + _edge_limit);
101.151 + }
101.152 + }
101.153 + return INVALID;
101.154 + }
101.155 +
101.156 + Arc findArc(Node u, Node v, Arc prev = INVALID) const {
101.157 + if (prev != INVALID) return INVALID;
101.158 + if (v._id > u._id) {
101.159 + if (v._id - u._id == _width)
101.160 + return Arc((u._id << 1) | 1);
101.161 + if (v._id - u._id == 1 && u._id % _width < _width - 1) {
101.162 + return Arc(((u._id / _width * (_width - 1) +
101.163 + u._id % _width + _edge_limit) << 1) | 1);
101.164 + }
101.165 + } else {
101.166 + if (u._id - v._id == _width)
101.167 + return Arc(v._id << 1);
101.168 + if (u._id - v._id == 1 && v._id % _width < _width - 1) {
101.169 + return Arc((v._id / _width * (_width - 1) +
101.170 + v._id % _width + _edge_limit) << 1);
101.171 + }
101.172 + }
101.173 + return INVALID;
101.174 + }
101.175 +
101.176 + class Node {
101.177 + friend class GridGraphBase;
101.178 +
101.179 + protected:
101.180 + int _id;
101.181 + Node(int id) : _id(id) {}
101.182 + public:
101.183 + Node() {}
101.184 + Node (Invalid) : _id(-1) {}
101.185 + bool operator==(const Node node) const {return _id == node._id;}
101.186 + bool operator!=(const Node node) const {return _id != node._id;}
101.187 + bool operator<(const Node node) const {return _id < node._id;}
101.188 + };
101.189 +
101.190 + class Edge {
101.191 + friend class GridGraphBase;
101.192 + friend class Arc;
101.193 +
101.194 + protected:
101.195 + int _id;
101.196 +
101.197 + Edge(int id) : _id(id) {}
101.198 +
101.199 + public:
101.200 + Edge() {}
101.201 + Edge (Invalid) : _id(-1) {}
101.202 + bool operator==(const Edge edge) const {return _id == edge._id;}
101.203 + bool operator!=(const Edge edge) const {return _id != edge._id;}
101.204 + bool operator<(const Edge edge) const {return _id < edge._id;}
101.205 + };
101.206 +
101.207 + class Arc {
101.208 + friend class GridGraphBase;
101.209 +
101.210 + protected:
101.211 + int _id;
101.212 +
101.213 + Arc(int id) : _id(id) {}
101.214 +
101.215 + public:
101.216 + Arc() {}
101.217 + Arc (Invalid) : _id(-1) {}
101.218 + operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
101.219 + bool operator==(const Arc arc) const {return _id == arc._id;}
101.220 + bool operator!=(const Arc arc) const {return _id != arc._id;}
101.221 + bool operator<(const Arc arc) const {return _id < arc._id;}
101.222 + };
101.223 +
101.224 + static bool direction(Arc arc) {
101.225 + return (arc._id & 1) == 1;
101.226 + }
101.227 +
101.228 + static Arc direct(Edge edge, bool dir) {
101.229 + return Arc((edge._id << 1) | (dir ? 1 : 0));
101.230 + }
101.231 +
101.232 + void first(Node& node) const {
101.233 + node._id = _node_num - 1;
101.234 + }
101.235 +
101.236 + static void next(Node& node) {
101.237 + --node._id;
101.238 + }
101.239 +
101.240 + void first(Edge& edge) const {
101.241 + edge._id = _edge_num - 1;
101.242 + }
101.243 +
101.244 + static void next(Edge& edge) {
101.245 + --edge._id;
101.246 + }
101.247 +
101.248 + void first(Arc& arc) const {
101.249 + arc._id = 2 * _edge_num - 1;
101.250 + }
101.251 +
101.252 + static void next(Arc& arc) {
101.253 + --arc._id;
101.254 + }
101.255 +
101.256 + void firstOut(Arc& arc, const Node& node) const {
101.257 + if (node._id % _width < _width - 1) {
101.258 + arc._id = (_edge_limit + node._id % _width +
101.259 + (node._id / _width) * (_width - 1)) << 1 | 1;
101.260 + return;
101.261 + }
101.262 + if (node._id < _node_num - _width) {
101.263 + arc._id = node._id << 1 | 1;
101.264 + return;
101.265 + }
101.266 + if (node._id % _width > 0) {
101.267 + arc._id = (_edge_limit + node._id % _width +
101.268 + (node._id / _width) * (_width - 1) - 1) << 1;
101.269 + return;
101.270 + }
101.271 + if (node._id >= _width) {
101.272 + arc._id = (node._id - _width) << 1;
101.273 + return;
101.274 + }
101.275 + arc._id = -1;
101.276 + }
101.277 +
101.278 + void nextOut(Arc& arc) const {
101.279 + int nid = arc._id >> 1;
101.280 + if ((arc._id & 1) == 1) {
101.281 + if (nid >= _edge_limit) {
101.282 + nid = (nid - _edge_limit) % (_width - 1) +
101.283 + (nid - _edge_limit) / (_width - 1) * _width;
101.284 + if (nid < _node_num - _width) {
101.285 + arc._id = nid << 1 | 1;
101.286 + return;
101.287 + }
101.288 + }
101.289 + if (nid % _width > 0) {
101.290 + arc._id = (_edge_limit + nid % _width +
101.291 + (nid / _width) * (_width - 1) - 1) << 1;
101.292 + return;
101.293 + }
101.294 + if (nid >= _width) {
101.295 + arc._id = (nid - _width) << 1;
101.296 + return;
101.297 + }
101.298 + } else {
101.299 + if (nid >= _edge_limit) {
101.300 + nid = (nid - _edge_limit) % (_width - 1) +
101.301 + (nid - _edge_limit) / (_width - 1) * _width + 1;
101.302 + if (nid >= _width) {
101.303 + arc._id = (nid - _width) << 1;
101.304 + return;
101.305 + }
101.306 + }
101.307 + }
101.308 + arc._id = -1;
101.309 + }
101.310 +
101.311 + void firstIn(Arc& arc, const Node& node) const {
101.312 + if (node._id % _width < _width - 1) {
101.313 + arc._id = (_edge_limit + node._id % _width +
101.314 + (node._id / _width) * (_width - 1)) << 1;
101.315 + return;
101.316 + }
101.317 + if (node._id < _node_num - _width) {
101.318 + arc._id = node._id << 1;
101.319 + return;
101.320 + }
101.321 + if (node._id % _width > 0) {
101.322 + arc._id = (_edge_limit + node._id % _width +
101.323 + (node._id / _width) * (_width - 1) - 1) << 1 | 1;
101.324 + return;
101.325 + }
101.326 + if (node._id >= _width) {
101.327 + arc._id = (node._id - _width) << 1 | 1;
101.328 + return;
101.329 + }
101.330 + arc._id = -1;
101.331 + }
101.332 +
101.333 + void nextIn(Arc& arc) const {
101.334 + int nid = arc._id >> 1;
101.335 + if ((arc._id & 1) == 0) {
101.336 + if (nid >= _edge_limit) {
101.337 + nid = (nid - _edge_limit) % (_width - 1) +
101.338 + (nid - _edge_limit) / (_width - 1) * _width;
101.339 + if (nid < _node_num - _width) {
101.340 + arc._id = nid << 1;
101.341 + return;
101.342 + }
101.343 + }
101.344 + if (nid % _width > 0) {
101.345 + arc._id = (_edge_limit + nid % _width +
101.346 + (nid / _width) * (_width - 1) - 1) << 1 | 1;
101.347 + return;
101.348 + }
101.349 + if (nid >= _width) {
101.350 + arc._id = (nid - _width) << 1 | 1;
101.351 + return;
101.352 + }
101.353 + } else {
101.354 + if (nid >= _edge_limit) {
101.355 + nid = (nid - _edge_limit) % (_width - 1) +
101.356 + (nid - _edge_limit) / (_width - 1) * _width + 1;
101.357 + if (nid >= _width) {
101.358 + arc._id = (nid - _width) << 1 | 1;
101.359 + return;
101.360 + }
101.361 + }
101.362 + }
101.363 + arc._id = -1;
101.364 + }
101.365 +
101.366 + void firstInc(Edge& edge, bool& dir, const Node& node) const {
101.367 + if (node._id % _width < _width - 1) {
101.368 + edge._id = _edge_limit + node._id % _width +
101.369 + (node._id / _width) * (_width - 1);
101.370 + dir = true;
101.371 + return;
101.372 + }
101.373 + if (node._id < _node_num - _width) {
101.374 + edge._id = node._id;
101.375 + dir = true;
101.376 + return;
101.377 + }
101.378 + if (node._id % _width > 0) {
101.379 + edge._id = _edge_limit + node._id % _width +
101.380 + (node._id / _width) * (_width - 1) - 1;
101.381 + dir = false;
101.382 + return;
101.383 + }
101.384 + if (node._id >= _width) {
101.385 + edge._id = node._id - _width;
101.386 + dir = false;
101.387 + return;
101.388 + }
101.389 + edge._id = -1;
101.390 + dir = true;
101.391 + }
101.392 +
101.393 + void nextInc(Edge& edge, bool& dir) const {
101.394 + int nid = edge._id;
101.395 + if (dir) {
101.396 + if (nid >= _edge_limit) {
101.397 + nid = (nid - _edge_limit) % (_width - 1) +
101.398 + (nid - _edge_limit) / (_width - 1) * _width;
101.399 + if (nid < _node_num - _width) {
101.400 + edge._id = nid;
101.401 + return;
101.402 + }
101.403 + }
101.404 + if (nid % _width > 0) {
101.405 + edge._id = _edge_limit + nid % _width +
101.406 + (nid / _width) * (_width - 1) - 1;
101.407 + dir = false;
101.408 + return;
101.409 + }
101.410 + if (nid >= _width) {
101.411 + edge._id = nid - _width;
101.412 + dir = false;
101.413 + return;
101.414 + }
101.415 + } else {
101.416 + if (nid >= _edge_limit) {
101.417 + nid = (nid - _edge_limit) % (_width - 1) +
101.418 + (nid - _edge_limit) / (_width - 1) * _width + 1;
101.419 + if (nid >= _width) {
101.420 + edge._id = nid - _width;
101.421 + return;
101.422 + }
101.423 + }
101.424 + }
101.425 + edge._id = -1;
101.426 + dir = true;
101.427 + }
101.428 +
101.429 + Arc right(Node n) const {
101.430 + if (n._id % _width < _width - 1) {
101.431 + return Arc(((_edge_limit + n._id % _width +
101.432 + (n._id / _width) * (_width - 1)) << 1) | 1);
101.433 + } else {
101.434 + return INVALID;
101.435 + }
101.436 + }
101.437 +
101.438 + Arc left(Node n) const {
101.439 + if (n._id % _width > 0) {
101.440 + return Arc((_edge_limit + n._id % _width +
101.441 + (n._id / _width) * (_width - 1) - 1) << 1);
101.442 + } else {
101.443 + return INVALID;
101.444 + }
101.445 + }
101.446 +
101.447 + Arc up(Node n) const {
101.448 + if (n._id < _edge_limit) {
101.449 + return Arc((n._id << 1) | 1);
101.450 + } else {
101.451 + return INVALID;
101.452 + }
101.453 + }
101.454 +
101.455 + Arc down(Node n) const {
101.456 + if (n._id >= _width) {
101.457 + return Arc((n._id - _width) << 1);
101.458 + } else {
101.459 + return INVALID;
101.460 + }
101.461 + }
101.462 +
101.463 + private:
101.464 + int _width, _height;
101.465 + int _node_num, _edge_num;
101.466 + int _edge_limit;
101.467 + };
101.468 +
101.469 +
101.470 + typedef GraphExtender<GridGraphBase> ExtendedGridGraphBase;
101.471 +
101.472 + /// \ingroup graphs
101.473 + ///
101.474 + /// \brief Grid graph class
101.475 + ///
101.476 + /// This class implements a special graph type. The nodes of the
101.477 + /// graph can be indexed by two integer \c (i,j) value where \c i is
101.478 + /// in the \c [0..width()-1] range and j is in the \c
101.479 + /// [0..height()-1] range. Two nodes are connected in the graph if
101.480 + /// the indexes differ exactly on one position and exactly one is
101.481 + /// the difference. The nodes of the graph can be indexed by position
101.482 + /// with the \c operator()() function. The positions of the nodes can be
101.483 + /// get with \c pos(), \c col() and \c row() members. The outgoing
101.484 + /// arcs can be retrieved with the \c right(), \c up(), \c left()
101.485 + /// and \c down() functions, where the bottom-left corner is the
101.486 + /// origin.
101.487 + ///
101.488 + /// \image html grid_graph.png
101.489 + /// \image latex grid_graph.eps "Grid graph" width=\textwidth
101.490 + ///
101.491 + /// A short example about the basic usage:
101.492 + ///\code
101.493 + /// GridGraph graph(rows, cols);
101.494 + /// GridGraph::NodeMap<int> val(graph);
101.495 + /// for (int i = 0; i < graph.width(); ++i) {
101.496 + /// for (int j = 0; j < graph.height(); ++j) {
101.497 + /// val[graph(i, j)] = i + j;
101.498 + /// }
101.499 + /// }
101.500 + ///\endcode
101.501 + ///
101.502 + /// This graph type fully conforms to the \ref concepts::Graph
101.503 + /// "Graph concept".
101.504 + class GridGraph : public ExtendedGridGraphBase {
101.505 + typedef ExtendedGridGraphBase Parent;
101.506 +
101.507 + public:
101.508 +
101.509 + /// \brief Map to get the indices of the nodes as dim2::Point<int>.
101.510 + ///
101.511 + /// Map to get the indices of the nodes as dim2::Point<int>.
101.512 + class IndexMap {
101.513 + public:
101.514 + /// \brief The key type of the map
101.515 + typedef GridGraph::Node Key;
101.516 + /// \brief The value type of the map
101.517 + typedef dim2::Point<int> Value;
101.518 +
101.519 + /// \brief Constructor
101.520 + ///
101.521 + /// Constructor
101.522 + IndexMap(const GridGraph& graph) : _graph(graph) {}
101.523 +
101.524 + /// \brief The subscript operator
101.525 + ///
101.526 + /// The subscript operator.
101.527 + Value operator[](Key key) const {
101.528 + return _graph.pos(key);
101.529 + }
101.530 +
101.531 + private:
101.532 + const GridGraph& _graph;
101.533 + };
101.534 +
101.535 + /// \brief Map to get the column of the nodes.
101.536 + ///
101.537 + /// Map to get the column of the nodes.
101.538 + class ColMap {
101.539 + public:
101.540 + /// \brief The key type of the map
101.541 + typedef GridGraph::Node Key;
101.542 + /// \brief The value type of the map
101.543 + typedef int Value;
101.544 +
101.545 + /// \brief Constructor
101.546 + ///
101.547 + /// Constructor
101.548 + ColMap(const GridGraph& graph) : _graph(graph) {}
101.549 +
101.550 + /// \brief The subscript operator
101.551 + ///
101.552 + /// The subscript operator.
101.553 + Value operator[](Key key) const {
101.554 + return _graph.col(key);
101.555 + }
101.556 +
101.557 + private:
101.558 + const GridGraph& _graph;
101.559 + };
101.560 +
101.561 + /// \brief Map to get the row of the nodes.
101.562 + ///
101.563 + /// Map to get the row of the nodes.
101.564 + class RowMap {
101.565 + public:
101.566 + /// \brief The key type of the map
101.567 + typedef GridGraph::Node Key;
101.568 + /// \brief The value type of the map
101.569 + typedef int Value;
101.570 +
101.571 + /// \brief Constructor
101.572 + ///
101.573 + /// Constructor
101.574 + RowMap(const GridGraph& graph) : _graph(graph) {}
101.575 +
101.576 + /// \brief The subscript operator
101.577 + ///
101.578 + /// The subscript operator.
101.579 + Value operator[](Key key) const {
101.580 + return _graph.row(key);
101.581 + }
101.582 +
101.583 + private:
101.584 + const GridGraph& _graph;
101.585 + };
101.586 +
101.587 + /// \brief Constructor
101.588 + ///
101.589 + /// Construct a grid graph with given size.
101.590 + GridGraph(int width, int height) { construct(width, height); }
101.591 +
101.592 + /// \brief Resize the graph
101.593 + ///
101.594 + /// Resize the graph. The function will fully destroy and rebuild
101.595 + /// the graph. This cause that the maps of the graph will
101.596 + /// reallocated automatically and the previous values will be
101.597 + /// lost.
101.598 + void resize(int width, int height) {
101.599 + Parent::notifier(Arc()).clear();
101.600 + Parent::notifier(Edge()).clear();
101.601 + Parent::notifier(Node()).clear();
101.602 + construct(width, height);
101.603 + Parent::notifier(Node()).build();
101.604 + Parent::notifier(Edge()).build();
101.605 + Parent::notifier(Arc()).build();
101.606 + }
101.607 +
101.608 + /// \brief The node on the given position.
101.609 + ///
101.610 + /// Gives back the node on the given position.
101.611 + Node operator()(int i, int j) const {
101.612 + return Parent::operator()(i, j);
101.613 + }
101.614 +
101.615 + /// \brief Gives back the column index of the node.
101.616 + ///
101.617 + /// Gives back the column index of the node.
101.618 + int col(Node n) const {
101.619 + return Parent::col(n);
101.620 + }
101.621 +
101.622 + /// \brief Gives back the row index of the node.
101.623 + ///
101.624 + /// Gives back the row index of the node.
101.625 + int row(Node n) const {
101.626 + return Parent::row(n);
101.627 + }
101.628 +
101.629 + /// \brief Gives back the position of the node.
101.630 + ///
101.631 + /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
101.632 + dim2::Point<int> pos(Node n) const {
101.633 + return Parent::pos(n);
101.634 + }
101.635 +
101.636 + /// \brief Gives back the number of the columns.
101.637 + ///
101.638 + /// Gives back the number of the columns.
101.639 + int width() const {
101.640 + return Parent::width();
101.641 + }
101.642 +
101.643 + /// \brief Gives back the number of the rows.
101.644 + ///
101.645 + /// Gives back the number of the rows.
101.646 + int height() const {
101.647 + return Parent::height();
101.648 + }
101.649 +
101.650 + /// \brief Gives back the arc goes right from the node.
101.651 + ///
101.652 + /// Gives back the arc goes right from the node. If there is not
101.653 + /// outgoing arc then it gives back INVALID.
101.654 + Arc right(Node n) const {
101.655 + return Parent::right(n);
101.656 + }
101.657 +
101.658 + /// \brief Gives back the arc goes left from the node.
101.659 + ///
101.660 + /// Gives back the arc goes left from the node. If there is not
101.661 + /// outgoing arc then it gives back INVALID.
101.662 + Arc left(Node n) const {
101.663 + return Parent::left(n);
101.664 + }
101.665 +
101.666 + /// \brief Gives back the arc goes up from the node.
101.667 + ///
101.668 + /// Gives back the arc goes up from the node. If there is not
101.669 + /// outgoing arc then it gives back INVALID.
101.670 + Arc up(Node n) const {
101.671 + return Parent::up(n);
101.672 + }
101.673 +
101.674 + /// \brief Gives back the arc goes down from the node.
101.675 + ///
101.676 + /// Gives back the arc goes down from the node. If there is not
101.677 + /// outgoing arc then it gives back INVALID.
101.678 + Arc down(Node n) const {
101.679 + return Parent::down(n);
101.680 + }
101.681 +
101.682 + /// \brief Index map of the grid graph
101.683 + ///
101.684 + /// Just returns an IndexMap for the grid graph.
101.685 + IndexMap indexMap() const {
101.686 + return IndexMap(*this);
101.687 + }
101.688 +
101.689 + /// \brief Row map of the grid graph
101.690 + ///
101.691 + /// Just returns a RowMap for the grid graph.
101.692 + RowMap rowMap() const {
101.693 + return RowMap(*this);
101.694 + }
101.695 +
101.696 + /// \brief Column map of the grid graph
101.697 + ///
101.698 + /// Just returns a ColMap for the grid graph.
101.699 + ColMap colMap() const {
101.700 + return ColMap(*this);
101.701 + }
101.702 +
101.703 + };
101.704 +
101.705 +}
101.706 +#endif
102.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
102.2 +++ b/lemon/hao_orlin.h Thu Dec 10 17:05:35 2009 +0100
102.3 @@ -0,0 +1,988 @@
102.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
102.5 + *
102.6 + * This file is a part of LEMON, a generic C++ optimization library.
102.7 + *
102.8 + * Copyright (C) 2003-2009
102.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
102.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
102.11 + *
102.12 + * Permission to use, modify and distribute this software is granted
102.13 + * provided that this copyright notice appears in all copies. For
102.14 + * precise terms see the accompanying LICENSE file.
102.15 + *
102.16 + * This software is provided "AS IS" with no warranty of any kind,
102.17 + * express or implied, and with no claim as to its suitability for any
102.18 + * purpose.
102.19 + *
102.20 + */
102.21 +
102.22 +#ifndef LEMON_HAO_ORLIN_H
102.23 +#define LEMON_HAO_ORLIN_H
102.24 +
102.25 +#include <vector>
102.26 +#include <list>
102.27 +#include <limits>
102.28 +
102.29 +#include <lemon/maps.h>
102.30 +#include <lemon/core.h>
102.31 +#include <lemon/tolerance.h>
102.32 +
102.33 +/// \file
102.34 +/// \ingroup min_cut
102.35 +/// \brief Implementation of the Hao-Orlin algorithm.
102.36 +///
102.37 +/// Implementation of the Hao-Orlin algorithm for finding a minimum cut
102.38 +/// in a digraph.
102.39 +
102.40 +namespace lemon {
102.41 +
102.42 + /// \ingroup min_cut
102.43 + ///
102.44 + /// \brief Hao-Orlin algorithm for finding a minimum cut in a digraph.
102.45 + ///
102.46 + /// This class implements the Hao-Orlin algorithm for finding a minimum
102.47 + /// value cut in a directed graph \f$D=(V,A)\f$.
102.48 + /// It takes a fixed node \f$ source \in V \f$ and
102.49 + /// consists of two phases: in the first phase it determines a
102.50 + /// minimum cut with \f$ source \f$ on the source-side (i.e. a set
102.51 + /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal outgoing
102.52 + /// capacity) and in the second phase it determines a minimum cut
102.53 + /// with \f$ source \f$ on the sink-side (i.e. a set
102.54 + /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal outgoing
102.55 + /// capacity). Obviously, the smaller of these two cuts will be a
102.56 + /// minimum cut of \f$ D \f$. The algorithm is a modified
102.57 + /// preflow push-relabel algorithm. Our implementation calculates
102.58 + /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the
102.59 + /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The
102.60 + /// purpose of such algorithm is e.g. testing network reliability.
102.61 + ///
102.62 + /// For an undirected graph you can run just the first phase of the
102.63 + /// algorithm or you can use the algorithm of Nagamochi and Ibaraki,
102.64 + /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$
102.65 + /// time. It is implemented in the NagamochiIbaraki algorithm class.
102.66 + ///
102.67 + /// \tparam GR The type of the digraph the algorithm runs on.
102.68 + /// \tparam CAP The type of the arc map containing the capacities,
102.69 + /// which can be any numreric type. The default map type is
102.70 + /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
102.71 + /// \tparam TOL Tolerance class for handling inexact computations. The
102.72 + /// default tolerance type is \ref Tolerance "Tolerance<CAP::Value>".
102.73 +#ifdef DOXYGEN
102.74 + template <typename GR, typename CAP, typename TOL>
102.75 +#else
102.76 + template <typename GR,
102.77 + typename CAP = typename GR::template ArcMap<int>,
102.78 + typename TOL = Tolerance<typename CAP::Value> >
102.79 +#endif
102.80 + class HaoOrlin {
102.81 + public:
102.82 +
102.83 + /// The digraph type of the algorithm
102.84 + typedef GR Digraph;
102.85 + /// The capacity map type of the algorithm
102.86 + typedef CAP CapacityMap;
102.87 + /// The tolerance type of the algorithm
102.88 + typedef TOL Tolerance;
102.89 +
102.90 + private:
102.91 +
102.92 + typedef typename CapacityMap::Value Value;
102.93 +
102.94 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
102.95 +
102.96 + const Digraph& _graph;
102.97 + const CapacityMap* _capacity;
102.98 +
102.99 + typedef typename Digraph::template ArcMap<Value> FlowMap;
102.100 + FlowMap* _flow;
102.101 +
102.102 + Node _source;
102.103 +
102.104 + int _node_num;
102.105 +
102.106 + // Bucketing structure
102.107 + std::vector<Node> _first, _last;
102.108 + typename Digraph::template NodeMap<Node>* _next;
102.109 + typename Digraph::template NodeMap<Node>* _prev;
102.110 + typename Digraph::template NodeMap<bool>* _active;
102.111 + typename Digraph::template NodeMap<int>* _bucket;
102.112 +
102.113 + std::vector<bool> _dormant;
102.114 +
102.115 + std::list<std::list<int> > _sets;
102.116 + std::list<int>::iterator _highest;
102.117 +
102.118 + typedef typename Digraph::template NodeMap<Value> ExcessMap;
102.119 + ExcessMap* _excess;
102.120 +
102.121 + typedef typename Digraph::template NodeMap<bool> SourceSetMap;
102.122 + SourceSetMap* _source_set;
102.123 +
102.124 + Value _min_cut;
102.125 +
102.126 + typedef typename Digraph::template NodeMap<bool> MinCutMap;
102.127 + MinCutMap* _min_cut_map;
102.128 +
102.129 + Tolerance _tolerance;
102.130 +
102.131 + public:
102.132 +
102.133 + /// \brief Constructor
102.134 + ///
102.135 + /// Constructor of the algorithm class.
102.136 + HaoOrlin(const Digraph& graph, const CapacityMap& capacity,
102.137 + const Tolerance& tolerance = Tolerance()) :
102.138 + _graph(graph), _capacity(&capacity), _flow(0), _source(),
102.139 + _node_num(), _first(), _last(), _next(0), _prev(0),
102.140 + _active(0), _bucket(0), _dormant(), _sets(), _highest(),
102.141 + _excess(0), _source_set(0), _min_cut(), _min_cut_map(0),
102.142 + _tolerance(tolerance) {}
102.143 +
102.144 + ~HaoOrlin() {
102.145 + if (_min_cut_map) {
102.146 + delete _min_cut_map;
102.147 + }
102.148 + if (_source_set) {
102.149 + delete _source_set;
102.150 + }
102.151 + if (_excess) {
102.152 + delete _excess;
102.153 + }
102.154 + if (_next) {
102.155 + delete _next;
102.156 + }
102.157 + if (_prev) {
102.158 + delete _prev;
102.159 + }
102.160 + if (_active) {
102.161 + delete _active;
102.162 + }
102.163 + if (_bucket) {
102.164 + delete _bucket;
102.165 + }
102.166 + if (_flow) {
102.167 + delete _flow;
102.168 + }
102.169 + }
102.170 +
102.171 + private:
102.172 +
102.173 + void activate(const Node& i) {
102.174 + (*_active)[i] = true;
102.175 +
102.176 + int bucket = (*_bucket)[i];
102.177 +
102.178 + if ((*_prev)[i] == INVALID || (*_active)[(*_prev)[i]]) return;
102.179 + //unlace
102.180 + (*_next)[(*_prev)[i]] = (*_next)[i];
102.181 + if ((*_next)[i] != INVALID) {
102.182 + (*_prev)[(*_next)[i]] = (*_prev)[i];
102.183 + } else {
102.184 + _last[bucket] = (*_prev)[i];
102.185 + }
102.186 + //lace
102.187 + (*_next)[i] = _first[bucket];
102.188 + (*_prev)[_first[bucket]] = i;
102.189 + (*_prev)[i] = INVALID;
102.190 + _first[bucket] = i;
102.191 + }
102.192 +
102.193 + void deactivate(const Node& i) {
102.194 + (*_active)[i] = false;
102.195 + int bucket = (*_bucket)[i];
102.196 +
102.197 + if ((*_next)[i] == INVALID || !(*_active)[(*_next)[i]]) return;
102.198 +
102.199 + //unlace
102.200 + (*_prev)[(*_next)[i]] = (*_prev)[i];
102.201 + if ((*_prev)[i] != INVALID) {
102.202 + (*_next)[(*_prev)[i]] = (*_next)[i];
102.203 + } else {
102.204 + _first[bucket] = (*_next)[i];
102.205 + }
102.206 + //lace
102.207 + (*_prev)[i] = _last[bucket];
102.208 + (*_next)[_last[bucket]] = i;
102.209 + (*_next)[i] = INVALID;
102.210 + _last[bucket] = i;
102.211 + }
102.212 +
102.213 + void addItem(const Node& i, int bucket) {
102.214 + (*_bucket)[i] = bucket;
102.215 + if (_last[bucket] != INVALID) {
102.216 + (*_prev)[i] = _last[bucket];
102.217 + (*_next)[_last[bucket]] = i;
102.218 + (*_next)[i] = INVALID;
102.219 + _last[bucket] = i;
102.220 + } else {
102.221 + (*_prev)[i] = INVALID;
102.222 + _first[bucket] = i;
102.223 + (*_next)[i] = INVALID;
102.224 + _last[bucket] = i;
102.225 + }
102.226 + }
102.227 +
102.228 + void findMinCutOut() {
102.229 +
102.230 + for (NodeIt n(_graph); n != INVALID; ++n) {
102.231 + (*_excess)[n] = 0;
102.232 + (*_source_set)[n] = false;
102.233 + }
102.234 +
102.235 + for (ArcIt a(_graph); a != INVALID; ++a) {
102.236 + (*_flow)[a] = 0;
102.237 + }
102.238 +
102.239 + int bucket_num = 0;
102.240 + std::vector<Node> queue(_node_num);
102.241 + int qfirst = 0, qlast = 0, qsep = 0;
102.242 +
102.243 + {
102.244 + typename Digraph::template NodeMap<bool> reached(_graph, false);
102.245 +
102.246 + reached[_source] = true;
102.247 + bool first_set = true;
102.248 +
102.249 + for (NodeIt t(_graph); t != INVALID; ++t) {
102.250 + if (reached[t]) continue;
102.251 + _sets.push_front(std::list<int>());
102.252 +
102.253 + queue[qlast++] = t;
102.254 + reached[t] = true;
102.255 +
102.256 + while (qfirst != qlast) {
102.257 + if (qsep == qfirst) {
102.258 + ++bucket_num;
102.259 + _sets.front().push_front(bucket_num);
102.260 + _dormant[bucket_num] = !first_set;
102.261 + _first[bucket_num] = _last[bucket_num] = INVALID;
102.262 + qsep = qlast;
102.263 + }
102.264 +
102.265 + Node n = queue[qfirst++];
102.266 + addItem(n, bucket_num);
102.267 +
102.268 + for (InArcIt a(_graph, n); a != INVALID; ++a) {
102.269 + Node u = _graph.source(a);
102.270 + if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
102.271 + reached[u] = true;
102.272 + queue[qlast++] = u;
102.273 + }
102.274 + }
102.275 + }
102.276 + first_set = false;
102.277 + }
102.278 +
102.279 + ++bucket_num;
102.280 + (*_bucket)[_source] = 0;
102.281 + _dormant[0] = true;
102.282 + }
102.283 + (*_source_set)[_source] = true;
102.284 +
102.285 + Node target = _last[_sets.back().back()];
102.286 + {
102.287 + for (OutArcIt a(_graph, _source); a != INVALID; ++a) {
102.288 + if (_tolerance.positive((*_capacity)[a])) {
102.289 + Node u = _graph.target(a);
102.290 + (*_flow)[a] = (*_capacity)[a];
102.291 + (*_excess)[u] += (*_capacity)[a];
102.292 + if (!(*_active)[u] && u != _source) {
102.293 + activate(u);
102.294 + }
102.295 + }
102.296 + }
102.297 +
102.298 + if ((*_active)[target]) {
102.299 + deactivate(target);
102.300 + }
102.301 +
102.302 + _highest = _sets.back().begin();
102.303 + while (_highest != _sets.back().end() &&
102.304 + !(*_active)[_first[*_highest]]) {
102.305 + ++_highest;
102.306 + }
102.307 + }
102.308 +
102.309 + while (true) {
102.310 + while (_highest != _sets.back().end()) {
102.311 + Node n = _first[*_highest];
102.312 + Value excess = (*_excess)[n];
102.313 + int next_bucket = _node_num;
102.314 +
102.315 + int under_bucket;
102.316 + if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
102.317 + under_bucket = -1;
102.318 + } else {
102.319 + under_bucket = *(++std::list<int>::iterator(_highest));
102.320 + }
102.321 +
102.322 + for (OutArcIt a(_graph, n); a != INVALID; ++a) {
102.323 + Node v = _graph.target(a);
102.324 + if (_dormant[(*_bucket)[v]]) continue;
102.325 + Value rem = (*_capacity)[a] - (*_flow)[a];
102.326 + if (!_tolerance.positive(rem)) continue;
102.327 + if ((*_bucket)[v] == under_bucket) {
102.328 + if (!(*_active)[v] && v != target) {
102.329 + activate(v);
102.330 + }
102.331 + if (!_tolerance.less(rem, excess)) {
102.332 + (*_flow)[a] += excess;
102.333 + (*_excess)[v] += excess;
102.334 + excess = 0;
102.335 + goto no_more_push;
102.336 + } else {
102.337 + excess -= rem;
102.338 + (*_excess)[v] += rem;
102.339 + (*_flow)[a] = (*_capacity)[a];
102.340 + }
102.341 + } else if (next_bucket > (*_bucket)[v]) {
102.342 + next_bucket = (*_bucket)[v];
102.343 + }
102.344 + }
102.345 +
102.346 + for (InArcIt a(_graph, n); a != INVALID; ++a) {
102.347 + Node v = _graph.source(a);
102.348 + if (_dormant[(*_bucket)[v]]) continue;
102.349 + Value rem = (*_flow)[a];
102.350 + if (!_tolerance.positive(rem)) continue;
102.351 + if ((*_bucket)[v] == under_bucket) {
102.352 + if (!(*_active)[v] && v != target) {
102.353 + activate(v);
102.354 + }
102.355 + if (!_tolerance.less(rem, excess)) {
102.356 + (*_flow)[a] -= excess;
102.357 + (*_excess)[v] += excess;
102.358 + excess = 0;
102.359 + goto no_more_push;
102.360 + } else {
102.361 + excess -= rem;
102.362 + (*_excess)[v] += rem;
102.363 + (*_flow)[a] = 0;
102.364 + }
102.365 + } else if (next_bucket > (*_bucket)[v]) {
102.366 + next_bucket = (*_bucket)[v];
102.367 + }
102.368 + }
102.369 +
102.370 + no_more_push:
102.371 +
102.372 + (*_excess)[n] = excess;
102.373 +
102.374 + if (excess != 0) {
102.375 + if ((*_next)[n] == INVALID) {
102.376 + typename std::list<std::list<int> >::iterator new_set =
102.377 + _sets.insert(--_sets.end(), std::list<int>());
102.378 + new_set->splice(new_set->end(), _sets.back(),
102.379 + _sets.back().begin(), ++_highest);
102.380 + for (std::list<int>::iterator it = new_set->begin();
102.381 + it != new_set->end(); ++it) {
102.382 + _dormant[*it] = true;
102.383 + }
102.384 + while (_highest != _sets.back().end() &&
102.385 + !(*_active)[_first[*_highest]]) {
102.386 + ++_highest;
102.387 + }
102.388 + } else if (next_bucket == _node_num) {
102.389 + _first[(*_bucket)[n]] = (*_next)[n];
102.390 + (*_prev)[(*_next)[n]] = INVALID;
102.391 +
102.392 + std::list<std::list<int> >::iterator new_set =
102.393 + _sets.insert(--_sets.end(), std::list<int>());
102.394 +
102.395 + new_set->push_front(bucket_num);
102.396 + (*_bucket)[n] = bucket_num;
102.397 + _first[bucket_num] = _last[bucket_num] = n;
102.398 + (*_next)[n] = INVALID;
102.399 + (*_prev)[n] = INVALID;
102.400 + _dormant[bucket_num] = true;
102.401 + ++bucket_num;
102.402 +
102.403 + while (_highest != _sets.back().end() &&
102.404 + !(*_active)[_first[*_highest]]) {
102.405 + ++_highest;
102.406 + }
102.407 + } else {
102.408 + _first[*_highest] = (*_next)[n];
102.409 + (*_prev)[(*_next)[n]] = INVALID;
102.410 +
102.411 + while (next_bucket != *_highest) {
102.412 + --_highest;
102.413 + }
102.414 +
102.415 + if (_highest == _sets.back().begin()) {
102.416 + _sets.back().push_front(bucket_num);
102.417 + _dormant[bucket_num] = false;
102.418 + _first[bucket_num] = _last[bucket_num] = INVALID;
102.419 + ++bucket_num;
102.420 + }
102.421 + --_highest;
102.422 +
102.423 + (*_bucket)[n] = *_highest;
102.424 + (*_next)[n] = _first[*_highest];
102.425 + if (_first[*_highest] != INVALID) {
102.426 + (*_prev)[_first[*_highest]] = n;
102.427 + } else {
102.428 + _last[*_highest] = n;
102.429 + }
102.430 + _first[*_highest] = n;
102.431 + }
102.432 + } else {
102.433 +
102.434 + deactivate(n);
102.435 + if (!(*_active)[_first[*_highest]]) {
102.436 + ++_highest;
102.437 + if (_highest != _sets.back().end() &&
102.438 + !(*_active)[_first[*_highest]]) {
102.439 + _highest = _sets.back().end();
102.440 + }
102.441 + }
102.442 + }
102.443 + }
102.444 +
102.445 + if ((*_excess)[target] < _min_cut) {
102.446 + _min_cut = (*_excess)[target];
102.447 + for (NodeIt i(_graph); i != INVALID; ++i) {
102.448 + (*_min_cut_map)[i] = true;
102.449 + }
102.450 + for (std::list<int>::iterator it = _sets.back().begin();
102.451 + it != _sets.back().end(); ++it) {
102.452 + Node n = _first[*it];
102.453 + while (n != INVALID) {
102.454 + (*_min_cut_map)[n] = false;
102.455 + n = (*_next)[n];
102.456 + }
102.457 + }
102.458 + }
102.459 +
102.460 + {
102.461 + Node new_target;
102.462 + if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
102.463 + if ((*_next)[target] == INVALID) {
102.464 + _last[(*_bucket)[target]] = (*_prev)[target];
102.465 + new_target = (*_prev)[target];
102.466 + } else {
102.467 + (*_prev)[(*_next)[target]] = (*_prev)[target];
102.468 + new_target = (*_next)[target];
102.469 + }
102.470 + if ((*_prev)[target] == INVALID) {
102.471 + _first[(*_bucket)[target]] = (*_next)[target];
102.472 + } else {
102.473 + (*_next)[(*_prev)[target]] = (*_next)[target];
102.474 + }
102.475 + } else {
102.476 + _sets.back().pop_back();
102.477 + if (_sets.back().empty()) {
102.478 + _sets.pop_back();
102.479 + if (_sets.empty())
102.480 + break;
102.481 + for (std::list<int>::iterator it = _sets.back().begin();
102.482 + it != _sets.back().end(); ++it) {
102.483 + _dormant[*it] = false;
102.484 + }
102.485 + }
102.486 + new_target = _last[_sets.back().back()];
102.487 + }
102.488 +
102.489 + (*_bucket)[target] = 0;
102.490 +
102.491 + (*_source_set)[target] = true;
102.492 + for (OutArcIt a(_graph, target); a != INVALID; ++a) {
102.493 + Value rem = (*_capacity)[a] - (*_flow)[a];
102.494 + if (!_tolerance.positive(rem)) continue;
102.495 + Node v = _graph.target(a);
102.496 + if (!(*_active)[v] && !(*_source_set)[v]) {
102.497 + activate(v);
102.498 + }
102.499 + (*_excess)[v] += rem;
102.500 + (*_flow)[a] = (*_capacity)[a];
102.501 + }
102.502 +
102.503 + for (InArcIt a(_graph, target); a != INVALID; ++a) {
102.504 + Value rem = (*_flow)[a];
102.505 + if (!_tolerance.positive(rem)) continue;
102.506 + Node v = _graph.source(a);
102.507 + if (!(*_active)[v] && !(*_source_set)[v]) {
102.508 + activate(v);
102.509 + }
102.510 + (*_excess)[v] += rem;
102.511 + (*_flow)[a] = 0;
102.512 + }
102.513 +
102.514 + target = new_target;
102.515 + if ((*_active)[target]) {
102.516 + deactivate(target);
102.517 + }
102.518 +
102.519 + _highest = _sets.back().begin();
102.520 + while (_highest != _sets.back().end() &&
102.521 + !(*_active)[_first[*_highest]]) {
102.522 + ++_highest;
102.523 + }
102.524 + }
102.525 + }
102.526 + }
102.527 +
102.528 + void findMinCutIn() {
102.529 +
102.530 + for (NodeIt n(_graph); n != INVALID; ++n) {
102.531 + (*_excess)[n] = 0;
102.532 + (*_source_set)[n] = false;
102.533 + }
102.534 +
102.535 + for (ArcIt a(_graph); a != INVALID; ++a) {
102.536 + (*_flow)[a] = 0;
102.537 + }
102.538 +
102.539 + int bucket_num = 0;
102.540 + std::vector<Node> queue(_node_num);
102.541 + int qfirst = 0, qlast = 0, qsep = 0;
102.542 +
102.543 + {
102.544 + typename Digraph::template NodeMap<bool> reached(_graph, false);
102.545 +
102.546 + reached[_source] = true;
102.547 +
102.548 + bool first_set = true;
102.549 +
102.550 + for (NodeIt t(_graph); t != INVALID; ++t) {
102.551 + if (reached[t]) continue;
102.552 + _sets.push_front(std::list<int>());
102.553 +
102.554 + queue[qlast++] = t;
102.555 + reached[t] = true;
102.556 +
102.557 + while (qfirst != qlast) {
102.558 + if (qsep == qfirst) {
102.559 + ++bucket_num;
102.560 + _sets.front().push_front(bucket_num);
102.561 + _dormant[bucket_num] = !first_set;
102.562 + _first[bucket_num] = _last[bucket_num] = INVALID;
102.563 + qsep = qlast;
102.564 + }
102.565 +
102.566 + Node n = queue[qfirst++];
102.567 + addItem(n, bucket_num);
102.568 +
102.569 + for (OutArcIt a(_graph, n); a != INVALID; ++a) {
102.570 + Node u = _graph.target(a);
102.571 + if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
102.572 + reached[u] = true;
102.573 + queue[qlast++] = u;
102.574 + }
102.575 + }
102.576 + }
102.577 + first_set = false;
102.578 + }
102.579 +
102.580 + ++bucket_num;
102.581 + (*_bucket)[_source] = 0;
102.582 + _dormant[0] = true;
102.583 + }
102.584 + (*_source_set)[_source] = true;
102.585 +
102.586 + Node target = _last[_sets.back().back()];
102.587 + {
102.588 + for (InArcIt a(_graph, _source); a != INVALID; ++a) {
102.589 + if (_tolerance.positive((*_capacity)[a])) {
102.590 + Node u = _graph.source(a);
102.591 + (*_flow)[a] = (*_capacity)[a];
102.592 + (*_excess)[u] += (*_capacity)[a];
102.593 + if (!(*_active)[u] && u != _source) {
102.594 + activate(u);
102.595 + }
102.596 + }
102.597 + }
102.598 + if ((*_active)[target]) {
102.599 + deactivate(target);
102.600 + }
102.601 +
102.602 + _highest = _sets.back().begin();
102.603 + while (_highest != _sets.back().end() &&
102.604 + !(*_active)[_first[*_highest]]) {
102.605 + ++_highest;
102.606 + }
102.607 + }
102.608 +
102.609 +
102.610 + while (true) {
102.611 + while (_highest != _sets.back().end()) {
102.612 + Node n = _first[*_highest];
102.613 + Value excess = (*_excess)[n];
102.614 + int next_bucket = _node_num;
102.615 +
102.616 + int under_bucket;
102.617 + if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
102.618 + under_bucket = -1;
102.619 + } else {
102.620 + under_bucket = *(++std::list<int>::iterator(_highest));
102.621 + }
102.622 +
102.623 + for (InArcIt a(_graph, n); a != INVALID; ++a) {
102.624 + Node v = _graph.source(a);
102.625 + if (_dormant[(*_bucket)[v]]) continue;
102.626 + Value rem = (*_capacity)[a] - (*_flow)[a];
102.627 + if (!_tolerance.positive(rem)) continue;
102.628 + if ((*_bucket)[v] == under_bucket) {
102.629 + if (!(*_active)[v] && v != target) {
102.630 + activate(v);
102.631 + }
102.632 + if (!_tolerance.less(rem, excess)) {
102.633 + (*_flow)[a] += excess;
102.634 + (*_excess)[v] += excess;
102.635 + excess = 0;
102.636 + goto no_more_push;
102.637 + } else {
102.638 + excess -= rem;
102.639 + (*_excess)[v] += rem;
102.640 + (*_flow)[a] = (*_capacity)[a];
102.641 + }
102.642 + } else if (next_bucket > (*_bucket)[v]) {
102.643 + next_bucket = (*_bucket)[v];
102.644 + }
102.645 + }
102.646 +
102.647 + for (OutArcIt a(_graph, n); a != INVALID; ++a) {
102.648 + Node v = _graph.target(a);
102.649 + if (_dormant[(*_bucket)[v]]) continue;
102.650 + Value rem = (*_flow)[a];
102.651 + if (!_tolerance.positive(rem)) continue;
102.652 + if ((*_bucket)[v] == under_bucket) {
102.653 + if (!(*_active)[v] && v != target) {
102.654 + activate(v);
102.655 + }
102.656 + if (!_tolerance.less(rem, excess)) {
102.657 + (*_flow)[a] -= excess;
102.658 + (*_excess)[v] += excess;
102.659 + excess = 0;
102.660 + goto no_more_push;
102.661 + } else {
102.662 + excess -= rem;
102.663 + (*_excess)[v] += rem;
102.664 + (*_flow)[a] = 0;
102.665 + }
102.666 + } else if (next_bucket > (*_bucket)[v]) {
102.667 + next_bucket = (*_bucket)[v];
102.668 + }
102.669 + }
102.670 +
102.671 + no_more_push:
102.672 +
102.673 + (*_excess)[n] = excess;
102.674 +
102.675 + if (excess != 0) {
102.676 + if ((*_next)[n] == INVALID) {
102.677 + typename std::list<std::list<int> >::iterator new_set =
102.678 + _sets.insert(--_sets.end(), std::list<int>());
102.679 + new_set->splice(new_set->end(), _sets.back(),
102.680 + _sets.back().begin(), ++_highest);
102.681 + for (std::list<int>::iterator it = new_set->begin();
102.682 + it != new_set->end(); ++it) {
102.683 + _dormant[*it] = true;
102.684 + }
102.685 + while (_highest != _sets.back().end() &&
102.686 + !(*_active)[_first[*_highest]]) {
102.687 + ++_highest;
102.688 + }
102.689 + } else if (next_bucket == _node_num) {
102.690 + _first[(*_bucket)[n]] = (*_next)[n];
102.691 + (*_prev)[(*_next)[n]] = INVALID;
102.692 +
102.693 + std::list<std::list<int> >::iterator new_set =
102.694 + _sets.insert(--_sets.end(), std::list<int>());
102.695 +
102.696 + new_set->push_front(bucket_num);
102.697 + (*_bucket)[n] = bucket_num;
102.698 + _first[bucket_num] = _last[bucket_num] = n;
102.699 + (*_next)[n] = INVALID;
102.700 + (*_prev)[n] = INVALID;
102.701 + _dormant[bucket_num] = true;
102.702 + ++bucket_num;
102.703 +
102.704 + while (_highest != _sets.back().end() &&
102.705 + !(*_active)[_first[*_highest]]) {
102.706 + ++_highest;
102.707 + }
102.708 + } else {
102.709 + _first[*_highest] = (*_next)[n];
102.710 + (*_prev)[(*_next)[n]] = INVALID;
102.711 +
102.712 + while (next_bucket != *_highest) {
102.713 + --_highest;
102.714 + }
102.715 + if (_highest == _sets.back().begin()) {
102.716 + _sets.back().push_front(bucket_num);
102.717 + _dormant[bucket_num] = false;
102.718 + _first[bucket_num] = _last[bucket_num] = INVALID;
102.719 + ++bucket_num;
102.720 + }
102.721 + --_highest;
102.722 +
102.723 + (*_bucket)[n] = *_highest;
102.724 + (*_next)[n] = _first[*_highest];
102.725 + if (_first[*_highest] != INVALID) {
102.726 + (*_prev)[_first[*_highest]] = n;
102.727 + } else {
102.728 + _last[*_highest] = n;
102.729 + }
102.730 + _first[*_highest] = n;
102.731 + }
102.732 + } else {
102.733 +
102.734 + deactivate(n);
102.735 + if (!(*_active)[_first[*_highest]]) {
102.736 + ++_highest;
102.737 + if (_highest != _sets.back().end() &&
102.738 + !(*_active)[_first[*_highest]]) {
102.739 + _highest = _sets.back().end();
102.740 + }
102.741 + }
102.742 + }
102.743 + }
102.744 +
102.745 + if ((*_excess)[target] < _min_cut) {
102.746 + _min_cut = (*_excess)[target];
102.747 + for (NodeIt i(_graph); i != INVALID; ++i) {
102.748 + (*_min_cut_map)[i] = false;
102.749 + }
102.750 + for (std::list<int>::iterator it = _sets.back().begin();
102.751 + it != _sets.back().end(); ++it) {
102.752 + Node n = _first[*it];
102.753 + while (n != INVALID) {
102.754 + (*_min_cut_map)[n] = true;
102.755 + n = (*_next)[n];
102.756 + }
102.757 + }
102.758 + }
102.759 +
102.760 + {
102.761 + Node new_target;
102.762 + if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
102.763 + if ((*_next)[target] == INVALID) {
102.764 + _last[(*_bucket)[target]] = (*_prev)[target];
102.765 + new_target = (*_prev)[target];
102.766 + } else {
102.767 + (*_prev)[(*_next)[target]] = (*_prev)[target];
102.768 + new_target = (*_next)[target];
102.769 + }
102.770 + if ((*_prev)[target] == INVALID) {
102.771 + _first[(*_bucket)[target]] = (*_next)[target];
102.772 + } else {
102.773 + (*_next)[(*_prev)[target]] = (*_next)[target];
102.774 + }
102.775 + } else {
102.776 + _sets.back().pop_back();
102.777 + if (_sets.back().empty()) {
102.778 + _sets.pop_back();
102.779 + if (_sets.empty())
102.780 + break;
102.781 + for (std::list<int>::iterator it = _sets.back().begin();
102.782 + it != _sets.back().end(); ++it) {
102.783 + _dormant[*it] = false;
102.784 + }
102.785 + }
102.786 + new_target = _last[_sets.back().back()];
102.787 + }
102.788 +
102.789 + (*_bucket)[target] = 0;
102.790 +
102.791 + (*_source_set)[target] = true;
102.792 + for (InArcIt a(_graph, target); a != INVALID; ++a) {
102.793 + Value rem = (*_capacity)[a] - (*_flow)[a];
102.794 + if (!_tolerance.positive(rem)) continue;
102.795 + Node v = _graph.source(a);
102.796 + if (!(*_active)[v] && !(*_source_set)[v]) {
102.797 + activate(v);
102.798 + }
102.799 + (*_excess)[v] += rem;
102.800 + (*_flow)[a] = (*_capacity)[a];
102.801 + }
102.802 +
102.803 + for (OutArcIt a(_graph, target); a != INVALID; ++a) {
102.804 + Value rem = (*_flow)[a];
102.805 + if (!_tolerance.positive(rem)) continue;
102.806 + Node v = _graph.target(a);
102.807 + if (!(*_active)[v] && !(*_source_set)[v]) {
102.808 + activate(v);
102.809 + }
102.810 + (*_excess)[v] += rem;
102.811 + (*_flow)[a] = 0;
102.812 + }
102.813 +
102.814 + target = new_target;
102.815 + if ((*_active)[target]) {
102.816 + deactivate(target);
102.817 + }
102.818 +
102.819 + _highest = _sets.back().begin();
102.820 + while (_highest != _sets.back().end() &&
102.821 + !(*_active)[_first[*_highest]]) {
102.822 + ++_highest;
102.823 + }
102.824 + }
102.825 + }
102.826 + }
102.827 +
102.828 + public:
102.829 +
102.830 + /// \name Execution Control
102.831 + /// The simplest way to execute the algorithm is to use
102.832 + /// one of the member functions called \ref run().
102.833 + /// \n
102.834 + /// If you need better control on the execution,
102.835 + /// you have to call one of the \ref init() functions first, then
102.836 + /// \ref calculateOut() and/or \ref calculateIn().
102.837 +
102.838 + /// @{
102.839 +
102.840 + /// \brief Initialize the internal data structures.
102.841 + ///
102.842 + /// This function initializes the internal data structures. It creates
102.843 + /// the maps and some bucket structures for the algorithm.
102.844 + /// The first node is used as the source node for the push-relabel
102.845 + /// algorithm.
102.846 + void init() {
102.847 + init(NodeIt(_graph));
102.848 + }
102.849 +
102.850 + /// \brief Initialize the internal data structures.
102.851 + ///
102.852 + /// This function initializes the internal data structures. It creates
102.853 + /// the maps and some bucket structures for the algorithm.
102.854 + /// The given node is used as the source node for the push-relabel
102.855 + /// algorithm.
102.856 + void init(const Node& source) {
102.857 + _source = source;
102.858 +
102.859 + _node_num = countNodes(_graph);
102.860 +
102.861 + _first.resize(_node_num);
102.862 + _last.resize(_node_num);
102.863 +
102.864 + _dormant.resize(_node_num);
102.865 +
102.866 + if (!_flow) {
102.867 + _flow = new FlowMap(_graph);
102.868 + }
102.869 + if (!_next) {
102.870 + _next = new typename Digraph::template NodeMap<Node>(_graph);
102.871 + }
102.872 + if (!_prev) {
102.873 + _prev = new typename Digraph::template NodeMap<Node>(_graph);
102.874 + }
102.875 + if (!_active) {
102.876 + _active = new typename Digraph::template NodeMap<bool>(_graph);
102.877 + }
102.878 + if (!_bucket) {
102.879 + _bucket = new typename Digraph::template NodeMap<int>(_graph);
102.880 + }
102.881 + if (!_excess) {
102.882 + _excess = new ExcessMap(_graph);
102.883 + }
102.884 + if (!_source_set) {
102.885 + _source_set = new SourceSetMap(_graph);
102.886 + }
102.887 + if (!_min_cut_map) {
102.888 + _min_cut_map = new MinCutMap(_graph);
102.889 + }
102.890 +
102.891 + _min_cut = std::numeric_limits<Value>::max();
102.892 + }
102.893 +
102.894 +
102.895 + /// \brief Calculate a minimum cut with \f$ source \f$ on the
102.896 + /// source-side.
102.897 + ///
102.898 + /// This function calculates a minimum cut with \f$ source \f$ on the
102.899 + /// source-side (i.e. a set \f$ X\subsetneq V \f$ with
102.900 + /// \f$ source \in X \f$ and minimal outgoing capacity).
102.901 + ///
102.902 + /// \pre \ref init() must be called before using this function.
102.903 + void calculateOut() {
102.904 + findMinCutOut();
102.905 + }
102.906 +
102.907 + /// \brief Calculate a minimum cut with \f$ source \f$ on the
102.908 + /// sink-side.
102.909 + ///
102.910 + /// This function calculates a minimum cut with \f$ source \f$ on the
102.911 + /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with
102.912 + /// \f$ source \notin X \f$ and minimal outgoing capacity).
102.913 + ///
102.914 + /// \pre \ref init() must be called before using this function.
102.915 + void calculateIn() {
102.916 + findMinCutIn();
102.917 + }
102.918 +
102.919 +
102.920 + /// \brief Run the algorithm.
102.921 + ///
102.922 + /// This function runs the algorithm. It finds nodes \c source and
102.923 + /// \c target arbitrarily and then calls \ref init(), \ref calculateOut()
102.924 + /// and \ref calculateIn().
102.925 + void run() {
102.926 + init();
102.927 + calculateOut();
102.928 + calculateIn();
102.929 + }
102.930 +
102.931 + /// \brief Run the algorithm.
102.932 + ///
102.933 + /// This function runs the algorithm. It uses the given \c source node,
102.934 + /// finds a proper \c target node and then calls the \ref init(),
102.935 + /// \ref calculateOut() and \ref calculateIn().
102.936 + void run(const Node& s) {
102.937 + init(s);
102.938 + calculateOut();
102.939 + calculateIn();
102.940 + }
102.941 +
102.942 + /// @}
102.943 +
102.944 + /// \name Query Functions
102.945 + /// The result of the %HaoOrlin algorithm
102.946 + /// can be obtained using these functions.\n
102.947 + /// \ref run(), \ref calculateOut() or \ref calculateIn()
102.948 + /// should be called before using them.
102.949 +
102.950 + /// @{
102.951 +
102.952 + /// \brief Return the value of the minimum cut.
102.953 + ///
102.954 + /// This function returns the value of the minimum cut.
102.955 + ///
102.956 + /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
102.957 + /// must be called before using this function.
102.958 + Value minCutValue() const {
102.959 + return _min_cut;
102.960 + }
102.961 +
102.962 +
102.963 + /// \brief Return a minimum cut.
102.964 + ///
102.965 + /// This function sets \c cutMap to the characteristic vector of a
102.966 + /// minimum value cut: it will give a non-empty set \f$ X\subsetneq V \f$
102.967 + /// with minimal outgoing capacity (i.e. \c cutMap will be \c true exactly
102.968 + /// for the nodes of \f$ X \f$).
102.969 + ///
102.970 + /// \param cutMap A \ref concepts::WriteMap "writable" node map with
102.971 + /// \c bool (or convertible) value type.
102.972 + ///
102.973 + /// \return The value of the minimum cut.
102.974 + ///
102.975 + /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
102.976 + /// must be called before using this function.
102.977 + template <typename CutMap>
102.978 + Value minCutMap(CutMap& cutMap) const {
102.979 + for (NodeIt it(_graph); it != INVALID; ++it) {
102.980 + cutMap.set(it, (*_min_cut_map)[it]);
102.981 + }
102.982 + return _min_cut;
102.983 + }
102.984 +
102.985 + /// @}
102.986 +
102.987 + }; //class HaoOrlin
102.988 +
102.989 +} //namespace lemon
102.990 +
102.991 +#endif //LEMON_HAO_ORLIN_H
103.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
103.2 +++ b/lemon/hypercube_graph.h Thu Dec 10 17:05:35 2009 +0100
103.3 @@ -0,0 +1,438 @@
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 HYPERCUBE_GRAPH_H
103.23 +#define HYPERCUBE_GRAPH_H
103.24 +
103.25 +#include <vector>
103.26 +#include <lemon/core.h>
103.27 +#include <lemon/assert.h>
103.28 +#include <lemon/bits/graph_extender.h>
103.29 +
103.30 +///\ingroup graphs
103.31 +///\file
103.32 +///\brief HypercubeGraph class.
103.33 +
103.34 +namespace lemon {
103.35 +
103.36 + class HypercubeGraphBase {
103.37 +
103.38 + public:
103.39 +
103.40 + typedef HypercubeGraphBase Graph;
103.41 +
103.42 + class Node;
103.43 + class Edge;
103.44 + class Arc;
103.45 +
103.46 + public:
103.47 +
103.48 + HypercubeGraphBase() {}
103.49 +
103.50 + protected:
103.51 +
103.52 + void construct(int dim) {
103.53 + LEMON_ASSERT(dim >= 1, "The number of dimensions must be at least 1.");
103.54 + _dim = dim;
103.55 + _node_num = 1 << dim;
103.56 + _edge_num = dim * (1 << (dim-1));
103.57 + }
103.58 +
103.59 + public:
103.60 +
103.61 + typedef True NodeNumTag;
103.62 + typedef True EdgeNumTag;
103.63 + typedef True ArcNumTag;
103.64 +
103.65 + int nodeNum() const { return _node_num; }
103.66 + int edgeNum() const { return _edge_num; }
103.67 + int arcNum() const { return 2 * _edge_num; }
103.68 +
103.69 + int maxNodeId() const { return _node_num - 1; }
103.70 + int maxEdgeId() const { return _edge_num - 1; }
103.71 + int maxArcId() const { return 2 * _edge_num - 1; }
103.72 +
103.73 + static Node nodeFromId(int id) { return Node(id); }
103.74 + static Edge edgeFromId(int id) { return Edge(id); }
103.75 + static Arc arcFromId(int id) { return Arc(id); }
103.76 +
103.77 + static int id(Node node) { return node._id; }
103.78 + static int id(Edge edge) { return edge._id; }
103.79 + static int id(Arc arc) { return arc._id; }
103.80 +
103.81 + Node u(Edge edge) const {
103.82 + int base = edge._id & ((1 << (_dim-1)) - 1);
103.83 + int k = edge._id >> (_dim-1);
103.84 + return ((base >> k) << (k+1)) | (base & ((1 << k) - 1));
103.85 + }
103.86 +
103.87 + Node v(Edge edge) const {
103.88 + int base = edge._id & ((1 << (_dim-1)) - 1);
103.89 + int k = edge._id >> (_dim-1);
103.90 + return ((base >> k) << (k+1)) | (base & ((1 << k) - 1)) | (1 << k);
103.91 + }
103.92 +
103.93 + Node source(Arc arc) const {
103.94 + return (arc._id & 1) == 1 ? u(arc) : v(arc);
103.95 + }
103.96 +
103.97 + Node target(Arc arc) const {
103.98 + return (arc._id & 1) == 1 ? v(arc) : u(arc);
103.99 + }
103.100 +
103.101 + typedef True FindEdgeTag;
103.102 + typedef True FindArcTag;
103.103 +
103.104 + Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
103.105 + if (prev != INVALID) return INVALID;
103.106 + int d = u._id ^ v._id;
103.107 + int k = 0;
103.108 + if (d == 0) return INVALID;
103.109 + for ( ; (d & 1) == 0; d >>= 1) ++k;
103.110 + if (d >> 1 != 0) return INVALID;
103.111 + return (k << (_dim-1)) | ((u._id >> (k+1)) << k) |
103.112 + (u._id & ((1 << k) - 1));
103.113 + }
103.114 +
103.115 + Arc findArc(Node u, Node v, Arc prev = INVALID) const {
103.116 + Edge edge = findEdge(u, v, prev);
103.117 + if (edge == INVALID) return INVALID;
103.118 + int k = edge._id >> (_dim-1);
103.119 + return ((u._id >> k) & 1) == 1 ? edge._id << 1 : (edge._id << 1) | 1;
103.120 + }
103.121 +
103.122 + class Node {
103.123 + friend class HypercubeGraphBase;
103.124 +
103.125 + protected:
103.126 + int _id;
103.127 + Node(int id) : _id(id) {}
103.128 + public:
103.129 + Node() {}
103.130 + Node (Invalid) : _id(-1) {}
103.131 + bool operator==(const Node node) const {return _id == node._id;}
103.132 + bool operator!=(const Node node) const {return _id != node._id;}
103.133 + bool operator<(const Node node) const {return _id < node._id;}
103.134 + };
103.135 +
103.136 + class Edge {
103.137 + friend class HypercubeGraphBase;
103.138 + friend class Arc;
103.139 +
103.140 + protected:
103.141 + int _id;
103.142 +
103.143 + Edge(int id) : _id(id) {}
103.144 +
103.145 + public:
103.146 + Edge() {}
103.147 + Edge (Invalid) : _id(-1) {}
103.148 + bool operator==(const Edge edge) const {return _id == edge._id;}
103.149 + bool operator!=(const Edge edge) const {return _id != edge._id;}
103.150 + bool operator<(const Edge edge) const {return _id < edge._id;}
103.151 + };
103.152 +
103.153 + class Arc {
103.154 + friend class HypercubeGraphBase;
103.155 +
103.156 + protected:
103.157 + int _id;
103.158 +
103.159 + Arc(int id) : _id(id) {}
103.160 +
103.161 + public:
103.162 + Arc() {}
103.163 + Arc (Invalid) : _id(-1) {}
103.164 + operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
103.165 + bool operator==(const Arc arc) const {return _id == arc._id;}
103.166 + bool operator!=(const Arc arc) const {return _id != arc._id;}
103.167 + bool operator<(const Arc arc) const {return _id < arc._id;}
103.168 + };
103.169 +
103.170 + void first(Node& node) const {
103.171 + node._id = _node_num - 1;
103.172 + }
103.173 +
103.174 + static void next(Node& node) {
103.175 + --node._id;
103.176 + }
103.177 +
103.178 + void first(Edge& edge) const {
103.179 + edge._id = _edge_num - 1;
103.180 + }
103.181 +
103.182 + static void next(Edge& edge) {
103.183 + --edge._id;
103.184 + }
103.185 +
103.186 + void first(Arc& arc) const {
103.187 + arc._id = 2 * _edge_num - 1;
103.188 + }
103.189 +
103.190 + static void next(Arc& arc) {
103.191 + --arc._id;
103.192 + }
103.193 +
103.194 + void firstInc(Edge& edge, bool& dir, const Node& node) const {
103.195 + edge._id = node._id >> 1;
103.196 + dir = (node._id & 1) == 0;
103.197 + }
103.198 +
103.199 + void nextInc(Edge& edge, bool& dir) const {
103.200 + Node n = dir ? u(edge) : v(edge);
103.201 + int k = (edge._id >> (_dim-1)) + 1;
103.202 + if (k < _dim) {
103.203 + edge._id = (k << (_dim-1)) |
103.204 + ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
103.205 + dir = ((n._id >> k) & 1) == 0;
103.206 + } else {
103.207 + edge._id = -1;
103.208 + dir = true;
103.209 + }
103.210 + }
103.211 +
103.212 + void firstOut(Arc& arc, const Node& node) const {
103.213 + arc._id = ((node._id >> 1) << 1) | (~node._id & 1);
103.214 + }
103.215 +
103.216 + void nextOut(Arc& arc) const {
103.217 + Node n = (arc._id & 1) == 1 ? u(arc) : v(arc);
103.218 + int k = (arc._id >> _dim) + 1;
103.219 + if (k < _dim) {
103.220 + arc._id = (k << (_dim-1)) |
103.221 + ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
103.222 + arc._id = (arc._id << 1) | (~(n._id >> k) & 1);
103.223 + } else {
103.224 + arc._id = -1;
103.225 + }
103.226 + }
103.227 +
103.228 + void firstIn(Arc& arc, const Node& node) const {
103.229 + arc._id = ((node._id >> 1) << 1) | (node._id & 1);
103.230 + }
103.231 +
103.232 + void nextIn(Arc& arc) const {
103.233 + Node n = (arc._id & 1) == 1 ? v(arc) : u(arc);
103.234 + int k = (arc._id >> _dim) + 1;
103.235 + if (k < _dim) {
103.236 + arc._id = (k << (_dim-1)) |
103.237 + ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
103.238 + arc._id = (arc._id << 1) | ((n._id >> k) & 1);
103.239 + } else {
103.240 + arc._id = -1;
103.241 + }
103.242 + }
103.243 +
103.244 + static bool direction(Arc arc) {
103.245 + return (arc._id & 1) == 1;
103.246 + }
103.247 +
103.248 + static Arc direct(Edge edge, bool dir) {
103.249 + return Arc((edge._id << 1) | (dir ? 1 : 0));
103.250 + }
103.251 +
103.252 + int dimension() const {
103.253 + return _dim;
103.254 + }
103.255 +
103.256 + bool projection(Node node, int n) const {
103.257 + return static_cast<bool>(node._id & (1 << n));
103.258 + }
103.259 +
103.260 + int dimension(Edge edge) const {
103.261 + return edge._id >> (_dim-1);
103.262 + }
103.263 +
103.264 + int dimension(Arc arc) const {
103.265 + return arc._id >> _dim;
103.266 + }
103.267 +
103.268 + int index(Node node) const {
103.269 + return node._id;
103.270 + }
103.271 +
103.272 + Node operator()(int ix) const {
103.273 + return Node(ix);
103.274 + }
103.275 +
103.276 + private:
103.277 + int _dim;
103.278 + int _node_num, _edge_num;
103.279 + };
103.280 +
103.281 +
103.282 + typedef GraphExtender<HypercubeGraphBase> ExtendedHypercubeGraphBase;
103.283 +
103.284 + /// \ingroup graphs
103.285 + ///
103.286 + /// \brief Hypercube graph class
103.287 + ///
103.288 + /// This class implements a special graph type. The nodes of the graph
103.289 + /// are indiced with integers with at most \c dim binary digits.
103.290 + /// Two nodes are connected in the graph if and only if their indices
103.291 + /// differ only on one position in the binary form.
103.292 + ///
103.293 + /// \note The type of the indices is chosen to \c int for efficiency
103.294 + /// reasons. Thus the maximum dimension of this implementation is 26
103.295 + /// (assuming that the size of \c int is 32 bit).
103.296 + ///
103.297 + /// This graph type fully conforms to the \ref concepts::Graph
103.298 + /// "Graph concept".
103.299 + class HypercubeGraph : public ExtendedHypercubeGraphBase {
103.300 + typedef ExtendedHypercubeGraphBase Parent;
103.301 +
103.302 + public:
103.303 +
103.304 + /// \brief Constructs a hypercube graph with \c dim dimensions.
103.305 + ///
103.306 + /// Constructs a hypercube graph with \c dim dimensions.
103.307 + HypercubeGraph(int dim) { construct(dim); }
103.308 +
103.309 + /// \brief The number of dimensions.
103.310 + ///
103.311 + /// Gives back the number of dimensions.
103.312 + int dimension() const {
103.313 + return Parent::dimension();
103.314 + }
103.315 +
103.316 + /// \brief Returns \c true if the n'th bit of the node is one.
103.317 + ///
103.318 + /// Returns \c true if the n'th bit of the node is one.
103.319 + bool projection(Node node, int n) const {
103.320 + return Parent::projection(node, n);
103.321 + }
103.322 +
103.323 + /// \brief The dimension id of an edge.
103.324 + ///
103.325 + /// Gives back the dimension id of the given edge.
103.326 + /// It is in the [0..dim-1] range.
103.327 + int dimension(Edge edge) const {
103.328 + return Parent::dimension(edge);
103.329 + }
103.330 +
103.331 + /// \brief The dimension id of an arc.
103.332 + ///
103.333 + /// Gives back the dimension id of the given arc.
103.334 + /// It is in the [0..dim-1] range.
103.335 + int dimension(Arc arc) const {
103.336 + return Parent::dimension(arc);
103.337 + }
103.338 +
103.339 + /// \brief The index of a node.
103.340 + ///
103.341 + /// Gives back the index of the given node.
103.342 + /// The lower bits of the integer describes the node.
103.343 + int index(Node node) const {
103.344 + return Parent::index(node);
103.345 + }
103.346 +
103.347 + /// \brief Gives back a node by its index.
103.348 + ///
103.349 + /// Gives back a node by its index.
103.350 + Node operator()(int ix) const {
103.351 + return Parent::operator()(ix);
103.352 + }
103.353 +
103.354 + /// \brief Number of nodes.
103.355 + int nodeNum() const { return Parent::nodeNum(); }
103.356 + /// \brief Number of edges.
103.357 + int edgeNum() const { return Parent::edgeNum(); }
103.358 + /// \brief Number of arcs.
103.359 + int arcNum() const { return Parent::arcNum(); }
103.360 +
103.361 + /// \brief Linear combination map.
103.362 + ///
103.363 + /// This map makes possible to give back a linear combination
103.364 + /// for each node. It works like the \c std::accumulate function,
103.365 + /// so it accumulates the \c bf binary function with the \c fv first
103.366 + /// value. The map accumulates only on that positions (dimensions)
103.367 + /// where the index of the node is one. The values that have to be
103.368 + /// accumulated should be given by the \c begin and \c end iterators
103.369 + /// and the length of this range should be equal to the dimension
103.370 + /// number of the graph.
103.371 + ///
103.372 + ///\code
103.373 + /// const int DIM = 3;
103.374 + /// HypercubeGraph graph(DIM);
103.375 + /// dim2::Point<double> base[DIM];
103.376 + /// for (int k = 0; k < DIM; ++k) {
103.377 + /// base[k].x = rnd();
103.378 + /// base[k].y = rnd();
103.379 + /// }
103.380 + /// HypercubeGraph::HyperMap<dim2::Point<double> >
103.381 + /// pos(graph, base, base + DIM, dim2::Point<double>(0.0, 0.0));
103.382 + ///\endcode
103.383 + ///
103.384 + /// \see HypercubeGraph
103.385 + template <typename T, typename BF = std::plus<T> >
103.386 + class HyperMap {
103.387 + public:
103.388 +
103.389 + /// \brief The key type of the map
103.390 + typedef Node Key;
103.391 + /// \brief The value type of the map
103.392 + typedef T Value;
103.393 +
103.394 + /// \brief Constructor for HyperMap.
103.395 + ///
103.396 + /// Construct a HyperMap for the given graph. The values that have
103.397 + /// to be accumulated should be given by the \c begin and \c end
103.398 + /// iterators and the length of this range should be equal to the
103.399 + /// dimension number of the graph.
103.400 + ///
103.401 + /// This map accumulates the \c bf binary function with the \c fv
103.402 + /// first value on that positions (dimensions) where the index of
103.403 + /// the node is one.
103.404 + template <typename It>
103.405 + HyperMap(const Graph& graph, It begin, It end,
103.406 + T fv = 0, const BF& bf = BF())
103.407 + : _graph(graph), _values(begin, end), _first_value(fv), _bin_func(bf)
103.408 + {
103.409 + LEMON_ASSERT(_values.size() == graph.dimension(),
103.410 + "Wrong size of range");
103.411 + }
103.412 +
103.413 + /// \brief The partial accumulated value.
103.414 + ///
103.415 + /// Gives back the partial accumulated value.
103.416 + Value operator[](const Key& k) const {
103.417 + Value val = _first_value;
103.418 + int id = _graph.index(k);
103.419 + int n = 0;
103.420 + while (id != 0) {
103.421 + if (id & 1) {
103.422 + val = _bin_func(val, _values[n]);
103.423 + }
103.424 + id >>= 1;
103.425 + ++n;
103.426 + }
103.427 + return val;
103.428 + }
103.429 +
103.430 + private:
103.431 + const Graph& _graph;
103.432 + std::vector<T> _values;
103.433 + T _first_value;
103.434 + BF _bin_func;
103.435 + };
103.436 +
103.437 + };
103.438 +
103.439 +}
103.440 +
103.441 +#endif
104.1 --- a/lemon/kruskal.h Fri Nov 13 12:33:33 2009 +0100
104.2 +++ b/lemon/kruskal.h Thu Dec 10 17:05:35 2009 +0100
104.3 @@ -2,7 +2,7 @@
104.4 *
104.5 * This file is a part of LEMON, a generic C++ optimization library.
104.6 *
104.7 - * Copyright (C) 2003-2008
104.8 + * Copyright (C) 2003-2009
104.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
104.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
104.11 *
104.12 @@ -248,11 +248,11 @@
104.13
104.14 /// \ingroup spantree
104.15 ///
104.16 - /// \brief Kruskal algorithm to find a minimum cost spanning tree of
104.17 + /// \brief Kruskal's algorithm for finding a minimum cost spanning tree of
104.18 /// a graph.
104.19 ///
104.20 /// This function runs Kruskal's algorithm to find a minimum cost
104.21 - /// spanning tree.
104.22 + /// spanning tree of a graph.
104.23 /// Due to some C++ hacking, it accepts various input and output types.
104.24 ///
104.25 /// \param g The graph the algorithm runs on.
104.26 @@ -264,17 +264,17 @@
104.27 /// \param in This object is used to describe the arc/edge costs.
104.28 /// It can be one of the following choices.
104.29 /// - An STL compatible 'Forward Container' with
104.30 - /// <tt>std::pair<GR::Arc,X></tt> or
104.31 - /// <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, where
104.32 - /// \c X is the type of the costs. The pairs indicates the arcs/edges
104.33 + /// <tt>std::pair<GR::Arc,C></tt> or
104.34 + /// <tt>std::pair<GR::Edge,C></tt> as its <tt>value_type</tt>, where
104.35 + /// \c C is the type of the costs. The pairs indicates the arcs/edges
104.36 /// along with the assigned cost. <em>They must be in a
104.37 /// cost-ascending order.</em>
104.38 /// - Any readable arc/edge map. The values of the map indicate the
104.39 /// arc/edge costs.
104.40 ///
104.41 /// \retval out Here we also have a choice.
104.42 - /// - It can be a writable \c bool arc/edge map. After running the
104.43 - /// algorithm it will contain the found minimum cost spanning
104.44 + /// - It can be a writable arc/edge map with \c bool value type. After
104.45 + /// running the algorithm it will contain the found minimum cost spanning
104.46 /// tree: the value of an arc/edge will be set to \c true if it belongs
104.47 /// to the tree, otherwise it will be set to \c false. The value of
104.48 /// each arc/edge will be set exactly once.
104.49 @@ -301,8 +301,8 @@
104.50 /// forest is calculated instead of a spanning tree.
104.51
104.52 #ifdef DOXYGEN
104.53 - template <class Graph, class In, class Out>
104.54 - Value kruskal(GR const& g, const In& in, Out& out)
104.55 + template <typename Graph, typename In, typename Out>
104.56 + Value kruskal(const Graph& g, const In& in, Out& out)
104.57 #else
104.58 template <class Graph, class In, class Out>
104.59 inline typename _kruskal_bits::KruskalValueSelector<In>::Value
104.60 @@ -314,8 +314,6 @@
104.61 }
104.62
104.63
104.64 -
104.65 -
104.66 template <class Graph, class In, class Out>
104.67 inline typename _kruskal_bits::KruskalValueSelector<In>::Value
104.68 kruskal(const Graph& graph, const In& in, const Out& out)
105.1 --- a/lemon/lemon.pc.in Fri Nov 13 12:33:33 2009 +0100
105.2 +++ b/lemon/lemon.pc.in Thu Dec 10 17:05:35 2009 +0100
105.3 @@ -4,7 +4,7 @@
105.4 includedir=@includedir@
105.5
105.6 Name: @PACKAGE_NAME@
105.7 -Description: Library of Efficient Models and Optimization in Networks
105.8 +Description: Library for Efficient Modeling and Optimization in Networks
105.9 Version: @PACKAGE_VERSION@
105.10 -Libs: -L${libdir} -lemon
105.11 +Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@
105.12 Cflags: -I${includedir}
106.1 --- a/lemon/lgf_reader.h Fri Nov 13 12:33:33 2009 +0100
106.2 +++ b/lemon/lgf_reader.h Thu Dec 10 17:05:35 2009 +0100
106.3 @@ -2,7 +2,7 @@
106.4 *
106.5 * This file is a part of LEMON, a generic C++ optimization library.
106.6 *
106.7 - * Copyright (C) 2003-2008
106.8 + * Copyright (C) 2003-2009
106.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
106.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
106.11 *
106.12 @@ -101,23 +101,23 @@
106.13 }
106.14 };
106.15
106.16 - template <typename _Graph, bool _dir, typename _Map,
106.17 + template <typename _GR, bool _dir, typename _Map,
106.18 typename _Converter = DefaultConverter<typename _Map::Value> >
106.19 - class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
106.20 + class GraphArcMapStorage : public MapStorageBase<typename _GR::Edge> {
106.21 public:
106.22 typedef _Map Map;
106.23 typedef _Converter Converter;
106.24 - typedef _Graph Graph;
106.25 - typedef typename Graph::Edge Item;
106.26 + typedef _GR GR;
106.27 + typedef typename GR::Edge Item;
106.28 static const bool dir = _dir;
106.29
106.30 private:
106.31 - const Graph& _graph;
106.32 + const GR& _graph;
106.33 Map& _map;
106.34 Converter _converter;
106.35
106.36 public:
106.37 - GraphArcMapStorage(const Graph& graph, Map& map,
106.38 + GraphArcMapStorage(const GR& graph, Map& map,
106.39 const Converter& converter = Converter())
106.40 : _graph(graph), _map(map), _converter(converter) {}
106.41 virtual ~GraphArcMapStorage() {}
106.42 @@ -173,21 +173,21 @@
106.43 }
106.44 };
106.45
106.46 - template <typename Graph>
106.47 + template <typename GR>
106.48 struct GraphArcLookUpConverter {
106.49 - const Graph& _graph;
106.50 - const std::map<std::string, typename Graph::Edge>& _map;
106.51 -
106.52 - GraphArcLookUpConverter(const Graph& graph,
106.53 + const GR& _graph;
106.54 + const std::map<std::string, typename GR::Edge>& _map;
106.55 +
106.56 + GraphArcLookUpConverter(const GR& graph,
106.57 const std::map<std::string,
106.58 - typename Graph::Edge>& map)
106.59 + typename GR::Edge>& map)
106.60 : _graph(graph), _map(map) {}
106.61
106.62 - typename Graph::Arc operator()(const std::string& str) {
106.63 + typename GR::Arc operator()(const std::string& str) {
106.64 if (str.empty() || (str[0] != '+' && str[0] != '-')) {
106.65 throw FormatError("Item must start with '+' or '-'");
106.66 }
106.67 - typename std::map<std::string, typename Graph::Edge>
106.68 + typename std::map<std::string, typename GR::Edge>
106.69 ::const_iterator it = _map.find(str.substr(1));
106.70 if (it == _map.end()) {
106.71 throw FormatError("Item not found");
106.72 @@ -387,16 +387,15 @@
106.73
106.74 }
106.75
106.76 - template <typename Digraph>
106.77 + template <typename DGR>
106.78 class DigraphReader;
106.79
106.80 - template <typename Digraph>
106.81 - DigraphReader<Digraph> digraphReader(Digraph& digraph,
106.82 - std::istream& is = std::cin);
106.83 - template <typename Digraph>
106.84 - DigraphReader<Digraph> digraphReader(Digraph& digraph, const std::string& fn);
106.85 - template <typename Digraph>
106.86 - DigraphReader<Digraph> digraphReader(Digraph& digraph, const char *fn);
106.87 + template <typename TDGR>
106.88 + DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is = std::cin);
106.89 + template <typename TDGR>
106.90 + DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn);
106.91 + template <typename TDGR>
106.92 + DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
106.93
106.94 /// \ingroup lemon_io
106.95 ///
106.96 @@ -419,7 +418,7 @@
106.97 /// rules.
106.98 ///
106.99 ///\code
106.100 - /// DigraphReader<Digraph>(digraph, std::cin).
106.101 + /// DigraphReader<DGR>(digraph, std::cin).
106.102 /// nodeMap("coordinates", coord_map).
106.103 /// arcMap("capacity", cap_map).
106.104 /// node("source", src).
106.105 @@ -448,21 +447,21 @@
106.106 /// It is impossible to read this in
106.107 /// a single pass, because the arcs are not constructed when the node
106.108 /// maps are read.
106.109 - template <typename _Digraph>
106.110 + template <typename DGR>
106.111 class DigraphReader {
106.112 public:
106.113
106.114 - typedef _Digraph Digraph;
106.115 - TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
106.116 + typedef DGR Digraph;
106.117
106.118 private:
106.119
106.120 + TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
106.121
106.122 std::istream* _is;
106.123 bool local_is;
106.124 std::string _filename;
106.125
106.126 - Digraph& _digraph;
106.127 + DGR& _digraph;
106.128
106.129 std::string _nodes_caption;
106.130 std::string _arcs_caption;
106.131 @@ -500,7 +499,7 @@
106.132 ///
106.133 /// Construct a directed graph reader, which reads from the given
106.134 /// input stream.
106.135 - DigraphReader(Digraph& digraph, std::istream& is = std::cin)
106.136 + DigraphReader(DGR& digraph, std::istream& is = std::cin)
106.137 : _is(&is), local_is(false), _digraph(digraph),
106.138 _use_nodes(false), _use_arcs(false),
106.139 _skip_nodes(false), _skip_arcs(false) {}
106.140 @@ -509,7 +508,7 @@
106.141 ///
106.142 /// Construct a directed graph reader, which reads from the given
106.143 /// file.
106.144 - DigraphReader(Digraph& digraph, const std::string& fn)
106.145 + DigraphReader(DGR& digraph, const std::string& fn)
106.146 : _is(new std::ifstream(fn.c_str())), local_is(true),
106.147 _filename(fn), _digraph(digraph),
106.148 _use_nodes(false), _use_arcs(false),
106.149 @@ -524,7 +523,7 @@
106.150 ///
106.151 /// Construct a directed graph reader, which reads from the given
106.152 /// file.
106.153 - DigraphReader(Digraph& digraph, const char* fn)
106.154 + DigraphReader(DGR& digraph, const char* fn)
106.155 : _is(new std::ifstream(fn)), local_is(true),
106.156 _filename(fn), _digraph(digraph),
106.157 _use_nodes(false), _use_arcs(false),
106.158 @@ -560,13 +559,13 @@
106.159
106.160 private:
106.161
106.162 - template <typename DGR>
106.163 - friend DigraphReader<DGR> digraphReader(DGR& digraph, std::istream& is);
106.164 - template <typename DGR>
106.165 - friend DigraphReader<DGR> digraphReader(DGR& digraph,
106.166 - const std::string& fn);
106.167 - template <typename DGR>
106.168 - friend DigraphReader<DGR> digraphReader(DGR& digraph, const char *fn);
106.169 + template <typename TDGR>
106.170 + friend DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is);
106.171 + template <typename TDGR>
106.172 + friend DigraphReader<TDGR> digraphReader(TDGR& digraph,
106.173 + const std::string& fn);
106.174 + template <typename TDGR>
106.175 + friend DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
106.176
106.177 DigraphReader(DigraphReader& other)
106.178 : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
106.179 @@ -593,7 +592,7 @@
106.180
106.181 public:
106.182
106.183 - /// \name Reading rules
106.184 + /// \name Reading Rules
106.185 /// @{
106.186
106.187 /// \brief Node map reading rule
106.188 @@ -698,7 +697,7 @@
106.189
106.190 /// @}
106.191
106.192 - /// \name Select section by name
106.193 + /// \name Select Section by Name
106.194 /// @{
106.195
106.196 /// \brief Set \c \@nodes section to be read
106.197 @@ -727,7 +726,7 @@
106.198
106.199 /// @}
106.200
106.201 - /// \name Using previously constructed node or arc set
106.202 + /// \name Using Previously Constructed Node or Arc Set
106.203 /// @{
106.204
106.205 /// \brief Use previously constructed node set
106.206 @@ -847,7 +846,9 @@
106.207 while (readSuccess() && line >> c && c != '@') {
106.208 readLine();
106.209 }
106.210 - line.putback(c);
106.211 + if (readSuccess()) {
106.212 + line.putback(c);
106.213 + }
106.214 }
106.215
106.216 void readNodes() {
106.217 @@ -1114,7 +1115,7 @@
106.218
106.219 public:
106.220
106.221 - /// \name Execution of the reader
106.222 + /// \name Execution of the Reader
106.223 /// @{
106.224
106.225 /// \brief Start the batch processing
106.226 @@ -1186,14 +1187,52 @@
106.227 /// @}
106.228
106.229 };
106.230 +
106.231 + /// \ingroup lemon_io
106.232 + ///
106.233 + /// \brief Return a \ref DigraphReader class
106.234 + ///
106.235 + /// This function just returns a \ref DigraphReader class.
106.236 + ///
106.237 + /// With this function a digraph can be read from an
106.238 + /// \ref lgf-format "LGF" file or input stream with several maps and
106.239 + /// attributes. For example, there is network flow problem on a
106.240 + /// digraph, i.e. a digraph with a \e capacity map on the arcs and
106.241 + /// \e source and \e target nodes. This digraph can be read with the
106.242 + /// following code:
106.243 + ///
106.244 + ///\code
106.245 + ///ListDigraph digraph;
106.246 + ///ListDigraph::ArcMap<int> cm(digraph);
106.247 + ///ListDigraph::Node src, trg;
106.248 + ///digraphReader(digraph, std::cin).
106.249 + /// arcMap("capacity", cap).
106.250 + /// node("source", src).
106.251 + /// node("target", trg).
106.252 + /// run();
106.253 + ///\endcode
106.254 + ///
106.255 + /// For a complete documentation, please see the \ref DigraphReader
106.256 + /// class documentation.
106.257 + /// \warning Don't forget to put the \ref DigraphReader::run() "run()"
106.258 + /// to the end of the parameter list.
106.259 + /// \relates DigraphReader
106.260 + /// \sa digraphReader(TDGR& digraph, const std::string& fn)
106.261 + /// \sa digraphReader(TDGR& digraph, const char* fn)
106.262 + template <typename TDGR>
106.263 + DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is) {
106.264 + DigraphReader<TDGR> tmp(digraph, is);
106.265 + return tmp;
106.266 + }
106.267
106.268 /// \brief Return a \ref DigraphReader class
106.269 ///
106.270 /// This function just returns a \ref DigraphReader class.
106.271 /// \relates DigraphReader
106.272 - template <typename Digraph>
106.273 - DigraphReader<Digraph> digraphReader(Digraph& digraph, std::istream& is) {
106.274 - DigraphReader<Digraph> tmp(digraph, is);
106.275 + /// \sa digraphReader(TDGR& digraph, std::istream& is)
106.276 + template <typename TDGR>
106.277 + DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn) {
106.278 + DigraphReader<TDGR> tmp(digraph, fn);
106.279 return tmp;
106.280 }
106.281
106.282 @@ -1201,33 +1240,22 @@
106.283 ///
106.284 /// This function just returns a \ref DigraphReader class.
106.285 /// \relates DigraphReader
106.286 - template <typename Digraph>
106.287 - DigraphReader<Digraph> digraphReader(Digraph& digraph,
106.288 - const std::string& fn) {
106.289 - DigraphReader<Digraph> tmp(digraph, fn);
106.290 + /// \sa digraphReader(TDGR& digraph, std::istream& is)
106.291 + template <typename TDGR>
106.292 + DigraphReader<TDGR> digraphReader(TDGR& digraph, const char* fn) {
106.293 + DigraphReader<TDGR> tmp(digraph, fn);
106.294 return tmp;
106.295 }
106.296
106.297 - /// \brief Return a \ref DigraphReader class
106.298 - ///
106.299 - /// This function just returns a \ref DigraphReader class.
106.300 - /// \relates DigraphReader
106.301 - template <typename Digraph>
106.302 - DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
106.303 - DigraphReader<Digraph> tmp(digraph, fn);
106.304 - return tmp;
106.305 - }
106.306 -
106.307 - template <typename Graph>
106.308 + template <typename GR>
106.309 class GraphReader;
106.310
106.311 - template <typename Graph>
106.312 - GraphReader<Graph> graphReader(Graph& graph,
106.313 - std::istream& is = std::cin);
106.314 - template <typename Graph>
106.315 - GraphReader<Graph> graphReader(Graph& graph, const std::string& fn);
106.316 - template <typename Graph>
106.317 - GraphReader<Graph> graphReader(Graph& graph, const char *fn);
106.318 + template <typename TGR>
106.319 + GraphReader<TGR> graphReader(TGR& graph, std::istream& is = std::cin);
106.320 + template <typename TGR>
106.321 + GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
106.322 + template <typename TGR>
106.323 + GraphReader<TGR> graphReader(TGR& graph, const char *fn);
106.324
106.325 /// \ingroup lemon_io
106.326 ///
106.327 @@ -1244,20 +1272,21 @@
106.328 /// prefixed with \c '+' and \c '-', then these can be read into an
106.329 /// arc map. Similarly, an attribute can be read into an arc, if
106.330 /// it's value is an edge label prefixed with \c '+' or \c '-'.
106.331 - template <typename _Graph>
106.332 + template <typename GR>
106.333 class GraphReader {
106.334 public:
106.335
106.336 - typedef _Graph Graph;
106.337 - TEMPLATE_GRAPH_TYPEDEFS(Graph);
106.338 + typedef GR Graph;
106.339
106.340 private:
106.341
106.342 + TEMPLATE_GRAPH_TYPEDEFS(GR);
106.343 +
106.344 std::istream* _is;
106.345 bool local_is;
106.346 std::string _filename;
106.347
106.348 - Graph& _graph;
106.349 + GR& _graph;
106.350
106.351 std::string _nodes_caption;
106.352 std::string _edges_caption;
106.353 @@ -1295,7 +1324,7 @@
106.354 ///
106.355 /// Construct an undirected graph reader, which reads from the given
106.356 /// input stream.
106.357 - GraphReader(Graph& graph, std::istream& is = std::cin)
106.358 + GraphReader(GR& graph, std::istream& is = std::cin)
106.359 : _is(&is), local_is(false), _graph(graph),
106.360 _use_nodes(false), _use_edges(false),
106.361 _skip_nodes(false), _skip_edges(false) {}
106.362 @@ -1304,7 +1333,7 @@
106.363 ///
106.364 /// Construct an undirected graph reader, which reads from the given
106.365 /// file.
106.366 - GraphReader(Graph& graph, const std::string& fn)
106.367 + GraphReader(GR& graph, const std::string& fn)
106.368 : _is(new std::ifstream(fn.c_str())), local_is(true),
106.369 _filename(fn), _graph(graph),
106.370 _use_nodes(false), _use_edges(false),
106.371 @@ -1319,7 +1348,7 @@
106.372 ///
106.373 /// Construct an undirected graph reader, which reads from the given
106.374 /// file.
106.375 - GraphReader(Graph& graph, const char* fn)
106.376 + GraphReader(GR& graph, const char* fn)
106.377 : _is(new std::ifstream(fn)), local_is(true),
106.378 _filename(fn), _graph(graph),
106.379 _use_nodes(false), _use_edges(false),
106.380 @@ -1354,12 +1383,12 @@
106.381 }
106.382
106.383 private:
106.384 - template <typename GR>
106.385 - friend GraphReader<GR> graphReader(GR& graph, std::istream& is);
106.386 - template <typename GR>
106.387 - friend GraphReader<GR> graphReader(GR& graph, const std::string& fn);
106.388 - template <typename GR>
106.389 - friend GraphReader<GR> graphReader(GR& graph, const char *fn);
106.390 + template <typename TGR>
106.391 + friend GraphReader<TGR> graphReader(TGR& graph, std::istream& is);
106.392 + template <typename TGR>
106.393 + friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
106.394 + template <typename TGR>
106.395 + friend GraphReader<TGR> graphReader(TGR& graph, const char *fn);
106.396
106.397 GraphReader(GraphReader& other)
106.398 : _is(other._is), local_is(other.local_is), _graph(other._graph),
106.399 @@ -1386,7 +1415,7 @@
106.400
106.401 public:
106.402
106.403 - /// \name Reading rules
106.404 + /// \name Reading Rules
106.405 /// @{
106.406
106.407 /// \brief Node map reading rule
106.408 @@ -1451,7 +1480,7 @@
106.409 new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
106.410 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
106.411 _reader_bits::MapStorageBase<Edge>* backward_storage =
106.412 - new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
106.413 + new _reader_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
106.414 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
106.415 return *this;
106.416 }
106.417 @@ -1465,11 +1494,11 @@
106.418 const Converter& converter = Converter()) {
106.419 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
106.420 _reader_bits::MapStorageBase<Edge>* forward_storage =
106.421 - new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
106.422 + new _reader_bits::GraphArcMapStorage<GR, true, Map, Converter>
106.423 (_graph, map, converter);
106.424 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
106.425 _reader_bits::MapStorageBase<Edge>* backward_storage =
106.426 - new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
106.427 + new _reader_bits::GraphArcMapStorage<GR, false, Map, Converter>
106.428 (_graph, map, converter);
106.429 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
106.430 return *this;
106.431 @@ -1527,7 +1556,7 @@
106.432 ///
106.433 /// Add an arc reading rule to reader.
106.434 GraphReader& arc(const std::string& caption, Arc& arc) {
106.435 - typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
106.436 + typedef _reader_bits::GraphArcLookUpConverter<GR> Converter;
106.437 Converter converter(_graph, _edge_index);
106.438 _reader_bits::ValueStorageBase* storage =
106.439 new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
106.440 @@ -1537,7 +1566,7 @@
106.441
106.442 /// @}
106.443
106.444 - /// \name Select section by name
106.445 + /// \name Select Section by Name
106.446 /// @{
106.447
106.448 /// \brief Set \c \@nodes section to be read
106.449 @@ -1566,7 +1595,7 @@
106.450
106.451 /// @}
106.452
106.453 - /// \name Using previously constructed node or edge set
106.454 + /// \name Using Previously Constructed Node or Edge Set
106.455 /// @{
106.456
106.457 /// \brief Use previously constructed node set
106.458 @@ -1687,7 +1716,9 @@
106.459 while (readSuccess() && line >> c && c != '@') {
106.460 readLine();
106.461 }
106.462 - line.putback(c);
106.463 + if (readSuccess()) {
106.464 + line.putback(c);
106.465 + }
106.466 }
106.467
106.468 void readNodes() {
106.469 @@ -1954,7 +1985,7 @@
106.470
106.471 public:
106.472
106.473 - /// \name Execution of the reader
106.474 + /// \name Execution of the Reader
106.475 /// @{
106.476
106.477 /// \brief Start the batch processing
106.478 @@ -2028,13 +2059,47 @@
106.479
106.480 };
106.481
106.482 + /// \ingroup lemon_io
106.483 + ///
106.484 + /// \brief Return a \ref GraphReader class
106.485 + ///
106.486 + /// This function just returns a \ref GraphReader class.
106.487 + ///
106.488 + /// With this function a graph can be read from an
106.489 + /// \ref lgf-format "LGF" file or input stream with several maps and
106.490 + /// attributes. For example, there is weighted matching problem on a
106.491 + /// graph, i.e. a graph with a \e weight map on the edges. This
106.492 + /// graph can be read with the following code:
106.493 + ///
106.494 + ///\code
106.495 + ///ListGraph graph;
106.496 + ///ListGraph::EdgeMap<int> weight(graph);
106.497 + ///graphReader(graph, std::cin).
106.498 + /// edgeMap("weight", weight).
106.499 + /// run();
106.500 + ///\endcode
106.501 + ///
106.502 + /// For a complete documentation, please see the \ref GraphReader
106.503 + /// class documentation.
106.504 + /// \warning Don't forget to put the \ref GraphReader::run() "run()"
106.505 + /// to the end of the parameter list.
106.506 + /// \relates GraphReader
106.507 + /// \sa graphReader(TGR& graph, const std::string& fn)
106.508 + /// \sa graphReader(TGR& graph, const char* fn)
106.509 + template <typename TGR>
106.510 + GraphReader<TGR> graphReader(TGR& graph, std::istream& is) {
106.511 + GraphReader<TGR> tmp(graph, is);
106.512 + return tmp;
106.513 + }
106.514 +
106.515 /// \brief Return a \ref GraphReader class
106.516 ///
106.517 /// This function just returns a \ref GraphReader class.
106.518 /// \relates GraphReader
106.519 - template <typename Graph>
106.520 - GraphReader<Graph> graphReader(Graph& graph, std::istream& is) {
106.521 - GraphReader<Graph> tmp(graph, is);
106.522 + /// \sa graphReader(TGR& graph, std::istream& is)
106.523 + template <typename TGR>
106.524 + GraphReader<TGR> graphReader(TGR& graph, const std::string& fn) {
106.525 + GraphReader<TGR> tmp(graph, fn);
106.526 return tmp;
106.527 }
106.528
106.529 @@ -2042,19 +2107,10 @@
106.530 ///
106.531 /// This function just returns a \ref GraphReader class.
106.532 /// \relates GraphReader
106.533 - template <typename Graph>
106.534 - GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
106.535 - GraphReader<Graph> tmp(graph, fn);
106.536 - return tmp;
106.537 - }
106.538 -
106.539 - /// \brief Return a \ref GraphReader class
106.540 - ///
106.541 - /// This function just returns a \ref GraphReader class.
106.542 - /// \relates GraphReader
106.543 - template <typename Graph>
106.544 - GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
106.545 - GraphReader<Graph> tmp(graph, fn);
106.546 + /// \sa graphReader(TGR& graph, std::istream& is)
106.547 + template <typename TGR>
106.548 + GraphReader<TGR> graphReader(TGR& graph, const char* fn) {
106.549 + GraphReader<TGR> tmp(graph, fn);
106.550 return tmp;
106.551 }
106.552
106.553 @@ -2153,7 +2209,7 @@
106.554
106.555 public:
106.556
106.557 - /// \name Section readers
106.558 + /// \name Section Readers
106.559 /// @{
106.560
106.561 /// \brief Add a section processor with line oriented reading
106.562 @@ -2244,13 +2300,15 @@
106.563 while (readSuccess() && line >> c && c != '@') {
106.564 readLine();
106.565 }
106.566 - line.putback(c);
106.567 + if (readSuccess()) {
106.568 + line.putback(c);
106.569 + }
106.570 }
106.571
106.572 public:
106.573
106.574
106.575 - /// \name Execution of the reader
106.576 + /// \name Execution of the Reader
106.577 /// @{
106.578
106.579 /// \brief Start the batch processing
106.580 @@ -2309,12 +2367,30 @@
106.581
106.582 };
106.583
106.584 + /// \ingroup lemon_io
106.585 + ///
106.586 + /// \brief Return a \ref SectionReader class
106.587 + ///
106.588 + /// This function just returns a \ref SectionReader class.
106.589 + ///
106.590 + /// Please see SectionReader documentation about the custom section
106.591 + /// input.
106.592 + ///
106.593 + /// \relates SectionReader
106.594 + /// \sa sectionReader(const std::string& fn)
106.595 + /// \sa sectionReader(const char *fn)
106.596 + inline SectionReader sectionReader(std::istream& is) {
106.597 + SectionReader tmp(is);
106.598 + return tmp;
106.599 + }
106.600 +
106.601 /// \brief Return a \ref SectionReader class
106.602 ///
106.603 /// This function just returns a \ref SectionReader class.
106.604 /// \relates SectionReader
106.605 - inline SectionReader sectionReader(std::istream& is) {
106.606 - SectionReader tmp(is);
106.607 + /// \sa sectionReader(std::istream& is)
106.608 + inline SectionReader sectionReader(const std::string& fn) {
106.609 + SectionReader tmp(fn);
106.610 return tmp;
106.611 }
106.612
106.613 @@ -2322,15 +2398,7 @@
106.614 ///
106.615 /// This function just returns a \ref SectionReader class.
106.616 /// \relates SectionReader
106.617 - inline SectionReader sectionReader(const std::string& fn) {
106.618 - SectionReader tmp(fn);
106.619 - return tmp;
106.620 - }
106.621 -
106.622 - /// \brief Return a \ref SectionReader class
106.623 - ///
106.624 - /// This function just returns a \ref SectionReader class.
106.625 - /// \relates SectionReader
106.626 + /// \sa sectionReader(std::istream& is)
106.627 inline SectionReader sectionReader(const char* fn) {
106.628 SectionReader tmp(fn);
106.629 return tmp;
106.630 @@ -2432,7 +2500,7 @@
106.631 public:
106.632
106.633
106.634 - /// \name Node sections
106.635 + /// \name Node Sections
106.636 /// @{
106.637
106.638 /// \brief Gives back the number of node sections in the file.
106.639 @@ -2458,7 +2526,7 @@
106.640
106.641 /// @}
106.642
106.643 - /// \name Arc/Edge sections
106.644 + /// \name Arc/Edge Sections
106.645 /// @{
106.646
106.647 /// \brief Gives back the number of arc/edge sections in the file.
106.648 @@ -2516,7 +2584,7 @@
106.649
106.650 /// @}
106.651
106.652 - /// \name Attribute sections
106.653 + /// \name Attribute Sections
106.654 /// @{
106.655
106.656 /// \brief Gives back the number of attribute sections in the file.
106.657 @@ -2542,7 +2610,7 @@
106.658
106.659 /// @}
106.660
106.661 - /// \name Extra sections
106.662 + /// \name Extra Sections
106.663 /// @{
106.664
106.665 /// \brief Gives back the number of extra sections in the file.
106.666 @@ -2585,7 +2653,9 @@
106.667 while (readSuccess() && line >> c && c != '@') {
106.668 readLine();
106.669 }
106.670 - line.putback(c);
106.671 + if (readSuccess()) {
106.672 + line.putback(c);
106.673 + }
106.674 }
106.675
106.676 void readMaps(std::vector<std::string>& maps) {
106.677 @@ -2616,7 +2686,7 @@
106.678
106.679 public:
106.680
106.681 - /// \name Execution of the contents reader
106.682 + /// \name Execution of the Contents Reader
106.683 /// @{
106.684
106.685 /// \brief Starts the reading
107.1 --- a/lemon/lgf_writer.h Fri Nov 13 12:33:33 2009 +0100
107.2 +++ b/lemon/lgf_writer.h Thu Dec 10 17:05:35 2009 +0100
107.3 @@ -2,7 +2,7 @@
107.4 *
107.5 * This file is a part of LEMON, a generic C++ optimization library.
107.6 *
107.7 - * Copyright (C) 2003-2008
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 @@ -347,19 +347,17 @@
107.13
107.14 }
107.15
107.16 - template <typename Digraph>
107.17 + template <typename DGR>
107.18 class DigraphWriter;
107.19
107.20 - template <typename Digraph>
107.21 - DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
107.22 - std::ostream& os = std::cout);
107.23 - template <typename Digraph>
107.24 - DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
107.25 - const std::string& fn);
107.26 + template <typename TDGR>
107.27 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
107.28 + std::ostream& os = std::cout);
107.29 + template <typename TDGR>
107.30 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const std::string& fn);
107.31
107.32 - template <typename Digraph>
107.33 - DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
107.34 - const char* fn);
107.35 + template <typename TDGR>
107.36 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn);
107.37
107.38
107.39 /// \ingroup lemon_io
107.40 @@ -381,7 +379,7 @@
107.41 /// arc() functions are used to add attribute writing rules.
107.42 ///
107.43 ///\code
107.44 - /// DigraphWriter<Digraph>(digraph, std::cout).
107.45 + /// DigraphWriter<DGR>(digraph, std::cout).
107.46 /// nodeMap("coordinates", coord_map).
107.47 /// nodeMap("size", size).
107.48 /// nodeMap("title", title).
107.49 @@ -406,12 +404,12 @@
107.50 /// section to the stream. The output stream can be retrieved with
107.51 /// the \c ostream() function, hence the second pass can append its
107.52 /// output to the output of the first pass.
107.53 - template <typename _Digraph>
107.54 + template <typename DGR>
107.55 class DigraphWriter {
107.56 public:
107.57
107.58 - typedef _Digraph Digraph;
107.59 - TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
107.60 + typedef DGR Digraph;
107.61 + TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
107.62
107.63 private:
107.64
107.65 @@ -419,7 +417,7 @@
107.66 std::ostream* _os;
107.67 bool local_os;
107.68
107.69 - const Digraph& _digraph;
107.70 + const DGR& _digraph;
107.71
107.72 std::string _nodes_caption;
107.73 std::string _arcs_caption;
107.74 @@ -451,7 +449,7 @@
107.75 ///
107.76 /// Construct a directed graph writer, which writes to the given
107.77 /// output stream.
107.78 - DigraphWriter(const Digraph& digraph, std::ostream& os = std::cout)
107.79 + DigraphWriter(const DGR& digraph, std::ostream& os = std::cout)
107.80 : _os(&os), local_os(false), _digraph(digraph),
107.81 _skip_nodes(false), _skip_arcs(false) {}
107.82
107.83 @@ -459,7 +457,7 @@
107.84 ///
107.85 /// Construct a directed graph writer, which writes to the given
107.86 /// output file.
107.87 - DigraphWriter(const Digraph& digraph, const std::string& fn)
107.88 + DigraphWriter(const DGR& digraph, const std::string& fn)
107.89 : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
107.90 _skip_nodes(false), _skip_arcs(false) {
107.91 if (!(*_os)) {
107.92 @@ -472,7 +470,7 @@
107.93 ///
107.94 /// Construct a directed graph writer, which writes to the given
107.95 /// output file.
107.96 - DigraphWriter(const Digraph& digraph, const char* fn)
107.97 + DigraphWriter(const DGR& digraph, const char* fn)
107.98 : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
107.99 _skip_nodes(false), _skip_arcs(false) {
107.100 if (!(*_os)) {
107.101 @@ -505,15 +503,15 @@
107.102
107.103 private:
107.104
107.105 - template <typename DGR>
107.106 - friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
107.107 - std::ostream& os);
107.108 - template <typename DGR>
107.109 - friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
107.110 - const std::string& fn);
107.111 - template <typename DGR>
107.112 - friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
107.113 - const char *fn);
107.114 + template <typename TDGR>
107.115 + friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
107.116 + std::ostream& os);
107.117 + template <typename TDGR>
107.118 + friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
107.119 + const std::string& fn);
107.120 + template <typename TDGR>
107.121 + friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
107.122 + const char *fn);
107.123
107.124 DigraphWriter(DigraphWriter& other)
107.125 : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
107.126 @@ -538,7 +536,7 @@
107.127
107.128 public:
107.129
107.130 - /// \name Writing rules
107.131 + /// \name Writing Rules
107.132 /// @{
107.133
107.134 /// \brief Node map writing rule
107.135 @@ -641,7 +639,7 @@
107.136 return *this;
107.137 }
107.138
107.139 - /// \name Section captions
107.140 + /// \name Section Captions
107.141 /// @{
107.142
107.143 /// \brief Add an additional caption to the \c \@nodes section
107.144 @@ -668,7 +666,7 @@
107.145 return *this;
107.146 }
107.147
107.148 - /// \name Skipping section
107.149 + /// \name Skipping Section
107.150 /// @{
107.151
107.152 /// \brief Skip writing the node set
107.153 @@ -724,8 +722,8 @@
107.154 }
107.155
107.156 if (label == 0) {
107.157 - IdMap<Digraph, Node> id_map(_digraph);
107.158 - _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
107.159 + IdMap<DGR, Node> id_map(_digraph);
107.160 + _writer_bits::MapLess<IdMap<DGR, Node> > id_less(id_map);
107.161 std::sort(nodes.begin(), nodes.end(), id_less);
107.162 } else {
107.163 label->sort(nodes);
107.164 @@ -809,8 +807,8 @@
107.165 }
107.166
107.167 if (label == 0) {
107.168 - IdMap<Digraph, Arc> id_map(_digraph);
107.169 - _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
107.170 + IdMap<DGR, Arc> id_map(_digraph);
107.171 + _writer_bits::MapLess<IdMap<DGR, Arc> > id_less(id_map);
107.172 std::sort(arcs.begin(), arcs.end(), id_less);
107.173 } else {
107.174 label->sort(arcs);
107.175 @@ -885,7 +883,7 @@
107.176
107.177 public:
107.178
107.179 - /// \name Execution of the writer
107.180 + /// \name Execution of the Writer
107.181 /// @{
107.182
107.183 /// \brief Start the batch processing
107.184 @@ -915,14 +913,41 @@
107.185 /// @}
107.186 };
107.187
107.188 + /// \ingroup lemon_io
107.189 + ///
107.190 /// \brief Return a \ref DigraphWriter class
107.191 ///
107.192 - /// This function just returns a \ref DigraphWriter class.
107.193 + /// This function just returns a \ref DigraphWriter class.
107.194 + ///
107.195 + /// With this function a digraph can be write to a file or output
107.196 + /// stream in \ref lgf-format "LGF" format with several maps and
107.197 + /// attributes. For example, with the following code a network flow
107.198 + /// problem can be written to the standard output, i.e. a digraph
107.199 + /// with a \e capacity map on the arcs and \e source and \e target
107.200 + /// nodes:
107.201 + ///
107.202 + ///\code
107.203 + ///ListDigraph digraph;
107.204 + ///ListDigraph::ArcMap<int> cap(digraph);
107.205 + ///ListDigraph::Node src, trg;
107.206 + /// // Setting the capacity map and source and target nodes
107.207 + ///digraphWriter(digraph, std::cout).
107.208 + /// arcMap("capacity", cap).
107.209 + /// node("source", src).
107.210 + /// node("target", trg).
107.211 + /// run();
107.212 + ///\endcode
107.213 + ///
107.214 + /// For a complete documentation, please see the \ref DigraphWriter
107.215 + /// class documentation.
107.216 + /// \warning Don't forget to put the \ref DigraphWriter::run() "run()"
107.217 + /// to the end of the parameter list.
107.218 /// \relates DigraphWriter
107.219 - template <typename Digraph>
107.220 - DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
107.221 - std::ostream& os) {
107.222 - DigraphWriter<Digraph> tmp(digraph, os);
107.223 + /// \sa digraphWriter(const TDGR& digraph, const std::string& fn)
107.224 + /// \sa digraphWriter(const TDGR& digraph, const char* fn)
107.225 + template <typename TDGR>
107.226 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, std::ostream& os) {
107.227 + DigraphWriter<TDGR> tmp(digraph, os);
107.228 return tmp;
107.229 }
107.230
107.231 @@ -930,10 +955,11 @@
107.232 ///
107.233 /// This function just returns a \ref DigraphWriter class.
107.234 /// \relates DigraphWriter
107.235 - template <typename Digraph>
107.236 - DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
107.237 - const std::string& fn) {
107.238 - DigraphWriter<Digraph> tmp(digraph, fn);
107.239 + /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
107.240 + template <typename TDGR>
107.241 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
107.242 + const std::string& fn) {
107.243 + DigraphWriter<TDGR> tmp(digraph, fn);
107.244 return tmp;
107.245 }
107.246
107.247 @@ -941,23 +967,22 @@
107.248 ///
107.249 /// This function just returns a \ref DigraphWriter class.
107.250 /// \relates DigraphWriter
107.251 - template <typename Digraph>
107.252 - DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
107.253 - const char* fn) {
107.254 - DigraphWriter<Digraph> tmp(digraph, fn);
107.255 + /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
107.256 + template <typename TDGR>
107.257 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn) {
107.258 + DigraphWriter<TDGR> tmp(digraph, fn);
107.259 return tmp;
107.260 }
107.261
107.262 - template <typename Graph>
107.263 + template <typename GR>
107.264 class GraphWriter;
107.265
107.266 - template <typename Graph>
107.267 - GraphWriter<Graph> graphWriter(const Graph& graph,
107.268 - std::ostream& os = std::cout);
107.269 - template <typename Graph>
107.270 - GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn);
107.271 - template <typename Graph>
107.272 - GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn);
107.273 + template <typename TGR>
107.274 + GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os = std::cout);
107.275 + template <typename TGR>
107.276 + GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn);
107.277 + template <typename TGR>
107.278 + GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn);
107.279
107.280 /// \ingroup lemon_io
107.281 ///
107.282 @@ -974,12 +999,12 @@
107.283 /// '+' and \c '-'. The arcs are written into the \c \@attributes
107.284 /// section as a \c '+' or a \c '-' prefix (depends on the direction
107.285 /// of the arc) and the label of corresponding edge.
107.286 - template <typename _Graph>
107.287 + template <typename GR>
107.288 class GraphWriter {
107.289 public:
107.290
107.291 - typedef _Graph Graph;
107.292 - TEMPLATE_GRAPH_TYPEDEFS(Graph);
107.293 + typedef GR Graph;
107.294 + TEMPLATE_GRAPH_TYPEDEFS(GR);
107.295
107.296 private:
107.297
107.298 @@ -987,7 +1012,7 @@
107.299 std::ostream* _os;
107.300 bool local_os;
107.301
107.302 - const Graph& _graph;
107.303 + const GR& _graph;
107.304
107.305 std::string _nodes_caption;
107.306 std::string _edges_caption;
107.307 @@ -1019,7 +1044,7 @@
107.308 ///
107.309 /// Construct a directed graph writer, which writes to the given
107.310 /// output stream.
107.311 - GraphWriter(const Graph& graph, std::ostream& os = std::cout)
107.312 + GraphWriter(const GR& graph, std::ostream& os = std::cout)
107.313 : _os(&os), local_os(false), _graph(graph),
107.314 _skip_nodes(false), _skip_edges(false) {}
107.315
107.316 @@ -1027,7 +1052,7 @@
107.317 ///
107.318 /// Construct a directed graph writer, which writes to the given
107.319 /// output file.
107.320 - GraphWriter(const Graph& graph, const std::string& fn)
107.321 + GraphWriter(const GR& graph, const std::string& fn)
107.322 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
107.323 _skip_nodes(false), _skip_edges(false) {
107.324 if (!(*_os)) {
107.325 @@ -1040,7 +1065,7 @@
107.326 ///
107.327 /// Construct a directed graph writer, which writes to the given
107.328 /// output file.
107.329 - GraphWriter(const Graph& graph, const char* fn)
107.330 + GraphWriter(const GR& graph, const char* fn)
107.331 : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
107.332 _skip_nodes(false), _skip_edges(false) {
107.333 if (!(*_os)) {
107.334 @@ -1073,15 +1098,13 @@
107.335
107.336 private:
107.337
107.338 - template <typename GR>
107.339 - friend GraphWriter<GR> graphWriter(const GR& graph,
107.340 - std::ostream& os);
107.341 - template <typename GR>
107.342 - friend GraphWriter<GR> graphWriter(const GR& graph,
107.343 - const std::string& fn);
107.344 - template <typename GR>
107.345 - friend GraphWriter<GR> graphWriter(const GR& graph,
107.346 - const char *fn);
107.347 + template <typename TGR>
107.348 + friend GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os);
107.349 + template <typename TGR>
107.350 + friend GraphWriter<TGR> graphWriter(const TGR& graph,
107.351 + const std::string& fn);
107.352 + template <typename TGR>
107.353 + friend GraphWriter<TGR> graphWriter(const TGR& graph, const char *fn);
107.354
107.355 GraphWriter(GraphWriter& other)
107.356 : _os(other._os), local_os(other.local_os), _graph(other._graph),
107.357 @@ -1106,7 +1129,7 @@
107.358
107.359 public:
107.360
107.361 - /// \name Writing rules
107.362 + /// \name Writing Rules
107.363 /// @{
107.364
107.365 /// \brief Node map writing rule
107.366 @@ -1168,10 +1191,10 @@
107.367 GraphWriter& arcMap(const std::string& caption, const Map& map) {
107.368 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
107.369 _writer_bits::MapStorageBase<Edge>* forward_storage =
107.370 - new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
107.371 + new _writer_bits::GraphArcMapStorage<GR, true, Map>(_graph, map);
107.372 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
107.373 _writer_bits::MapStorageBase<Edge>* backward_storage =
107.374 - new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
107.375 + new _writer_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
107.376 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
107.377 return *this;
107.378 }
107.379 @@ -1185,11 +1208,11 @@
107.380 const Converter& converter = Converter()) {
107.381 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
107.382 _writer_bits::MapStorageBase<Edge>* forward_storage =
107.383 - new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
107.384 + new _writer_bits::GraphArcMapStorage<GR, true, Map, Converter>
107.385 (_graph, map, converter);
107.386 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
107.387 _writer_bits::MapStorageBase<Edge>* backward_storage =
107.388 - new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
107.389 + new _writer_bits::GraphArcMapStorage<GR, false, Map, Converter>
107.390 (_graph, map, converter);
107.391 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
107.392 return *this;
107.393 @@ -1247,7 +1270,7 @@
107.394 ///
107.395 /// Add an arc writing rule to writer.
107.396 GraphWriter& arc(const std::string& caption, const Arc& arc) {
107.397 - typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
107.398 + typedef _writer_bits::GraphArcLookUpConverter<GR> Converter;
107.399 Converter converter(_graph, _edge_index);
107.400 _writer_bits::ValueStorageBase* storage =
107.401 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
107.402 @@ -1255,7 +1278,7 @@
107.403 return *this;
107.404 }
107.405
107.406 - /// \name Section captions
107.407 + /// \name Section Captions
107.408 /// @{
107.409
107.410 /// \brief Add an additional caption to the \c \@nodes section
107.411 @@ -1282,7 +1305,7 @@
107.412 return *this;
107.413 }
107.414
107.415 - /// \name Skipping section
107.416 + /// \name Skipping Section
107.417 /// @{
107.418
107.419 /// \brief Skip writing the node set
107.420 @@ -1338,8 +1361,8 @@
107.421 }
107.422
107.423 if (label == 0) {
107.424 - IdMap<Graph, Node> id_map(_graph);
107.425 - _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
107.426 + IdMap<GR, Node> id_map(_graph);
107.427 + _writer_bits::MapLess<IdMap<GR, Node> > id_less(id_map);
107.428 std::sort(nodes.begin(), nodes.end(), id_less);
107.429 } else {
107.430 label->sort(nodes);
107.431 @@ -1423,8 +1446,8 @@
107.432 }
107.433
107.434 if (label == 0) {
107.435 - IdMap<Graph, Edge> id_map(_graph);
107.436 - _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
107.437 + IdMap<GR, Edge> id_map(_graph);
107.438 + _writer_bits::MapLess<IdMap<GR, Edge> > id_less(id_map);
107.439 std::sort(edges.begin(), edges.end(), id_less);
107.440 } else {
107.441 label->sort(edges);
107.442 @@ -1499,7 +1522,7 @@
107.443
107.444 public:
107.445
107.446 - /// \name Execution of the writer
107.447 + /// \name Execution of the Writer
107.448 /// @{
107.449
107.450 /// \brief Start the batch processing
107.451 @@ -1529,14 +1552,37 @@
107.452 /// @}
107.453 };
107.454
107.455 + /// \ingroup lemon_io
107.456 + ///
107.457 /// \brief Return a \ref GraphWriter class
107.458 ///
107.459 - /// This function just returns a \ref GraphWriter class.
107.460 + /// This function just returns a \ref GraphWriter class.
107.461 + ///
107.462 + /// With this function a graph can be write to a file or output
107.463 + /// stream in \ref lgf-format "LGF" format with several maps and
107.464 + /// attributes. For example, with the following code a weighted
107.465 + /// matching problem can be written to the standard output, i.e. a
107.466 + /// graph with a \e weight map on the edges:
107.467 + ///
107.468 + ///\code
107.469 + ///ListGraph graph;
107.470 + ///ListGraph::EdgeMap<int> weight(graph);
107.471 + /// // Setting the weight map
107.472 + ///graphWriter(graph, std::cout).
107.473 + /// edgeMap("weight", weight).
107.474 + /// run();
107.475 + ///\endcode
107.476 + ///
107.477 + /// For a complete documentation, please see the \ref GraphWriter
107.478 + /// class documentation.
107.479 + /// \warning Don't forget to put the \ref GraphWriter::run() "run()"
107.480 + /// to the end of the parameter list.
107.481 /// \relates GraphWriter
107.482 - template <typename Graph>
107.483 - GraphWriter<Graph> graphWriter(const Graph& graph,
107.484 - std::ostream& os) {
107.485 - GraphWriter<Graph> tmp(graph, os);
107.486 + /// \sa graphWriter(const TGR& graph, const std::string& fn)
107.487 + /// \sa graphWriter(const TGR& graph, const char* fn)
107.488 + template <typename TGR>
107.489 + GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os) {
107.490 + GraphWriter<TGR> tmp(graph, os);
107.491 return tmp;
107.492 }
107.493
107.494 @@ -1544,9 +1590,10 @@
107.495 ///
107.496 /// This function just returns a \ref GraphWriter class.
107.497 /// \relates GraphWriter
107.498 - template <typename Graph>
107.499 - GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
107.500 - GraphWriter<Graph> tmp(graph, fn);
107.501 + /// \sa graphWriter(const TGR& graph, std::ostream& os)
107.502 + template <typename TGR>
107.503 + GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn) {
107.504 + GraphWriter<TGR> tmp(graph, fn);
107.505 return tmp;
107.506 }
107.507
107.508 @@ -1554,9 +1601,10 @@
107.509 ///
107.510 /// This function just returns a \ref GraphWriter class.
107.511 /// \relates GraphWriter
107.512 - template <typename Graph>
107.513 - GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
107.514 - GraphWriter<Graph> tmp(graph, fn);
107.515 + /// \sa graphWriter(const TGR& graph, std::ostream& os)
107.516 + template <typename TGR>
107.517 + GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) {
107.518 + GraphWriter<TGR> tmp(graph, fn);
107.519 return tmp;
107.520 }
107.521
107.522 @@ -1651,7 +1699,7 @@
107.523
107.524 public:
107.525
107.526 - /// \name Section writers
107.527 + /// \name Section Writers
107.528 /// @{
107.529
107.530 /// \brief Add a section writer with line oriented writing
107.531 @@ -1718,7 +1766,7 @@
107.532 public:
107.533
107.534
107.535 - /// \name Execution of the writer
107.536 + /// \name Execution of the Writer
107.537 /// @{
107.538
107.539 /// \brief Start the batch processing
107.540 @@ -1746,10 +1794,18 @@
107.541
107.542 };
107.543
107.544 + /// \ingroup lemon_io
107.545 + ///
107.546 /// \brief Return a \ref SectionWriter class
107.547 ///
107.548 /// This function just returns a \ref SectionWriter class.
107.549 + ///
107.550 + /// Please see SectionWriter documentation about the custom section
107.551 + /// output.
107.552 + ///
107.553 /// \relates SectionWriter
107.554 + /// \sa sectionWriter(const std::string& fn)
107.555 + /// \sa sectionWriter(const char *fn)
107.556 inline SectionWriter sectionWriter(std::ostream& os) {
107.557 SectionWriter tmp(os);
107.558 return tmp;
107.559 @@ -1759,6 +1815,7 @@
107.560 ///
107.561 /// This function just returns a \ref SectionWriter class.
107.562 /// \relates SectionWriter
107.563 + /// \sa sectionWriter(std::ostream& os)
107.564 inline SectionWriter sectionWriter(const std::string& fn) {
107.565 SectionWriter tmp(fn);
107.566 return tmp;
107.567 @@ -1768,6 +1825,7 @@
107.568 ///
107.569 /// This function just returns a \ref SectionWriter class.
107.570 /// \relates SectionWriter
107.571 + /// \sa sectionWriter(std::ostream& os)
107.572 inline SectionWriter sectionWriter(const char* fn) {
107.573 SectionWriter tmp(fn);
107.574 return tmp;
108.1 --- a/lemon/list_graph.h Fri Nov 13 12:33:33 2009 +0100
108.2 +++ b/lemon/list_graph.h Thu Dec 10 17:05:35 2009 +0100
108.3 @@ -2,7 +2,7 @@
108.4 *
108.5 * This file is a part of LEMON, a generic C++ optimization library.
108.6 *
108.7 - * Copyright (C) 2003-2008
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 @@ -320,12 +320,11 @@
108.13 ///Most of the member functions and nested classes are documented
108.14 ///only in the concept class.
108.15 ///
108.16 - ///An important extra feature of this digraph implementation is that
108.17 - ///its maps are real \ref concepts::ReferenceMap "reference map"s.
108.18 - ///
108.19 ///\sa concepts::Digraph
108.20
108.21 class ListDigraph : public ExtendedListDigraphBase {
108.22 + typedef ExtendedListDigraphBase Parent;
108.23 +
108.24 private:
108.25 ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
108.26
108.27 @@ -340,8 +339,6 @@
108.28 void operator=(const ListDigraph &) {}
108.29 public:
108.30
108.31 - typedef ExtendedListDigraphBase Parent;
108.32 -
108.33 /// Constructor
108.34
108.35 /// Constructor.
108.36 @@ -351,14 +348,14 @@
108.37 ///Add a new node to the digraph.
108.38
108.39 ///Add a new node to the digraph.
108.40 - ///\return the new node.
108.41 + ///\return The new node.
108.42 Node addNode() { return Parent::addNode(); }
108.43
108.44 ///Add a new arc to the digraph.
108.45
108.46 ///Add a new arc to the digraph with source node \c s
108.47 ///and target node \c t.
108.48 - ///\return the new arc.
108.49 + ///\return The new arc.
108.50 Arc addArc(const Node& s, const Node& t) {
108.51 return Parent::addArc(s, t);
108.52 }
108.53 @@ -796,7 +793,7 @@
108.54
108.55 public:
108.56
108.57 - typedef ListGraphBase Digraph;
108.58 + typedef ListGraphBase Graph;
108.59
108.60 class Node;
108.61 class Arc;
108.62 @@ -840,8 +837,8 @@
108.63 explicit Arc(int pid) { id = pid;}
108.64
108.65 public:
108.66 - operator Edge() const {
108.67 - return id != -1 ? edgeFromId(id / 2) : INVALID;
108.68 + operator Edge() const {
108.69 + return id != -1 ? edgeFromId(id / 2) : INVALID;
108.70 }
108.71
108.72 Arc() {}
108.73 @@ -1176,12 +1173,11 @@
108.74 ///Most of the member functions and nested classes are documented
108.75 ///only in the concept class.
108.76 ///
108.77 - ///An important extra feature of this graph implementation is that
108.78 - ///its maps are real \ref concepts::ReferenceMap "reference map"s.
108.79 - ///
108.80 ///\sa concepts::Graph
108.81
108.82 class ListGraph : public ExtendedListGraphBase {
108.83 + typedef ExtendedListGraphBase Parent;
108.84 +
108.85 private:
108.86 ///ListGraph is \e not copy constructible. Use copyGraph() instead.
108.87
108.88 @@ -1201,21 +1197,19 @@
108.89 ///
108.90 ListGraph() {}
108.91
108.92 - typedef ExtendedListGraphBase Parent;
108.93 -
108.94 typedef Parent::OutArcIt IncEdgeIt;
108.95
108.96 /// \brief Add a new node to the graph.
108.97 ///
108.98 /// Add a new node to the graph.
108.99 - /// \return the new node.
108.100 + /// \return The new node.
108.101 Node addNode() { return Parent::addNode(); }
108.102
108.103 /// \brief Add a new edge to the graph.
108.104 ///
108.105 /// Add a new edge to the graph with source node \c s
108.106 /// and target node \c t.
108.107 - /// \return the new edge.
108.108 + /// \return The new edge.
108.109 Edge addEdge(const Node& s, const Node& t) {
108.110 return Parent::addEdge(s, t);
108.111 }
109.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
109.2 +++ b/lemon/lp.h Thu Dec 10 17:05:35 2009 +0100
109.3 @@ -0,0 +1,93 @@
109.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
109.5 + *
109.6 + * This file is a part of LEMON, a generic C++ optimization library.
109.7 + *
109.8 + * Copyright (C) 2003-2008
109.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
109.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
109.11 + *
109.12 + * Permission to use, modify and distribute this software is granted
109.13 + * provided that this copyright notice appears in all copies. For
109.14 + * precise terms see the accompanying LICENSE file.
109.15 + *
109.16 + * This software is provided "AS IS" with no warranty of any kind,
109.17 + * express or implied, and with no claim as to its suitability for any
109.18 + * purpose.
109.19 + *
109.20 + */
109.21 +
109.22 +#ifndef LEMON_LP_H
109.23 +#define LEMON_LP_H
109.24 +
109.25 +#include<lemon/config.h>
109.26 +
109.27 +
109.28 +#ifdef LEMON_HAVE_GLPK
109.29 +#include <lemon/glpk.h>
109.30 +#elif LEMON_HAVE_CPLEX
109.31 +#include <lemon/cplex.h>
109.32 +#elif LEMON_HAVE_SOPLEX
109.33 +#include <lemon/soplex.h>
109.34 +#elif LEMON_HAVE_CLP
109.35 +#include <lemon/clp.h>
109.36 +#endif
109.37 +
109.38 +///\file
109.39 +///\brief Defines a default LP solver
109.40 +///\ingroup lp_group
109.41 +namespace lemon {
109.42 +
109.43 +#ifdef DOXYGEN
109.44 + ///The default LP solver identifier
109.45 +
109.46 + ///The default LP solver identifier.
109.47 + ///\ingroup lp_group
109.48 + ///
109.49 + ///Currently, the possible values are \c GLPK, \c CPLEX,
109.50 + ///\c SOPLEX or \c CLP
109.51 +#define LEMON_DEFAULT_LP SOLVER
109.52 + ///The default LP solver
109.53 +
109.54 + ///The default LP solver.
109.55 + ///\ingroup lp_group
109.56 + ///
109.57 + ///Currently, it is either \c GlpkLp, \c CplexLp, \c SoplexLp or \c ClpLp
109.58 + typedef GlpkLp Lp;
109.59 +
109.60 + ///The default MIP solver identifier
109.61 +
109.62 + ///The default MIP solver identifier.
109.63 + ///\ingroup lp_group
109.64 + ///
109.65 + ///Currently, the possible values are \c GLPK or \c CPLEX
109.66 +#define LEMON_DEFAULT_MIP SOLVER
109.67 + ///The default MIP solver.
109.68 +
109.69 + ///The default MIP solver.
109.70 + ///\ingroup lp_group
109.71 + ///
109.72 + ///Currently, it is either \c GlpkMip or \c CplexMip
109.73 + typedef GlpkMip Mip;
109.74 +#else
109.75 +#ifdef LEMON_HAVE_GLPK
109.76 +# define LEMON_DEFAULT_LP GLPK
109.77 + typedef GlpkLp Lp;
109.78 +# define LEMON_DEFAULT_MIP GLPK
109.79 + typedef GlpkMip Mip;
109.80 +#elif LEMON_HAVE_CPLEX
109.81 +# define LEMON_DEFAULT_LP CPLEX
109.82 + typedef CplexLp Lp;
109.83 +# define LEMON_DEFAULT_MIP CPLEX
109.84 + typedef CplexMip Mip;
109.85 +#elif LEMON_HAVE_SOPLEX
109.86 +# define DEFAULT_LP SOPLEX
109.87 + typedef SoplexLp Lp;
109.88 +#elif LEMON_HAVE_CLP
109.89 +# define DEFAULT_LP CLP
109.90 + typedef ClpLp Lp;
109.91 +#endif
109.92 +#endif
109.93 +
109.94 +} //namespace lemon
109.95 +
109.96 +#endif //LEMON_LP_H
110.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
110.2 +++ b/lemon/lp_base.cc Thu Dec 10 17:05:35 2009 +0100
110.3 @@ -0,0 +1,30 @@
110.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
110.5 + *
110.6 + * This file is a part of LEMON, a generic C++ optimization library.
110.7 + *
110.8 + * Copyright (C) 2003-2008
110.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
110.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
110.11 + *
110.12 + * Permission to use, modify and distribute this software is granted
110.13 + * provided that this copyright notice appears in all copies. For
110.14 + * precise terms see the accompanying LICENSE file.
110.15 + *
110.16 + * This software is provided "AS IS" with no warranty of any kind,
110.17 + * express or implied, and with no claim as to its suitability for any
110.18 + * purpose.
110.19 + *
110.20 + */
110.21 +
110.22 +///\file
110.23 +///\brief The implementation of the LP solver interface.
110.24 +
110.25 +#include <lemon/lp_base.h>
110.26 +namespace lemon {
110.27 +
110.28 + const LpBase::Value LpBase::INF =
110.29 + std::numeric_limits<LpBase::Value>::infinity();
110.30 + const LpBase::Value LpBase::NaN =
110.31 + std::numeric_limits<LpBase::Value>::quiet_NaN();
110.32 +
110.33 +} //namespace lemon
111.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
111.2 +++ b/lemon/lp_base.h Thu Dec 10 17:05:35 2009 +0100
111.3 @@ -0,0 +1,2088 @@
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-2008
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_LP_BASE_H
111.23 +#define LEMON_LP_BASE_H
111.24 +
111.25 +#include<iostream>
111.26 +#include<vector>
111.27 +#include<map>
111.28 +#include<limits>
111.29 +#include<lemon/math.h>
111.30 +
111.31 +#include<lemon/error.h>
111.32 +#include<lemon/assert.h>
111.33 +
111.34 +#include<lemon/core.h>
111.35 +#include<lemon/bits/solver_bits.h>
111.36 +
111.37 +///\file
111.38 +///\brief The interface of the LP solver interface.
111.39 +///\ingroup lp_group
111.40 +namespace lemon {
111.41 +
111.42 + ///Common base class for LP and MIP solvers
111.43 +
111.44 + ///Usually this class is not used directly, please use one of the concrete
111.45 + ///implementations of the solver interface.
111.46 + ///\ingroup lp_group
111.47 + class LpBase {
111.48 +
111.49 + protected:
111.50 +
111.51 + _solver_bits::VarIndex rows;
111.52 + _solver_bits::VarIndex cols;
111.53 +
111.54 + public:
111.55 +
111.56 + ///Possible outcomes of an LP solving procedure
111.57 + enum SolveExitStatus {
111.58 + /// = 0. It means that the problem has been successfully solved: either
111.59 + ///an optimal solution has been found or infeasibility/unboundedness
111.60 + ///has been proved.
111.61 + SOLVED = 0,
111.62 + /// = 1. Any other case (including the case when some user specified
111.63 + ///limit has been exceeded).
111.64 + UNSOLVED = 1
111.65 + };
111.66 +
111.67 + ///Direction of the optimization
111.68 + enum Sense {
111.69 + /// Minimization
111.70 + MIN,
111.71 + /// Maximization
111.72 + MAX
111.73 + };
111.74 +
111.75 + ///Enum for \c messageLevel() parameter
111.76 + enum MessageLevel {
111.77 + /// No output (default value).
111.78 + MESSAGE_NOTHING,
111.79 + /// Error messages only.
111.80 + MESSAGE_ERROR,
111.81 + /// Warnings.
111.82 + MESSAGE_WARNING,
111.83 + /// Normal output.
111.84 + MESSAGE_NORMAL,
111.85 + /// Verbose output.
111.86 + MESSAGE_VERBOSE
111.87 + };
111.88 +
111.89 +
111.90 + ///The floating point type used by the solver
111.91 + typedef double Value;
111.92 + ///The infinity constant
111.93 + static const Value INF;
111.94 + ///The not a number constant
111.95 + static const Value NaN;
111.96 +
111.97 + friend class Col;
111.98 + friend class ColIt;
111.99 + friend class Row;
111.100 + friend class RowIt;
111.101 +
111.102 + ///Refer to a column of the LP.
111.103 +
111.104 + ///This type is used to refer to a column of the LP.
111.105 + ///
111.106 + ///Its value remains valid and correct even after the addition or erase of
111.107 + ///other columns.
111.108 + ///
111.109 + ///\note This class is similar to other Item types in LEMON, like
111.110 + ///Node and Arc types in digraph.
111.111 + class Col {
111.112 + friend class LpBase;
111.113 + protected:
111.114 + int _id;
111.115 + explicit Col(int id) : _id(id) {}
111.116 + public:
111.117 + typedef Value ExprValue;
111.118 + typedef True LpCol;
111.119 + /// Default constructor
111.120 +
111.121 + /// \warning The default constructor sets the Col to an
111.122 + /// undefined value.
111.123 + Col() {}
111.124 + /// Invalid constructor \& conversion.
111.125 +
111.126 + /// This constructor initializes the Col to be invalid.
111.127 + /// \sa Invalid for more details.
111.128 + Col(const Invalid&) : _id(-1) {}
111.129 + /// Equality operator
111.130 +
111.131 + /// Two \ref Col "Col"s are equal if and only if they point to
111.132 + /// the same LP column or both are invalid.
111.133 + bool operator==(Col c) const {return _id == c._id;}
111.134 + /// Inequality operator
111.135 +
111.136 + /// \sa operator==(Col c)
111.137 + ///
111.138 + bool operator!=(Col c) const {return _id != c._id;}
111.139 + /// Artificial ordering operator.
111.140 +
111.141 + /// To allow the use of this object in std::map or similar
111.142 + /// associative container we require this.
111.143 + ///
111.144 + /// \note This operator only have to define some strict ordering of
111.145 + /// the items; this order has nothing to do with the iteration
111.146 + /// ordering of the items.
111.147 + bool operator<(Col c) const {return _id < c._id;}
111.148 + };
111.149 +
111.150 + ///Iterator for iterate over the columns of an LP problem
111.151 +
111.152 + /// Its usage is quite simple, for example you can count the number
111.153 + /// of columns in an LP \c lp:
111.154 + ///\code
111.155 + /// int count=0;
111.156 + /// for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
111.157 + ///\endcode
111.158 + class ColIt : public Col {
111.159 + const LpBase *_solver;
111.160 + public:
111.161 + /// Default constructor
111.162 +
111.163 + /// \warning The default constructor sets the iterator
111.164 + /// to an undefined value.
111.165 + ColIt() {}
111.166 + /// Sets the iterator to the first Col
111.167 +
111.168 + /// Sets the iterator to the first Col.
111.169 + ///
111.170 + ColIt(const LpBase &solver) : _solver(&solver)
111.171 + {
111.172 + _solver->cols.firstItem(_id);
111.173 + }
111.174 + /// Invalid constructor \& conversion
111.175 +
111.176 + /// Initialize the iterator to be invalid.
111.177 + /// \sa Invalid for more details.
111.178 + ColIt(const Invalid&) : Col(INVALID) {}
111.179 + /// Next column
111.180 +
111.181 + /// Assign the iterator to the next column.
111.182 + ///
111.183 + ColIt &operator++()
111.184 + {
111.185 + _solver->cols.nextItem(_id);
111.186 + return *this;
111.187 + }
111.188 + };
111.189 +
111.190 + /// \brief Returns the ID of the column.
111.191 + static int id(const Col& col) { return col._id; }
111.192 + /// \brief Returns the column with the given ID.
111.193 + ///
111.194 + /// \pre The argument should be a valid column ID in the LP problem.
111.195 + static Col colFromId(int id) { return Col(id); }
111.196 +
111.197 + ///Refer to a row of the LP.
111.198 +
111.199 + ///This type is used to refer to a row of the LP.
111.200 + ///
111.201 + ///Its value remains valid and correct even after the addition or erase of
111.202 + ///other rows.
111.203 + ///
111.204 + ///\note This class is similar to other Item types in LEMON, like
111.205 + ///Node and Arc types in digraph.
111.206 + class Row {
111.207 + friend class LpBase;
111.208 + protected:
111.209 + int _id;
111.210 + explicit Row(int id) : _id(id) {}
111.211 + public:
111.212 + typedef Value ExprValue;
111.213 + typedef True LpRow;
111.214 + /// Default constructor
111.215 +
111.216 + /// \warning The default constructor sets the Row to an
111.217 + /// undefined value.
111.218 + Row() {}
111.219 + /// Invalid constructor \& conversion.
111.220 +
111.221 + /// This constructor initializes the Row to be invalid.
111.222 + /// \sa Invalid for more details.
111.223 + Row(const Invalid&) : _id(-1) {}
111.224 + /// Equality operator
111.225 +
111.226 + /// Two \ref Row "Row"s are equal if and only if they point to
111.227 + /// the same LP row or both are invalid.
111.228 + bool operator==(Row r) const {return _id == r._id;}
111.229 + /// Inequality operator
111.230 +
111.231 + /// \sa operator==(Row r)
111.232 + ///
111.233 + bool operator!=(Row r) const {return _id != r._id;}
111.234 + /// Artificial ordering operator.
111.235 +
111.236 + /// To allow the use of this object in std::map or similar
111.237 + /// associative container we require this.
111.238 + ///
111.239 + /// \note This operator only have to define some strict ordering of
111.240 + /// the items; this order has nothing to do with the iteration
111.241 + /// ordering of the items.
111.242 + bool operator<(Row r) const {return _id < r._id;}
111.243 + };
111.244 +
111.245 + ///Iterator for iterate over the rows of an LP problem
111.246 +
111.247 + /// Its usage is quite simple, for example you can count the number
111.248 + /// of rows in an LP \c lp:
111.249 + ///\code
111.250 + /// int count=0;
111.251 + /// for (LpBase::RowIt c(lp); c!=INVALID; ++c) ++count;
111.252 + ///\endcode
111.253 + class RowIt : public Row {
111.254 + const LpBase *_solver;
111.255 + public:
111.256 + /// Default constructor
111.257 +
111.258 + /// \warning The default constructor sets the iterator
111.259 + /// to an undefined value.
111.260 + RowIt() {}
111.261 + /// Sets the iterator to the first Row
111.262 +
111.263 + /// Sets the iterator to the first Row.
111.264 + ///
111.265 + RowIt(const LpBase &solver) : _solver(&solver)
111.266 + {
111.267 + _solver->rows.firstItem(_id);
111.268 + }
111.269 + /// Invalid constructor \& conversion
111.270 +
111.271 + /// Initialize the iterator to be invalid.
111.272 + /// \sa Invalid for more details.
111.273 + RowIt(const Invalid&) : Row(INVALID) {}
111.274 + /// Next row
111.275 +
111.276 + /// Assign the iterator to the next row.
111.277 + ///
111.278 + RowIt &operator++()
111.279 + {
111.280 + _solver->rows.nextItem(_id);
111.281 + return *this;
111.282 + }
111.283 + };
111.284 +
111.285 + /// \brief Returns the ID of the row.
111.286 + static int id(const Row& row) { return row._id; }
111.287 + /// \brief Returns the row with the given ID.
111.288 + ///
111.289 + /// \pre The argument should be a valid row ID in the LP problem.
111.290 + static Row rowFromId(int id) { return Row(id); }
111.291 +
111.292 + public:
111.293 +
111.294 + ///Linear expression of variables and a constant component
111.295 +
111.296 + ///This data structure stores a linear expression of the variables
111.297 + ///(\ref Col "Col"s) and also has a constant component.
111.298 + ///
111.299 + ///There are several ways to access and modify the contents of this
111.300 + ///container.
111.301 + ///\code
111.302 + ///e[v]=5;
111.303 + ///e[v]+=12;
111.304 + ///e.erase(v);
111.305 + ///\endcode
111.306 + ///or you can also iterate through its elements.
111.307 + ///\code
111.308 + ///double s=0;
111.309 + ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
111.310 + /// s+=*i * primal(i);
111.311 + ///\endcode
111.312 + ///(This code computes the primal value of the expression).
111.313 + ///- Numbers (<tt>double</tt>'s)
111.314 + ///and variables (\ref Col "Col"s) directly convert to an
111.315 + ///\ref Expr and the usual linear operations are defined, so
111.316 + ///\code
111.317 + ///v+w
111.318 + ///2*v-3.12*(v-w/2)+2
111.319 + ///v*2.1+(3*v+(v*12+w+6)*3)/2
111.320 + ///\endcode
111.321 + ///are valid expressions.
111.322 + ///The usual assignment operations are also defined.
111.323 + ///\code
111.324 + ///e=v+w;
111.325 + ///e+=2*v-3.12*(v-w/2)+2;
111.326 + ///e*=3.4;
111.327 + ///e/=5;
111.328 + ///\endcode
111.329 + ///- The constant member can be set and read by dereference
111.330 + /// operator (unary *)
111.331 + ///
111.332 + ///\code
111.333 + ///*e=12;
111.334 + ///double c=*e;
111.335 + ///\endcode
111.336 + ///
111.337 + ///\sa Constr
111.338 + class Expr {
111.339 + friend class LpBase;
111.340 + public:
111.341 + /// The key type of the expression
111.342 + typedef LpBase::Col Key;
111.343 + /// The value type of the expression
111.344 + typedef LpBase::Value Value;
111.345 +
111.346 + protected:
111.347 + Value const_comp;
111.348 + std::map<int, Value> comps;
111.349 +
111.350 + public:
111.351 + typedef True SolverExpr;
111.352 + /// Default constructor
111.353 +
111.354 + /// Construct an empty expression, the coefficients and
111.355 + /// the constant component are initialized to zero.
111.356 + Expr() : const_comp(0) {}
111.357 + /// Construct an expression from a column
111.358 +
111.359 + /// Construct an expression, which has a term with \c c variable
111.360 + /// and 1.0 coefficient.
111.361 + Expr(const Col &c) : const_comp(0) {
111.362 + typedef std::map<int, Value>::value_type pair_type;
111.363 + comps.insert(pair_type(id(c), 1));
111.364 + }
111.365 + /// Construct an expression from a constant
111.366 +
111.367 + /// Construct an expression, which's constant component is \c v.
111.368 + ///
111.369 + Expr(const Value &v) : const_comp(v) {}
111.370 + /// Returns the coefficient of the column
111.371 + Value operator[](const Col& c) const {
111.372 + std::map<int, Value>::const_iterator it=comps.find(id(c));
111.373 + if (it != comps.end()) {
111.374 + return it->second;
111.375 + } else {
111.376 + return 0;
111.377 + }
111.378 + }
111.379 + /// Returns the coefficient of the column
111.380 + Value& operator[](const Col& c) {
111.381 + return comps[id(c)];
111.382 + }
111.383 + /// Sets the coefficient of the column
111.384 + void set(const Col &c, const Value &v) {
111.385 + if (v != 0.0) {
111.386 + typedef std::map<int, Value>::value_type pair_type;
111.387 + comps.insert(pair_type(id(c), v));
111.388 + } else {
111.389 + comps.erase(id(c));
111.390 + }
111.391 + }
111.392 + /// Returns the constant component of the expression
111.393 + Value& operator*() { return const_comp; }
111.394 + /// Returns the constant component of the expression
111.395 + const Value& operator*() const { return const_comp; }
111.396 + /// \brief Removes the coefficients which's absolute value does
111.397 + /// not exceed \c epsilon. It also sets to zero the constant
111.398 + /// component, if it does not exceed epsilon in absolute value.
111.399 + void simplify(Value epsilon = 0.0) {
111.400 + std::map<int, Value>::iterator it=comps.begin();
111.401 + while (it != comps.end()) {
111.402 + std::map<int, Value>::iterator jt=it;
111.403 + ++jt;
111.404 + if (std::fabs((*it).second) <= epsilon) comps.erase(it);
111.405 + it=jt;
111.406 + }
111.407 + if (std::fabs(const_comp) <= epsilon) const_comp = 0;
111.408 + }
111.409 +
111.410 + void simplify(Value epsilon = 0.0) const {
111.411 + const_cast<Expr*>(this)->simplify(epsilon);
111.412 + }
111.413 +
111.414 + ///Sets all coefficients and the constant component to 0.
111.415 + void clear() {
111.416 + comps.clear();
111.417 + const_comp=0;
111.418 + }
111.419 +
111.420 + ///Compound assignment
111.421 + Expr &operator+=(const Expr &e) {
111.422 + for (std::map<int, Value>::const_iterator it=e.comps.begin();
111.423 + it!=e.comps.end(); ++it)
111.424 + comps[it->first]+=it->second;
111.425 + const_comp+=e.const_comp;
111.426 + return *this;
111.427 + }
111.428 + ///Compound assignment
111.429 + Expr &operator-=(const Expr &e) {
111.430 + for (std::map<int, Value>::const_iterator it=e.comps.begin();
111.431 + it!=e.comps.end(); ++it)
111.432 + comps[it->first]-=it->second;
111.433 + const_comp-=e.const_comp;
111.434 + return *this;
111.435 + }
111.436 + ///Multiply with a constant
111.437 + Expr &operator*=(const Value &v) {
111.438 + for (std::map<int, Value>::iterator it=comps.begin();
111.439 + it!=comps.end(); ++it)
111.440 + it->second*=v;
111.441 + const_comp*=v;
111.442 + return *this;
111.443 + }
111.444 + ///Division with a constant
111.445 + Expr &operator/=(const Value &c) {
111.446 + for (std::map<int, Value>::iterator it=comps.begin();
111.447 + it!=comps.end(); ++it)
111.448 + it->second/=c;
111.449 + const_comp/=c;
111.450 + return *this;
111.451 + }
111.452 +
111.453 + ///Iterator over the expression
111.454 +
111.455 + ///The iterator iterates over the terms of the expression.
111.456 + ///
111.457 + ///\code
111.458 + ///double s=0;
111.459 + ///for(LpBase::Expr::CoeffIt i(e);i!=INVALID;++i)
111.460 + /// s+= *i * primal(i);
111.461 + ///\endcode
111.462 + class CoeffIt {
111.463 + private:
111.464 +
111.465 + std::map<int, Value>::iterator _it, _end;
111.466 +
111.467 + public:
111.468 +
111.469 + /// Sets the iterator to the first term
111.470 +
111.471 + /// Sets the iterator to the first term of the expression.
111.472 + ///
111.473 + CoeffIt(Expr& e)
111.474 + : _it(e.comps.begin()), _end(e.comps.end()){}
111.475 +
111.476 + /// Convert the iterator to the column of the term
111.477 + operator Col() const {
111.478 + return colFromId(_it->first);
111.479 + }
111.480 +
111.481 + /// Returns the coefficient of the term
111.482 + Value& operator*() { return _it->second; }
111.483 +
111.484 + /// Returns the coefficient of the term
111.485 + const Value& operator*() const { return _it->second; }
111.486 + /// Next term
111.487 +
111.488 + /// Assign the iterator to the next term.
111.489 + ///
111.490 + CoeffIt& operator++() { ++_it; return *this; }
111.491 +
111.492 + /// Equality operator
111.493 + bool operator==(Invalid) const { return _it == _end; }
111.494 + /// Inequality operator
111.495 + bool operator!=(Invalid) const { return _it != _end; }
111.496 + };
111.497 +
111.498 + /// Const iterator over the expression
111.499 +
111.500 + ///The iterator iterates over the terms of the expression.
111.501 + ///
111.502 + ///\code
111.503 + ///double s=0;
111.504 + ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
111.505 + /// s+=*i * primal(i);
111.506 + ///\endcode
111.507 + class ConstCoeffIt {
111.508 + private:
111.509 +
111.510 + std::map<int, Value>::const_iterator _it, _end;
111.511 +
111.512 + public:
111.513 +
111.514 + /// Sets the iterator to the first term
111.515 +
111.516 + /// Sets the iterator to the first term of the expression.
111.517 + ///
111.518 + ConstCoeffIt(const Expr& e)
111.519 + : _it(e.comps.begin()), _end(e.comps.end()){}
111.520 +
111.521 + /// Convert the iterator to the column of the term
111.522 + operator Col() const {
111.523 + return colFromId(_it->first);
111.524 + }
111.525 +
111.526 + /// Returns the coefficient of the term
111.527 + const Value& operator*() const { return _it->second; }
111.528 +
111.529 + /// Next term
111.530 +
111.531 + /// Assign the iterator to the next term.
111.532 + ///
111.533 + ConstCoeffIt& operator++() { ++_it; return *this; }
111.534 +
111.535 + /// Equality operator
111.536 + bool operator==(Invalid) const { return _it == _end; }
111.537 + /// Inequality operator
111.538 + bool operator!=(Invalid) const { return _it != _end; }
111.539 + };
111.540 +
111.541 + };
111.542 +
111.543 + ///Linear constraint
111.544 +
111.545 + ///This data stucture represents a linear constraint in the LP.
111.546 + ///Basically it is a linear expression with a lower or an upper bound
111.547 + ///(or both). These parts of the constraint can be obtained by the member
111.548 + ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
111.549 + ///respectively.
111.550 + ///There are two ways to construct a constraint.
111.551 + ///- You can set the linear expression and the bounds directly
111.552 + /// by the functions above.
111.553 + ///- The operators <tt>\<=</tt>, <tt>==</tt> and <tt>\>=</tt>
111.554 + /// are defined between expressions, or even between constraints whenever
111.555 + /// it makes sense. Therefore if \c e and \c f are linear expressions and
111.556 + /// \c s and \c t are numbers, then the followings are valid expressions
111.557 + /// and thus they can be used directly e.g. in \ref addRow() whenever
111.558 + /// it makes sense.
111.559 + ///\code
111.560 + /// e<=s
111.561 + /// e<=f
111.562 + /// e==f
111.563 + /// s<=e<=t
111.564 + /// e>=t
111.565 + ///\endcode
111.566 + ///\warning The validity of a constraint is checked only at run
111.567 + ///time, so e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will
111.568 + ///compile, but will fail an assertion.
111.569 + class Constr
111.570 + {
111.571 + public:
111.572 + typedef LpBase::Expr Expr;
111.573 + typedef Expr::Key Key;
111.574 + typedef Expr::Value Value;
111.575 +
111.576 + protected:
111.577 + Expr _expr;
111.578 + Value _lb,_ub;
111.579 + public:
111.580 + ///\e
111.581 + Constr() : _expr(), _lb(NaN), _ub(NaN) {}
111.582 + ///\e
111.583 + Constr(Value lb, const Expr &e, Value ub) :
111.584 + _expr(e), _lb(lb), _ub(ub) {}
111.585 + Constr(const Expr &e) :
111.586 + _expr(e), _lb(NaN), _ub(NaN) {}
111.587 + ///\e
111.588 + void clear()
111.589 + {
111.590 + _expr.clear();
111.591 + _lb=_ub=NaN;
111.592 + }
111.593 +
111.594 + ///Reference to the linear expression
111.595 + Expr &expr() { return _expr; }
111.596 + ///Cont reference to the linear expression
111.597 + const Expr &expr() const { return _expr; }
111.598 + ///Reference to the lower bound.
111.599 +
111.600 + ///\return
111.601 + ///- \ref INF "INF": the constraint is lower unbounded.
111.602 + ///- \ref NaN "NaN": lower bound has not been set.
111.603 + ///- finite number: the lower bound
111.604 + Value &lowerBound() { return _lb; }
111.605 + ///The const version of \ref lowerBound()
111.606 + const Value &lowerBound() const { return _lb; }
111.607 + ///Reference to the upper bound.
111.608 +
111.609 + ///\return
111.610 + ///- \ref INF "INF": the constraint is upper unbounded.
111.611 + ///- \ref NaN "NaN": upper bound has not been set.
111.612 + ///- finite number: the upper bound
111.613 + Value &upperBound() { return _ub; }
111.614 + ///The const version of \ref upperBound()
111.615 + const Value &upperBound() const { return _ub; }
111.616 + ///Is the constraint lower bounded?
111.617 + bool lowerBounded() const {
111.618 + return _lb != -INF && !isNaN(_lb);
111.619 + }
111.620 + ///Is the constraint upper bounded?
111.621 + bool upperBounded() const {
111.622 + return _ub != INF && !isNaN(_ub);
111.623 + }
111.624 +
111.625 + };
111.626 +
111.627 + ///Linear expression of rows
111.628 +
111.629 + ///This data structure represents a column of the matrix,
111.630 + ///thas is it strores a linear expression of the dual variables
111.631 + ///(\ref Row "Row"s).
111.632 + ///
111.633 + ///There are several ways to access and modify the contents of this
111.634 + ///container.
111.635 + ///\code
111.636 + ///e[v]=5;
111.637 + ///e[v]+=12;
111.638 + ///e.erase(v);
111.639 + ///\endcode
111.640 + ///or you can also iterate through its elements.
111.641 + ///\code
111.642 + ///double s=0;
111.643 + ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
111.644 + /// s+=*i;
111.645 + ///\endcode
111.646 + ///(This code computes the sum of all coefficients).
111.647 + ///- Numbers (<tt>double</tt>'s)
111.648 + ///and variables (\ref Row "Row"s) directly convert to an
111.649 + ///\ref DualExpr and the usual linear operations are defined, so
111.650 + ///\code
111.651 + ///v+w
111.652 + ///2*v-3.12*(v-w/2)
111.653 + ///v*2.1+(3*v+(v*12+w)*3)/2
111.654 + ///\endcode
111.655 + ///are valid \ref DualExpr dual expressions.
111.656 + ///The usual assignment operations are also defined.
111.657 + ///\code
111.658 + ///e=v+w;
111.659 + ///e+=2*v-3.12*(v-w/2);
111.660 + ///e*=3.4;
111.661 + ///e/=5;
111.662 + ///\endcode
111.663 + ///
111.664 + ///\sa Expr
111.665 + class DualExpr {
111.666 + friend class LpBase;
111.667 + public:
111.668 + /// The key type of the expression
111.669 + typedef LpBase::Row Key;
111.670 + /// The value type of the expression
111.671 + typedef LpBase::Value Value;
111.672 +
111.673 + protected:
111.674 + std::map<int, Value> comps;
111.675 +
111.676 + public:
111.677 + typedef True SolverExpr;
111.678 + /// Default constructor
111.679 +
111.680 + /// Construct an empty expression, the coefficients are
111.681 + /// initialized to zero.
111.682 + DualExpr() {}
111.683 + /// Construct an expression from a row
111.684 +
111.685 + /// Construct an expression, which has a term with \c r dual
111.686 + /// variable and 1.0 coefficient.
111.687 + DualExpr(const Row &r) {
111.688 + typedef std::map<int, Value>::value_type pair_type;
111.689 + comps.insert(pair_type(id(r), 1));
111.690 + }
111.691 + /// Returns the coefficient of the row
111.692 + Value operator[](const Row& r) const {
111.693 + std::map<int, Value>::const_iterator it = comps.find(id(r));
111.694 + if (it != comps.end()) {
111.695 + return it->second;
111.696 + } else {
111.697 + return 0;
111.698 + }
111.699 + }
111.700 + /// Returns the coefficient of the row
111.701 + Value& operator[](const Row& r) {
111.702 + return comps[id(r)];
111.703 + }
111.704 + /// Sets the coefficient of the row
111.705 + void set(const Row &r, const Value &v) {
111.706 + if (v != 0.0) {
111.707 + typedef std::map<int, Value>::value_type pair_type;
111.708 + comps.insert(pair_type(id(r), v));
111.709 + } else {
111.710 + comps.erase(id(r));
111.711 + }
111.712 + }
111.713 + /// \brief Removes the coefficients which's absolute value does
111.714 + /// not exceed \c epsilon.
111.715 + void simplify(Value epsilon = 0.0) {
111.716 + std::map<int, Value>::iterator it=comps.begin();
111.717 + while (it != comps.end()) {
111.718 + std::map<int, Value>::iterator jt=it;
111.719 + ++jt;
111.720 + if (std::fabs((*it).second) <= epsilon) comps.erase(it);
111.721 + it=jt;
111.722 + }
111.723 + }
111.724 +
111.725 + void simplify(Value epsilon = 0.0) const {
111.726 + const_cast<DualExpr*>(this)->simplify(epsilon);
111.727 + }
111.728 +
111.729 + ///Sets all coefficients to 0.
111.730 + void clear() {
111.731 + comps.clear();
111.732 + }
111.733 + ///Compound assignment
111.734 + DualExpr &operator+=(const DualExpr &e) {
111.735 + for (std::map<int, Value>::const_iterator it=e.comps.begin();
111.736 + it!=e.comps.end(); ++it)
111.737 + comps[it->first]+=it->second;
111.738 + return *this;
111.739 + }
111.740 + ///Compound assignment
111.741 + DualExpr &operator-=(const DualExpr &e) {
111.742 + for (std::map<int, Value>::const_iterator it=e.comps.begin();
111.743 + it!=e.comps.end(); ++it)
111.744 + comps[it->first]-=it->second;
111.745 + return *this;
111.746 + }
111.747 + ///Multiply with a constant
111.748 + DualExpr &operator*=(const Value &v) {
111.749 + for (std::map<int, Value>::iterator it=comps.begin();
111.750 + it!=comps.end(); ++it)
111.751 + it->second*=v;
111.752 + return *this;
111.753 + }
111.754 + ///Division with a constant
111.755 + DualExpr &operator/=(const Value &v) {
111.756 + for (std::map<int, Value>::iterator it=comps.begin();
111.757 + it!=comps.end(); ++it)
111.758 + it->second/=v;
111.759 + return *this;
111.760 + }
111.761 +
111.762 + ///Iterator over the expression
111.763 +
111.764 + ///The iterator iterates over the terms of the expression.
111.765 + ///
111.766 + ///\code
111.767 + ///double s=0;
111.768 + ///for(LpBase::DualExpr::CoeffIt i(e);i!=INVALID;++i)
111.769 + /// s+= *i * dual(i);
111.770 + ///\endcode
111.771 + class CoeffIt {
111.772 + private:
111.773 +
111.774 + std::map<int, Value>::iterator _it, _end;
111.775 +
111.776 + public:
111.777 +
111.778 + /// Sets the iterator to the first term
111.779 +
111.780 + /// Sets the iterator to the first term of the expression.
111.781 + ///
111.782 + CoeffIt(DualExpr& e)
111.783 + : _it(e.comps.begin()), _end(e.comps.end()){}
111.784 +
111.785 + /// Convert the iterator to the row of the term
111.786 + operator Row() const {
111.787 + return rowFromId(_it->first);
111.788 + }
111.789 +
111.790 + /// Returns the coefficient of the term
111.791 + Value& operator*() { return _it->second; }
111.792 +
111.793 + /// Returns the coefficient of the term
111.794 + const Value& operator*() const { return _it->second; }
111.795 +
111.796 + /// Next term
111.797 +
111.798 + /// Assign the iterator to the next term.
111.799 + ///
111.800 + CoeffIt& operator++() { ++_it; return *this; }
111.801 +
111.802 + /// Equality operator
111.803 + bool operator==(Invalid) const { return _it == _end; }
111.804 + /// Inequality operator
111.805 + bool operator!=(Invalid) const { return _it != _end; }
111.806 + };
111.807 +
111.808 + ///Iterator over the expression
111.809 +
111.810 + ///The iterator iterates over the terms of the expression.
111.811 + ///
111.812 + ///\code
111.813 + ///double s=0;
111.814 + ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
111.815 + /// s+= *i * dual(i);
111.816 + ///\endcode
111.817 + class ConstCoeffIt {
111.818 + private:
111.819 +
111.820 + std::map<int, Value>::const_iterator _it, _end;
111.821 +
111.822 + public:
111.823 +
111.824 + /// Sets the iterator to the first term
111.825 +
111.826 + /// Sets the iterator to the first term of the expression.
111.827 + ///
111.828 + ConstCoeffIt(const DualExpr& e)
111.829 + : _it(e.comps.begin()), _end(e.comps.end()){}
111.830 +
111.831 + /// Convert the iterator to the row of the term
111.832 + operator Row() const {
111.833 + return rowFromId(_it->first);
111.834 + }
111.835 +
111.836 + /// Returns the coefficient of the term
111.837 + const Value& operator*() const { return _it->second; }
111.838 +
111.839 + /// Next term
111.840 +
111.841 + /// Assign the iterator to the next term.
111.842 + ///
111.843 + ConstCoeffIt& operator++() { ++_it; return *this; }
111.844 +
111.845 + /// Equality operator
111.846 + bool operator==(Invalid) const { return _it == _end; }
111.847 + /// Inequality operator
111.848 + bool operator!=(Invalid) const { return _it != _end; }
111.849 + };
111.850 + };
111.851 +
111.852 +
111.853 + protected:
111.854 +
111.855 + class InsertIterator {
111.856 + private:
111.857 +
111.858 + std::map<int, Value>& _host;
111.859 + const _solver_bits::VarIndex& _index;
111.860 +
111.861 + public:
111.862 +
111.863 + typedef std::output_iterator_tag iterator_category;
111.864 + typedef void difference_type;
111.865 + typedef void value_type;
111.866 + typedef void reference;
111.867 + typedef void pointer;
111.868 +
111.869 + InsertIterator(std::map<int, Value>& host,
111.870 + const _solver_bits::VarIndex& index)
111.871 + : _host(host), _index(index) {}
111.872 +
111.873 + InsertIterator& operator=(const std::pair<int, Value>& value) {
111.874 + typedef std::map<int, Value>::value_type pair_type;
111.875 + _host.insert(pair_type(_index[value.first], value.second));
111.876 + return *this;
111.877 + }
111.878 +
111.879 + InsertIterator& operator*() { return *this; }
111.880 + InsertIterator& operator++() { return *this; }
111.881 + InsertIterator operator++(int) { return *this; }
111.882 +
111.883 + };
111.884 +
111.885 + class ExprIterator {
111.886 + private:
111.887 + std::map<int, Value>::const_iterator _host_it;
111.888 + const _solver_bits::VarIndex& _index;
111.889 + public:
111.890 +
111.891 + typedef std::bidirectional_iterator_tag iterator_category;
111.892 + typedef std::ptrdiff_t difference_type;
111.893 + typedef const std::pair<int, Value> value_type;
111.894 + typedef value_type reference;
111.895 +
111.896 + class pointer {
111.897 + public:
111.898 + pointer(value_type& _value) : value(_value) {}
111.899 + value_type* operator->() { return &value; }
111.900 + private:
111.901 + value_type value;
111.902 + };
111.903 +
111.904 + ExprIterator(const std::map<int, Value>::const_iterator& host_it,
111.905 + const _solver_bits::VarIndex& index)
111.906 + : _host_it(host_it), _index(index) {}
111.907 +
111.908 + reference operator*() {
111.909 + return std::make_pair(_index(_host_it->first), _host_it->second);
111.910 + }
111.911 +
111.912 + pointer operator->() {
111.913 + return pointer(operator*());
111.914 + }
111.915 +
111.916 + ExprIterator& operator++() { ++_host_it; return *this; }
111.917 + ExprIterator operator++(int) {
111.918 + ExprIterator tmp(*this); ++_host_it; return tmp;
111.919 + }
111.920 +
111.921 + ExprIterator& operator--() { --_host_it; return *this; }
111.922 + ExprIterator operator--(int) {
111.923 + ExprIterator tmp(*this); --_host_it; return tmp;
111.924 + }
111.925 +
111.926 + bool operator==(const ExprIterator& it) const {
111.927 + return _host_it == it._host_it;
111.928 + }
111.929 +
111.930 + bool operator!=(const ExprIterator& it) const {
111.931 + return _host_it != it._host_it;
111.932 + }
111.933 +
111.934 + };
111.935 +
111.936 + protected:
111.937 +
111.938 + //Abstract virtual functions
111.939 +
111.940 + virtual int _addColId(int col) { return cols.addIndex(col); }
111.941 + virtual int _addRowId(int row) { return rows.addIndex(row); }
111.942 +
111.943 + virtual void _eraseColId(int col) { cols.eraseIndex(col); }
111.944 + virtual void _eraseRowId(int row) { rows.eraseIndex(row); }
111.945 +
111.946 + virtual int _addCol() = 0;
111.947 + virtual int _addRow() = 0;
111.948 +
111.949 + virtual void _eraseCol(int col) = 0;
111.950 + virtual void _eraseRow(int row) = 0;
111.951 +
111.952 + virtual void _getColName(int col, std::string& name) const = 0;
111.953 + virtual void _setColName(int col, const std::string& name) = 0;
111.954 + virtual int _colByName(const std::string& name) const = 0;
111.955 +
111.956 + virtual void _getRowName(int row, std::string& name) const = 0;
111.957 + virtual void _setRowName(int row, const std::string& name) = 0;
111.958 + virtual int _rowByName(const std::string& name) const = 0;
111.959 +
111.960 + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
111.961 + virtual void _getRowCoeffs(int i, InsertIterator b) const = 0;
111.962 +
111.963 + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
111.964 + virtual void _getColCoeffs(int i, InsertIterator b) const = 0;
111.965 +
111.966 + virtual void _setCoeff(int row, int col, Value value) = 0;
111.967 + virtual Value _getCoeff(int row, int col) const = 0;
111.968 +
111.969 + virtual void _setColLowerBound(int i, Value value) = 0;
111.970 + virtual Value _getColLowerBound(int i) const = 0;
111.971 +
111.972 + virtual void _setColUpperBound(int i, Value value) = 0;
111.973 + virtual Value _getColUpperBound(int i) const = 0;
111.974 +
111.975 + virtual void _setRowLowerBound(int i, Value value) = 0;
111.976 + virtual Value _getRowLowerBound(int i) const = 0;
111.977 +
111.978 + virtual void _setRowUpperBound(int i, Value value) = 0;
111.979 + virtual Value _getRowUpperBound(int i) const = 0;
111.980 +
111.981 + virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0;
111.982 + virtual void _getObjCoeffs(InsertIterator b) const = 0;
111.983 +
111.984 + virtual void _setObjCoeff(int i, Value obj_coef) = 0;
111.985 + virtual Value _getObjCoeff(int i) const = 0;
111.986 +
111.987 + virtual void _setSense(Sense) = 0;
111.988 + virtual Sense _getSense() const = 0;
111.989 +
111.990 + virtual void _clear() = 0;
111.991 +
111.992 + virtual const char* _solverName() const = 0;
111.993 +
111.994 + virtual void _messageLevel(MessageLevel level) = 0;
111.995 +
111.996 + //Own protected stuff
111.997 +
111.998 + //Constant component of the objective function
111.999 + Value obj_const_comp;
111.1000 +
111.1001 + LpBase() : rows(), cols(), obj_const_comp(0) {}
111.1002 +
111.1003 + public:
111.1004 +
111.1005 + /// Virtual destructor
111.1006 + virtual ~LpBase() {}
111.1007 +
111.1008 + ///Gives back the name of the solver.
111.1009 + const char* solverName() const {return _solverName();}
111.1010 +
111.1011 + ///\name Build Up and Modify the LP
111.1012 +
111.1013 + ///@{
111.1014 +
111.1015 + ///Add a new empty column (i.e a new variable) to the LP
111.1016 + Col addCol() { Col c; c._id = _addColId(_addCol()); return c;}
111.1017 +
111.1018 + ///\brief Adds several new columns (i.e variables) at once
111.1019 + ///
111.1020 + ///This magic function takes a container as its argument and fills
111.1021 + ///its elements with new columns (i.e. variables)
111.1022 + ///\param t can be
111.1023 + ///- a standard STL compatible iterable container with
111.1024 + ///\ref Col as its \c values_type like
111.1025 + ///\code
111.1026 + ///std::vector<LpBase::Col>
111.1027 + ///std::list<LpBase::Col>
111.1028 + ///\endcode
111.1029 + ///- a standard STL compatible iterable container with
111.1030 + ///\ref Col as its \c mapped_type like
111.1031 + ///\code
111.1032 + ///std::map<AnyType,LpBase::Col>
111.1033 + ///\endcode
111.1034 + ///- an iterable lemon \ref concepts::WriteMap "write map" like
111.1035 + ///\code
111.1036 + ///ListGraph::NodeMap<LpBase::Col>
111.1037 + ///ListGraph::ArcMap<LpBase::Col>
111.1038 + ///\endcode
111.1039 + ///\return The number of the created column.
111.1040 +#ifdef DOXYGEN
111.1041 + template<class T>
111.1042 + int addColSet(T &t) { return 0;}
111.1043 +#else
111.1044 + template<class T>
111.1045 + typename enable_if<typename T::value_type::LpCol,int>::type
111.1046 + addColSet(T &t,dummy<0> = 0) {
111.1047 + int s=0;
111.1048 + for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
111.1049 + return s;
111.1050 + }
111.1051 + template<class T>
111.1052 + typename enable_if<typename T::value_type::second_type::LpCol,
111.1053 + int>::type
111.1054 + addColSet(T &t,dummy<1> = 1) {
111.1055 + int s=0;
111.1056 + for(typename T::iterator i=t.begin();i!=t.end();++i) {
111.1057 + i->second=addCol();
111.1058 + s++;
111.1059 + }
111.1060 + return s;
111.1061 + }
111.1062 + template<class T>
111.1063 + typename enable_if<typename T::MapIt::Value::LpCol,
111.1064 + int>::type
111.1065 + addColSet(T &t,dummy<2> = 2) {
111.1066 + int s=0;
111.1067 + for(typename T::MapIt i(t); i!=INVALID; ++i)
111.1068 + {
111.1069 + i.set(addCol());
111.1070 + s++;
111.1071 + }
111.1072 + return s;
111.1073 + }
111.1074 +#endif
111.1075 +
111.1076 + ///Set a column (i.e a dual constraint) of the LP
111.1077 +
111.1078 + ///\param c is the column to be modified
111.1079 + ///\param e is a dual linear expression (see \ref DualExpr)
111.1080 + ///a better one.
111.1081 + void col(Col c, const DualExpr &e) {
111.1082 + e.simplify();
111.1083 + _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), rows),
111.1084 + ExprIterator(e.comps.end(), rows));
111.1085 + }
111.1086 +
111.1087 + ///Get a column (i.e a dual constraint) of the LP
111.1088 +
111.1089 + ///\param c is the column to get
111.1090 + ///\return the dual expression associated to the column
111.1091 + DualExpr col(Col c) const {
111.1092 + DualExpr e;
111.1093 + _getColCoeffs(cols(id(c)), InsertIterator(e.comps, rows));
111.1094 + return e;
111.1095 + }
111.1096 +
111.1097 + ///Add a new column to the LP
111.1098 +
111.1099 + ///\param e is a dual linear expression (see \ref DualExpr)
111.1100 + ///\param o is the corresponding component of the objective
111.1101 + ///function. It is 0 by default.
111.1102 + ///\return The created column.
111.1103 + Col addCol(const DualExpr &e, Value o = 0) {
111.1104 + Col c=addCol();
111.1105 + col(c,e);
111.1106 + objCoeff(c,o);
111.1107 + return c;
111.1108 + }
111.1109 +
111.1110 + ///Add a new empty row (i.e a new constraint) to the LP
111.1111 +
111.1112 + ///This function adds a new empty row (i.e a new constraint) to the LP.
111.1113 + ///\return The created row
111.1114 + Row addRow() { Row r; r._id = _addRowId(_addRow()); return r;}
111.1115 +
111.1116 + ///\brief Add several new rows (i.e constraints) at once
111.1117 + ///
111.1118 + ///This magic function takes a container as its argument and fills
111.1119 + ///its elements with new row (i.e. variables)
111.1120 + ///\param t can be
111.1121 + ///- a standard STL compatible iterable container with
111.1122 + ///\ref Row as its \c values_type like
111.1123 + ///\code
111.1124 + ///std::vector<LpBase::Row>
111.1125 + ///std::list<LpBase::Row>
111.1126 + ///\endcode
111.1127 + ///- a standard STL compatible iterable container with
111.1128 + ///\ref Row as its \c mapped_type like
111.1129 + ///\code
111.1130 + ///std::map<AnyType,LpBase::Row>
111.1131 + ///\endcode
111.1132 + ///- an iterable lemon \ref concepts::WriteMap "write map" like
111.1133 + ///\code
111.1134 + ///ListGraph::NodeMap<LpBase::Row>
111.1135 + ///ListGraph::ArcMap<LpBase::Row>
111.1136 + ///\endcode
111.1137 + ///\return The number of rows created.
111.1138 +#ifdef DOXYGEN
111.1139 + template<class T>
111.1140 + int addRowSet(T &t) { return 0;}
111.1141 +#else
111.1142 + template<class T>
111.1143 + typename enable_if<typename T::value_type::LpRow,int>::type
111.1144 + addRowSet(T &t, dummy<0> = 0) {
111.1145 + int s=0;
111.1146 + for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
111.1147 + return s;
111.1148 + }
111.1149 + template<class T>
111.1150 + typename enable_if<typename T::value_type::second_type::LpRow, int>::type
111.1151 + addRowSet(T &t, dummy<1> = 1) {
111.1152 + int s=0;
111.1153 + for(typename T::iterator i=t.begin();i!=t.end();++i) {
111.1154 + i->second=addRow();
111.1155 + s++;
111.1156 + }
111.1157 + return s;
111.1158 + }
111.1159 + template<class T>
111.1160 + typename enable_if<typename T::MapIt::Value::LpRow, int>::type
111.1161 + addRowSet(T &t, dummy<2> = 2) {
111.1162 + int s=0;
111.1163 + for(typename T::MapIt i(t); i!=INVALID; ++i)
111.1164 + {
111.1165 + i.set(addRow());
111.1166 + s++;
111.1167 + }
111.1168 + return s;
111.1169 + }
111.1170 +#endif
111.1171 +
111.1172 + ///Set a row (i.e a constraint) of the LP
111.1173 +
111.1174 + ///\param r is the row to be modified
111.1175 + ///\param l is lower bound (-\ref INF means no bound)
111.1176 + ///\param e is a linear expression (see \ref Expr)
111.1177 + ///\param u is the upper bound (\ref INF means no bound)
111.1178 + void row(Row r, Value l, const Expr &e, Value u) {
111.1179 + e.simplify();
111.1180 + _setRowCoeffs(rows(id(r)), ExprIterator(e.comps.begin(), cols),
111.1181 + ExprIterator(e.comps.end(), cols));
111.1182 + _setRowLowerBound(rows(id(r)),l - *e);
111.1183 + _setRowUpperBound(rows(id(r)),u - *e);
111.1184 + }
111.1185 +
111.1186 + ///Set a row (i.e a constraint) of the LP
111.1187 +
111.1188 + ///\param r is the row to be modified
111.1189 + ///\param c is a linear expression (see \ref Constr)
111.1190 + void row(Row r, const Constr &c) {
111.1191 + row(r, c.lowerBounded()?c.lowerBound():-INF,
111.1192 + c.expr(), c.upperBounded()?c.upperBound():INF);
111.1193 + }
111.1194 +
111.1195 +
111.1196 + ///Get a row (i.e a constraint) of the LP
111.1197 +
111.1198 + ///\param r is the row to get
111.1199 + ///\return the expression associated to the row
111.1200 + Expr row(Row r) const {
111.1201 + Expr e;
111.1202 + _getRowCoeffs(rows(id(r)), InsertIterator(e.comps, cols));
111.1203 + return e;
111.1204 + }
111.1205 +
111.1206 + ///Add a new row (i.e a new constraint) to the LP
111.1207 +
111.1208 + ///\param l is the lower bound (-\ref INF means no bound)
111.1209 + ///\param e is a linear expression (see \ref Expr)
111.1210 + ///\param u is the upper bound (\ref INF means no bound)
111.1211 + ///\return The created row.
111.1212 + Row addRow(Value l,const Expr &e, Value u) {
111.1213 + Row r=addRow();
111.1214 + row(r,l,e,u);
111.1215 + return r;
111.1216 + }
111.1217 +
111.1218 + ///Add a new row (i.e a new constraint) to the LP
111.1219 +
111.1220 + ///\param c is a linear expression (see \ref Constr)
111.1221 + ///\return The created row.
111.1222 + Row addRow(const Constr &c) {
111.1223 + Row r=addRow();
111.1224 + row(r,c);
111.1225 + return r;
111.1226 + }
111.1227 + ///Erase a column (i.e a variable) from the LP
111.1228 +
111.1229 + ///\param c is the column to be deleted
111.1230 + void erase(Col c) {
111.1231 + _eraseCol(cols(id(c)));
111.1232 + _eraseColId(cols(id(c)));
111.1233 + }
111.1234 + ///Erase a row (i.e a constraint) from the LP
111.1235 +
111.1236 + ///\param r is the row to be deleted
111.1237 + void erase(Row r) {
111.1238 + _eraseRow(rows(id(r)));
111.1239 + _eraseRowId(rows(id(r)));
111.1240 + }
111.1241 +
111.1242 + /// Get the name of a column
111.1243 +
111.1244 + ///\param c is the coresponding column
111.1245 + ///\return The name of the colunm
111.1246 + std::string colName(Col c) const {
111.1247 + std::string name;
111.1248 + _getColName(cols(id(c)), name);
111.1249 + return name;
111.1250 + }
111.1251 +
111.1252 + /// Set the name of a column
111.1253 +
111.1254 + ///\param c is the coresponding column
111.1255 + ///\param name The name to be given
111.1256 + void colName(Col c, const std::string& name) {
111.1257 + _setColName(cols(id(c)), name);
111.1258 + }
111.1259 +
111.1260 + /// Get the column by its name
111.1261 +
111.1262 + ///\param name The name of the column
111.1263 + ///\return the proper column or \c INVALID
111.1264 + Col colByName(const std::string& name) const {
111.1265 + int k = _colByName(name);
111.1266 + return k != -1 ? Col(cols[k]) : Col(INVALID);
111.1267 + }
111.1268 +
111.1269 + /// Get the name of a row
111.1270 +
111.1271 + ///\param r is the coresponding row
111.1272 + ///\return The name of the row
111.1273 + std::string rowName(Row r) const {
111.1274 + std::string name;
111.1275 + _getRowName(rows(id(r)), name);
111.1276 + return name;
111.1277 + }
111.1278 +
111.1279 + /// Set the name of a row
111.1280 +
111.1281 + ///\param r is the coresponding row
111.1282 + ///\param name The name to be given
111.1283 + void rowName(Row r, const std::string& name) {
111.1284 + _setRowName(rows(id(r)), name);
111.1285 + }
111.1286 +
111.1287 + /// Get the row by its name
111.1288 +
111.1289 + ///\param name The name of the row
111.1290 + ///\return the proper row or \c INVALID
111.1291 + Row rowByName(const std::string& name) const {
111.1292 + int k = _rowByName(name);
111.1293 + return k != -1 ? Row(rows[k]) : Row(INVALID);
111.1294 + }
111.1295 +
111.1296 + /// Set an element of the coefficient matrix of the LP
111.1297 +
111.1298 + ///\param r is the row of the element to be modified
111.1299 + ///\param c is the column of the element to be modified
111.1300 + ///\param val is the new value of the coefficient
111.1301 + void coeff(Row r, Col c, Value val) {
111.1302 + _setCoeff(rows(id(r)),cols(id(c)), val);
111.1303 + }
111.1304 +
111.1305 + /// Get an element of the coefficient matrix of the LP
111.1306 +
111.1307 + ///\param r is the row of the element
111.1308 + ///\param c is the column of the element
111.1309 + ///\return the corresponding coefficient
111.1310 + Value coeff(Row r, Col c) const {
111.1311 + return _getCoeff(rows(id(r)),cols(id(c)));
111.1312 + }
111.1313 +
111.1314 + /// Set the lower bound of a column (i.e a variable)
111.1315 +
111.1316 + /// The lower bound of a variable (column) has to be given by an
111.1317 + /// extended number of type Value, i.e. a finite number of type
111.1318 + /// Value or -\ref INF.
111.1319 + void colLowerBound(Col c, Value value) {
111.1320 + _setColLowerBound(cols(id(c)),value);
111.1321 + }
111.1322 +
111.1323 + /// Get the lower bound of a column (i.e a variable)
111.1324 +
111.1325 + /// This function returns the lower bound for column (variable) \c c
111.1326 + /// (this might be -\ref INF as well).
111.1327 + ///\return The lower bound for column \c c
111.1328 + Value colLowerBound(Col c) const {
111.1329 + return _getColLowerBound(cols(id(c)));
111.1330 + }
111.1331 +
111.1332 + ///\brief Set the lower bound of several columns
111.1333 + ///(i.e variables) at once
111.1334 + ///
111.1335 + ///This magic function takes a container as its argument
111.1336 + ///and applies the function on all of its elements.
111.1337 + ///The lower bound of a variable (column) has to be given by an
111.1338 + ///extended number of type Value, i.e. a finite number of type
111.1339 + ///Value or -\ref INF.
111.1340 +#ifdef DOXYGEN
111.1341 + template<class T>
111.1342 + void colLowerBound(T &t, Value value) { return 0;}
111.1343 +#else
111.1344 + template<class T>
111.1345 + typename enable_if<typename T::value_type::LpCol,void>::type
111.1346 + colLowerBound(T &t, Value value,dummy<0> = 0) {
111.1347 + for(typename T::iterator i=t.begin();i!=t.end();++i) {
111.1348 + colLowerBound(*i, value);
111.1349 + }
111.1350 + }
111.1351 + template<class T>
111.1352 + typename enable_if<typename T::value_type::second_type::LpCol,
111.1353 + void>::type
111.1354 + colLowerBound(T &t, Value value,dummy<1> = 1) {
111.1355 + for(typename T::iterator i=t.begin();i!=t.end();++i) {
111.1356 + colLowerBound(i->second, value);
111.1357 + }
111.1358 + }
111.1359 + template<class T>
111.1360 + typename enable_if<typename T::MapIt::Value::LpCol,
111.1361 + void>::type
111.1362 + colLowerBound(T &t, Value value,dummy<2> = 2) {
111.1363 + for(typename T::MapIt i(t); i!=INVALID; ++i){
111.1364 + colLowerBound(*i, value);
111.1365 + }
111.1366 + }
111.1367 +#endif
111.1368 +
111.1369 + /// Set the upper bound of a column (i.e a variable)
111.1370 +
111.1371 + /// The upper bound of a variable (column) has to be given by an
111.1372 + /// extended number of type Value, i.e. a finite number of type
111.1373 + /// Value or \ref INF.
111.1374 + void colUpperBound(Col c, Value value) {
111.1375 + _setColUpperBound(cols(id(c)),value);
111.1376 + };
111.1377 +
111.1378 + /// Get the upper bound of a column (i.e a variable)
111.1379 +
111.1380 + /// This function returns the upper bound for column (variable) \c c
111.1381 + /// (this might be \ref INF as well).
111.1382 + /// \return The upper bound for column \c c
111.1383 + Value colUpperBound(Col c) const {
111.1384 + return _getColUpperBound(cols(id(c)));
111.1385 + }
111.1386 +
111.1387 + ///\brief Set the upper bound of several columns
111.1388 + ///(i.e variables) at once
111.1389 + ///
111.1390 + ///This magic function takes a container as its argument
111.1391 + ///and applies the function on all of its elements.
111.1392 + ///The upper bound of a variable (column) has to be given by an
111.1393 + ///extended number of type Value, i.e. a finite number of type
111.1394 + ///Value or \ref INF.
111.1395 +#ifdef DOXYGEN
111.1396 + template<class T>
111.1397 + void colUpperBound(T &t, Value value) { return 0;}
111.1398 +#else
111.1399 + template<class T1>
111.1400 + typename enable_if<typename T1::value_type::LpCol,void>::type
111.1401 + colUpperBound(T1 &t, Value value,dummy<0> = 0) {
111.1402 + for(typename T1::iterator i=t.begin();i!=t.end();++i) {
111.1403 + colUpperBound(*i, value);
111.1404 + }
111.1405 + }
111.1406 + template<class T1>
111.1407 + typename enable_if<typename T1::value_type::second_type::LpCol,
111.1408 + void>::type
111.1409 + colUpperBound(T1 &t, Value value,dummy<1> = 1) {
111.1410 + for(typename T1::iterator i=t.begin();i!=t.end();++i) {
111.1411 + colUpperBound(i->second, value);
111.1412 + }
111.1413 + }
111.1414 + template<class T1>
111.1415 + typename enable_if<typename T1::MapIt::Value::LpCol,
111.1416 + void>::type
111.1417 + colUpperBound(T1 &t, Value value,dummy<2> = 2) {
111.1418 + for(typename T1::MapIt i(t); i!=INVALID; ++i){
111.1419 + colUpperBound(*i, value);
111.1420 + }
111.1421 + }
111.1422 +#endif
111.1423 +
111.1424 + /// Set the lower and the upper bounds of a column (i.e a variable)
111.1425 +
111.1426 + /// The lower and the upper bounds of
111.1427 + /// a variable (column) have to be given by an
111.1428 + /// extended number of type Value, i.e. a finite number of type
111.1429 + /// Value, -\ref INF or \ref INF.
111.1430 + void colBounds(Col c, Value lower, Value upper) {
111.1431 + _setColLowerBound(cols(id(c)),lower);
111.1432 + _setColUpperBound(cols(id(c)),upper);
111.1433 + }
111.1434 +
111.1435 + ///\brief Set the lower and the upper bound of several columns
111.1436 + ///(i.e variables) at once
111.1437 + ///
111.1438 + ///This magic function takes a container as its argument
111.1439 + ///and applies the function on all of its elements.
111.1440 + /// The lower and the upper bounds of
111.1441 + /// a variable (column) have to be given by an
111.1442 + /// extended number of type Value, i.e. a finite number of type
111.1443 + /// Value, -\ref INF or \ref INF.
111.1444 +#ifdef DOXYGEN
111.1445 + template<class T>
111.1446 + void colBounds(T &t, Value lower, Value upper) { return 0;}
111.1447 +#else
111.1448 + template<class T2>
111.1449 + typename enable_if<typename T2::value_type::LpCol,void>::type
111.1450 + colBounds(T2 &t, Value lower, Value upper,dummy<0> = 0) {
111.1451 + for(typename T2::iterator i=t.begin();i!=t.end();++i) {
111.1452 + colBounds(*i, lower, upper);
111.1453 + }
111.1454 + }
111.1455 + template<class T2>
111.1456 + typename enable_if<typename T2::value_type::second_type::LpCol, void>::type
111.1457 + colBounds(T2 &t, Value lower, Value upper,dummy<1> = 1) {
111.1458 + for(typename T2::iterator i=t.begin();i!=t.end();++i) {
111.1459 + colBounds(i->second, lower, upper);
111.1460 + }
111.1461 + }
111.1462 + template<class T2>
111.1463 + typename enable_if<typename T2::MapIt::Value::LpCol, void>::type
111.1464 + colBounds(T2 &t, Value lower, Value upper,dummy<2> = 2) {
111.1465 + for(typename T2::MapIt i(t); i!=INVALID; ++i){
111.1466 + colBounds(*i, lower, upper);
111.1467 + }
111.1468 + }
111.1469 +#endif
111.1470 +
111.1471 + /// Set the lower bound of a row (i.e a constraint)
111.1472 +
111.1473 + /// The lower bound of a constraint (row) has to be given by an
111.1474 + /// extended number of type Value, i.e. a finite number of type
111.1475 + /// Value or -\ref INF.
111.1476 + void rowLowerBound(Row r, Value value) {
111.1477 + _setRowLowerBound(rows(id(r)),value);
111.1478 + }
111.1479 +
111.1480 + /// Get the lower bound of a row (i.e a constraint)
111.1481 +
111.1482 + /// This function returns the lower bound for row (constraint) \c c
111.1483 + /// (this might be -\ref INF as well).
111.1484 + ///\return The lower bound for row \c r
111.1485 + Value rowLowerBound(Row r) const {
111.1486 + return _getRowLowerBound(rows(id(r)));
111.1487 + }
111.1488 +
111.1489 + /// Set the upper bound of a row (i.e a constraint)
111.1490 +
111.1491 + /// The upper bound of a constraint (row) has to be given by an
111.1492 + /// extended number of type Value, i.e. a finite number of type
111.1493 + /// Value or -\ref INF.
111.1494 + void rowUpperBound(Row r, Value value) {
111.1495 + _setRowUpperBound(rows(id(r)),value);
111.1496 + }
111.1497 +
111.1498 + /// Get the upper bound of a row (i.e a constraint)
111.1499 +
111.1500 + /// This function returns the upper bound for row (constraint) \c c
111.1501 + /// (this might be -\ref INF as well).
111.1502 + ///\return The upper bound for row \c r
111.1503 + Value rowUpperBound(Row r) const {
111.1504 + return _getRowUpperBound(rows(id(r)));
111.1505 + }
111.1506 +
111.1507 + ///Set an element of the objective function
111.1508 + void objCoeff(Col c, Value v) {_setObjCoeff(cols(id(c)),v); };
111.1509 +
111.1510 + ///Get an element of the objective function
111.1511 + Value objCoeff(Col c) const { return _getObjCoeff(cols(id(c))); };
111.1512 +
111.1513 + ///Set the objective function
111.1514 +
111.1515 + ///\param e is a linear expression of type \ref Expr.
111.1516 + ///
111.1517 + void obj(const Expr& e) {
111.1518 + _setObjCoeffs(ExprIterator(e.comps.begin(), cols),
111.1519 + ExprIterator(e.comps.end(), cols));
111.1520 + obj_const_comp = *e;
111.1521 + }
111.1522 +
111.1523 + ///Get the objective function
111.1524 +
111.1525 + ///\return the objective function as a linear expression of type
111.1526 + ///Expr.
111.1527 + Expr obj() const {
111.1528 + Expr e;
111.1529 + _getObjCoeffs(InsertIterator(e.comps, cols));
111.1530 + *e = obj_const_comp;
111.1531 + return e;
111.1532 + }
111.1533 +
111.1534 +
111.1535 + ///Set the direction of optimization
111.1536 + void sense(Sense sense) { _setSense(sense); }
111.1537 +
111.1538 + ///Query the direction of the optimization
111.1539 + Sense sense() const {return _getSense(); }
111.1540 +
111.1541 + ///Set the sense to maximization
111.1542 + void max() { _setSense(MAX); }
111.1543 +
111.1544 + ///Set the sense to maximization
111.1545 + void min() { _setSense(MIN); }
111.1546 +
111.1547 + ///Clears the problem
111.1548 + void clear() { _clear(); }
111.1549 +
111.1550 + /// Sets the message level of the solver
111.1551 + void messageLevel(MessageLevel level) { _messageLevel(level); }
111.1552 +
111.1553 + ///@}
111.1554 +
111.1555 + };
111.1556 +
111.1557 + /// Addition
111.1558 +
111.1559 + ///\relates LpBase::Expr
111.1560 + ///
111.1561 + inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) {
111.1562 + LpBase::Expr tmp(a);
111.1563 + tmp+=b;
111.1564 + return tmp;
111.1565 + }
111.1566 + ///Substraction
111.1567 +
111.1568 + ///\relates LpBase::Expr
111.1569 + ///
111.1570 + inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) {
111.1571 + LpBase::Expr tmp(a);
111.1572 + tmp-=b;
111.1573 + return tmp;
111.1574 + }
111.1575 + ///Multiply with constant
111.1576 +
111.1577 + ///\relates LpBase::Expr
111.1578 + ///
111.1579 + inline LpBase::Expr operator*(const LpBase::Expr &a, const LpBase::Value &b) {
111.1580 + LpBase::Expr tmp(a);
111.1581 + tmp*=b;
111.1582 + return tmp;
111.1583 + }
111.1584 +
111.1585 + ///Multiply with constant
111.1586 +
111.1587 + ///\relates LpBase::Expr
111.1588 + ///
111.1589 + inline LpBase::Expr operator*(const LpBase::Value &a, const LpBase::Expr &b) {
111.1590 + LpBase::Expr tmp(b);
111.1591 + tmp*=a;
111.1592 + return tmp;
111.1593 + }
111.1594 + ///Divide with constant
111.1595 +
111.1596 + ///\relates LpBase::Expr
111.1597 + ///
111.1598 + inline LpBase::Expr operator/(const LpBase::Expr &a, const LpBase::Value &b) {
111.1599 + LpBase::Expr tmp(a);
111.1600 + tmp/=b;
111.1601 + return tmp;
111.1602 + }
111.1603 +
111.1604 + ///Create constraint
111.1605 +
111.1606 + ///\relates LpBase::Constr
111.1607 + ///
111.1608 + inline LpBase::Constr operator<=(const LpBase::Expr &e,
111.1609 + const LpBase::Expr &f) {
111.1610 + return LpBase::Constr(0, f - e, LpBase::INF);
111.1611 + }
111.1612 +
111.1613 + ///Create constraint
111.1614 +
111.1615 + ///\relates LpBase::Constr
111.1616 + ///
111.1617 + inline LpBase::Constr operator<=(const LpBase::Value &e,
111.1618 + const LpBase::Expr &f) {
111.1619 + return LpBase::Constr(e, f, LpBase::NaN);
111.1620 + }
111.1621 +
111.1622 + ///Create constraint
111.1623 +
111.1624 + ///\relates LpBase::Constr
111.1625 + ///
111.1626 + inline LpBase::Constr operator<=(const LpBase::Expr &e,
111.1627 + const LpBase::Value &f) {
111.1628 + return LpBase::Constr(- LpBase::INF, e, f);
111.1629 + }
111.1630 +
111.1631 + ///Create constraint
111.1632 +
111.1633 + ///\relates LpBase::Constr
111.1634 + ///
111.1635 + inline LpBase::Constr operator>=(const LpBase::Expr &e,
111.1636 + const LpBase::Expr &f) {
111.1637 + return LpBase::Constr(0, e - f, LpBase::INF);
111.1638 + }
111.1639 +
111.1640 +
111.1641 + ///Create constraint
111.1642 +
111.1643 + ///\relates LpBase::Constr
111.1644 + ///
111.1645 + inline LpBase::Constr operator>=(const LpBase::Value &e,
111.1646 + const LpBase::Expr &f) {
111.1647 + return LpBase::Constr(LpBase::NaN, f, e);
111.1648 + }
111.1649 +
111.1650 +
111.1651 + ///Create constraint
111.1652 +
111.1653 + ///\relates LpBase::Constr
111.1654 + ///
111.1655 + inline LpBase::Constr operator>=(const LpBase::Expr &e,
111.1656 + const LpBase::Value &f) {
111.1657 + return LpBase::Constr(f, e, LpBase::INF);
111.1658 + }
111.1659 +
111.1660 + ///Create constraint
111.1661 +
111.1662 + ///\relates LpBase::Constr
111.1663 + ///
111.1664 + inline LpBase::Constr operator==(const LpBase::Expr &e,
111.1665 + const LpBase::Value &f) {
111.1666 + return LpBase::Constr(f, e, f);
111.1667 + }
111.1668 +
111.1669 + ///Create constraint
111.1670 +
111.1671 + ///\relates LpBase::Constr
111.1672 + ///
111.1673 + inline LpBase::Constr operator==(const LpBase::Expr &e,
111.1674 + const LpBase::Expr &f) {
111.1675 + return LpBase::Constr(0, f - e, 0);
111.1676 + }
111.1677 +
111.1678 + ///Create constraint
111.1679 +
111.1680 + ///\relates LpBase::Constr
111.1681 + ///
111.1682 + inline LpBase::Constr operator<=(const LpBase::Value &n,
111.1683 + const LpBase::Constr &c) {
111.1684 + LpBase::Constr tmp(c);
111.1685 + LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
111.1686 + tmp.lowerBound()=n;
111.1687 + return tmp;
111.1688 + }
111.1689 + ///Create constraint
111.1690 +
111.1691 + ///\relates LpBase::Constr
111.1692 + ///
111.1693 + inline LpBase::Constr operator<=(const LpBase::Constr &c,
111.1694 + const LpBase::Value &n)
111.1695 + {
111.1696 + LpBase::Constr tmp(c);
111.1697 + LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
111.1698 + tmp.upperBound()=n;
111.1699 + return tmp;
111.1700 + }
111.1701 +
111.1702 + ///Create constraint
111.1703 +
111.1704 + ///\relates LpBase::Constr
111.1705 + ///
111.1706 + inline LpBase::Constr operator>=(const LpBase::Value &n,
111.1707 + const LpBase::Constr &c) {
111.1708 + LpBase::Constr tmp(c);
111.1709 + LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
111.1710 + tmp.upperBound()=n;
111.1711 + return tmp;
111.1712 + }
111.1713 + ///Create constraint
111.1714 +
111.1715 + ///\relates LpBase::Constr
111.1716 + ///
111.1717 + inline LpBase::Constr operator>=(const LpBase::Constr &c,
111.1718 + const LpBase::Value &n)
111.1719 + {
111.1720 + LpBase::Constr tmp(c);
111.1721 + LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
111.1722 + tmp.lowerBound()=n;
111.1723 + return tmp;
111.1724 + }
111.1725 +
111.1726 + ///Addition
111.1727 +
111.1728 + ///\relates LpBase::DualExpr
111.1729 + ///
111.1730 + inline LpBase::DualExpr operator+(const LpBase::DualExpr &a,
111.1731 + const LpBase::DualExpr &b) {
111.1732 + LpBase::DualExpr tmp(a);
111.1733 + tmp+=b;
111.1734 + return tmp;
111.1735 + }
111.1736 + ///Substraction
111.1737 +
111.1738 + ///\relates LpBase::DualExpr
111.1739 + ///
111.1740 + inline LpBase::DualExpr operator-(const LpBase::DualExpr &a,
111.1741 + const LpBase::DualExpr &b) {
111.1742 + LpBase::DualExpr tmp(a);
111.1743 + tmp-=b;
111.1744 + return tmp;
111.1745 + }
111.1746 + ///Multiply with constant
111.1747 +
111.1748 + ///\relates LpBase::DualExpr
111.1749 + ///
111.1750 + inline LpBase::DualExpr operator*(const LpBase::DualExpr &a,
111.1751 + const LpBase::Value &b) {
111.1752 + LpBase::DualExpr tmp(a);
111.1753 + tmp*=b;
111.1754 + return tmp;
111.1755 + }
111.1756 +
111.1757 + ///Multiply with constant
111.1758 +
111.1759 + ///\relates LpBase::DualExpr
111.1760 + ///
111.1761 + inline LpBase::DualExpr operator*(const LpBase::Value &a,
111.1762 + const LpBase::DualExpr &b) {
111.1763 + LpBase::DualExpr tmp(b);
111.1764 + tmp*=a;
111.1765 + return tmp;
111.1766 + }
111.1767 + ///Divide with constant
111.1768 +
111.1769 + ///\relates LpBase::DualExpr
111.1770 + ///
111.1771 + inline LpBase::DualExpr operator/(const LpBase::DualExpr &a,
111.1772 + const LpBase::Value &b) {
111.1773 + LpBase::DualExpr tmp(a);
111.1774 + tmp/=b;
111.1775 + return tmp;
111.1776 + }
111.1777 +
111.1778 + /// \ingroup lp_group
111.1779 + ///
111.1780 + /// \brief Common base class for LP solvers
111.1781 + ///
111.1782 + /// This class is an abstract base class for LP solvers. This class
111.1783 + /// provides a full interface for set and modify an LP problem,
111.1784 + /// solve it and retrieve the solution. You can use one of the
111.1785 + /// descendants as a concrete implementation, or the \c Lp
111.1786 + /// default LP solver. However, if you would like to handle LP
111.1787 + /// solvers as reference or pointer in a generic way, you can use
111.1788 + /// this class directly.
111.1789 + class LpSolver : virtual public LpBase {
111.1790 + public:
111.1791 +
111.1792 + /// The problem types for primal and dual problems
111.1793 + enum ProblemType {
111.1794 + /// = 0. Feasible solution hasn't been found (but may exist).
111.1795 + UNDEFINED = 0,
111.1796 + /// = 1. The problem has no feasible solution.
111.1797 + INFEASIBLE = 1,
111.1798 + /// = 2. Feasible solution found.
111.1799 + FEASIBLE = 2,
111.1800 + /// = 3. Optimal solution exists and found.
111.1801 + OPTIMAL = 3,
111.1802 + /// = 4. The cost function is unbounded.
111.1803 + UNBOUNDED = 4
111.1804 + };
111.1805 +
111.1806 + ///The basis status of variables
111.1807 + enum VarStatus {
111.1808 + /// The variable is in the basis
111.1809 + BASIC,
111.1810 + /// The variable is free, but not basic
111.1811 + FREE,
111.1812 + /// The variable has active lower bound
111.1813 + LOWER,
111.1814 + /// The variable has active upper bound
111.1815 + UPPER,
111.1816 + /// The variable is non-basic and fixed
111.1817 + FIXED
111.1818 + };
111.1819 +
111.1820 + protected:
111.1821 +
111.1822 + virtual SolveExitStatus _solve() = 0;
111.1823 +
111.1824 + virtual Value _getPrimal(int i) const = 0;
111.1825 + virtual Value _getDual(int i) const = 0;
111.1826 +
111.1827 + virtual Value _getPrimalRay(int i) const = 0;
111.1828 + virtual Value _getDualRay(int i) const = 0;
111.1829 +
111.1830 + virtual Value _getPrimalValue() const = 0;
111.1831 +
111.1832 + virtual VarStatus _getColStatus(int i) const = 0;
111.1833 + virtual VarStatus _getRowStatus(int i) const = 0;
111.1834 +
111.1835 + virtual ProblemType _getPrimalType() const = 0;
111.1836 + virtual ProblemType _getDualType() const = 0;
111.1837 +
111.1838 + public:
111.1839 +
111.1840 + ///Allocate a new LP problem instance
111.1841 + virtual LpSolver* newSolver() const = 0;
111.1842 + ///Make a copy of the LP problem
111.1843 + virtual LpSolver* cloneSolver() const = 0;
111.1844 +
111.1845 + ///\name Solve the LP
111.1846 +
111.1847 + ///@{
111.1848 +
111.1849 + ///\e Solve the LP problem at hand
111.1850 + ///
111.1851 + ///\return The result of the optimization procedure. Possible
111.1852 + ///values and their meanings can be found in the documentation of
111.1853 + ///\ref SolveExitStatus.
111.1854 + SolveExitStatus solve() { return _solve(); }
111.1855 +
111.1856 + ///@}
111.1857 +
111.1858 + ///\name Obtain the Solution
111.1859 +
111.1860 + ///@{
111.1861 +
111.1862 + /// The type of the primal problem
111.1863 + ProblemType primalType() const {
111.1864 + return _getPrimalType();
111.1865 + }
111.1866 +
111.1867 + /// The type of the dual problem
111.1868 + ProblemType dualType() const {
111.1869 + return _getDualType();
111.1870 + }
111.1871 +
111.1872 + /// Return the primal value of the column
111.1873 +
111.1874 + /// Return the primal value of the column.
111.1875 + /// \pre The problem is solved.
111.1876 + Value primal(Col c) const { return _getPrimal(cols(id(c))); }
111.1877 +
111.1878 + /// Return the primal value of the expression
111.1879 +
111.1880 + /// Return the primal value of the expression, i.e. the dot
111.1881 + /// product of the primal solution and the expression.
111.1882 + /// \pre The problem is solved.
111.1883 + Value primal(const Expr& e) const {
111.1884 + double res = *e;
111.1885 + for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
111.1886 + res += *c * primal(c);
111.1887 + }
111.1888 + return res;
111.1889 + }
111.1890 + /// Returns a component of the primal ray
111.1891 +
111.1892 + /// The primal ray is solution of the modified primal problem,
111.1893 + /// where we change each finite bound to 0, and we looking for a
111.1894 + /// negative objective value in case of minimization, and positive
111.1895 + /// objective value for maximization. If there is such solution,
111.1896 + /// that proofs the unsolvability of the dual problem, and if a
111.1897 + /// feasible primal solution exists, then the unboundness of
111.1898 + /// primal problem.
111.1899 + ///
111.1900 + /// \pre The problem is solved and the dual problem is infeasible.
111.1901 + /// \note Some solvers does not provide primal ray calculation
111.1902 + /// functions.
111.1903 + Value primalRay(Col c) const { return _getPrimalRay(cols(id(c))); }
111.1904 +
111.1905 + /// Return the dual value of the row
111.1906 +
111.1907 + /// Return the dual value of the row.
111.1908 + /// \pre The problem is solved.
111.1909 + Value dual(Row r) const { return _getDual(rows(id(r))); }
111.1910 +
111.1911 + /// Return the dual value of the dual expression
111.1912 +
111.1913 + /// Return the dual value of the dual expression, i.e. the dot
111.1914 + /// product of the dual solution and the dual expression.
111.1915 + /// \pre The problem is solved.
111.1916 + Value dual(const DualExpr& e) const {
111.1917 + double res = 0.0;
111.1918 + for (DualExpr::ConstCoeffIt r(e); r != INVALID; ++r) {
111.1919 + res += *r * dual(r);
111.1920 + }
111.1921 + return res;
111.1922 + }
111.1923 +
111.1924 + /// Returns a component of the dual ray
111.1925 +
111.1926 + /// The dual ray is solution of the modified primal problem, where
111.1927 + /// we change each finite bound to 0 (i.e. the objective function
111.1928 + /// coefficients in the primal problem), and we looking for a
111.1929 + /// ositive objective value. If there is such solution, that
111.1930 + /// proofs the unsolvability of the primal problem, and if a
111.1931 + /// feasible dual solution exists, then the unboundness of
111.1932 + /// dual problem.
111.1933 + ///
111.1934 + /// \pre The problem is solved and the primal problem is infeasible.
111.1935 + /// \note Some solvers does not provide dual ray calculation
111.1936 + /// functions.
111.1937 + Value dualRay(Row r) const { return _getDualRay(rows(id(r))); }
111.1938 +
111.1939 + /// Return the basis status of the column
111.1940 +
111.1941 + /// \see VarStatus
111.1942 + VarStatus colStatus(Col c) const { return _getColStatus(cols(id(c))); }
111.1943 +
111.1944 + /// Return the basis status of the row
111.1945 +
111.1946 + /// \see VarStatus
111.1947 + VarStatus rowStatus(Row r) const { return _getRowStatus(rows(id(r))); }
111.1948 +
111.1949 + ///The value of the objective function
111.1950 +
111.1951 + ///\return
111.1952 + ///- \ref INF or -\ref INF means either infeasibility or unboundedness
111.1953 + /// of the primal problem, depending on whether we minimize or maximize.
111.1954 + ///- \ref NaN if no primal solution is found.
111.1955 + ///- The (finite) objective value if an optimal solution is found.
111.1956 + Value primal() const { return _getPrimalValue()+obj_const_comp;}
111.1957 + ///@}
111.1958 +
111.1959 + protected:
111.1960 +
111.1961 + };
111.1962 +
111.1963 +
111.1964 + /// \ingroup lp_group
111.1965 + ///
111.1966 + /// \brief Common base class for MIP solvers
111.1967 + ///
111.1968 + /// This class is an abstract base class for MIP solvers. This class
111.1969 + /// provides a full interface for set and modify an MIP problem,
111.1970 + /// solve it and retrieve the solution. You can use one of the
111.1971 + /// descendants as a concrete implementation, or the \c Lp
111.1972 + /// default MIP solver. However, if you would like to handle MIP
111.1973 + /// solvers as reference or pointer in a generic way, you can use
111.1974 + /// this class directly.
111.1975 + class MipSolver : virtual public LpBase {
111.1976 + public:
111.1977 +
111.1978 + /// The problem types for MIP problems
111.1979 + enum ProblemType {
111.1980 + /// = 0. Feasible solution hasn't been found (but may exist).
111.1981 + UNDEFINED = 0,
111.1982 + /// = 1. The problem has no feasible solution.
111.1983 + INFEASIBLE = 1,
111.1984 + /// = 2. Feasible solution found.
111.1985 + FEASIBLE = 2,
111.1986 + /// = 3. Optimal solution exists and found.
111.1987 + OPTIMAL = 3,
111.1988 + /// = 4. The cost function is unbounded.
111.1989 + ///The Mip or at least the relaxed problem is unbounded.
111.1990 + UNBOUNDED = 4
111.1991 + };
111.1992 +
111.1993 + ///Allocate a new MIP problem instance
111.1994 + virtual MipSolver* newSolver() const = 0;
111.1995 + ///Make a copy of the MIP problem
111.1996 + virtual MipSolver* cloneSolver() const = 0;
111.1997 +
111.1998 + ///\name Solve the MIP
111.1999 +
111.2000 + ///@{
111.2001 +
111.2002 + /// Solve the MIP problem at hand
111.2003 + ///
111.2004 + ///\return The result of the optimization procedure. Possible
111.2005 + ///values and their meanings can be found in the documentation of
111.2006 + ///\ref SolveExitStatus.
111.2007 + SolveExitStatus solve() { return _solve(); }
111.2008 +
111.2009 + ///@}
111.2010 +
111.2011 + ///\name Set Column Type
111.2012 + ///@{
111.2013 +
111.2014 + ///Possible variable (column) types (e.g. real, integer, binary etc.)
111.2015 + enum ColTypes {
111.2016 + /// = 0. Continuous variable (default).
111.2017 + REAL = 0,
111.2018 + /// = 1. Integer variable.
111.2019 + INTEGER = 1
111.2020 + };
111.2021 +
111.2022 + ///Sets the type of the given column to the given type
111.2023 +
111.2024 + ///Sets the type of the given column to the given type.
111.2025 + ///
111.2026 + void colType(Col c, ColTypes col_type) {
111.2027 + _setColType(cols(id(c)),col_type);
111.2028 + }
111.2029 +
111.2030 + ///Gives back the type of the column.
111.2031 +
111.2032 + ///Gives back the type of the column.
111.2033 + ///
111.2034 + ColTypes colType(Col c) const {
111.2035 + return _getColType(cols(id(c)));
111.2036 + }
111.2037 + ///@}
111.2038 +
111.2039 + ///\name Obtain the Solution
111.2040 +
111.2041 + ///@{
111.2042 +
111.2043 + /// The type of the MIP problem
111.2044 + ProblemType type() const {
111.2045 + return _getType();
111.2046 + }
111.2047 +
111.2048 + /// Return the value of the row in the solution
111.2049 +
111.2050 + /// Return the value of the row in the solution.
111.2051 + /// \pre The problem is solved.
111.2052 + Value sol(Col c) const { return _getSol(cols(id(c))); }
111.2053 +
111.2054 + /// Return the value of the expression in the solution
111.2055 +
111.2056 + /// Return the value of the expression in the solution, i.e. the
111.2057 + /// dot product of the solution and the expression.
111.2058 + /// \pre The problem is solved.
111.2059 + Value sol(const Expr& e) const {
111.2060 + double res = *e;
111.2061 + for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
111.2062 + res += *c * sol(c);
111.2063 + }
111.2064 + return res;
111.2065 + }
111.2066 + ///The value of the objective function
111.2067 +
111.2068 + ///\return
111.2069 + ///- \ref INF or -\ref INF means either infeasibility or unboundedness
111.2070 + /// of the problem, depending on whether we minimize or maximize.
111.2071 + ///- \ref NaN if no primal solution is found.
111.2072 + ///- The (finite) objective value if an optimal solution is found.
111.2073 + Value solValue() const { return _getSolValue()+obj_const_comp;}
111.2074 + ///@}
111.2075 +
111.2076 + protected:
111.2077 +
111.2078 + virtual SolveExitStatus _solve() = 0;
111.2079 + virtual ColTypes _getColType(int col) const = 0;
111.2080 + virtual void _setColType(int col, ColTypes col_type) = 0;
111.2081 + virtual ProblemType _getType() const = 0;
111.2082 + virtual Value _getSol(int i) const = 0;
111.2083 + virtual Value _getSolValue() const = 0;
111.2084 +
111.2085 + };
111.2086 +
111.2087 +
111.2088 +
111.2089 +} //namespace lemon
111.2090 +
111.2091 +#endif //LEMON_LP_BASE_H
112.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
112.2 +++ b/lemon/lp_skeleton.cc Thu Dec 10 17:05:35 2009 +0100
112.3 @@ -0,0 +1,136 @@
112.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
112.5 + *
112.6 + * This file is a part of LEMON, a generic C++ optimization library.
112.7 + *
112.8 + * Copyright (C) 2003-2008
112.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
112.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
112.11 + *
112.12 + * Permission to use, modify and distribute this software is granted
112.13 + * provided that this copyright notice appears in all copies. For
112.14 + * precise terms see the accompanying LICENSE file.
112.15 + *
112.16 + * This software is provided "AS IS" with no warranty of any kind,
112.17 + * express or implied, and with no claim as to its suitability for any
112.18 + * purpose.
112.19 + *
112.20 + */
112.21 +
112.22 +#include <lemon/lp_skeleton.h>
112.23 +
112.24 +///\file
112.25 +///\brief A skeleton file to implement LP solver interfaces
112.26 +namespace lemon {
112.27 +
112.28 + int SkeletonSolverBase::_addCol()
112.29 + {
112.30 + return ++col_num;
112.31 + }
112.32 +
112.33 + int SkeletonSolverBase::_addRow()
112.34 + {
112.35 + return ++row_num;
112.36 + }
112.37 +
112.38 + void SkeletonSolverBase::_eraseCol(int) {}
112.39 + void SkeletonSolverBase::_eraseRow(int) {}
112.40 +
112.41 + void SkeletonSolverBase::_getColName(int, std::string &) const {}
112.42 + void SkeletonSolverBase::_setColName(int, const std::string &) {}
112.43 + int SkeletonSolverBase::_colByName(const std::string&) const { return -1; }
112.44 +
112.45 + void SkeletonSolverBase::_getRowName(int, std::string &) const {}
112.46 + void SkeletonSolverBase::_setRowName(int, const std::string &) {}
112.47 + int SkeletonSolverBase::_rowByName(const std::string&) const { return -1; }
112.48 +
112.49 + void SkeletonSolverBase::_setRowCoeffs(int, ExprIterator, ExprIterator) {}
112.50 + void SkeletonSolverBase::_getRowCoeffs(int, InsertIterator) const {}
112.51 +
112.52 + void SkeletonSolverBase::_setColCoeffs(int, ExprIterator, ExprIterator) {}
112.53 + void SkeletonSolverBase::_getColCoeffs(int, InsertIterator) const {}
112.54 +
112.55 + void SkeletonSolverBase::_setCoeff(int, int, Value) {}
112.56 + SkeletonSolverBase::Value SkeletonSolverBase::_getCoeff(int, int) const
112.57 + { return 0; }
112.58 +
112.59 + void SkeletonSolverBase::_setColLowerBound(int, Value) {}
112.60 + SkeletonSolverBase::Value SkeletonSolverBase::_getColLowerBound(int) const
112.61 + { return 0; }
112.62 +
112.63 + void SkeletonSolverBase::_setColUpperBound(int, Value) {}
112.64 + SkeletonSolverBase::Value SkeletonSolverBase::_getColUpperBound(int) const
112.65 + { return 0; }
112.66 +
112.67 + void SkeletonSolverBase::_setRowLowerBound(int, Value) {}
112.68 + SkeletonSolverBase::Value SkeletonSolverBase::_getRowLowerBound(int) const
112.69 + { return 0; }
112.70 +
112.71 + void SkeletonSolverBase::_setRowUpperBound(int, Value) {}
112.72 + SkeletonSolverBase::Value SkeletonSolverBase::_getRowUpperBound(int) const
112.73 + { return 0; }
112.74 +
112.75 + void SkeletonSolverBase::_setObjCoeffs(ExprIterator, ExprIterator) {}
112.76 + void SkeletonSolverBase::_getObjCoeffs(InsertIterator) const {};
112.77 +
112.78 + void SkeletonSolverBase::_setObjCoeff(int, Value) {}
112.79 + SkeletonSolverBase::Value SkeletonSolverBase::_getObjCoeff(int) const
112.80 + { return 0; }
112.81 +
112.82 + void SkeletonSolverBase::_setSense(Sense) {}
112.83 + SkeletonSolverBase::Sense SkeletonSolverBase::_getSense() const
112.84 + { return MIN; }
112.85 +
112.86 + void SkeletonSolverBase::_clear() {
112.87 + row_num = col_num = 0;
112.88 + }
112.89 +
112.90 + void SkeletonSolverBase::_messageLevel(MessageLevel) {}
112.91 +
112.92 + LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
112.93 +
112.94 + LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
112.95 + LpSkeleton::Value LpSkeleton::_getDual(int) const { return 0; }
112.96 + LpSkeleton::Value LpSkeleton::_getPrimalValue() const { return 0; }
112.97 +
112.98 + LpSkeleton::Value LpSkeleton::_getPrimalRay(int) const { return 0; }
112.99 + LpSkeleton::Value LpSkeleton::_getDualRay(int) const { return 0; }
112.100 +
112.101 + LpSkeleton::ProblemType LpSkeleton::_getPrimalType() const
112.102 + { return UNDEFINED; }
112.103 +
112.104 + LpSkeleton::ProblemType LpSkeleton::_getDualType() const
112.105 + { return UNDEFINED; }
112.106 +
112.107 + LpSkeleton::VarStatus LpSkeleton::_getColStatus(int) const
112.108 + { return BASIC; }
112.109 +
112.110 + LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
112.111 + { return BASIC; }
112.112 +
112.113 + LpSkeleton* LpSkeleton::newSolver() const
112.114 + { return static_cast<LpSkeleton*>(0); }
112.115 +
112.116 + LpSkeleton* LpSkeleton::cloneSolver() const
112.117 + { return static_cast<LpSkeleton*>(0); }
112.118 +
112.119 + const char* LpSkeleton::_solverName() const { return "LpSkeleton"; }
112.120 +
112.121 + MipSkeleton::SolveExitStatus MipSkeleton::_solve()
112.122 + { return SOLVED; }
112.123 +
112.124 + MipSkeleton::Value MipSkeleton::_getSol(int) const { return 0; }
112.125 + MipSkeleton::Value MipSkeleton::_getSolValue() const { return 0; }
112.126 +
112.127 + MipSkeleton::ProblemType MipSkeleton::_getType() const
112.128 + { return UNDEFINED; }
112.129 +
112.130 + MipSkeleton* MipSkeleton::newSolver() const
112.131 + { return static_cast<MipSkeleton*>(0); }
112.132 +
112.133 + MipSkeleton* MipSkeleton::cloneSolver() const
112.134 + { return static_cast<MipSkeleton*>(0); }
112.135 +
112.136 + const char* MipSkeleton::_solverName() const { return "MipSkeleton"; }
112.137 +
112.138 +} //namespace lemon
112.139 +
113.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
113.2 +++ b/lemon/lp_skeleton.h Thu Dec 10 17:05:35 2009 +0100
113.3 @@ -0,0 +1,227 @@
113.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
113.5 + *
113.6 + * This file is a part of LEMON, a generic C++ optimization library.
113.7 + *
113.8 + * Copyright (C) 2003-2008
113.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
113.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
113.11 + *
113.12 + * Permission to use, modify and distribute this software is granted
113.13 + * provided that this copyright notice appears in all copies. For
113.14 + * precise terms see the accompanying LICENSE file.
113.15 + *
113.16 + * This software is provided "AS IS" with no warranty of any kind,
113.17 + * express or implied, and with no claim as to its suitability for any
113.18 + * purpose.
113.19 + *
113.20 + */
113.21 +
113.22 +#ifndef LEMON_LP_SKELETON_H
113.23 +#define LEMON_LP_SKELETON_H
113.24 +
113.25 +#include <lemon/lp_base.h>
113.26 +
113.27 +///\file
113.28 +///\brief Skeleton file to implement LP/MIP solver interfaces
113.29 +///
113.30 +///The classes in this file do nothing, but they can serve as skeletons when
113.31 +///implementing an interface to new solvers.
113.32 +namespace lemon {
113.33 +
113.34 + ///A skeleton class to implement LP/MIP solver base interface
113.35 +
113.36 + ///This class does nothing, but it can serve as a skeleton when
113.37 + ///implementing an interface to new solvers.
113.38 + class SkeletonSolverBase : public virtual LpBase {
113.39 + int col_num,row_num;
113.40 +
113.41 + protected:
113.42 +
113.43 + SkeletonSolverBase()
113.44 + : col_num(-1), row_num(-1) {}
113.45 +
113.46 + /// \e
113.47 + virtual int _addCol();
113.48 + /// \e
113.49 + virtual int _addRow();
113.50 + /// \e
113.51 + virtual void _eraseCol(int i);
113.52 + /// \e
113.53 + virtual void _eraseRow(int i);
113.54 +
113.55 + /// \e
113.56 + virtual void _getColName(int col, std::string& name) const;
113.57 + /// \e
113.58 + virtual void _setColName(int col, const std::string& name);
113.59 + /// \e
113.60 + virtual int _colByName(const std::string& name) const;
113.61 +
113.62 + /// \e
113.63 + virtual void _getRowName(int row, std::string& name) const;
113.64 + /// \e
113.65 + virtual void _setRowName(int row, const std::string& name);
113.66 + /// \e
113.67 + virtual int _rowByName(const std::string& name) const;
113.68 +
113.69 + /// \e
113.70 + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
113.71 + /// \e
113.72 + virtual void _getRowCoeffs(int i, InsertIterator b) const;
113.73 + /// \e
113.74 + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
113.75 + /// \e
113.76 + virtual void _getColCoeffs(int i, InsertIterator b) const;
113.77 +
113.78 + /// Set one element of the coefficient matrix
113.79 + virtual void _setCoeff(int row, int col, Value value);
113.80 +
113.81 + /// Get one element of the coefficient matrix
113.82 + virtual Value _getCoeff(int row, int col) const;
113.83 +
113.84 + /// The lower bound of a variable (column) have to be given by an
113.85 + /// extended number of type Value, i.e. a finite number of type
113.86 + /// Value or -\ref INF.
113.87 + virtual void _setColLowerBound(int i, Value value);
113.88 + /// \e
113.89 +
113.90 + /// The lower bound of a variable (column) is an
113.91 + /// extended number of type Value, i.e. a finite number of type
113.92 + /// Value or -\ref INF.
113.93 + virtual Value _getColLowerBound(int i) const;
113.94 +
113.95 + /// The upper bound of a variable (column) have to be given by an
113.96 + /// extended number of type Value, i.e. a finite number of type
113.97 + /// Value or \ref INF.
113.98 + virtual void _setColUpperBound(int i, Value value);
113.99 + /// \e
113.100 +
113.101 + /// The upper bound of a variable (column) is an
113.102 + /// extended number of type Value, i.e. a finite number of type
113.103 + /// Value or \ref INF.
113.104 + virtual Value _getColUpperBound(int i) const;
113.105 +
113.106 + /// The lower bound of a constraint (row) have to be given by an
113.107 + /// extended number of type Value, i.e. a finite number of type
113.108 + /// Value or -\ref INF.
113.109 + virtual void _setRowLowerBound(int i, Value value);
113.110 + /// \e
113.111 +
113.112 + /// The lower bound of a constraint (row) is an
113.113 + /// extended number of type Value, i.e. a finite number of type
113.114 + /// Value or -\ref INF.
113.115 + virtual Value _getRowLowerBound(int i) const;
113.116 +
113.117 + /// The upper bound of a constraint (row) have to be given by an
113.118 + /// extended number of type Value, i.e. a finite number of type
113.119 + /// Value or \ref INF.
113.120 + virtual void _setRowUpperBound(int i, Value value);
113.121 + /// \e
113.122 +
113.123 + /// The upper bound of a constraint (row) is an
113.124 + /// extended number of type Value, i.e. a finite number of type
113.125 + /// Value or \ref INF.
113.126 + virtual Value _getRowUpperBound(int i) const;
113.127 +
113.128 + /// \e
113.129 + virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
113.130 + /// \e
113.131 + virtual void _getObjCoeffs(InsertIterator b) const;
113.132 +
113.133 + /// \e
113.134 + virtual void _setObjCoeff(int i, Value obj_coef);
113.135 + /// \e
113.136 + virtual Value _getObjCoeff(int i) const;
113.137 +
113.138 + ///\e
113.139 + virtual void _setSense(Sense);
113.140 + ///\e
113.141 + virtual Sense _getSense() const;
113.142 +
113.143 + ///\e
113.144 + virtual void _clear();
113.145 +
113.146 + ///\e
113.147 + virtual void _messageLevel(MessageLevel);
113.148 + };
113.149 +
113.150 + /// \brief Skeleton class for an LP solver interface
113.151 + ///
113.152 + ///This class does nothing, but it can serve as a skeleton when
113.153 + ///implementing an interface to new solvers.
113.154 +
113.155 + ///\ingroup lp_group
113.156 + class LpSkeleton : public LpSolver, public SkeletonSolverBase {
113.157 + public:
113.158 + ///\e
113.159 + LpSkeleton() : LpSolver(), SkeletonSolverBase() {}
113.160 + ///\e
113.161 + virtual LpSkeleton* newSolver() const;
113.162 + ///\e
113.163 + virtual LpSkeleton* cloneSolver() const;
113.164 + protected:
113.165 +
113.166 + ///\e
113.167 + virtual SolveExitStatus _solve();
113.168 +
113.169 + ///\e
113.170 + virtual Value _getPrimal(int i) const;
113.171 + ///\e
113.172 + virtual Value _getDual(int i) const;
113.173 +
113.174 + ///\e
113.175 + virtual Value _getPrimalValue() const;
113.176 +
113.177 + ///\e
113.178 + virtual Value _getPrimalRay(int i) const;
113.179 + ///\e
113.180 + virtual Value _getDualRay(int i) const;
113.181 +
113.182 + ///\e
113.183 + virtual ProblemType _getPrimalType() const;
113.184 + ///\e
113.185 + virtual ProblemType _getDualType() const;
113.186 +
113.187 + ///\e
113.188 + virtual VarStatus _getColStatus(int i) const;
113.189 + ///\e
113.190 + virtual VarStatus _getRowStatus(int i) const;
113.191 +
113.192 + ///\e
113.193 + virtual const char* _solverName() const;
113.194 +
113.195 + };
113.196 +
113.197 + /// \brief Skeleton class for a MIP solver interface
113.198 + ///
113.199 + ///This class does nothing, but it can serve as a skeleton when
113.200 + ///implementing an interface to new solvers.
113.201 + ///\ingroup lp_group
113.202 + class MipSkeleton : public MipSolver, public SkeletonSolverBase {
113.203 + public:
113.204 + ///\e
113.205 + MipSkeleton() : MipSolver(), SkeletonSolverBase() {}
113.206 + ///\e
113.207 + virtual MipSkeleton* newSolver() const;
113.208 + ///\e
113.209 + virtual MipSkeleton* cloneSolver() const;
113.210 +
113.211 + protected:
113.212 + ///\e
113.213 + virtual SolveExitStatus _solve();
113.214 +
113.215 + ///\e
113.216 + virtual Value _getSol(int i) const;
113.217 +
113.218 + ///\e
113.219 + virtual Value _getSolValue() const;
113.220 +
113.221 + ///\e
113.222 + virtual ProblemType _getType() const;
113.223 +
113.224 + ///\e
113.225 + virtual const char* _solverName() const;
113.226 + };
113.227 +
113.228 +} //namespace lemon
113.229 +
113.230 +#endif
114.1 --- a/lemon/maps.h Fri Nov 13 12:33:33 2009 +0100
114.2 +++ b/lemon/maps.h Thu Dec 10 17:05:35 2009 +0100
114.3 @@ -2,7 +2,7 @@
114.4 *
114.5 * This file is a part of LEMON, a generic C++ optimization library.
114.6 *
114.7 - * Copyright (C) 2003-2008
114.8 + * Copyright (C) 2003-2009
114.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
114.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
114.11 *
114.12 @@ -63,9 +63,10 @@
114.13 template<typename K, typename V>
114.14 class NullMap : public MapBase<K, V> {
114.15 public:
114.16 - typedef MapBase<K, V> Parent;
114.17 - typedef typename Parent::Key Key;
114.18 - typedef typename Parent::Value Value;
114.19 + ///\e
114.20 + typedef K Key;
114.21 + ///\e
114.22 + typedef V Value;
114.23
114.24 /// Gives back a default constructed element.
114.25 Value operator[](const Key&) const { return Value(); }
114.26 @@ -102,9 +103,10 @@
114.27 private:
114.28 V _value;
114.29 public:
114.30 - typedef MapBase<K, V> Parent;
114.31 - typedef typename Parent::Key Key;
114.32 - typedef typename Parent::Value Value;
114.33 + ///\e
114.34 + typedef K Key;
114.35 + ///\e
114.36 + typedef V Value;
114.37
114.38 /// Default constructor
114.39
114.40 @@ -168,9 +170,10 @@
114.41 template<typename K, typename V, V v>
114.42 class ConstMap<K, Const<V, v> > : public MapBase<K, V> {
114.43 public:
114.44 - typedef MapBase<K, V> Parent;
114.45 - typedef typename Parent::Key Key;
114.46 - typedef typename Parent::Value Value;
114.47 + ///\e
114.48 + typedef K Key;
114.49 + ///\e
114.50 + typedef V Value;
114.51
114.52 /// Constructor.
114.53 ConstMap() {}
114.54 @@ -202,9 +205,10 @@
114.55 template <typename T>
114.56 class IdentityMap : public MapBase<T, T> {
114.57 public:
114.58 - typedef MapBase<T, T> Parent;
114.59 - typedef typename Parent::Key Key;
114.60 - typedef typename Parent::Value Value;
114.61 + ///\e
114.62 + typedef T Key;
114.63 + ///\e
114.64 + typedef T Value;
114.65
114.66 /// Gives back the given value without any modification.
114.67 Value operator[](const Key &k) const {
114.68 @@ -245,11 +249,10 @@
114.69
114.70 public:
114.71
114.72 - typedef MapBase<int, V> Parent;
114.73 /// Key type
114.74 - typedef typename Parent::Key Key;
114.75 + typedef int Key;
114.76 /// Value type
114.77 - typedef typename Parent::Value Value;
114.78 + typedef V Value;
114.79 /// Reference type
114.80 typedef typename Vector::reference Reference;
114.81 /// Const reference type
114.82 @@ -353,17 +356,16 @@
114.83 ///
114.84 /// The simplest way of using this map is through the sparseMap()
114.85 /// function.
114.86 - template <typename K, typename V, typename Compare = std::less<K> >
114.87 + template <typename K, typename V, typename Comp = std::less<K> >
114.88 class SparseMap : public MapBase<K, V> {
114.89 template <typename K1, typename V1, typename C1>
114.90 friend class SparseMap;
114.91 public:
114.92
114.93 - typedef MapBase<K, V> Parent;
114.94 /// Key type
114.95 - typedef typename Parent::Key Key;
114.96 + typedef K Key;
114.97 /// Value type
114.98 - typedef typename Parent::Value Value;
114.99 + typedef V Value;
114.100 /// Reference type
114.101 typedef Value& Reference;
114.102 /// Const reference type
114.103 @@ -373,7 +375,7 @@
114.104
114.105 private:
114.106
114.107 - typedef std::map<K, V, Compare> Map;
114.108 + typedef std::map<K, V, Comp> Map;
114.109 Map _map;
114.110 Value _value;
114.111
114.112 @@ -489,14 +491,15 @@
114.113 const M1 &_m1;
114.114 const M2 &_m2;
114.115 public:
114.116 - typedef MapBase<typename M2::Key, typename M1::Value> Parent;
114.117 - typedef typename Parent::Key Key;
114.118 - typedef typename Parent::Value Value;
114.119 + ///\e
114.120 + typedef typename M2::Key Key;
114.121 + ///\e
114.122 + typedef typename M1::Value Value;
114.123
114.124 /// Constructor
114.125 ComposeMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
114.126
114.127 - /// \e
114.128 + ///\e
114.129 typename MapTraits<M1>::ConstReturnValue
114.130 operator[](const Key &k) const { return _m1[_m2[k]]; }
114.131 };
114.132 @@ -545,14 +548,15 @@
114.133 const M2 &_m2;
114.134 F _f;
114.135 public:
114.136 - typedef MapBase<typename M1::Key, V> Parent;
114.137 - typedef typename Parent::Key Key;
114.138 - typedef typename Parent::Value Value;
114.139 + ///\e
114.140 + typedef typename M1::Key Key;
114.141 + ///\e
114.142 + typedef V Value;
114.143
114.144 /// Constructor
114.145 CombineMap(const M1 &m1, const M2 &m2, const F &f = F())
114.146 : _m1(m1), _m2(m2), _f(f) {}
114.147 - /// \e
114.148 + ///\e
114.149 Value operator[](const Key &k) const { return _f(_m1[k],_m2[k]); }
114.150 };
114.151
114.152 @@ -615,13 +619,14 @@
114.153 class FunctorToMap : public MapBase<K, V> {
114.154 F _f;
114.155 public:
114.156 - typedef MapBase<K, V> Parent;
114.157 - typedef typename Parent::Key Key;
114.158 - typedef typename Parent::Value Value;
114.159 + ///\e
114.160 + typedef K Key;
114.161 + ///\e
114.162 + typedef V Value;
114.163
114.164 /// Constructor
114.165 FunctorToMap(const F &f = F()) : _f(f) {}
114.166 - /// \e
114.167 + ///\e
114.168 Value operator[](const Key &k) const { return _f(k); }
114.169 };
114.170
114.171 @@ -669,18 +674,19 @@
114.172 class MapToFunctor : public MapBase<typename M::Key, typename M::Value> {
114.173 const M &_m;
114.174 public:
114.175 - typedef MapBase<typename M::Key, typename M::Value> Parent;
114.176 - typedef typename Parent::Key Key;
114.177 - typedef typename Parent::Value Value;
114.178 -
114.179 - typedef typename Parent::Key argument_type;
114.180 - typedef typename Parent::Value result_type;
114.181 + ///\e
114.182 + typedef typename M::Key Key;
114.183 + ///\e
114.184 + typedef typename M::Value Value;
114.185 +
114.186 + typedef typename M::Key argument_type;
114.187 + typedef typename M::Value result_type;
114.188
114.189 /// Constructor
114.190 MapToFunctor(const M &m) : _m(m) {}
114.191 - /// \e
114.192 + ///\e
114.193 Value operator()(const Key &k) const { return _m[k]; }
114.194 - /// \e
114.195 + ///\e
114.196 Value operator[](const Key &k) const { return _m[k]; }
114.197 };
114.198
114.199 @@ -709,9 +715,10 @@
114.200 class ConvertMap : public MapBase<typename M::Key, V> {
114.201 const M &_m;
114.202 public:
114.203 - typedef MapBase<typename M::Key, V> Parent;
114.204 - typedef typename Parent::Key Key;
114.205 - typedef typename Parent::Value Value;
114.206 + ///\e
114.207 + typedef typename M::Key Key;
114.208 + ///\e
114.209 + typedef V Value;
114.210
114.211 /// Constructor
114.212
114.213 @@ -719,7 +726,7 @@
114.214 /// \param m The underlying map.
114.215 ConvertMap(const M &m) : _m(m) {}
114.216
114.217 - /// \e
114.218 + ///\e
114.219 Value operator[](const Key &k) const { return _m[k]; }
114.220 };
114.221
114.222 @@ -751,9 +758,10 @@
114.223 M1 &_m1;
114.224 M2 &_m2;
114.225 public:
114.226 - typedef MapBase<typename M1::Key, typename M1::Value> Parent;
114.227 - typedef typename Parent::Key Key;
114.228 - typedef typename Parent::Value Value;
114.229 + ///\e
114.230 + typedef typename M1::Key Key;
114.231 + ///\e
114.232 + typedef typename M1::Value Value;
114.233
114.234 /// Constructor
114.235 ForkMap(M1 &m1, M2 &m2) : _m1(m1), _m2(m2) {}
114.236 @@ -797,13 +805,14 @@
114.237 const M1 &_m1;
114.238 const M2 &_m2;
114.239 public:
114.240 - typedef MapBase<typename M1::Key, typename M1::Value> Parent;
114.241 - typedef typename Parent::Key Key;
114.242 - typedef typename Parent::Value Value;
114.243 + ///\e
114.244 + typedef typename M1::Key Key;
114.245 + ///\e
114.246 + typedef typename M1::Value Value;
114.247
114.248 /// Constructor
114.249 AddMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
114.250 - /// \e
114.251 + ///\e
114.252 Value operator[](const Key &k) const { return _m1[k]+_m2[k]; }
114.253 };
114.254
114.255 @@ -845,13 +854,14 @@
114.256 const M1 &_m1;
114.257 const M2 &_m2;
114.258 public:
114.259 - typedef MapBase<typename M1::Key, typename M1::Value> Parent;
114.260 - typedef typename Parent::Key Key;
114.261 - typedef typename Parent::Value Value;
114.262 + ///\e
114.263 + typedef typename M1::Key Key;
114.264 + ///\e
114.265 + typedef typename M1::Value Value;
114.266
114.267 /// Constructor
114.268 SubMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
114.269 - /// \e
114.270 + ///\e
114.271 Value operator[](const Key &k) const { return _m1[k]-_m2[k]; }
114.272 };
114.273
114.274 @@ -894,13 +904,14 @@
114.275 const M1 &_m1;
114.276 const M2 &_m2;
114.277 public:
114.278 - typedef MapBase<typename M1::Key, typename M1::Value> Parent;
114.279 - typedef typename Parent::Key Key;
114.280 - typedef typename Parent::Value Value;
114.281 + ///\e
114.282 + typedef typename M1::Key Key;
114.283 + ///\e
114.284 + typedef typename M1::Value Value;
114.285
114.286 /// Constructor
114.287 MulMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
114.288 - /// \e
114.289 + ///\e
114.290 Value operator[](const Key &k) const { return _m1[k]*_m2[k]; }
114.291 };
114.292
114.293 @@ -942,13 +953,14 @@
114.294 const M1 &_m1;
114.295 const M2 &_m2;
114.296 public:
114.297 - typedef MapBase<typename M1::Key, typename M1::Value> Parent;
114.298 - typedef typename Parent::Key Key;
114.299 - typedef typename Parent::Value Value;
114.300 + ///\e
114.301 + typedef typename M1::Key Key;
114.302 + ///\e
114.303 + typedef typename M1::Value Value;
114.304
114.305 /// Constructor
114.306 DivMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
114.307 - /// \e
114.308 + ///\e
114.309 Value operator[](const Key &k) const { return _m1[k]/_m2[k]; }
114.310 };
114.311
114.312 @@ -992,9 +1004,10 @@
114.313 const M &_m;
114.314 C _v;
114.315 public:
114.316 - typedef MapBase<typename M::Key, typename M::Value> Parent;
114.317 - typedef typename Parent::Key Key;
114.318 - typedef typename Parent::Value Value;
114.319 + ///\e
114.320 + typedef typename M::Key Key;
114.321 + ///\e
114.322 + typedef typename M::Value Value;
114.323
114.324 /// Constructor
114.325
114.326 @@ -1002,7 +1015,7 @@
114.327 /// \param m The undelying map.
114.328 /// \param v The constant value.
114.329 ShiftMap(const M &m, const C &v) : _m(m), _v(v) {}
114.330 - /// \e
114.331 + ///\e
114.332 Value operator[](const Key &k) const { return _m[k]+_v; }
114.333 };
114.334
114.335 @@ -1022,9 +1035,10 @@
114.336 M &_m;
114.337 C _v;
114.338 public:
114.339 - typedef MapBase<typename M::Key, typename M::Value> Parent;
114.340 - typedef typename Parent::Key Key;
114.341 - typedef typename Parent::Value Value;
114.342 + ///\e
114.343 + typedef typename M::Key Key;
114.344 + ///\e
114.345 + typedef typename M::Value Value;
114.346
114.347 /// Constructor
114.348
114.349 @@ -1032,9 +1046,9 @@
114.350 /// \param m The undelying map.
114.351 /// \param v The constant value.
114.352 ShiftWriteMap(M &m, const C &v) : _m(m), _v(v) {}
114.353 - /// \e
114.354 + ///\e
114.355 Value operator[](const Key &k) const { return _m[k]+_v; }
114.356 - /// \e
114.357 + ///\e
114.358 void set(const Key &k, const Value &v) { _m.set(k, v-_v); }
114.359 };
114.360
114.361 @@ -1093,9 +1107,10 @@
114.362 const M &_m;
114.363 C _v;
114.364 public:
114.365 - typedef MapBase<typename M::Key, typename M::Value> Parent;
114.366 - typedef typename Parent::Key Key;
114.367 - typedef typename Parent::Value Value;
114.368 + ///\e
114.369 + typedef typename M::Key Key;
114.370 + ///\e
114.371 + typedef typename M::Value Value;
114.372
114.373 /// Constructor
114.374
114.375 @@ -1103,7 +1118,7 @@
114.376 /// \param m The undelying map.
114.377 /// \param v The constant value.
114.378 ScaleMap(const M &m, const C &v) : _m(m), _v(v) {}
114.379 - /// \e
114.380 + ///\e
114.381 Value operator[](const Key &k) const { return _v*_m[k]; }
114.382 };
114.383
114.384 @@ -1124,9 +1139,10 @@
114.385 M &_m;
114.386 C _v;
114.387 public:
114.388 - typedef MapBase<typename M::Key, typename M::Value> Parent;
114.389 - typedef typename Parent::Key Key;
114.390 - typedef typename Parent::Value Value;
114.391 + ///\e
114.392 + typedef typename M::Key Key;
114.393 + ///\e
114.394 + typedef typename M::Value Value;
114.395
114.396 /// Constructor
114.397
114.398 @@ -1134,9 +1150,9 @@
114.399 /// \param m The undelying map.
114.400 /// \param v The constant value.
114.401 ScaleWriteMap(M &m, const C &v) : _m(m), _v(v) {}
114.402 - /// \e
114.403 + ///\e
114.404 Value operator[](const Key &k) const { return _v*_m[k]; }
114.405 - /// \e
114.406 + ///\e
114.407 void set(const Key &k, const Value &v) { _m.set(k, v/_v); }
114.408 };
114.409
114.410 @@ -1193,13 +1209,14 @@
114.411 class NegMap : public MapBase<typename M::Key, typename M::Value> {
114.412 const M& _m;
114.413 public:
114.414 - typedef MapBase<typename M::Key, typename M::Value> Parent;
114.415 - typedef typename Parent::Key Key;
114.416 - typedef typename Parent::Value Value;
114.417 + ///\e
114.418 + typedef typename M::Key Key;
114.419 + ///\e
114.420 + typedef typename M::Value Value;
114.421
114.422 /// Constructor
114.423 NegMap(const M &m) : _m(m) {}
114.424 - /// \e
114.425 + ///\e
114.426 Value operator[](const Key &k) const { return -_m[k]; }
114.427 };
114.428
114.429 @@ -1228,15 +1245,16 @@
114.430 class NegWriteMap : public MapBase<typename M::Key, typename M::Value> {
114.431 M &_m;
114.432 public:
114.433 - typedef MapBase<typename M::Key, typename M::Value> Parent;
114.434 - typedef typename Parent::Key Key;
114.435 - typedef typename Parent::Value Value;
114.436 + ///\e
114.437 + typedef typename M::Key Key;
114.438 + ///\e
114.439 + typedef typename M::Value Value;
114.440
114.441 /// Constructor
114.442 NegWriteMap(M &m) : _m(m) {}
114.443 - /// \e
114.444 + ///\e
114.445 Value operator[](const Key &k) const { return -_m[k]; }
114.446 - /// \e
114.447 + ///\e
114.448 void set(const Key &k, const Value &v) { _m.set(k, -v); }
114.449 };
114.450
114.451 @@ -1282,13 +1300,14 @@
114.452 class AbsMap : public MapBase<typename M::Key, typename M::Value> {
114.453 const M &_m;
114.454 public:
114.455 - typedef MapBase<typename M::Key, typename M::Value> Parent;
114.456 - typedef typename Parent::Key Key;
114.457 - typedef typename Parent::Value Value;
114.458 + ///\e
114.459 + typedef typename M::Key Key;
114.460 + ///\e
114.461 + typedef typename M::Value Value;
114.462
114.463 /// Constructor
114.464 AbsMap(const M &m) : _m(m) {}
114.465 - /// \e
114.466 + ///\e
114.467 Value operator[](const Key &k) const {
114.468 Value tmp = _m[k];
114.469 return tmp >= 0 ? tmp : -tmp;
114.470 @@ -1337,9 +1356,10 @@
114.471 template <typename K>
114.472 class TrueMap : public MapBase<K, bool> {
114.473 public:
114.474 - typedef MapBase<K, bool> Parent;
114.475 - typedef typename Parent::Key Key;
114.476 - typedef typename Parent::Value Value;
114.477 + ///\e
114.478 + typedef K Key;
114.479 + ///\e
114.480 + typedef bool Value;
114.481
114.482 /// Gives back \c true.
114.483 Value operator[](const Key&) const { return true; }
114.484 @@ -1374,9 +1394,10 @@
114.485 template <typename K>
114.486 class FalseMap : public MapBase<K, bool> {
114.487 public:
114.488 - typedef MapBase<K, bool> Parent;
114.489 - typedef typename Parent::Key Key;
114.490 - typedef typename Parent::Value Value;
114.491 + ///\e
114.492 + typedef K Key;
114.493 + ///\e
114.494 + typedef bool Value;
114.495
114.496 /// Gives back \c false.
114.497 Value operator[](const Key&) const { return false; }
114.498 @@ -1419,13 +1440,14 @@
114.499 const M1 &_m1;
114.500 const M2 &_m2;
114.501 public:
114.502 - typedef MapBase<typename M1::Key, bool> Parent;
114.503 - typedef typename Parent::Key Key;
114.504 - typedef typename Parent::Value Value;
114.505 + ///\e
114.506 + typedef typename M1::Key Key;
114.507 + ///\e
114.508 + typedef bool Value;
114.509
114.510 /// Constructor
114.511 AndMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
114.512 - /// \e
114.513 + ///\e
114.514 Value operator[](const Key &k) const { return _m1[k]&&_m2[k]; }
114.515 };
114.516
114.517 @@ -1467,13 +1489,14 @@
114.518 const M1 &_m1;
114.519 const M2 &_m2;
114.520 public:
114.521 - typedef MapBase<typename M1::Key, bool> Parent;
114.522 - typedef typename Parent::Key Key;
114.523 - typedef typename Parent::Value Value;
114.524 + ///\e
114.525 + typedef typename M1::Key Key;
114.526 + ///\e
114.527 + typedef bool Value;
114.528
114.529 /// Constructor
114.530 OrMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
114.531 - /// \e
114.532 + ///\e
114.533 Value operator[](const Key &k) const { return _m1[k]||_m2[k]; }
114.534 };
114.535
114.536 @@ -1506,13 +1529,14 @@
114.537 class NotMap : public MapBase<typename M::Key, bool> {
114.538 const M &_m;
114.539 public:
114.540 - typedef MapBase<typename M::Key, bool> Parent;
114.541 - typedef typename Parent::Key Key;
114.542 - typedef typename Parent::Value Value;
114.543 + ///\e
114.544 + typedef typename M::Key Key;
114.545 + ///\e
114.546 + typedef bool Value;
114.547
114.548 /// Constructor
114.549 NotMap(const M &m) : _m(m) {}
114.550 - /// \e
114.551 + ///\e
114.552 Value operator[](const Key &k) const { return !_m[k]; }
114.553 };
114.554
114.555 @@ -1532,15 +1556,16 @@
114.556 class NotWriteMap : public MapBase<typename M::Key, bool> {
114.557 M &_m;
114.558 public:
114.559 - typedef MapBase<typename M::Key, bool> Parent;
114.560 - typedef typename Parent::Key Key;
114.561 - typedef typename Parent::Value Value;
114.562 + ///\e
114.563 + typedef typename M::Key Key;
114.564 + ///\e
114.565 + typedef bool Value;
114.566
114.567 /// Constructor
114.568 NotWriteMap(M &m) : _m(m) {}
114.569 - /// \e
114.570 + ///\e
114.571 Value operator[](const Key &k) const { return !_m[k]; }
114.572 - /// \e
114.573 + ///\e
114.574 void set(const Key &k, bool v) { _m.set(k, !v); }
114.575 };
114.576
114.577 @@ -1595,13 +1620,14 @@
114.578 const M1 &_m1;
114.579 const M2 &_m2;
114.580 public:
114.581 - typedef MapBase<typename M1::Key, bool> Parent;
114.582 - typedef typename Parent::Key Key;
114.583 - typedef typename Parent::Value Value;
114.584 + ///\e
114.585 + typedef typename M1::Key Key;
114.586 + ///\e
114.587 + typedef bool Value;
114.588
114.589 /// Constructor
114.590 EqualMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
114.591 - /// \e
114.592 + ///\e
114.593 Value operator[](const Key &k) const { return _m1[k]==_m2[k]; }
114.594 };
114.595
114.596 @@ -1643,13 +1669,14 @@
114.597 const M1 &_m1;
114.598 const M2 &_m2;
114.599 public:
114.600 - typedef MapBase<typename M1::Key, bool> Parent;
114.601 - typedef typename Parent::Key Key;
114.602 - typedef typename Parent::Value Value;
114.603 + ///\e
114.604 + typedef typename M1::Key Key;
114.605 + ///\e
114.606 + typedef bool Value;
114.607
114.608 /// Constructor
114.609 LessMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
114.610 - /// \e
114.611 + ///\e
114.612 Value operator[](const Key &k) const { return _m1[k]<_m2[k]; }
114.613 };
114.614
114.615 @@ -1705,24 +1732,27 @@
114.616 /// The simplest way of using this map is through the loggerBoolMap()
114.617 /// function.
114.618 ///
114.619 - /// \tparam It The type of the iterator.
114.620 - /// \tparam Ke The key type of the map. The default value set
114.621 + /// \tparam IT The type of the iterator.
114.622 + /// \tparam KEY The key type of the map. The default value set
114.623 /// according to the iterator type should work in most cases.
114.624 ///
114.625 /// \note The container of the iterator must contain enough space
114.626 /// for the elements or the iterator should be an inserter iterator.
114.627 #ifdef DOXYGEN
114.628 - template <typename It, typename Ke>
114.629 + template <typename IT, typename KEY>
114.630 #else
114.631 - template <typename It,
114.632 - typename Ke=typename _maps_bits::IteratorTraits<It>::Value>
114.633 + template <typename IT,
114.634 + typename KEY = typename _maps_bits::IteratorTraits<IT>::Value>
114.635 #endif
114.636 - class LoggerBoolMap {
114.637 + class LoggerBoolMap : public MapBase<KEY, bool> {
114.638 public:
114.639 - typedef It Iterator;
114.640 -
114.641 - typedef Ke Key;
114.642 +
114.643 + ///\e
114.644 + typedef KEY Key;
114.645 + ///\e
114.646 typedef bool Value;
114.647 + ///\e
114.648 + typedef IT Iterator;
114.649
114.650 /// Constructor
114.651 LoggerBoolMap(Iterator it)
114.652 @@ -1785,23 +1815,36 @@
114.653 /// \addtogroup graph_maps
114.654 /// @{
114.655
114.656 - /// Provides an immutable and unique id for each item in the graph.
114.657 -
114.658 - /// The IdMap class provides a unique and immutable id for each item of the
114.659 - /// same type (e.g. node) in the graph. This id is <ul><li>\b unique:
114.660 - /// different items (nodes) get different ids <li>\b immutable: the id of an
114.661 - /// item (node) does not change (even if you delete other nodes). </ul>
114.662 - /// Through this map you get access (i.e. can read) the inner id values of
114.663 - /// the items stored in the graph. This map can be inverted with its member
114.664 + /// \brief Provides an immutable and unique id for each item in a graph.
114.665 + ///
114.666 + /// IdMap provides a unique and immutable id for each item of the
114.667 + /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
114.668 + /// - \b unique: different items get different ids,
114.669 + /// - \b immutable: the id of an item does not change (even if you
114.670 + /// delete other nodes).
114.671 + ///
114.672 + /// Using this map you get access (i.e. can read) the inner id values of
114.673 + /// the items stored in the graph, which is returned by the \c id()
114.674 + /// function of the graph. This map can be inverted with its member
114.675 /// class \c InverseMap or with the \c operator() member.
114.676 ///
114.677 - template <typename _Graph, typename _Item>
114.678 - class IdMap {
114.679 + /// \tparam GR The graph type.
114.680 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
114.681 + /// \c GR::Edge).
114.682 + ///
114.683 + /// \see RangeIdMap
114.684 + template <typename GR, typename K>
114.685 + class IdMap : public MapBase<K, int> {
114.686 public:
114.687 - typedef _Graph Graph;
114.688 + /// The graph type of IdMap.
114.689 + typedef GR Graph;
114.690 + typedef GR Digraph;
114.691 + /// The key type of IdMap (\c Node, \c Arc or \c Edge).
114.692 + typedef K Item;
114.693 + /// The key type of IdMap (\c Node, \c Arc or \c Edge).
114.694 + typedef K Key;
114.695 + /// The value type of IdMap.
114.696 typedef int Value;
114.697 - typedef _Item Item;
114.698 - typedef _Item Key;
114.699
114.700 /// \brief Constructor.
114.701 ///
114.702 @@ -1813,9 +1856,9 @@
114.703 /// Gives back the immutable and unique \e id of the item.
114.704 int operator[](const Item& item) const { return _graph->id(item);}
114.705
114.706 - /// \brief Gives back the item by its id.
114.707 + /// \brief Gives back the \e item by its id.
114.708 ///
114.709 - /// Gives back the item by its id.
114.710 + /// Gives back the \e item by its id.
114.711 Item operator()(int id) { return _graph->fromId(id, Item()); }
114.712
114.713 private:
114.714 @@ -1823,9 +1866,9 @@
114.715
114.716 public:
114.717
114.718 - /// \brief The class represents the inverse of its owner (IdMap).
114.719 + /// \brief This class represents the inverse of its owner (IdMap).
114.720 ///
114.721 - /// The class represents the inverse of its owner (IdMap).
114.722 + /// This class represents the inverse of its owner (IdMap).
114.723 /// \see inverse()
114.724 class InverseMap {
114.725 public:
114.726 @@ -1843,7 +1886,6 @@
114.727 /// \brief Gives back the given item from its id.
114.728 ///
114.729 /// Gives back the given item from its id.
114.730 - ///
114.731 Item operator[](int id) const { return _graph->fromId(id, Item());}
114.732
114.733 private:
114.734 @@ -1854,59 +1896,61 @@
114.735 ///
114.736 /// Gives back the inverse of the IdMap.
114.737 InverseMap inverse() const { return InverseMap(*_graph);}
114.738 -
114.739 };
114.740
114.741
114.742 - /// \brief General invertable graph-map type.
114.743 -
114.744 - /// This type provides simple invertable graph-maps.
114.745 - /// The InvertableMap wraps an arbitrary ReadWriteMap
114.746 + /// \brief General cross reference graph map type.
114.747 +
114.748 + /// This class provides simple invertable graph maps.
114.749 + /// It wraps an arbitrary \ref concepts::ReadWriteMap "ReadWriteMap"
114.750 /// and if a key is set to a new value then store it
114.751 /// in the inverse map.
114.752 ///
114.753 /// The values of the map can be accessed
114.754 /// with stl compatible forward iterator.
114.755 ///
114.756 - /// \tparam _Graph The graph type.
114.757 - /// \tparam _Item The item type of the graph.
114.758 - /// \tparam _Value The value type of the map.
114.759 + /// \tparam GR The graph type.
114.760 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
114.761 + /// \c GR::Edge).
114.762 + /// \tparam V The value type of the map.
114.763 ///
114.764 /// \see IterableValueMap
114.765 - template <typename _Graph, typename _Item, typename _Value>
114.766 - class InvertableMap
114.767 - : protected ItemSetTraits<_Graph, _Item>::template Map<_Value>::Type {
114.768 + template <typename GR, typename K, typename V>
114.769 + class CrossRefMap
114.770 + : protected ItemSetTraits<GR, K>::template Map<V>::Type {
114.771 private:
114.772
114.773 - typedef typename ItemSetTraits<_Graph, _Item>::
114.774 - template Map<_Value>::Type Map;
114.775 - typedef _Graph Graph;
114.776 -
114.777 - typedef std::map<_Value, _Item> Container;
114.778 + typedef typename ItemSetTraits<GR, K>::
114.779 + template Map<V>::Type Map;
114.780 +
114.781 + typedef std::map<V, K> Container;
114.782 Container _inv_map;
114.783
114.784 public:
114.785
114.786 - /// The key type of InvertableMap (Node, Arc, Edge).
114.787 - typedef typename Map::Key Key;
114.788 - /// The value type of the InvertableMap.
114.789 - typedef typename Map::Value Value;
114.790 + /// The graph type of CrossRefMap.
114.791 + typedef GR Graph;
114.792 + typedef GR Digraph;
114.793 + /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
114.794 + typedef K Item;
114.795 + /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
114.796 + typedef K Key;
114.797 + /// The value type of CrossRefMap.
114.798 + typedef V Value;
114.799
114.800 /// \brief Constructor.
114.801 ///
114.802 - /// Construct a new InvertableMap for the graph.
114.803 - ///
114.804 - explicit InvertableMap(const Graph& graph) : Map(graph) {}
114.805 + /// Construct a new CrossRefMap for the given graph.
114.806 + explicit CrossRefMap(const Graph& graph) : Map(graph) {}
114.807
114.808 /// \brief Forward iterator for values.
114.809 ///
114.810 /// This iterator is an stl compatible forward
114.811 /// iterator on the values of the map. The values can
114.812 - /// be accessed in the [beginValue, endValue) range.
114.813 - ///
114.814 + /// be accessed in the <tt>[beginValue, endValue)</tt> range.
114.815 class ValueIterator
114.816 : public std::iterator<std::forward_iterator_tag, Value> {
114.817 - friend class InvertableMap;
114.818 + friend class CrossRefMap;
114.819 private:
114.820 ValueIterator(typename Container::const_iterator _it)
114.821 : it(_it) {}
114.822 @@ -1935,7 +1979,7 @@
114.823 ///
114.824 /// Returns an stl compatible iterator to the
114.825 /// first value of the map. The values of the
114.826 - /// map can be accessed in the [beginValue, endValue)
114.827 + /// map can be accessed in the <tt>[beginValue, endValue)</tt>
114.828 /// range.
114.829 ValueIterator beginValue() const {
114.830 return ValueIterator(_inv_map.begin());
114.831 @@ -1945,15 +1989,15 @@
114.832 ///
114.833 /// Returns an stl compatible iterator after the
114.834 /// last value of the map. The values of the
114.835 - /// map can be accessed in the [beginValue, endValue)
114.836 + /// map can be accessed in the <tt>[beginValue, endValue)</tt>
114.837 /// range.
114.838 ValueIterator endValue() const {
114.839 return ValueIterator(_inv_map.end());
114.840 }
114.841
114.842 - /// \brief The setter function of the map.
114.843 + /// \brief Sets the value associated with the given key.
114.844 ///
114.845 - /// Sets the mapped value.
114.846 + /// Sets the value associated with the given key.
114.847 void set(const Key& key, const Value& val) {
114.848 Value oldval = Map::operator[](key);
114.849 typename Container::iterator it = _inv_map.find(oldval);
114.850 @@ -1964,9 +2008,9 @@
114.851 Map::set(key, val);
114.852 }
114.853
114.854 - /// \brief The getter function of the map.
114.855 + /// \brief Returns the value associated with the given key.
114.856 ///
114.857 - /// It gives back the value associated with the key.
114.858 + /// Returns the value associated with the given key.
114.859 typename MapTraits<Map>::ConstReturnValue
114.860 operator[](const Key& key) const {
114.861 return Map::operator[](key);
114.862 @@ -1982,9 +2026,9 @@
114.863
114.864 protected:
114.865
114.866 - /// \brief Erase the key from the map.
114.867 + /// \brief Erase the key from the map and the inverse map.
114.868 ///
114.869 - /// Erase the key to the map. It is called by the
114.870 + /// Erase the key from the map and the inverse map. It is called by the
114.871 /// \c AlterationNotifier.
114.872 virtual void erase(const Key& key) {
114.873 Value val = Map::operator[](key);
114.874 @@ -1995,9 +2039,9 @@
114.875 Map::erase(key);
114.876 }
114.877
114.878 - /// \brief Erase more keys from the map.
114.879 + /// \brief Erase more keys from the map and the inverse map.
114.880 ///
114.881 - /// Erase more keys from the map. It is called by the
114.882 + /// Erase more keys from the map and the inverse map. It is called by the
114.883 /// \c AlterationNotifier.
114.884 virtual void erase(const std::vector<Key>& keys) {
114.885 for (int i = 0; i < int(keys.size()); ++i) {
114.886 @@ -2010,9 +2054,9 @@
114.887 Map::erase(keys);
114.888 }
114.889
114.890 - /// \brief Clear the keys from the map and inverse map.
114.891 + /// \brief Clear the keys from the map and the inverse map.
114.892 ///
114.893 - /// Clear the keys from the map and inverse map. It is called by the
114.894 + /// Clear the keys from the map and the inverse map. It is called by the
114.895 /// \c AlterationNotifier.
114.896 virtual void clear() {
114.897 _inv_map.clear();
114.898 @@ -2024,76 +2068,84 @@
114.899 /// \brief The inverse map type.
114.900 ///
114.901 /// The inverse of this map. The subscript operator of the map
114.902 - /// gives back always the item what was last assigned to the value.
114.903 + /// gives back the item that was last assigned to the value.
114.904 class InverseMap {
114.905 public:
114.906 - /// \brief Constructor of the InverseMap.
114.907 + /// \brief Constructor
114.908 ///
114.909 /// Constructor of the InverseMap.
114.910 - explicit InverseMap(const InvertableMap& inverted)
114.911 + explicit InverseMap(const CrossRefMap& inverted)
114.912 : _inverted(inverted) {}
114.913
114.914 /// The value type of the InverseMap.
114.915 - typedef typename InvertableMap::Key Value;
114.916 + typedef typename CrossRefMap::Key Value;
114.917 /// The key type of the InverseMap.
114.918 - typedef typename InvertableMap::Value Key;
114.919 + typedef typename CrossRefMap::Value Key;
114.920
114.921 /// \brief Subscript operator.
114.922 ///
114.923 - /// Subscript operator. It gives back always the item
114.924 - /// what was last assigned to the value.
114.925 + /// Subscript operator. It gives back the item
114.926 + /// that was last assigned to the given value.
114.927 Value operator[](const Key& key) const {
114.928 return _inverted(key);
114.929 }
114.930
114.931 private:
114.932 - const InvertableMap& _inverted;
114.933 + const CrossRefMap& _inverted;
114.934 };
114.935
114.936 - /// \brief It gives back the just readable inverse map.
114.937 + /// \brief It gives back the read-only inverse map.
114.938 ///
114.939 - /// It gives back the just readable inverse map.
114.940 + /// It gives back the read-only inverse map.
114.941 InverseMap inverse() const {
114.942 return InverseMap(*this);
114.943 }
114.944
114.945 };
114.946
114.947 - /// \brief Provides a mutable, continuous and unique descriptor for each
114.948 - /// item in the graph.
114.949 + /// \brief Provides continuous and unique ID for the
114.950 + /// items of a graph.
114.951 ///
114.952 - /// The DescriptorMap class provides a unique and continuous (but mutable)
114.953 - /// descriptor (id) for each item of the same type (e.g. node) in the
114.954 - /// graph. This id is <ul><li>\b unique: different items (nodes) get
114.955 - /// different ids <li>\b continuous: the range of the ids is the set of
114.956 - /// integers between 0 and \c n-1, where \c n is the number of the items of
114.957 - /// this type (e.g. nodes) (so the id of a node can change if you delete an
114.958 - /// other node, i.e. this id is mutable). </ul> This map can be inverted
114.959 - /// with its member class \c InverseMap, or with the \c operator() member.
114.960 + /// RangeIdMap provides a unique and continuous
114.961 + /// ID for each item of a given type (\c Node, \c Arc or
114.962 + /// \c Edge) in a graph. This id is
114.963 + /// - \b unique: different items get different ids,
114.964 + /// - \b continuous: the range of the ids is the set of integers
114.965 + /// between 0 and \c n-1, where \c n is the number of the items of
114.966 + /// this type (\c Node, \c Arc or \c Edge).
114.967 + /// - So, the ids can change when deleting an item of the same type.
114.968 ///
114.969 - /// \tparam _Graph The graph class the \c DescriptorMap belongs to.
114.970 - /// \tparam _Item The Item is the Key of the Map. It may be Node, Arc or
114.971 - /// Edge.
114.972 - template <typename _Graph, typename _Item>
114.973 - class DescriptorMap
114.974 - : protected ItemSetTraits<_Graph, _Item>::template Map<int>::Type {
114.975 -
114.976 - typedef _Item Item;
114.977 - typedef typename ItemSetTraits<_Graph, _Item>::template Map<int>::Type Map;
114.978 + /// Thus this id is not (necessarily) the same as what can get using
114.979 + /// the \c id() function of the graph or \ref IdMap.
114.980 + /// This map can be inverted with its member class \c InverseMap,
114.981 + /// or with the \c operator() member.
114.982 + ///
114.983 + /// \tparam GR The graph type.
114.984 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
114.985 + /// \c GR::Edge).
114.986 + ///
114.987 + /// \see IdMap
114.988 + template <typename GR, typename K>
114.989 + class RangeIdMap
114.990 + : protected ItemSetTraits<GR, K>::template Map<int>::Type {
114.991 +
114.992 + typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Map;
114.993
114.994 public:
114.995 - /// The graph class of DescriptorMap.
114.996 - typedef _Graph Graph;
114.997 -
114.998 - /// The key type of DescriptorMap (Node, Arc, Edge).
114.999 - typedef typename Map::Key Key;
114.1000 - /// The value type of DescriptorMap.
114.1001 - typedef typename Map::Value Value;
114.1002 + /// The graph type of RangeIdMap.
114.1003 + typedef GR Graph;
114.1004 + typedef GR Digraph;
114.1005 + /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
114.1006 + typedef K Item;
114.1007 + /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
114.1008 + typedef K Key;
114.1009 + /// The value type of RangeIdMap.
114.1010 + typedef int Value;
114.1011
114.1012 /// \brief Constructor.
114.1013 ///
114.1014 - /// Constructor for descriptor map.
114.1015 - explicit DescriptorMap(const Graph& _graph) : Map(_graph) {
114.1016 + /// Constructor.
114.1017 + explicit RangeIdMap(const Graph& gr) : Map(gr) {
114.1018 Item it;
114.1019 const typename Map::Notifier* nf = Map::notifier();
114.1020 for (nf->first(it); it != INVALID; nf->next(it)) {
114.1021 @@ -2104,7 +2156,7 @@
114.1022
114.1023 protected:
114.1024
114.1025 - /// \brief Add a new key to the map.
114.1026 + /// \brief Adds a new key to the map.
114.1027 ///
114.1028 /// Add a new key to the map. It is called by the
114.1029 /// \c AlterationNotifier.
114.1030 @@ -2194,16 +2246,16 @@
114.1031 _inv_map[pi] = q;
114.1032 }
114.1033
114.1034 - /// \brief Gives back the \e descriptor of the item.
114.1035 + /// \brief Gives back the \e RangeId of the item
114.1036 ///
114.1037 - /// Gives back the mutable and unique \e descriptor of the map.
114.1038 + /// Gives back the \e RangeId of the item.
114.1039 int operator[](const Item& item) const {
114.1040 return Map::operator[](item);
114.1041 }
114.1042
114.1043 - /// \brief Gives back the item by its descriptor.
114.1044 - ///
114.1045 - /// Gives back th item by its descriptor.
114.1046 + /// \brief Gives back the item belonging to a \e RangeId
114.1047 + ///
114.1048 + /// Gives back the item belonging to a \e RangeId.
114.1049 Item operator()(int id) const {
114.1050 return _inv_map[id];
114.1051 }
114.1052 @@ -2214,27 +2266,28 @@
114.1053 Container _inv_map;
114.1054
114.1055 public:
114.1056 - /// \brief The inverse map type of DescriptorMap.
114.1057 +
114.1058 + /// \brief The inverse map type of RangeIdMap.
114.1059 ///
114.1060 - /// The inverse map type of DescriptorMap.
114.1061 + /// The inverse map type of RangeIdMap.
114.1062 class InverseMap {
114.1063 public:
114.1064 - /// \brief Constructor of the InverseMap.
114.1065 + /// \brief Constructor
114.1066 ///
114.1067 /// Constructor of the InverseMap.
114.1068 - explicit InverseMap(const DescriptorMap& inverted)
114.1069 + explicit InverseMap(const RangeIdMap& inverted)
114.1070 : _inverted(inverted) {}
114.1071
114.1072
114.1073 /// The value type of the InverseMap.
114.1074 - typedef typename DescriptorMap::Key Value;
114.1075 + typedef typename RangeIdMap::Key Value;
114.1076 /// The key type of the InverseMap.
114.1077 - typedef typename DescriptorMap::Value Key;
114.1078 + typedef typename RangeIdMap::Value Key;
114.1079
114.1080 /// \brief Subscript operator.
114.1081 ///
114.1082 /// Subscript operator. It gives back the item
114.1083 - /// that the descriptor belongs to currently.
114.1084 + /// that the descriptor currently belongs to.
114.1085 Value operator[](const Key& key) const {
114.1086 return _inverted(key);
114.1087 }
114.1088 @@ -2247,7 +2300,7 @@
114.1089 }
114.1090
114.1091 private:
114.1092 - const DescriptorMap& _inverted;
114.1093 + const RangeIdMap& _inverted;
114.1094 };
114.1095
114.1096 /// \brief Gives back the inverse of the map.
114.1097 @@ -2258,230 +2311,199 @@
114.1098 }
114.1099 };
114.1100
114.1101 - /// \brief Returns the source of the given arc.
114.1102 + /// \brief Map of the source nodes of arcs in a digraph.
114.1103 ///
114.1104 - /// The SourceMap gives back the source Node of the given arc.
114.1105 + /// SourceMap provides access for the source node of each arc in a digraph,
114.1106 + /// which is returned by the \c source() function of the digraph.
114.1107 + /// \tparam GR The digraph type.
114.1108 /// \see TargetMap
114.1109 - template <typename Digraph>
114.1110 + template <typename GR>
114.1111 class SourceMap {
114.1112 public:
114.1113
114.1114 - typedef typename Digraph::Node Value;
114.1115 - typedef typename Digraph::Arc Key;
114.1116 + ///\e
114.1117 + typedef typename GR::Arc Key;
114.1118 + ///\e
114.1119 + typedef typename GR::Node Value;
114.1120
114.1121 /// \brief Constructor
114.1122 ///
114.1123 - /// Constructor
114.1124 + /// Constructor.
114.1125 /// \param digraph The digraph that the map belongs to.
114.1126 - explicit SourceMap(const Digraph& digraph) : _digraph(digraph) {}
114.1127 -
114.1128 - /// \brief The subscript operator.
114.1129 + explicit SourceMap(const GR& digraph) : _graph(digraph) {}
114.1130 +
114.1131 + /// \brief Returns the source node of the given arc.
114.1132 ///
114.1133 - /// The subscript operator.
114.1134 - /// \param arc The arc
114.1135 - /// \return The source of the arc
114.1136 + /// Returns the source node of the given arc.
114.1137 Value operator[](const Key& arc) const {
114.1138 - return _digraph.source(arc);
114.1139 + return _graph.source(arc);
114.1140 }
114.1141
114.1142 private:
114.1143 - const Digraph& _digraph;
114.1144 + const GR& _graph;
114.1145 };
114.1146
114.1147 /// \brief Returns a \c SourceMap class.
114.1148 ///
114.1149 /// This function just returns an \c SourceMap class.
114.1150 /// \relates SourceMap
114.1151 - template <typename Digraph>
114.1152 - inline SourceMap<Digraph> sourceMap(const Digraph& digraph) {
114.1153 - return SourceMap<Digraph>(digraph);
114.1154 + template <typename GR>
114.1155 + inline SourceMap<GR> sourceMap(const GR& graph) {
114.1156 + return SourceMap<GR>(graph);
114.1157 }
114.1158
114.1159 - /// \brief Returns the target of the given arc.
114.1160 + /// \brief Map of the target nodes of arcs in a digraph.
114.1161 ///
114.1162 - /// The TargetMap gives back the target Node of the given arc.
114.1163 + /// TargetMap provides access for the target node of each arc in a digraph,
114.1164 + /// which is returned by the \c target() function of the digraph.
114.1165 + /// \tparam GR The digraph type.
114.1166 /// \see SourceMap
114.1167 - template <typename Digraph>
114.1168 + template <typename GR>
114.1169 class TargetMap {
114.1170 public:
114.1171
114.1172 - typedef typename Digraph::Node Value;
114.1173 - typedef typename Digraph::Arc Key;
114.1174 + ///\e
114.1175 + typedef typename GR::Arc Key;
114.1176 + ///\e
114.1177 + typedef typename GR::Node Value;
114.1178
114.1179 /// \brief Constructor
114.1180 ///
114.1181 - /// Constructor
114.1182 + /// Constructor.
114.1183 /// \param digraph The digraph that the map belongs to.
114.1184 - explicit TargetMap(const Digraph& digraph) : _digraph(digraph) {}
114.1185 -
114.1186 - /// \brief The subscript operator.
114.1187 + explicit TargetMap(const GR& digraph) : _graph(digraph) {}
114.1188 +
114.1189 + /// \brief Returns the target node of the given arc.
114.1190 ///
114.1191 - /// The subscript operator.
114.1192 - /// \param e The arc
114.1193 - /// \return The target of the arc
114.1194 + /// Returns the target node of the given arc.
114.1195 Value operator[](const Key& e) const {
114.1196 - return _digraph.target(e);
114.1197 + return _graph.target(e);
114.1198 }
114.1199
114.1200 private:
114.1201 - const Digraph& _digraph;
114.1202 + const GR& _graph;
114.1203 };
114.1204
114.1205 /// \brief Returns a \c TargetMap class.
114.1206 ///
114.1207 /// This function just returns a \c TargetMap class.
114.1208 /// \relates TargetMap
114.1209 - template <typename Digraph>
114.1210 - inline TargetMap<Digraph> targetMap(const Digraph& digraph) {
114.1211 - return TargetMap<Digraph>(digraph);
114.1212 + template <typename GR>
114.1213 + inline TargetMap<GR> targetMap(const GR& graph) {
114.1214 + return TargetMap<GR>(graph);
114.1215 }
114.1216
114.1217 - /// \brief Returns the "forward" directed arc view of an edge.
114.1218 + /// \brief Map of the "forward" directed arc view of edges in a graph.
114.1219 ///
114.1220 - /// Returns the "forward" directed arc view of an edge.
114.1221 + /// ForwardMap provides access for the "forward" directed arc view of
114.1222 + /// each edge in a graph, which is returned by the \c direct() function
114.1223 + /// of the graph with \c true parameter.
114.1224 + /// \tparam GR The graph type.
114.1225 /// \see BackwardMap
114.1226 - template <typename Graph>
114.1227 + template <typename GR>
114.1228 class ForwardMap {
114.1229 public:
114.1230
114.1231 - typedef typename Graph::Arc Value;
114.1232 - typedef typename Graph::Edge Key;
114.1233 + typedef typename GR::Arc Value;
114.1234 + typedef typename GR::Edge Key;
114.1235
114.1236 /// \brief Constructor
114.1237 ///
114.1238 - /// Constructor
114.1239 + /// Constructor.
114.1240 /// \param graph The graph that the map belongs to.
114.1241 - explicit ForwardMap(const Graph& graph) : _graph(graph) {}
114.1242 -
114.1243 - /// \brief The subscript operator.
114.1244 + explicit ForwardMap(const GR& graph) : _graph(graph) {}
114.1245 +
114.1246 + /// \brief Returns the "forward" directed arc view of the given edge.
114.1247 ///
114.1248 - /// The subscript operator.
114.1249 - /// \param key An edge
114.1250 - /// \return The "forward" directed arc view of edge
114.1251 + /// Returns the "forward" directed arc view of the given edge.
114.1252 Value operator[](const Key& key) const {
114.1253 return _graph.direct(key, true);
114.1254 }
114.1255
114.1256 private:
114.1257 - const Graph& _graph;
114.1258 + const GR& _graph;
114.1259 };
114.1260
114.1261 /// \brief Returns a \c ForwardMap class.
114.1262 ///
114.1263 /// This function just returns an \c ForwardMap class.
114.1264 /// \relates ForwardMap
114.1265 - template <typename Graph>
114.1266 - inline ForwardMap<Graph> forwardMap(const Graph& graph) {
114.1267 - return ForwardMap<Graph>(graph);
114.1268 + template <typename GR>
114.1269 + inline ForwardMap<GR> forwardMap(const GR& graph) {
114.1270 + return ForwardMap<GR>(graph);
114.1271 }
114.1272
114.1273 - /// \brief Returns the "backward" directed arc view of an edge.
114.1274 + /// \brief Map of the "backward" directed arc view of edges in a graph.
114.1275 ///
114.1276 - /// Returns the "backward" directed arc view of an edge.
114.1277 + /// BackwardMap provides access for the "backward" directed arc view of
114.1278 + /// each edge in a graph, which is returned by the \c direct() function
114.1279 + /// of the graph with \c false parameter.
114.1280 + /// \tparam GR The graph type.
114.1281 /// \see ForwardMap
114.1282 - template <typename Graph>
114.1283 + template <typename GR>
114.1284 class BackwardMap {
114.1285 public:
114.1286
114.1287 - typedef typename Graph::Arc Value;
114.1288 - typedef typename Graph::Edge Key;
114.1289 + typedef typename GR::Arc Value;
114.1290 + typedef typename GR::Edge Key;
114.1291
114.1292 /// \brief Constructor
114.1293 ///
114.1294 - /// Constructor
114.1295 + /// Constructor.
114.1296 /// \param graph The graph that the map belongs to.
114.1297 - explicit BackwardMap(const Graph& graph) : _graph(graph) {}
114.1298 -
114.1299 - /// \brief The subscript operator.
114.1300 + explicit BackwardMap(const GR& graph) : _graph(graph) {}
114.1301 +
114.1302 + /// \brief Returns the "backward" directed arc view of the given edge.
114.1303 ///
114.1304 - /// The subscript operator.
114.1305 - /// \param key An edge
114.1306 - /// \return The "backward" directed arc view of edge
114.1307 + /// Returns the "backward" directed arc view of the given edge.
114.1308 Value operator[](const Key& key) const {
114.1309 return _graph.direct(key, false);
114.1310 }
114.1311
114.1312 private:
114.1313 - const Graph& _graph;
114.1314 + const GR& _graph;
114.1315 };
114.1316
114.1317 /// \brief Returns a \c BackwardMap class
114.1318
114.1319 /// This function just returns a \c BackwardMap class.
114.1320 /// \relates BackwardMap
114.1321 - template <typename Graph>
114.1322 - inline BackwardMap<Graph> backwardMap(const Graph& graph) {
114.1323 - return BackwardMap<Graph>(graph);
114.1324 + template <typename GR>
114.1325 + inline BackwardMap<GR> backwardMap(const GR& graph) {
114.1326 + return BackwardMap<GR>(graph);
114.1327 }
114.1328
114.1329 - /// \brief Potential difference map
114.1330 - ///
114.1331 - /// If there is an potential map on the nodes then we
114.1332 - /// can get an arc map as we get the substraction of the
114.1333 - /// values of the target and source.
114.1334 - template <typename Digraph, typename NodeMap>
114.1335 - class PotentialDifferenceMap {
114.1336 - public:
114.1337 - typedef typename Digraph::Arc Key;
114.1338 - typedef typename NodeMap::Value Value;
114.1339 -
114.1340 - /// \brief Constructor
114.1341 - ///
114.1342 - /// Contructor of the map
114.1343 - explicit PotentialDifferenceMap(const Digraph& digraph,
114.1344 - const NodeMap& potential)
114.1345 - : _digraph(digraph), _potential(potential) {}
114.1346 -
114.1347 - /// \brief Const subscription operator
114.1348 - ///
114.1349 - /// Const subscription operator
114.1350 - Value operator[](const Key& arc) const {
114.1351 - return _potential[_digraph.target(arc)] -
114.1352 - _potential[_digraph.source(arc)];
114.1353 - }
114.1354 -
114.1355 - private:
114.1356 - const Digraph& _digraph;
114.1357 - const NodeMap& _potential;
114.1358 - };
114.1359 -
114.1360 - /// \brief Returns a PotentialDifferenceMap.
114.1361 - ///
114.1362 - /// This function just returns a PotentialDifferenceMap.
114.1363 - /// \relates PotentialDifferenceMap
114.1364 - template <typename Digraph, typename NodeMap>
114.1365 - PotentialDifferenceMap<Digraph, NodeMap>
114.1366 - potentialDifferenceMap(const Digraph& digraph, const NodeMap& potential) {
114.1367 - return PotentialDifferenceMap<Digraph, NodeMap>(digraph, potential);
114.1368 - }
114.1369 -
114.1370 - /// \brief Map of the node in-degrees.
114.1371 + /// \brief Map of the in-degrees of nodes in a digraph.
114.1372 ///
114.1373 /// This map returns the in-degree of a node. Once it is constructed,
114.1374 - /// the degrees are stored in a standard NodeMap, so each query is done
114.1375 + /// the degrees are stored in a standard \c NodeMap, so each query is done
114.1376 /// in constant time. On the other hand, the values are updated automatically
114.1377 /// whenever the digraph changes.
114.1378 ///
114.1379 - /// \warning Besides addNode() and addArc(), a digraph structure may provide
114.1380 - /// alternative ways to modify the digraph. The correct behavior of InDegMap
114.1381 - /// is not guarantied if these additional features are used. For example
114.1382 - /// the functions \ref ListDigraph::changeSource() "changeSource()",
114.1383 + /// \warning Besides \c addNode() and \c addArc(), a digraph structure
114.1384 + /// may provide alternative ways to modify the digraph.
114.1385 + /// The correct behavior of InDegMap is not guarantied if these additional
114.1386 + /// features are used. For example the functions
114.1387 + /// \ref ListDigraph::changeSource() "changeSource()",
114.1388 /// \ref ListDigraph::changeTarget() "changeTarget()" and
114.1389 /// \ref ListDigraph::reverseArc() "reverseArc()"
114.1390 /// of \ref ListDigraph will \e not update the degree values correctly.
114.1391 ///
114.1392 /// \sa OutDegMap
114.1393 -
114.1394 - template <typename _Digraph>
114.1395 + template <typename GR>
114.1396 class InDegMap
114.1397 - : protected ItemSetTraits<_Digraph, typename _Digraph::Arc>
114.1398 + : protected ItemSetTraits<GR, typename GR::Arc>
114.1399 ::ItemNotifier::ObserverBase {
114.1400
114.1401 public:
114.1402 -
114.1403 - typedef _Digraph Digraph;
114.1404 +
114.1405 + /// The graph type of InDegMap
114.1406 + typedef GR Graph;
114.1407 + typedef GR Digraph;
114.1408 + /// The key type
114.1409 + typedef typename Digraph::Node Key;
114.1410 + /// The value type
114.1411 typedef int Value;
114.1412 - typedef typename Digraph::Node Key;
114.1413
114.1414 typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
114.1415 ::ItemNotifier::ObserverBase Parent;
114.1416 @@ -2523,9 +2545,9 @@
114.1417
114.1418 /// \brief Constructor.
114.1419 ///
114.1420 - /// Constructor for creating in-degree map.
114.1421 - explicit InDegMap(const Digraph& digraph)
114.1422 - : _digraph(digraph), _deg(digraph) {
114.1423 + /// Constructor for creating an in-degree map.
114.1424 + explicit InDegMap(const Digraph& graph)
114.1425 + : _digraph(graph), _deg(graph) {
114.1426 Parent::attach(_digraph.notifier(typename Digraph::Arc()));
114.1427
114.1428 for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
114.1429 @@ -2533,6 +2555,8 @@
114.1430 }
114.1431 }
114.1432
114.1433 + /// \brief Gives back the in-degree of a Node.
114.1434 + ///
114.1435 /// Gives back the in-degree of a Node.
114.1436 int operator[](const Key& key) const {
114.1437 return _deg[key];
114.1438 @@ -2579,33 +2603,37 @@
114.1439 AutoNodeMap _deg;
114.1440 };
114.1441
114.1442 - /// \brief Map of the node out-degrees.
114.1443 + /// \brief Map of the out-degrees of nodes in a digraph.
114.1444 ///
114.1445 /// This map returns the out-degree of a node. Once it is constructed,
114.1446 - /// the degrees are stored in a standard NodeMap, so each query is done
114.1447 + /// the degrees are stored in a standard \c NodeMap, so each query is done
114.1448 /// in constant time. On the other hand, the values are updated automatically
114.1449 /// whenever the digraph changes.
114.1450 ///
114.1451 - /// \warning Besides addNode() and addArc(), a digraph structure may provide
114.1452 - /// alternative ways to modify the digraph. The correct behavior of OutDegMap
114.1453 - /// is not guarantied if these additional features are used. For example
114.1454 - /// the functions \ref ListDigraph::changeSource() "changeSource()",
114.1455 + /// \warning Besides \c addNode() and \c addArc(), a digraph structure
114.1456 + /// may provide alternative ways to modify the digraph.
114.1457 + /// The correct behavior of OutDegMap is not guarantied if these additional
114.1458 + /// features are used. For example the functions
114.1459 + /// \ref ListDigraph::changeSource() "changeSource()",
114.1460 /// \ref ListDigraph::changeTarget() "changeTarget()" and
114.1461 /// \ref ListDigraph::reverseArc() "reverseArc()"
114.1462 /// of \ref ListDigraph will \e not update the degree values correctly.
114.1463 ///
114.1464 /// \sa InDegMap
114.1465 -
114.1466 - template <typename _Digraph>
114.1467 + template <typename GR>
114.1468 class OutDegMap
114.1469 - : protected ItemSetTraits<_Digraph, typename _Digraph::Arc>
114.1470 + : protected ItemSetTraits<GR, typename GR::Arc>
114.1471 ::ItemNotifier::ObserverBase {
114.1472
114.1473 public:
114.1474
114.1475 - typedef _Digraph Digraph;
114.1476 + /// The graph type of OutDegMap
114.1477 + typedef GR Graph;
114.1478 + typedef GR Digraph;
114.1479 + /// The key type
114.1480 + typedef typename Digraph::Node Key;
114.1481 + /// The value type
114.1482 typedef int Value;
114.1483 - typedef typename Digraph::Node Key;
114.1484
114.1485 typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
114.1486 ::ItemNotifier::ObserverBase Parent;
114.1487 @@ -2645,9 +2673,9 @@
114.1488
114.1489 /// \brief Constructor.
114.1490 ///
114.1491 - /// Constructor for creating out-degree map.
114.1492 - explicit OutDegMap(const Digraph& digraph)
114.1493 - : _digraph(digraph), _deg(digraph) {
114.1494 + /// Constructor for creating an out-degree map.
114.1495 + explicit OutDegMap(const Digraph& graph)
114.1496 + : _digraph(graph), _deg(graph) {
114.1497 Parent::attach(_digraph.notifier(typename Digraph::Arc()));
114.1498
114.1499 for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
114.1500 @@ -2655,6 +2683,8 @@
114.1501 }
114.1502 }
114.1503
114.1504 + /// \brief Gives back the out-degree of a Node.
114.1505 + ///
114.1506 /// Gives back the out-degree of a Node.
114.1507 int operator[](const Key& key) const {
114.1508 return _deg[key];
114.1509 @@ -2701,6 +2731,56 @@
114.1510 AutoNodeMap _deg;
114.1511 };
114.1512
114.1513 + /// \brief Potential difference map
114.1514 + ///
114.1515 + /// PotentialDifferenceMap returns the difference between the potentials of
114.1516 + /// the source and target nodes of each arc in a digraph, i.e. it returns
114.1517 + /// \code
114.1518 + /// potential[gr.target(arc)] - potential[gr.source(arc)].
114.1519 + /// \endcode
114.1520 + /// \tparam GR The digraph type.
114.1521 + /// \tparam POT A node map storing the potentials.
114.1522 + template <typename GR, typename POT>
114.1523 + class PotentialDifferenceMap {
114.1524 + public:
114.1525 + /// Key type
114.1526 + typedef typename GR::Arc Key;
114.1527 + /// Value type
114.1528 + typedef typename POT::Value Value;
114.1529 +
114.1530 + /// \brief Constructor
114.1531 + ///
114.1532 + /// Contructor of the map.
114.1533 + explicit PotentialDifferenceMap(const GR& gr,
114.1534 + const POT& potential)
114.1535 + : _digraph(gr), _potential(potential) {}
114.1536 +
114.1537 + /// \brief Returns the potential difference for the given arc.
114.1538 + ///
114.1539 + /// Returns the potential difference for the given arc, i.e.
114.1540 + /// \code
114.1541 + /// potential[gr.target(arc)] - potential[gr.source(arc)].
114.1542 + /// \endcode
114.1543 + Value operator[](const Key& arc) const {
114.1544 + return _potential[_digraph.target(arc)] -
114.1545 + _potential[_digraph.source(arc)];
114.1546 + }
114.1547 +
114.1548 + private:
114.1549 + const GR& _digraph;
114.1550 + const POT& _potential;
114.1551 + };
114.1552 +
114.1553 + /// \brief Returns a PotentialDifferenceMap.
114.1554 + ///
114.1555 + /// This function just returns a PotentialDifferenceMap.
114.1556 + /// \relates PotentialDifferenceMap
114.1557 + template <typename GR, typename POT>
114.1558 + PotentialDifferenceMap<GR, POT>
114.1559 + potentialDifferenceMap(const GR& gr, const POT& potential) {
114.1560 + return PotentialDifferenceMap<GR, POT>(gr, potential);
114.1561 + }
114.1562 +
114.1563 /// @}
114.1564 }
114.1565
115.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
115.2 +++ b/lemon/matching.h Thu Dec 10 17:05:35 2009 +0100
115.3 @@ -0,0 +1,3244 @@
115.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
115.5 + *
115.6 + * This file is a part of LEMON, a generic C++ optimization library.
115.7 + *
115.8 + * Copyright (C) 2003-2009
115.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
115.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
115.11 + *
115.12 + * Permission to use, modify and distribute this software is granted
115.13 + * provided that this copyright notice appears in all copies. For
115.14 + * precise terms see the accompanying LICENSE file.
115.15 + *
115.16 + * This software is provided "AS IS" with no warranty of any kind,
115.17 + * express or implied, and with no claim as to its suitability for any
115.18 + * purpose.
115.19 + *
115.20 + */
115.21 +
115.22 +#ifndef LEMON_MAX_MATCHING_H
115.23 +#define LEMON_MAX_MATCHING_H
115.24 +
115.25 +#include <vector>
115.26 +#include <queue>
115.27 +#include <set>
115.28 +#include <limits>
115.29 +
115.30 +#include <lemon/core.h>
115.31 +#include <lemon/unionfind.h>
115.32 +#include <lemon/bin_heap.h>
115.33 +#include <lemon/maps.h>
115.34 +
115.35 +///\ingroup matching
115.36 +///\file
115.37 +///\brief Maximum matching algorithms in general graphs.
115.38 +
115.39 +namespace lemon {
115.40 +
115.41 + /// \ingroup matching
115.42 + ///
115.43 + /// \brief Maximum cardinality matching in general graphs
115.44 + ///
115.45 + /// This class implements Edmonds' alternating forest matching algorithm
115.46 + /// for finding a maximum cardinality matching in a general undirected graph.
115.47 + /// It can be started from an arbitrary initial matching
115.48 + /// (the default is the empty one).
115.49 + ///
115.50 + /// The dual solution of the problem is a map of the nodes to
115.51 + /// \ref MaxMatching::Status "Status", having values \c EVEN (or \c D),
115.52 + /// \c ODD (or \c A) and \c MATCHED (or \c C) defining the Gallai-Edmonds
115.53 + /// decomposition of the graph. The nodes in \c EVEN/D induce a subgraph
115.54 + /// with factor-critical components, the nodes in \c ODD/A form the
115.55 + /// canonical barrier, and the nodes in \c MATCHED/C induce a graph having
115.56 + /// a perfect matching. The number of the factor-critical components
115.57 + /// minus the number of barrier nodes is a lower bound on the
115.58 + /// unmatched nodes, and the matching is optimal if and only if this bound is
115.59 + /// tight. This decomposition can be obtained using \ref status() or
115.60 + /// \ref statusMap() after running the algorithm.
115.61 + ///
115.62 + /// \tparam GR The undirected graph type the algorithm runs on.
115.63 + template <typename GR>
115.64 + class MaxMatching {
115.65 + public:
115.66 +
115.67 + /// The graph type of the algorithm
115.68 + typedef GR Graph;
115.69 + /// The type of the matching map
115.70 + typedef typename Graph::template NodeMap<typename Graph::Arc>
115.71 + MatchingMap;
115.72 +
115.73 + ///\brief Status constants for Gallai-Edmonds decomposition.
115.74 + ///
115.75 + ///These constants are used for indicating the Gallai-Edmonds
115.76 + ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
115.77 + ///induce a subgraph with factor-critical components, the nodes with
115.78 + ///status \c ODD (or \c A) form the canonical barrier, and the nodes
115.79 + ///with status \c MATCHED (or \c C) induce a subgraph having a
115.80 + ///perfect matching.
115.81 + enum Status {
115.82 + EVEN = 1, ///< = 1. (\c D is an alias for \c EVEN.)
115.83 + D = 1,
115.84 + MATCHED = 0, ///< = 0. (\c C is an alias for \c MATCHED.)
115.85 + C = 0,
115.86 + ODD = -1, ///< = -1. (\c A is an alias for \c ODD.)
115.87 + A = -1,
115.88 + UNMATCHED = -2 ///< = -2.
115.89 + };
115.90 +
115.91 + /// The type of the status map
115.92 + typedef typename Graph::template NodeMap<Status> StatusMap;
115.93 +
115.94 + private:
115.95 +
115.96 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
115.97 +
115.98 + typedef UnionFindEnum<IntNodeMap> BlossomSet;
115.99 + typedef ExtendFindEnum<IntNodeMap> TreeSet;
115.100 + typedef RangeMap<Node> NodeIntMap;
115.101 + typedef MatchingMap EarMap;
115.102 + typedef std::vector<Node> NodeQueue;
115.103 +
115.104 + const Graph& _graph;
115.105 + MatchingMap* _matching;
115.106 + StatusMap* _status;
115.107 +
115.108 + EarMap* _ear;
115.109 +
115.110 + IntNodeMap* _blossom_set_index;
115.111 + BlossomSet* _blossom_set;
115.112 + NodeIntMap* _blossom_rep;
115.113 +
115.114 + IntNodeMap* _tree_set_index;
115.115 + TreeSet* _tree_set;
115.116 +
115.117 + NodeQueue _node_queue;
115.118 + int _process, _postpone, _last;
115.119 +
115.120 + int _node_num;
115.121 +
115.122 + private:
115.123 +
115.124 + void createStructures() {
115.125 + _node_num = countNodes(_graph);
115.126 + if (!_matching) {
115.127 + _matching = new MatchingMap(_graph);
115.128 + }
115.129 + if (!_status) {
115.130 + _status = new StatusMap(_graph);
115.131 + }
115.132 + if (!_ear) {
115.133 + _ear = new EarMap(_graph);
115.134 + }
115.135 + if (!_blossom_set) {
115.136 + _blossom_set_index = new IntNodeMap(_graph);
115.137 + _blossom_set = new BlossomSet(*_blossom_set_index);
115.138 + }
115.139 + if (!_blossom_rep) {
115.140 + _blossom_rep = new NodeIntMap(_node_num);
115.141 + }
115.142 + if (!_tree_set) {
115.143 + _tree_set_index = new IntNodeMap(_graph);
115.144 + _tree_set = new TreeSet(*_tree_set_index);
115.145 + }
115.146 + _node_queue.resize(_node_num);
115.147 + }
115.148 +
115.149 + void destroyStructures() {
115.150 + if (_matching) {
115.151 + delete _matching;
115.152 + }
115.153 + if (_status) {
115.154 + delete _status;
115.155 + }
115.156 + if (_ear) {
115.157 + delete _ear;
115.158 + }
115.159 + if (_blossom_set) {
115.160 + delete _blossom_set;
115.161 + delete _blossom_set_index;
115.162 + }
115.163 + if (_blossom_rep) {
115.164 + delete _blossom_rep;
115.165 + }
115.166 + if (_tree_set) {
115.167 + delete _tree_set_index;
115.168 + delete _tree_set;
115.169 + }
115.170 + }
115.171 +
115.172 + void processDense(const Node& n) {
115.173 + _process = _postpone = _last = 0;
115.174 + _node_queue[_last++] = n;
115.175 +
115.176 + while (_process != _last) {
115.177 + Node u = _node_queue[_process++];
115.178 + for (OutArcIt a(_graph, u); a != INVALID; ++a) {
115.179 + Node v = _graph.target(a);
115.180 + if ((*_status)[v] == MATCHED) {
115.181 + extendOnArc(a);
115.182 + } else if ((*_status)[v] == UNMATCHED) {
115.183 + augmentOnArc(a);
115.184 + return;
115.185 + }
115.186 + }
115.187 + }
115.188 +
115.189 + while (_postpone != _last) {
115.190 + Node u = _node_queue[_postpone++];
115.191 +
115.192 + for (OutArcIt a(_graph, u); a != INVALID ; ++a) {
115.193 + Node v = _graph.target(a);
115.194 +
115.195 + if ((*_status)[v] == EVEN) {
115.196 + if (_blossom_set->find(u) != _blossom_set->find(v)) {
115.197 + shrinkOnEdge(a);
115.198 + }
115.199 + }
115.200 +
115.201 + while (_process != _last) {
115.202 + Node w = _node_queue[_process++];
115.203 + for (OutArcIt b(_graph, w); b != INVALID; ++b) {
115.204 + Node x = _graph.target(b);
115.205 + if ((*_status)[x] == MATCHED) {
115.206 + extendOnArc(b);
115.207 + } else if ((*_status)[x] == UNMATCHED) {
115.208 + augmentOnArc(b);
115.209 + return;
115.210 + }
115.211 + }
115.212 + }
115.213 + }
115.214 + }
115.215 + }
115.216 +
115.217 + void processSparse(const Node& n) {
115.218 + _process = _last = 0;
115.219 + _node_queue[_last++] = n;
115.220 + while (_process != _last) {
115.221 + Node u = _node_queue[_process++];
115.222 + for (OutArcIt a(_graph, u); a != INVALID; ++a) {
115.223 + Node v = _graph.target(a);
115.224 +
115.225 + if ((*_status)[v] == EVEN) {
115.226 + if (_blossom_set->find(u) != _blossom_set->find(v)) {
115.227 + shrinkOnEdge(a);
115.228 + }
115.229 + } else if ((*_status)[v] == MATCHED) {
115.230 + extendOnArc(a);
115.231 + } else if ((*_status)[v] == UNMATCHED) {
115.232 + augmentOnArc(a);
115.233 + return;
115.234 + }
115.235 + }
115.236 + }
115.237 + }
115.238 +
115.239 + void shrinkOnEdge(const Edge& e) {
115.240 + Node nca = INVALID;
115.241 +
115.242 + {
115.243 + std::set<Node> left_set, right_set;
115.244 +
115.245 + Node left = (*_blossom_rep)[_blossom_set->find(_graph.u(e))];
115.246 + left_set.insert(left);
115.247 +
115.248 + Node right = (*_blossom_rep)[_blossom_set->find(_graph.v(e))];
115.249 + right_set.insert(right);
115.250 +
115.251 + while (true) {
115.252 + if ((*_matching)[left] == INVALID) break;
115.253 + left = _graph.target((*_matching)[left]);
115.254 + left = (*_blossom_rep)[_blossom_set->
115.255 + find(_graph.target((*_ear)[left]))];
115.256 + if (right_set.find(left) != right_set.end()) {
115.257 + nca = left;
115.258 + break;
115.259 + }
115.260 + left_set.insert(left);
115.261 +
115.262 + if ((*_matching)[right] == INVALID) break;
115.263 + right = _graph.target((*_matching)[right]);
115.264 + right = (*_blossom_rep)[_blossom_set->
115.265 + find(_graph.target((*_ear)[right]))];
115.266 + if (left_set.find(right) != left_set.end()) {
115.267 + nca = right;
115.268 + break;
115.269 + }
115.270 + right_set.insert(right);
115.271 + }
115.272 +
115.273 + if (nca == INVALID) {
115.274 + if ((*_matching)[left] == INVALID) {
115.275 + nca = right;
115.276 + while (left_set.find(nca) == left_set.end()) {
115.277 + nca = _graph.target((*_matching)[nca]);
115.278 + nca =(*_blossom_rep)[_blossom_set->
115.279 + find(_graph.target((*_ear)[nca]))];
115.280 + }
115.281 + } else {
115.282 + nca = left;
115.283 + while (right_set.find(nca) == right_set.end()) {
115.284 + nca = _graph.target((*_matching)[nca]);
115.285 + nca = (*_blossom_rep)[_blossom_set->
115.286 + find(_graph.target((*_ear)[nca]))];
115.287 + }
115.288 + }
115.289 + }
115.290 + }
115.291 +
115.292 + {
115.293 +
115.294 + Node node = _graph.u(e);
115.295 + Arc arc = _graph.direct(e, true);
115.296 + Node base = (*_blossom_rep)[_blossom_set->find(node)];
115.297 +
115.298 + while (base != nca) {
115.299 + (*_ear)[node] = arc;
115.300 +
115.301 + Node n = node;
115.302 + while (n != base) {
115.303 + n = _graph.target((*_matching)[n]);
115.304 + Arc a = (*_ear)[n];
115.305 + n = _graph.target(a);
115.306 + (*_ear)[n] = _graph.oppositeArc(a);
115.307 + }
115.308 + node = _graph.target((*_matching)[base]);
115.309 + _tree_set->erase(base);
115.310 + _tree_set->erase(node);
115.311 + _blossom_set->insert(node, _blossom_set->find(base));
115.312 + (*_status)[node] = EVEN;
115.313 + _node_queue[_last++] = node;
115.314 + arc = _graph.oppositeArc((*_ear)[node]);
115.315 + node = _graph.target((*_ear)[node]);
115.316 + base = (*_blossom_rep)[_blossom_set->find(node)];
115.317 + _blossom_set->join(_graph.target(arc), base);
115.318 + }
115.319 + }
115.320 +
115.321 + (*_blossom_rep)[_blossom_set->find(nca)] = nca;
115.322 +
115.323 + {
115.324 +
115.325 + Node node = _graph.v(e);
115.326 + Arc arc = _graph.direct(e, false);
115.327 + Node base = (*_blossom_rep)[_blossom_set->find(node)];
115.328 +
115.329 + while (base != nca) {
115.330 + (*_ear)[node] = arc;
115.331 +
115.332 + Node n = node;
115.333 + while (n != base) {
115.334 + n = _graph.target((*_matching)[n]);
115.335 + Arc a = (*_ear)[n];
115.336 + n = _graph.target(a);
115.337 + (*_ear)[n] = _graph.oppositeArc(a);
115.338 + }
115.339 + node = _graph.target((*_matching)[base]);
115.340 + _tree_set->erase(base);
115.341 + _tree_set->erase(node);
115.342 + _blossom_set->insert(node, _blossom_set->find(base));
115.343 + (*_status)[node] = EVEN;
115.344 + _node_queue[_last++] = node;
115.345 + arc = _graph.oppositeArc((*_ear)[node]);
115.346 + node = _graph.target((*_ear)[node]);
115.347 + base = (*_blossom_rep)[_blossom_set->find(node)];
115.348 + _blossom_set->join(_graph.target(arc), base);
115.349 + }
115.350 + }
115.351 +
115.352 + (*_blossom_rep)[_blossom_set->find(nca)] = nca;
115.353 + }
115.354 +
115.355 + void extendOnArc(const Arc& a) {
115.356 + Node base = _graph.source(a);
115.357 + Node odd = _graph.target(a);
115.358 +
115.359 + (*_ear)[odd] = _graph.oppositeArc(a);
115.360 + Node even = _graph.target((*_matching)[odd]);
115.361 + (*_blossom_rep)[_blossom_set->insert(even)] = even;
115.362 + (*_status)[odd] = ODD;
115.363 + (*_status)[even] = EVEN;
115.364 + int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(base)]);
115.365 + _tree_set->insert(odd, tree);
115.366 + _tree_set->insert(even, tree);
115.367 + _node_queue[_last++] = even;
115.368 +
115.369 + }
115.370 +
115.371 + void augmentOnArc(const Arc& a) {
115.372 + Node even = _graph.source(a);
115.373 + Node odd = _graph.target(a);
115.374 +
115.375 + int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(even)]);
115.376 +
115.377 + (*_matching)[odd] = _graph.oppositeArc(a);
115.378 + (*_status)[odd] = MATCHED;
115.379 +
115.380 + Arc arc = (*_matching)[even];
115.381 + (*_matching)[even] = a;
115.382 +
115.383 + while (arc != INVALID) {
115.384 + odd = _graph.target(arc);
115.385 + arc = (*_ear)[odd];
115.386 + even = _graph.target(arc);
115.387 + (*_matching)[odd] = arc;
115.388 + arc = (*_matching)[even];
115.389 + (*_matching)[even] = _graph.oppositeArc((*_matching)[odd]);
115.390 + }
115.391 +
115.392 + for (typename TreeSet::ItemIt it(*_tree_set, tree);
115.393 + it != INVALID; ++it) {
115.394 + if ((*_status)[it] == ODD) {
115.395 + (*_status)[it] = MATCHED;
115.396 + } else {
115.397 + int blossom = _blossom_set->find(it);
115.398 + for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom);
115.399 + jt != INVALID; ++jt) {
115.400 + (*_status)[jt] = MATCHED;
115.401 + }
115.402 + _blossom_set->eraseClass(blossom);
115.403 + }
115.404 + }
115.405 + _tree_set->eraseClass(tree);
115.406 +
115.407 + }
115.408 +
115.409 + public:
115.410 +
115.411 + /// \brief Constructor
115.412 + ///
115.413 + /// Constructor.
115.414 + MaxMatching(const Graph& graph)
115.415 + : _graph(graph), _matching(0), _status(0), _ear(0),
115.416 + _blossom_set_index(0), _blossom_set(0), _blossom_rep(0),
115.417 + _tree_set_index(0), _tree_set(0) {}
115.418 +
115.419 + ~MaxMatching() {
115.420 + destroyStructures();
115.421 + }
115.422 +
115.423 + /// \name Execution Control
115.424 + /// The simplest way to execute the algorithm is to use the
115.425 + /// \c run() member function.\n
115.426 + /// If you need better control on the execution, you have to call
115.427 + /// one of the functions \ref init(), \ref greedyInit() or
115.428 + /// \ref matchingInit() first, then you can start the algorithm with
115.429 + /// \ref startSparse() or \ref startDense().
115.430 +
115.431 + ///@{
115.432 +
115.433 + /// \brief Set the initial matching to the empty matching.
115.434 + ///
115.435 + /// This function sets the initial matching to the empty matching.
115.436 + void init() {
115.437 + createStructures();
115.438 + for(NodeIt n(_graph); n != INVALID; ++n) {
115.439 + (*_matching)[n] = INVALID;
115.440 + (*_status)[n] = UNMATCHED;
115.441 + }
115.442 + }
115.443 +
115.444 + /// \brief Find an initial matching in a greedy way.
115.445 + ///
115.446 + /// This function finds an initial matching in a greedy way.
115.447 + void greedyInit() {
115.448 + createStructures();
115.449 + for (NodeIt n(_graph); n != INVALID; ++n) {
115.450 + (*_matching)[n] = INVALID;
115.451 + (*_status)[n] = UNMATCHED;
115.452 + }
115.453 + for (NodeIt n(_graph); n != INVALID; ++n) {
115.454 + if ((*_matching)[n] == INVALID) {
115.455 + for (OutArcIt a(_graph, n); a != INVALID ; ++a) {
115.456 + Node v = _graph.target(a);
115.457 + if ((*_matching)[v] == INVALID && v != n) {
115.458 + (*_matching)[n] = a;
115.459 + (*_status)[n] = MATCHED;
115.460 + (*_matching)[v] = _graph.oppositeArc(a);
115.461 + (*_status)[v] = MATCHED;
115.462 + break;
115.463 + }
115.464 + }
115.465 + }
115.466 + }
115.467 + }
115.468 +
115.469 +
115.470 + /// \brief Initialize the matching from a map.
115.471 + ///
115.472 + /// This function initializes the matching from a \c bool valued edge
115.473 + /// map. This map should have the property that there are no two incident
115.474 + /// edges with \c true value, i.e. it really contains a matching.
115.475 + /// \return \c true if the map contains a matching.
115.476 + template <typename MatchingMap>
115.477 + bool matchingInit(const MatchingMap& matching) {
115.478 + createStructures();
115.479 +
115.480 + for (NodeIt n(_graph); n != INVALID; ++n) {
115.481 + (*_matching)[n] = INVALID;
115.482 + (*_status)[n] = UNMATCHED;
115.483 + }
115.484 + for(EdgeIt e(_graph); e!=INVALID; ++e) {
115.485 + if (matching[e]) {
115.486 +
115.487 + Node u = _graph.u(e);
115.488 + if ((*_matching)[u] != INVALID) return false;
115.489 + (*_matching)[u] = _graph.direct(e, true);
115.490 + (*_status)[u] = MATCHED;
115.491 +
115.492 + Node v = _graph.v(e);
115.493 + if ((*_matching)[v] != INVALID) return false;
115.494 + (*_matching)[v] = _graph.direct(e, false);
115.495 + (*_status)[v] = MATCHED;
115.496 + }
115.497 + }
115.498 + return true;
115.499 + }
115.500 +
115.501 + /// \brief Start Edmonds' algorithm
115.502 + ///
115.503 + /// This function runs the original Edmonds' algorithm.
115.504 + ///
115.505 + /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
115.506 + /// called before using this function.
115.507 + void startSparse() {
115.508 + for(NodeIt n(_graph); n != INVALID; ++n) {
115.509 + if ((*_status)[n] == UNMATCHED) {
115.510 + (*_blossom_rep)[_blossom_set->insert(n)] = n;
115.511 + _tree_set->insert(n);
115.512 + (*_status)[n] = EVEN;
115.513 + processSparse(n);
115.514 + }
115.515 + }
115.516 + }
115.517 +
115.518 + /// \brief Start Edmonds' algorithm with a heuristic improvement
115.519 + /// for dense graphs
115.520 + ///
115.521 + /// This function runs Edmonds' algorithm with a heuristic of postponing
115.522 + /// shrinks, therefore resulting in a faster algorithm for dense graphs.
115.523 + ///
115.524 + /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
115.525 + /// called before using this function.
115.526 + void startDense() {
115.527 + for(NodeIt n(_graph); n != INVALID; ++n) {
115.528 + if ((*_status)[n] == UNMATCHED) {
115.529 + (*_blossom_rep)[_blossom_set->insert(n)] = n;
115.530 + _tree_set->insert(n);
115.531 + (*_status)[n] = EVEN;
115.532 + processDense(n);
115.533 + }
115.534 + }
115.535 + }
115.536 +
115.537 +
115.538 + /// \brief Run Edmonds' algorithm
115.539 + ///
115.540 + /// This function runs Edmonds' algorithm. An additional heuristic of
115.541 + /// postponing shrinks is used for relatively dense graphs
115.542 + /// (for which <tt>m>=2*n</tt> holds).
115.543 + void run() {
115.544 + if (countEdges(_graph) < 2 * countNodes(_graph)) {
115.545 + greedyInit();
115.546 + startSparse();
115.547 + } else {
115.548 + init();
115.549 + startDense();
115.550 + }
115.551 + }
115.552 +
115.553 + /// @}
115.554 +
115.555 + /// \name Primal Solution
115.556 + /// Functions to get the primal solution, i.e. the maximum matching.
115.557 +
115.558 + /// @{
115.559 +
115.560 + /// \brief Return the size (cardinality) of the matching.
115.561 + ///
115.562 + /// This function returns the size (cardinality) of the current matching.
115.563 + /// After run() it returns the size of the maximum matching in the graph.
115.564 + int matchingSize() const {
115.565 + int size = 0;
115.566 + for (NodeIt n(_graph); n != INVALID; ++n) {
115.567 + if ((*_matching)[n] != INVALID) {
115.568 + ++size;
115.569 + }
115.570 + }
115.571 + return size / 2;
115.572 + }
115.573 +
115.574 + /// \brief Return \c true if the given edge is in the matching.
115.575 + ///
115.576 + /// This function returns \c true if the given edge is in the current
115.577 + /// matching.
115.578 + bool matching(const Edge& edge) const {
115.579 + return edge == (*_matching)[_graph.u(edge)];
115.580 + }
115.581 +
115.582 + /// \brief Return the matching arc (or edge) incident to the given node.
115.583 + ///
115.584 + /// This function returns the matching arc (or edge) incident to the
115.585 + /// given node in the current matching or \c INVALID if the node is
115.586 + /// not covered by the matching.
115.587 + Arc matching(const Node& n) const {
115.588 + return (*_matching)[n];
115.589 + }
115.590 +
115.591 + /// \brief Return a const reference to the matching map.
115.592 + ///
115.593 + /// This function returns a const reference to a node map that stores
115.594 + /// the matching arc (or edge) incident to each node.
115.595 + const MatchingMap& matchingMap() const {
115.596 + return *_matching;
115.597 + }
115.598 +
115.599 + /// \brief Return the mate of the given node.
115.600 + ///
115.601 + /// This function returns the mate of the given node in the current
115.602 + /// matching or \c INVALID if the node is not covered by the matching.
115.603 + Node mate(const Node& n) const {
115.604 + return (*_matching)[n] != INVALID ?
115.605 + _graph.target((*_matching)[n]) : INVALID;
115.606 + }
115.607 +
115.608 + /// @}
115.609 +
115.610 + /// \name Dual Solution
115.611 + /// Functions to get the dual solution, i.e. the Gallai-Edmonds
115.612 + /// decomposition.
115.613 +
115.614 + /// @{
115.615 +
115.616 + /// \brief Return the status of the given node in the Edmonds-Gallai
115.617 + /// decomposition.
115.618 + ///
115.619 + /// This function returns the \ref Status "status" of the given node
115.620 + /// in the Edmonds-Gallai decomposition.
115.621 + Status status(const Node& n) const {
115.622 + return (*_status)[n];
115.623 + }
115.624 +
115.625 + /// \brief Return a const reference to the status map, which stores
115.626 + /// the Edmonds-Gallai decomposition.
115.627 + ///
115.628 + /// This function returns a const reference to a node map that stores the
115.629 + /// \ref Status "status" of each node in the Edmonds-Gallai decomposition.
115.630 + const StatusMap& statusMap() const {
115.631 + return *_status;
115.632 + }
115.633 +
115.634 + /// \brief Return \c true if the given node is in the barrier.
115.635 + ///
115.636 + /// This function returns \c true if the given node is in the barrier.
115.637 + bool barrier(const Node& n) const {
115.638 + return (*_status)[n] == ODD;
115.639 + }
115.640 +
115.641 + /// @}
115.642 +
115.643 + };
115.644 +
115.645 + /// \ingroup matching
115.646 + ///
115.647 + /// \brief Weighted matching in general graphs
115.648 + ///
115.649 + /// This class provides an efficient implementation of Edmond's
115.650 + /// maximum weighted matching algorithm. The implementation is based
115.651 + /// on extensive use of priority queues and provides
115.652 + /// \f$O(nm\log n)\f$ time complexity.
115.653 + ///
115.654 + /// The maximum weighted matching problem is to find a subset of the
115.655 + /// edges in an undirected graph with maximum overall weight for which
115.656 + /// each node has at most one incident edge.
115.657 + /// It can be formulated with the following linear program.
115.658 + /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
115.659 + /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
115.660 + \quad \forall B\in\mathcal{O}\f] */
115.661 + /// \f[x_e \ge 0\quad \forall e\in E\f]
115.662 + /// \f[\max \sum_{e\in E}x_ew_e\f]
115.663 + /// where \f$\delta(X)\f$ is the set of edges incident to a node in
115.664 + /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
115.665 + /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
115.666 + /// subsets of the nodes.
115.667 + ///
115.668 + /// The algorithm calculates an optimal matching and a proof of the
115.669 + /// optimality. The solution of the dual problem can be used to check
115.670 + /// the result of the algorithm. The dual linear problem is the
115.671 + /// following.
115.672 + /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
115.673 + z_B \ge w_{uv} \quad \forall uv\in E\f] */
115.674 + /// \f[y_u \ge 0 \quad \forall u \in V\f]
115.675 + /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
115.676 + /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
115.677 + \frac{\vert B \vert - 1}{2}z_B\f] */
115.678 + ///
115.679 + /// The algorithm can be executed with the run() function.
115.680 + /// After it the matching (the primal solution) and the dual solution
115.681 + /// can be obtained using the query functions and the
115.682 + /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class,
115.683 + /// which is able to iterate on the nodes of a blossom.
115.684 + /// If the value type is integer, then the dual solution is multiplied
115.685 + /// by \ref MaxWeightedMatching::dualScale "4".
115.686 + ///
115.687 + /// \tparam GR The undirected graph type the algorithm runs on.
115.688 + /// \tparam WM The type edge weight map. The default type is
115.689 + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
115.690 +#ifdef DOXYGEN
115.691 + template <typename GR, typename WM>
115.692 +#else
115.693 + template <typename GR,
115.694 + typename WM = typename GR::template EdgeMap<int> >
115.695 +#endif
115.696 + class MaxWeightedMatching {
115.697 + public:
115.698 +
115.699 + /// The graph type of the algorithm
115.700 + typedef GR Graph;
115.701 + /// The type of the edge weight map
115.702 + typedef WM WeightMap;
115.703 + /// The value type of the edge weights
115.704 + typedef typename WeightMap::Value Value;
115.705 +
115.706 + /// The type of the matching map
115.707 + typedef typename Graph::template NodeMap<typename Graph::Arc>
115.708 + MatchingMap;
115.709 +
115.710 + /// \brief Scaling factor for dual solution
115.711 + ///
115.712 + /// Scaling factor for dual solution. It is equal to 4 or 1
115.713 + /// according to the value type.
115.714 + static const int dualScale =
115.715 + std::numeric_limits<Value>::is_integer ? 4 : 1;
115.716 +
115.717 + private:
115.718 +
115.719 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
115.720 +
115.721 + typedef typename Graph::template NodeMap<Value> NodePotential;
115.722 + typedef std::vector<Node> BlossomNodeList;
115.723 +
115.724 + struct BlossomVariable {
115.725 + int begin, end;
115.726 + Value value;
115.727 +
115.728 + BlossomVariable(int _begin, int _end, Value _value)
115.729 + : begin(_begin), end(_end), value(_value) {}
115.730 +
115.731 + };
115.732 +
115.733 + typedef std::vector<BlossomVariable> BlossomPotential;
115.734 +
115.735 + const Graph& _graph;
115.736 + const WeightMap& _weight;
115.737 +
115.738 + MatchingMap* _matching;
115.739 +
115.740 + NodePotential* _node_potential;
115.741 +
115.742 + BlossomPotential _blossom_potential;
115.743 + BlossomNodeList _blossom_node_list;
115.744 +
115.745 + int _node_num;
115.746 + int _blossom_num;
115.747 +
115.748 + typedef RangeMap<int> IntIntMap;
115.749 +
115.750 + enum Status {
115.751 + EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
115.752 + };
115.753 +
115.754 + typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
115.755 + struct BlossomData {
115.756 + int tree;
115.757 + Status status;
115.758 + Arc pred, next;
115.759 + Value pot, offset;
115.760 + Node base;
115.761 + };
115.762 +
115.763 + IntNodeMap *_blossom_index;
115.764 + BlossomSet *_blossom_set;
115.765 + RangeMap<BlossomData>* _blossom_data;
115.766 +
115.767 + IntNodeMap *_node_index;
115.768 + IntArcMap *_node_heap_index;
115.769 +
115.770 + struct NodeData {
115.771 +
115.772 + NodeData(IntArcMap& node_heap_index)
115.773 + : heap(node_heap_index) {}
115.774 +
115.775 + int blossom;
115.776 + Value pot;
115.777 + BinHeap<Value, IntArcMap> heap;
115.778 + std::map<int, Arc> heap_index;
115.779 +
115.780 + int tree;
115.781 + };
115.782 +
115.783 + RangeMap<NodeData>* _node_data;
115.784 +
115.785 + typedef ExtendFindEnum<IntIntMap> TreeSet;
115.786 +
115.787 + IntIntMap *_tree_set_index;
115.788 + TreeSet *_tree_set;
115.789 +
115.790 + IntNodeMap *_delta1_index;
115.791 + BinHeap<Value, IntNodeMap> *_delta1;
115.792 +
115.793 + IntIntMap *_delta2_index;
115.794 + BinHeap<Value, IntIntMap> *_delta2;
115.795 +
115.796 + IntEdgeMap *_delta3_index;
115.797 + BinHeap<Value, IntEdgeMap> *_delta3;
115.798 +
115.799 + IntIntMap *_delta4_index;
115.800 + BinHeap<Value, IntIntMap> *_delta4;
115.801 +
115.802 + Value _delta_sum;
115.803 +
115.804 + void createStructures() {
115.805 + _node_num = countNodes(_graph);
115.806 + _blossom_num = _node_num * 3 / 2;
115.807 +
115.808 + if (!_matching) {
115.809 + _matching = new MatchingMap(_graph);
115.810 + }
115.811 + if (!_node_potential) {
115.812 + _node_potential = new NodePotential(_graph);
115.813 + }
115.814 + if (!_blossom_set) {
115.815 + _blossom_index = new IntNodeMap(_graph);
115.816 + _blossom_set = new BlossomSet(*_blossom_index);
115.817 + _blossom_data = new RangeMap<BlossomData>(_blossom_num);
115.818 + }
115.819 +
115.820 + if (!_node_index) {
115.821 + _node_index = new IntNodeMap(_graph);
115.822 + _node_heap_index = new IntArcMap(_graph);
115.823 + _node_data = new RangeMap<NodeData>(_node_num,
115.824 + NodeData(*_node_heap_index));
115.825 + }
115.826 +
115.827 + if (!_tree_set) {
115.828 + _tree_set_index = new IntIntMap(_blossom_num);
115.829 + _tree_set = new TreeSet(*_tree_set_index);
115.830 + }
115.831 + if (!_delta1) {
115.832 + _delta1_index = new IntNodeMap(_graph);
115.833 + _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
115.834 + }
115.835 + if (!_delta2) {
115.836 + _delta2_index = new IntIntMap(_blossom_num);
115.837 + _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
115.838 + }
115.839 + if (!_delta3) {
115.840 + _delta3_index = new IntEdgeMap(_graph);
115.841 + _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
115.842 + }
115.843 + if (!_delta4) {
115.844 + _delta4_index = new IntIntMap(_blossom_num);
115.845 + _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
115.846 + }
115.847 + }
115.848 +
115.849 + void destroyStructures() {
115.850 + _node_num = countNodes(_graph);
115.851 + _blossom_num = _node_num * 3 / 2;
115.852 +
115.853 + if (_matching) {
115.854 + delete _matching;
115.855 + }
115.856 + if (_node_potential) {
115.857 + delete _node_potential;
115.858 + }
115.859 + if (_blossom_set) {
115.860 + delete _blossom_index;
115.861 + delete _blossom_set;
115.862 + delete _blossom_data;
115.863 + }
115.864 +
115.865 + if (_node_index) {
115.866 + delete _node_index;
115.867 + delete _node_heap_index;
115.868 + delete _node_data;
115.869 + }
115.870 +
115.871 + if (_tree_set) {
115.872 + delete _tree_set_index;
115.873 + delete _tree_set;
115.874 + }
115.875 + if (_delta1) {
115.876 + delete _delta1_index;
115.877 + delete _delta1;
115.878 + }
115.879 + if (_delta2) {
115.880 + delete _delta2_index;
115.881 + delete _delta2;
115.882 + }
115.883 + if (_delta3) {
115.884 + delete _delta3_index;
115.885 + delete _delta3;
115.886 + }
115.887 + if (_delta4) {
115.888 + delete _delta4_index;
115.889 + delete _delta4;
115.890 + }
115.891 + }
115.892 +
115.893 + void matchedToEven(int blossom, int tree) {
115.894 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
115.895 + _delta2->erase(blossom);
115.896 + }
115.897 +
115.898 + if (!_blossom_set->trivial(blossom)) {
115.899 + (*_blossom_data)[blossom].pot -=
115.900 + 2 * (_delta_sum - (*_blossom_data)[blossom].offset);
115.901 + }
115.902 +
115.903 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
115.904 + n != INVALID; ++n) {
115.905 +
115.906 + _blossom_set->increase(n, std::numeric_limits<Value>::max());
115.907 + int ni = (*_node_index)[n];
115.908 +
115.909 + (*_node_data)[ni].heap.clear();
115.910 + (*_node_data)[ni].heap_index.clear();
115.911 +
115.912 + (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
115.913 +
115.914 + _delta1->push(n, (*_node_data)[ni].pot);
115.915 +
115.916 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
115.917 + Node v = _graph.source(e);
115.918 + int vb = _blossom_set->find(v);
115.919 + int vi = (*_node_index)[v];
115.920 +
115.921 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
115.922 + dualScale * _weight[e];
115.923 +
115.924 + if ((*_blossom_data)[vb].status == EVEN) {
115.925 + if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
115.926 + _delta3->push(e, rw / 2);
115.927 + }
115.928 + } else if ((*_blossom_data)[vb].status == UNMATCHED) {
115.929 + if (_delta3->state(e) != _delta3->IN_HEAP) {
115.930 + _delta3->push(e, rw);
115.931 + }
115.932 + } else {
115.933 + typename std::map<int, Arc>::iterator it =
115.934 + (*_node_data)[vi].heap_index.find(tree);
115.935 +
115.936 + if (it != (*_node_data)[vi].heap_index.end()) {
115.937 + if ((*_node_data)[vi].heap[it->second] > rw) {
115.938 + (*_node_data)[vi].heap.replace(it->second, e);
115.939 + (*_node_data)[vi].heap.decrease(e, rw);
115.940 + it->second = e;
115.941 + }
115.942 + } else {
115.943 + (*_node_data)[vi].heap.push(e, rw);
115.944 + (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
115.945 + }
115.946 +
115.947 + if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
115.948 + _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
115.949 +
115.950 + if ((*_blossom_data)[vb].status == MATCHED) {
115.951 + if (_delta2->state(vb) != _delta2->IN_HEAP) {
115.952 + _delta2->push(vb, _blossom_set->classPrio(vb) -
115.953 + (*_blossom_data)[vb].offset);
115.954 + } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
115.955 + (*_blossom_data)[vb].offset){
115.956 + _delta2->decrease(vb, _blossom_set->classPrio(vb) -
115.957 + (*_blossom_data)[vb].offset);
115.958 + }
115.959 + }
115.960 + }
115.961 + }
115.962 + }
115.963 + }
115.964 + (*_blossom_data)[blossom].offset = 0;
115.965 + }
115.966 +
115.967 + void matchedToOdd(int blossom) {
115.968 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
115.969 + _delta2->erase(blossom);
115.970 + }
115.971 + (*_blossom_data)[blossom].offset += _delta_sum;
115.972 + if (!_blossom_set->trivial(blossom)) {
115.973 + _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
115.974 + (*_blossom_data)[blossom].offset);
115.975 + }
115.976 + }
115.977 +
115.978 + void evenToMatched(int blossom, int tree) {
115.979 + if (!_blossom_set->trivial(blossom)) {
115.980 + (*_blossom_data)[blossom].pot += 2 * _delta_sum;
115.981 + }
115.982 +
115.983 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
115.984 + n != INVALID; ++n) {
115.985 + int ni = (*_node_index)[n];
115.986 + (*_node_data)[ni].pot -= _delta_sum;
115.987 +
115.988 + _delta1->erase(n);
115.989 +
115.990 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
115.991 + Node v = _graph.source(e);
115.992 + int vb = _blossom_set->find(v);
115.993 + int vi = (*_node_index)[v];
115.994 +
115.995 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
115.996 + dualScale * _weight[e];
115.997 +
115.998 + if (vb == blossom) {
115.999 + if (_delta3->state(e) == _delta3->IN_HEAP) {
115.1000 + _delta3->erase(e);
115.1001 + }
115.1002 + } else if ((*_blossom_data)[vb].status == EVEN) {
115.1003 +
115.1004 + if (_delta3->state(e) == _delta3->IN_HEAP) {
115.1005 + _delta3->erase(e);
115.1006 + }
115.1007 +
115.1008 + int vt = _tree_set->find(vb);
115.1009 +
115.1010 + if (vt != tree) {
115.1011 +
115.1012 + Arc r = _graph.oppositeArc(e);
115.1013 +
115.1014 + typename std::map<int, Arc>::iterator it =
115.1015 + (*_node_data)[ni].heap_index.find(vt);
115.1016 +
115.1017 + if (it != (*_node_data)[ni].heap_index.end()) {
115.1018 + if ((*_node_data)[ni].heap[it->second] > rw) {
115.1019 + (*_node_data)[ni].heap.replace(it->second, r);
115.1020 + (*_node_data)[ni].heap.decrease(r, rw);
115.1021 + it->second = r;
115.1022 + }
115.1023 + } else {
115.1024 + (*_node_data)[ni].heap.push(r, rw);
115.1025 + (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
115.1026 + }
115.1027 +
115.1028 + if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
115.1029 + _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
115.1030 +
115.1031 + if (_delta2->state(blossom) != _delta2->IN_HEAP) {
115.1032 + _delta2->push(blossom, _blossom_set->classPrio(blossom) -
115.1033 + (*_blossom_data)[blossom].offset);
115.1034 + } else if ((*_delta2)[blossom] >
115.1035 + _blossom_set->classPrio(blossom) -
115.1036 + (*_blossom_data)[blossom].offset){
115.1037 + _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
115.1038 + (*_blossom_data)[blossom].offset);
115.1039 + }
115.1040 + }
115.1041 + }
115.1042 +
115.1043 + } else if ((*_blossom_data)[vb].status == UNMATCHED) {
115.1044 + if (_delta3->state(e) == _delta3->IN_HEAP) {
115.1045 + _delta3->erase(e);
115.1046 + }
115.1047 + } else {
115.1048 +
115.1049 + typename std::map<int, Arc>::iterator it =
115.1050 + (*_node_data)[vi].heap_index.find(tree);
115.1051 +
115.1052 + if (it != (*_node_data)[vi].heap_index.end()) {
115.1053 + (*_node_data)[vi].heap.erase(it->second);
115.1054 + (*_node_data)[vi].heap_index.erase(it);
115.1055 + if ((*_node_data)[vi].heap.empty()) {
115.1056 + _blossom_set->increase(v, std::numeric_limits<Value>::max());
115.1057 + } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
115.1058 + _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
115.1059 + }
115.1060 +
115.1061 + if ((*_blossom_data)[vb].status == MATCHED) {
115.1062 + if (_blossom_set->classPrio(vb) ==
115.1063 + std::numeric_limits<Value>::max()) {
115.1064 + _delta2->erase(vb);
115.1065 + } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
115.1066 + (*_blossom_data)[vb].offset) {
115.1067 + _delta2->increase(vb, _blossom_set->classPrio(vb) -
115.1068 + (*_blossom_data)[vb].offset);
115.1069 + }
115.1070 + }
115.1071 + }
115.1072 + }
115.1073 + }
115.1074 + }
115.1075 + }
115.1076 +
115.1077 + void oddToMatched(int blossom) {
115.1078 + (*_blossom_data)[blossom].offset -= _delta_sum;
115.1079 +
115.1080 + if (_blossom_set->classPrio(blossom) !=
115.1081 + std::numeric_limits<Value>::max()) {
115.1082 + _delta2->push(blossom, _blossom_set->classPrio(blossom) -
115.1083 + (*_blossom_data)[blossom].offset);
115.1084 + }
115.1085 +
115.1086 + if (!_blossom_set->trivial(blossom)) {
115.1087 + _delta4->erase(blossom);
115.1088 + }
115.1089 + }
115.1090 +
115.1091 + void oddToEven(int blossom, int tree) {
115.1092 + if (!_blossom_set->trivial(blossom)) {
115.1093 + _delta4->erase(blossom);
115.1094 + (*_blossom_data)[blossom].pot -=
115.1095 + 2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
115.1096 + }
115.1097 +
115.1098 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
115.1099 + n != INVALID; ++n) {
115.1100 + int ni = (*_node_index)[n];
115.1101 +
115.1102 + _blossom_set->increase(n, std::numeric_limits<Value>::max());
115.1103 +
115.1104 + (*_node_data)[ni].heap.clear();
115.1105 + (*_node_data)[ni].heap_index.clear();
115.1106 + (*_node_data)[ni].pot +=
115.1107 + 2 * _delta_sum - (*_blossom_data)[blossom].offset;
115.1108 +
115.1109 + _delta1->push(n, (*_node_data)[ni].pot);
115.1110 +
115.1111 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
115.1112 + Node v = _graph.source(e);
115.1113 + int vb = _blossom_set->find(v);
115.1114 + int vi = (*_node_index)[v];
115.1115 +
115.1116 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
115.1117 + dualScale * _weight[e];
115.1118 +
115.1119 + if ((*_blossom_data)[vb].status == EVEN) {
115.1120 + if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
115.1121 + _delta3->push(e, rw / 2);
115.1122 + }
115.1123 + } else if ((*_blossom_data)[vb].status == UNMATCHED) {
115.1124 + if (_delta3->state(e) != _delta3->IN_HEAP) {
115.1125 + _delta3->push(e, rw);
115.1126 + }
115.1127 + } else {
115.1128 +
115.1129 + typename std::map<int, Arc>::iterator it =
115.1130 + (*_node_data)[vi].heap_index.find(tree);
115.1131 +
115.1132 + if (it != (*_node_data)[vi].heap_index.end()) {
115.1133 + if ((*_node_data)[vi].heap[it->second] > rw) {
115.1134 + (*_node_data)[vi].heap.replace(it->second, e);
115.1135 + (*_node_data)[vi].heap.decrease(e, rw);
115.1136 + it->second = e;
115.1137 + }
115.1138 + } else {
115.1139 + (*_node_data)[vi].heap.push(e, rw);
115.1140 + (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
115.1141 + }
115.1142 +
115.1143 + if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
115.1144 + _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
115.1145 +
115.1146 + if ((*_blossom_data)[vb].status == MATCHED) {
115.1147 + if (_delta2->state(vb) != _delta2->IN_HEAP) {
115.1148 + _delta2->push(vb, _blossom_set->classPrio(vb) -
115.1149 + (*_blossom_data)[vb].offset);
115.1150 + } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
115.1151 + (*_blossom_data)[vb].offset) {
115.1152 + _delta2->decrease(vb, _blossom_set->classPrio(vb) -
115.1153 + (*_blossom_data)[vb].offset);
115.1154 + }
115.1155 + }
115.1156 + }
115.1157 + }
115.1158 + }
115.1159 + }
115.1160 + (*_blossom_data)[blossom].offset = 0;
115.1161 + }
115.1162 +
115.1163 +
115.1164 + void matchedToUnmatched(int blossom) {
115.1165 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
115.1166 + _delta2->erase(blossom);
115.1167 + }
115.1168 +
115.1169 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
115.1170 + n != INVALID; ++n) {
115.1171 + int ni = (*_node_index)[n];
115.1172 +
115.1173 + _blossom_set->increase(n, std::numeric_limits<Value>::max());
115.1174 +
115.1175 + (*_node_data)[ni].heap.clear();
115.1176 + (*_node_data)[ni].heap_index.clear();
115.1177 +
115.1178 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
115.1179 + Node v = _graph.target(e);
115.1180 + int vb = _blossom_set->find(v);
115.1181 + int vi = (*_node_index)[v];
115.1182 +
115.1183 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
115.1184 + dualScale * _weight[e];
115.1185 +
115.1186 + if ((*_blossom_data)[vb].status == EVEN) {
115.1187 + if (_delta3->state(e) != _delta3->IN_HEAP) {
115.1188 + _delta3->push(e, rw);
115.1189 + }
115.1190 + }
115.1191 + }
115.1192 + }
115.1193 + }
115.1194 +
115.1195 + void unmatchedToMatched(int blossom) {
115.1196 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
115.1197 + n != INVALID; ++n) {
115.1198 + int ni = (*_node_index)[n];
115.1199 +
115.1200 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
115.1201 + Node v = _graph.source(e);
115.1202 + int vb = _blossom_set->find(v);
115.1203 + int vi = (*_node_index)[v];
115.1204 +
115.1205 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
115.1206 + dualScale * _weight[e];
115.1207 +
115.1208 + if (vb == blossom) {
115.1209 + if (_delta3->state(e) == _delta3->IN_HEAP) {
115.1210 + _delta3->erase(e);
115.1211 + }
115.1212 + } else if ((*_blossom_data)[vb].status == EVEN) {
115.1213 +
115.1214 + if (_delta3->state(e) == _delta3->IN_HEAP) {
115.1215 + _delta3->erase(e);
115.1216 + }
115.1217 +
115.1218 + int vt = _tree_set->find(vb);
115.1219 +
115.1220 + Arc r = _graph.oppositeArc(e);
115.1221 +
115.1222 + typename std::map<int, Arc>::iterator it =
115.1223 + (*_node_data)[ni].heap_index.find(vt);
115.1224 +
115.1225 + if (it != (*_node_data)[ni].heap_index.end()) {
115.1226 + if ((*_node_data)[ni].heap[it->second] > rw) {
115.1227 + (*_node_data)[ni].heap.replace(it->second, r);
115.1228 + (*_node_data)[ni].heap.decrease(r, rw);
115.1229 + it->second = r;
115.1230 + }
115.1231 + } else {
115.1232 + (*_node_data)[ni].heap.push(r, rw);
115.1233 + (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
115.1234 + }
115.1235 +
115.1236 + if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
115.1237 + _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
115.1238 +
115.1239 + if (_delta2->state(blossom) != _delta2->IN_HEAP) {
115.1240 + _delta2->push(blossom, _blossom_set->classPrio(blossom) -
115.1241 + (*_blossom_data)[blossom].offset);
115.1242 + } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
115.1243 + (*_blossom_data)[blossom].offset){
115.1244 + _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
115.1245 + (*_blossom_data)[blossom].offset);
115.1246 + }
115.1247 + }
115.1248 +
115.1249 + } else if ((*_blossom_data)[vb].status == UNMATCHED) {
115.1250 + if (_delta3->state(e) == _delta3->IN_HEAP) {
115.1251 + _delta3->erase(e);
115.1252 + }
115.1253 + }
115.1254 + }
115.1255 + }
115.1256 + }
115.1257 +
115.1258 + void alternatePath(int even, int tree) {
115.1259 + int odd;
115.1260 +
115.1261 + evenToMatched(even, tree);
115.1262 + (*_blossom_data)[even].status = MATCHED;
115.1263 +
115.1264 + while ((*_blossom_data)[even].pred != INVALID) {
115.1265 + odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
115.1266 + (*_blossom_data)[odd].status = MATCHED;
115.1267 + oddToMatched(odd);
115.1268 + (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
115.1269 +
115.1270 + even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
115.1271 + (*_blossom_data)[even].status = MATCHED;
115.1272 + evenToMatched(even, tree);
115.1273 + (*_blossom_data)[even].next =
115.1274 + _graph.oppositeArc((*_blossom_data)[odd].pred);
115.1275 + }
115.1276 +
115.1277 + }
115.1278 +
115.1279 + void destroyTree(int tree) {
115.1280 + for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
115.1281 + if ((*_blossom_data)[b].status == EVEN) {
115.1282 + (*_blossom_data)[b].status = MATCHED;
115.1283 + evenToMatched(b, tree);
115.1284 + } else if ((*_blossom_data)[b].status == ODD) {
115.1285 + (*_blossom_data)[b].status = MATCHED;
115.1286 + oddToMatched(b);
115.1287 + }
115.1288 + }
115.1289 + _tree_set->eraseClass(tree);
115.1290 + }
115.1291 +
115.1292 +
115.1293 + void unmatchNode(const Node& node) {
115.1294 + int blossom = _blossom_set->find(node);
115.1295 + int tree = _tree_set->find(blossom);
115.1296 +
115.1297 + alternatePath(blossom, tree);
115.1298 + destroyTree(tree);
115.1299 +
115.1300 + (*_blossom_data)[blossom].status = UNMATCHED;
115.1301 + (*_blossom_data)[blossom].base = node;
115.1302 + matchedToUnmatched(blossom);
115.1303 + }
115.1304 +
115.1305 +
115.1306 + void augmentOnEdge(const Edge& edge) {
115.1307 +
115.1308 + int left = _blossom_set->find(_graph.u(edge));
115.1309 + int right = _blossom_set->find(_graph.v(edge));
115.1310 +
115.1311 + if ((*_blossom_data)[left].status == EVEN) {
115.1312 + int left_tree = _tree_set->find(left);
115.1313 + alternatePath(left, left_tree);
115.1314 + destroyTree(left_tree);
115.1315 + } else {
115.1316 + (*_blossom_data)[left].status = MATCHED;
115.1317 + unmatchedToMatched(left);
115.1318 + }
115.1319 +
115.1320 + if ((*_blossom_data)[right].status == EVEN) {
115.1321 + int right_tree = _tree_set->find(right);
115.1322 + alternatePath(right, right_tree);
115.1323 + destroyTree(right_tree);
115.1324 + } else {
115.1325 + (*_blossom_data)[right].status = MATCHED;
115.1326 + unmatchedToMatched(right);
115.1327 + }
115.1328 +
115.1329 + (*_blossom_data)[left].next = _graph.direct(edge, true);
115.1330 + (*_blossom_data)[right].next = _graph.direct(edge, false);
115.1331 + }
115.1332 +
115.1333 + void extendOnArc(const Arc& arc) {
115.1334 + int base = _blossom_set->find(_graph.target(arc));
115.1335 + int tree = _tree_set->find(base);
115.1336 +
115.1337 + int odd = _blossom_set->find(_graph.source(arc));
115.1338 + _tree_set->insert(odd, tree);
115.1339 + (*_blossom_data)[odd].status = ODD;
115.1340 + matchedToOdd(odd);
115.1341 + (*_blossom_data)[odd].pred = arc;
115.1342 +
115.1343 + int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
115.1344 + (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
115.1345 + _tree_set->insert(even, tree);
115.1346 + (*_blossom_data)[even].status = EVEN;
115.1347 + matchedToEven(even, tree);
115.1348 + }
115.1349 +
115.1350 + void shrinkOnEdge(const Edge& edge, int tree) {
115.1351 + int nca = -1;
115.1352 + std::vector<int> left_path, right_path;
115.1353 +
115.1354 + {
115.1355 + std::set<int> left_set, right_set;
115.1356 + int left = _blossom_set->find(_graph.u(edge));
115.1357 + left_path.push_back(left);
115.1358 + left_set.insert(left);
115.1359 +
115.1360 + int right = _blossom_set->find(_graph.v(edge));
115.1361 + right_path.push_back(right);
115.1362 + right_set.insert(right);
115.1363 +
115.1364 + while (true) {
115.1365 +
115.1366 + if ((*_blossom_data)[left].pred == INVALID) break;
115.1367 +
115.1368 + left =
115.1369 + _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
115.1370 + left_path.push_back(left);
115.1371 + left =
115.1372 + _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
115.1373 + left_path.push_back(left);
115.1374 +
115.1375 + left_set.insert(left);
115.1376 +
115.1377 + if (right_set.find(left) != right_set.end()) {
115.1378 + nca = left;
115.1379 + break;
115.1380 + }
115.1381 +
115.1382 + if ((*_blossom_data)[right].pred == INVALID) break;
115.1383 +
115.1384 + right =
115.1385 + _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
115.1386 + right_path.push_back(right);
115.1387 + right =
115.1388 + _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
115.1389 + right_path.push_back(right);
115.1390 +
115.1391 + right_set.insert(right);
115.1392 +
115.1393 + if (left_set.find(right) != left_set.end()) {
115.1394 + nca = right;
115.1395 + break;
115.1396 + }
115.1397 +
115.1398 + }
115.1399 +
115.1400 + if (nca == -1) {
115.1401 + if ((*_blossom_data)[left].pred == INVALID) {
115.1402 + nca = right;
115.1403 + while (left_set.find(nca) == left_set.end()) {
115.1404 + nca =
115.1405 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
115.1406 + right_path.push_back(nca);
115.1407 + nca =
115.1408 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
115.1409 + right_path.push_back(nca);
115.1410 + }
115.1411 + } else {
115.1412 + nca = left;
115.1413 + while (right_set.find(nca) == right_set.end()) {
115.1414 + nca =
115.1415 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
115.1416 + left_path.push_back(nca);
115.1417 + nca =
115.1418 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
115.1419 + left_path.push_back(nca);
115.1420 + }
115.1421 + }
115.1422 + }
115.1423 + }
115.1424 +
115.1425 + std::vector<int> subblossoms;
115.1426 + Arc prev;
115.1427 +
115.1428 + prev = _graph.direct(edge, true);
115.1429 + for (int i = 0; left_path[i] != nca; i += 2) {
115.1430 + subblossoms.push_back(left_path[i]);
115.1431 + (*_blossom_data)[left_path[i]].next = prev;
115.1432 + _tree_set->erase(left_path[i]);
115.1433 +
115.1434 + subblossoms.push_back(left_path[i + 1]);
115.1435 + (*_blossom_data)[left_path[i + 1]].status = EVEN;
115.1436 + oddToEven(left_path[i + 1], tree);
115.1437 + _tree_set->erase(left_path[i + 1]);
115.1438 + prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
115.1439 + }
115.1440 +
115.1441 + int k = 0;
115.1442 + while (right_path[k] != nca) ++k;
115.1443 +
115.1444 + subblossoms.push_back(nca);
115.1445 + (*_blossom_data)[nca].next = prev;
115.1446 +
115.1447 + for (int i = k - 2; i >= 0; i -= 2) {
115.1448 + subblossoms.push_back(right_path[i + 1]);
115.1449 + (*_blossom_data)[right_path[i + 1]].status = EVEN;
115.1450 + oddToEven(right_path[i + 1], tree);
115.1451 + _tree_set->erase(right_path[i + 1]);
115.1452 +
115.1453 + (*_blossom_data)[right_path[i + 1]].next =
115.1454 + (*_blossom_data)[right_path[i + 1]].pred;
115.1455 +
115.1456 + subblossoms.push_back(right_path[i]);
115.1457 + _tree_set->erase(right_path[i]);
115.1458 + }
115.1459 +
115.1460 + int surface =
115.1461 + _blossom_set->join(subblossoms.begin(), subblossoms.end());
115.1462 +
115.1463 + for (int i = 0; i < int(subblossoms.size()); ++i) {
115.1464 + if (!_blossom_set->trivial(subblossoms[i])) {
115.1465 + (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
115.1466 + }
115.1467 + (*_blossom_data)[subblossoms[i]].status = MATCHED;
115.1468 + }
115.1469 +
115.1470 + (*_blossom_data)[surface].pot = -2 * _delta_sum;
115.1471 + (*_blossom_data)[surface].offset = 0;
115.1472 + (*_blossom_data)[surface].status = EVEN;
115.1473 + (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
115.1474 + (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
115.1475 +
115.1476 + _tree_set->insert(surface, tree);
115.1477 + _tree_set->erase(nca);
115.1478 + }
115.1479 +
115.1480 + void splitBlossom(int blossom) {
115.1481 + Arc next = (*_blossom_data)[blossom].next;
115.1482 + Arc pred = (*_blossom_data)[blossom].pred;
115.1483 +
115.1484 + int tree = _tree_set->find(blossom);
115.1485 +
115.1486 + (*_blossom_data)[blossom].status = MATCHED;
115.1487 + oddToMatched(blossom);
115.1488 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
115.1489 + _delta2->erase(blossom);
115.1490 + }
115.1491 +
115.1492 + std::vector<int> subblossoms;
115.1493 + _blossom_set->split(blossom, std::back_inserter(subblossoms));
115.1494 +
115.1495 + Value offset = (*_blossom_data)[blossom].offset;
115.1496 + int b = _blossom_set->find(_graph.source(pred));
115.1497 + int d = _blossom_set->find(_graph.source(next));
115.1498 +
115.1499 + int ib = -1, id = -1;
115.1500 + for (int i = 0; i < int(subblossoms.size()); ++i) {
115.1501 + if (subblossoms[i] == b) ib = i;
115.1502 + if (subblossoms[i] == d) id = i;
115.1503 +
115.1504 + (*_blossom_data)[subblossoms[i]].offset = offset;
115.1505 + if (!_blossom_set->trivial(subblossoms[i])) {
115.1506 + (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
115.1507 + }
115.1508 + if (_blossom_set->classPrio(subblossoms[i]) !=
115.1509 + std::numeric_limits<Value>::max()) {
115.1510 + _delta2->push(subblossoms[i],
115.1511 + _blossom_set->classPrio(subblossoms[i]) -
115.1512 + (*_blossom_data)[subblossoms[i]].offset);
115.1513 + }
115.1514 + }
115.1515 +
115.1516 + if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
115.1517 + for (int i = (id + 1) % subblossoms.size();
115.1518 + i != ib; i = (i + 2) % subblossoms.size()) {
115.1519 + int sb = subblossoms[i];
115.1520 + int tb = subblossoms[(i + 1) % subblossoms.size()];
115.1521 + (*_blossom_data)[sb].next =
115.1522 + _graph.oppositeArc((*_blossom_data)[tb].next);
115.1523 + }
115.1524 +
115.1525 + for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
115.1526 + int sb = subblossoms[i];
115.1527 + int tb = subblossoms[(i + 1) % subblossoms.size()];
115.1528 + int ub = subblossoms[(i + 2) % subblossoms.size()];
115.1529 +
115.1530 + (*_blossom_data)[sb].status = ODD;
115.1531 + matchedToOdd(sb);
115.1532 + _tree_set->insert(sb, tree);
115.1533 + (*_blossom_data)[sb].pred = pred;
115.1534 + (*_blossom_data)[sb].next =
115.1535 + _graph.oppositeArc((*_blossom_data)[tb].next);
115.1536 +
115.1537 + pred = (*_blossom_data)[ub].next;
115.1538 +
115.1539 + (*_blossom_data)[tb].status = EVEN;
115.1540 + matchedToEven(tb, tree);
115.1541 + _tree_set->insert(tb, tree);
115.1542 + (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
115.1543 + }
115.1544 +
115.1545 + (*_blossom_data)[subblossoms[id]].status = ODD;
115.1546 + matchedToOdd(subblossoms[id]);
115.1547 + _tree_set->insert(subblossoms[id], tree);
115.1548 + (*_blossom_data)[subblossoms[id]].next = next;
115.1549 + (*_blossom_data)[subblossoms[id]].pred = pred;
115.1550 +
115.1551 + } else {
115.1552 +
115.1553 + for (int i = (ib + 1) % subblossoms.size();
115.1554 + i != id; i = (i + 2) % subblossoms.size()) {
115.1555 + int sb = subblossoms[i];
115.1556 + int tb = subblossoms[(i + 1) % subblossoms.size()];
115.1557 + (*_blossom_data)[sb].next =
115.1558 + _graph.oppositeArc((*_blossom_data)[tb].next);
115.1559 + }
115.1560 +
115.1561 + for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
115.1562 + int sb = subblossoms[i];
115.1563 + int tb = subblossoms[(i + 1) % subblossoms.size()];
115.1564 + int ub = subblossoms[(i + 2) % subblossoms.size()];
115.1565 +
115.1566 + (*_blossom_data)[sb].status = ODD;
115.1567 + matchedToOdd(sb);
115.1568 + _tree_set->insert(sb, tree);
115.1569 + (*_blossom_data)[sb].next = next;
115.1570 + (*_blossom_data)[sb].pred =
115.1571 + _graph.oppositeArc((*_blossom_data)[tb].next);
115.1572 +
115.1573 + (*_blossom_data)[tb].status = EVEN;
115.1574 + matchedToEven(tb, tree);
115.1575 + _tree_set->insert(tb, tree);
115.1576 + (*_blossom_data)[tb].pred =
115.1577 + (*_blossom_data)[tb].next =
115.1578 + _graph.oppositeArc((*_blossom_data)[ub].next);
115.1579 + next = (*_blossom_data)[ub].next;
115.1580 + }
115.1581 +
115.1582 + (*_blossom_data)[subblossoms[ib]].status = ODD;
115.1583 + matchedToOdd(subblossoms[ib]);
115.1584 + _tree_set->insert(subblossoms[ib], tree);
115.1585 + (*_blossom_data)[subblossoms[ib]].next = next;
115.1586 + (*_blossom_data)[subblossoms[ib]].pred = pred;
115.1587 + }
115.1588 + _tree_set->erase(blossom);
115.1589 + }
115.1590 +
115.1591 + void extractBlossom(int blossom, const Node& base, const Arc& matching) {
115.1592 + if (_blossom_set->trivial(blossom)) {
115.1593 + int bi = (*_node_index)[base];
115.1594 + Value pot = (*_node_data)[bi].pot;
115.1595 +
115.1596 + (*_matching)[base] = matching;
115.1597 + _blossom_node_list.push_back(base);
115.1598 + (*_node_potential)[base] = pot;
115.1599 + } else {
115.1600 +
115.1601 + Value pot = (*_blossom_data)[blossom].pot;
115.1602 + int bn = _blossom_node_list.size();
115.1603 +
115.1604 + std::vector<int> subblossoms;
115.1605 + _blossom_set->split(blossom, std::back_inserter(subblossoms));
115.1606 + int b = _blossom_set->find(base);
115.1607 + int ib = -1;
115.1608 + for (int i = 0; i < int(subblossoms.size()); ++i) {
115.1609 + if (subblossoms[i] == b) { ib = i; break; }
115.1610 + }
115.1611 +
115.1612 + for (int i = 1; i < int(subblossoms.size()); i += 2) {
115.1613 + int sb = subblossoms[(ib + i) % subblossoms.size()];
115.1614 + int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
115.1615 +
115.1616 + Arc m = (*_blossom_data)[tb].next;
115.1617 + extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
115.1618 + extractBlossom(tb, _graph.source(m), m);
115.1619 + }
115.1620 + extractBlossom(subblossoms[ib], base, matching);
115.1621 +
115.1622 + int en = _blossom_node_list.size();
115.1623 +
115.1624 + _blossom_potential.push_back(BlossomVariable(bn, en, pot));
115.1625 + }
115.1626 + }
115.1627 +
115.1628 + void extractMatching() {
115.1629 + std::vector<int> blossoms;
115.1630 + for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
115.1631 + blossoms.push_back(c);
115.1632 + }
115.1633 +
115.1634 + for (int i = 0; i < int(blossoms.size()); ++i) {
115.1635 + if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
115.1636 +
115.1637 + Value offset = (*_blossom_data)[blossoms[i]].offset;
115.1638 + (*_blossom_data)[blossoms[i]].pot += 2 * offset;
115.1639 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
115.1640 + n != INVALID; ++n) {
115.1641 + (*_node_data)[(*_node_index)[n]].pot -= offset;
115.1642 + }
115.1643 +
115.1644 + Arc matching = (*_blossom_data)[blossoms[i]].next;
115.1645 + Node base = _graph.source(matching);
115.1646 + extractBlossom(blossoms[i], base, matching);
115.1647 + } else {
115.1648 + Node base = (*_blossom_data)[blossoms[i]].base;
115.1649 + extractBlossom(blossoms[i], base, INVALID);
115.1650 + }
115.1651 + }
115.1652 + }
115.1653 +
115.1654 + public:
115.1655 +
115.1656 + /// \brief Constructor
115.1657 + ///
115.1658 + /// Constructor.
115.1659 + MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
115.1660 + : _graph(graph), _weight(weight), _matching(0),
115.1661 + _node_potential(0), _blossom_potential(), _blossom_node_list(),
115.1662 + _node_num(0), _blossom_num(0),
115.1663 +
115.1664 + _blossom_index(0), _blossom_set(0), _blossom_data(0),
115.1665 + _node_index(0), _node_heap_index(0), _node_data(0),
115.1666 + _tree_set_index(0), _tree_set(0),
115.1667 +
115.1668 + _delta1_index(0), _delta1(0),
115.1669 + _delta2_index(0), _delta2(0),
115.1670 + _delta3_index(0), _delta3(0),
115.1671 + _delta4_index(0), _delta4(0),
115.1672 +
115.1673 + _delta_sum() {}
115.1674 +
115.1675 + ~MaxWeightedMatching() {
115.1676 + destroyStructures();
115.1677 + }
115.1678 +
115.1679 + /// \name Execution Control
115.1680 + /// The simplest way to execute the algorithm is to use the
115.1681 + /// \ref run() member function.
115.1682 +
115.1683 + ///@{
115.1684 +
115.1685 + /// \brief Initialize the algorithm
115.1686 + ///
115.1687 + /// This function initializes the algorithm.
115.1688 + void init() {
115.1689 + createStructures();
115.1690 +
115.1691 + for (ArcIt e(_graph); e != INVALID; ++e) {
115.1692 + (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
115.1693 + }
115.1694 + for (NodeIt n(_graph); n != INVALID; ++n) {
115.1695 + (*_delta1_index)[n] = _delta1->PRE_HEAP;
115.1696 + }
115.1697 + for (EdgeIt e(_graph); e != INVALID; ++e) {
115.1698 + (*_delta3_index)[e] = _delta3->PRE_HEAP;
115.1699 + }
115.1700 + for (int i = 0; i < _blossom_num; ++i) {
115.1701 + (*_delta2_index)[i] = _delta2->PRE_HEAP;
115.1702 + (*_delta4_index)[i] = _delta4->PRE_HEAP;
115.1703 + }
115.1704 +
115.1705 + int index = 0;
115.1706 + for (NodeIt n(_graph); n != INVALID; ++n) {
115.1707 + Value max = 0;
115.1708 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
115.1709 + if (_graph.target(e) == n) continue;
115.1710 + if ((dualScale * _weight[e]) / 2 > max) {
115.1711 + max = (dualScale * _weight[e]) / 2;
115.1712 + }
115.1713 + }
115.1714 + (*_node_index)[n] = index;
115.1715 + (*_node_data)[index].pot = max;
115.1716 + _delta1->push(n, max);
115.1717 + int blossom =
115.1718 + _blossom_set->insert(n, std::numeric_limits<Value>::max());
115.1719 +
115.1720 + _tree_set->insert(blossom);
115.1721 +
115.1722 + (*_blossom_data)[blossom].status = EVEN;
115.1723 + (*_blossom_data)[blossom].pred = INVALID;
115.1724 + (*_blossom_data)[blossom].next = INVALID;
115.1725 + (*_blossom_data)[blossom].pot = 0;
115.1726 + (*_blossom_data)[blossom].offset = 0;
115.1727 + ++index;
115.1728 + }
115.1729 + for (EdgeIt e(_graph); e != INVALID; ++e) {
115.1730 + int si = (*_node_index)[_graph.u(e)];
115.1731 + int ti = (*_node_index)[_graph.v(e)];
115.1732 + if (_graph.u(e) != _graph.v(e)) {
115.1733 + _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
115.1734 + dualScale * _weight[e]) / 2);
115.1735 + }
115.1736 + }
115.1737 + }
115.1738 +
115.1739 + /// \brief Start the algorithm
115.1740 + ///
115.1741 + /// This function starts the algorithm.
115.1742 + ///
115.1743 + /// \pre \ref init() must be called before using this function.
115.1744 + void start() {
115.1745 + enum OpType {
115.1746 + D1, D2, D3, D4
115.1747 + };
115.1748 +
115.1749 + int unmatched = _node_num;
115.1750 + while (unmatched > 0) {
115.1751 + Value d1 = !_delta1->empty() ?
115.1752 + _delta1->prio() : std::numeric_limits<Value>::max();
115.1753 +
115.1754 + Value d2 = !_delta2->empty() ?
115.1755 + _delta2->prio() : std::numeric_limits<Value>::max();
115.1756 +
115.1757 + Value d3 = !_delta3->empty() ?
115.1758 + _delta3->prio() : std::numeric_limits<Value>::max();
115.1759 +
115.1760 + Value d4 = !_delta4->empty() ?
115.1761 + _delta4->prio() : std::numeric_limits<Value>::max();
115.1762 +
115.1763 + _delta_sum = d1; OpType ot = D1;
115.1764 + if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
115.1765 + if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
115.1766 + if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
115.1767 +
115.1768 +
115.1769 + switch (ot) {
115.1770 + case D1:
115.1771 + {
115.1772 + Node n = _delta1->top();
115.1773 + unmatchNode(n);
115.1774 + --unmatched;
115.1775 + }
115.1776 + break;
115.1777 + case D2:
115.1778 + {
115.1779 + int blossom = _delta2->top();
115.1780 + Node n = _blossom_set->classTop(blossom);
115.1781 + Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
115.1782 + extendOnArc(e);
115.1783 + }
115.1784 + break;
115.1785 + case D3:
115.1786 + {
115.1787 + Edge e = _delta3->top();
115.1788 +
115.1789 + int left_blossom = _blossom_set->find(_graph.u(e));
115.1790 + int right_blossom = _blossom_set->find(_graph.v(e));
115.1791 +
115.1792 + if (left_blossom == right_blossom) {
115.1793 + _delta3->pop();
115.1794 + } else {
115.1795 + int left_tree;
115.1796 + if ((*_blossom_data)[left_blossom].status == EVEN) {
115.1797 + left_tree = _tree_set->find(left_blossom);
115.1798 + } else {
115.1799 + left_tree = -1;
115.1800 + ++unmatched;
115.1801 + }
115.1802 + int right_tree;
115.1803 + if ((*_blossom_data)[right_blossom].status == EVEN) {
115.1804 + right_tree = _tree_set->find(right_blossom);
115.1805 + } else {
115.1806 + right_tree = -1;
115.1807 + ++unmatched;
115.1808 + }
115.1809 +
115.1810 + if (left_tree == right_tree) {
115.1811 + shrinkOnEdge(e, left_tree);
115.1812 + } else {
115.1813 + augmentOnEdge(e);
115.1814 + unmatched -= 2;
115.1815 + }
115.1816 + }
115.1817 + } break;
115.1818 + case D4:
115.1819 + splitBlossom(_delta4->top());
115.1820 + break;
115.1821 + }
115.1822 + }
115.1823 + extractMatching();
115.1824 + }
115.1825 +
115.1826 + /// \brief Run the algorithm.
115.1827 + ///
115.1828 + /// This method runs the \c %MaxWeightedMatching algorithm.
115.1829 + ///
115.1830 + /// \note mwm.run() is just a shortcut of the following code.
115.1831 + /// \code
115.1832 + /// mwm.init();
115.1833 + /// mwm.start();
115.1834 + /// \endcode
115.1835 + void run() {
115.1836 + init();
115.1837 + start();
115.1838 + }
115.1839 +
115.1840 + /// @}
115.1841 +
115.1842 + /// \name Primal Solution
115.1843 + /// Functions to get the primal solution, i.e. the maximum weighted
115.1844 + /// matching.\n
115.1845 + /// Either \ref run() or \ref start() function should be called before
115.1846 + /// using them.
115.1847 +
115.1848 + /// @{
115.1849 +
115.1850 + /// \brief Return the weight of the matching.
115.1851 + ///
115.1852 + /// This function returns the weight of the found matching.
115.1853 + ///
115.1854 + /// \pre Either run() or start() must be called before using this function.
115.1855 + Value matchingWeight() const {
115.1856 + Value sum = 0;
115.1857 + for (NodeIt n(_graph); n != INVALID; ++n) {
115.1858 + if ((*_matching)[n] != INVALID) {
115.1859 + sum += _weight[(*_matching)[n]];
115.1860 + }
115.1861 + }
115.1862 + return sum /= 2;
115.1863 + }
115.1864 +
115.1865 + /// \brief Return the size (cardinality) of the matching.
115.1866 + ///
115.1867 + /// This function returns the size (cardinality) of the found matching.
115.1868 + ///
115.1869 + /// \pre Either run() or start() must be called before using this function.
115.1870 + int matchingSize() const {
115.1871 + int num = 0;
115.1872 + for (NodeIt n(_graph); n != INVALID; ++n) {
115.1873 + if ((*_matching)[n] != INVALID) {
115.1874 + ++num;
115.1875 + }
115.1876 + }
115.1877 + return num /= 2;
115.1878 + }
115.1879 +
115.1880 + /// \brief Return \c true if the given edge is in the matching.
115.1881 + ///
115.1882 + /// This function returns \c true if the given edge is in the found
115.1883 + /// matching.
115.1884 + ///
115.1885 + /// \pre Either run() or start() must be called before using this function.
115.1886 + bool matching(const Edge& edge) const {
115.1887 + return edge == (*_matching)[_graph.u(edge)];
115.1888 + }
115.1889 +
115.1890 + /// \brief Return the matching arc (or edge) incident to the given node.
115.1891 + ///
115.1892 + /// This function returns the matching arc (or edge) incident to the
115.1893 + /// given node in the found matching or \c INVALID if the node is
115.1894 + /// not covered by the matching.
115.1895 + ///
115.1896 + /// \pre Either run() or start() must be called before using this function.
115.1897 + Arc matching(const Node& node) const {
115.1898 + return (*_matching)[node];
115.1899 + }
115.1900 +
115.1901 + /// \brief Return a const reference to the matching map.
115.1902 + ///
115.1903 + /// This function returns a const reference to a node map that stores
115.1904 + /// the matching arc (or edge) incident to each node.
115.1905 + const MatchingMap& matchingMap() const {
115.1906 + return *_matching;
115.1907 + }
115.1908 +
115.1909 + /// \brief Return the mate of the given node.
115.1910 + ///
115.1911 + /// This function returns the mate of the given node in the found
115.1912 + /// matching or \c INVALID if the node is not covered by the matching.
115.1913 + ///
115.1914 + /// \pre Either run() or start() must be called before using this function.
115.1915 + Node mate(const Node& node) const {
115.1916 + return (*_matching)[node] != INVALID ?
115.1917 + _graph.target((*_matching)[node]) : INVALID;
115.1918 + }
115.1919 +
115.1920 + /// @}
115.1921 +
115.1922 + /// \name Dual Solution
115.1923 + /// Functions to get the dual solution.\n
115.1924 + /// Either \ref run() or \ref start() function should be called before
115.1925 + /// using them.
115.1926 +
115.1927 + /// @{
115.1928 +
115.1929 + /// \brief Return the value of the dual solution.
115.1930 + ///
115.1931 + /// This function returns the value of the dual solution.
115.1932 + /// It should be equal to the primal value scaled by \ref dualScale
115.1933 + /// "dual scale".
115.1934 + ///
115.1935 + /// \pre Either run() or start() must be called before using this function.
115.1936 + Value dualValue() const {
115.1937 + Value sum = 0;
115.1938 + for (NodeIt n(_graph); n != INVALID; ++n) {
115.1939 + sum += nodeValue(n);
115.1940 + }
115.1941 + for (int i = 0; i < blossomNum(); ++i) {
115.1942 + sum += blossomValue(i) * (blossomSize(i) / 2);
115.1943 + }
115.1944 + return sum;
115.1945 + }
115.1946 +
115.1947 + /// \brief Return the dual value (potential) of the given node.
115.1948 + ///
115.1949 + /// This function returns the dual value (potential) of the given node.
115.1950 + ///
115.1951 + /// \pre Either run() or start() must be called before using this function.
115.1952 + Value nodeValue(const Node& n) const {
115.1953 + return (*_node_potential)[n];
115.1954 + }
115.1955 +
115.1956 + /// \brief Return the number of the blossoms in the basis.
115.1957 + ///
115.1958 + /// This function returns the number of the blossoms in the basis.
115.1959 + ///
115.1960 + /// \pre Either run() or start() must be called before using this function.
115.1961 + /// \see BlossomIt
115.1962 + int blossomNum() const {
115.1963 + return _blossom_potential.size();
115.1964 + }
115.1965 +
115.1966 + /// \brief Return the number of the nodes in the given blossom.
115.1967 + ///
115.1968 + /// This function returns the number of the nodes in the given blossom.
115.1969 + ///
115.1970 + /// \pre Either run() or start() must be called before using this function.
115.1971 + /// \see BlossomIt
115.1972 + int blossomSize(int k) const {
115.1973 + return _blossom_potential[k].end - _blossom_potential[k].begin;
115.1974 + }
115.1975 +
115.1976 + /// \brief Return the dual value (ptential) of the given blossom.
115.1977 + ///
115.1978 + /// This function returns the dual value (ptential) of the given blossom.
115.1979 + ///
115.1980 + /// \pre Either run() or start() must be called before using this function.
115.1981 + Value blossomValue(int k) const {
115.1982 + return _blossom_potential[k].value;
115.1983 + }
115.1984 +
115.1985 + /// \brief Iterator for obtaining the nodes of a blossom.
115.1986 + ///
115.1987 + /// This class provides an iterator for obtaining the nodes of the
115.1988 + /// given blossom. It lists a subset of the nodes.
115.1989 + /// Before using this iterator, you must allocate a
115.1990 + /// MaxWeightedMatching class and execute it.
115.1991 + class BlossomIt {
115.1992 + public:
115.1993 +
115.1994 + /// \brief Constructor.
115.1995 + ///
115.1996 + /// Constructor to get the nodes of the given variable.
115.1997 + ///
115.1998 + /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or
115.1999 + /// \ref MaxWeightedMatching::start() "algorithm.start()" must be
115.2000 + /// called before initializing this iterator.
115.2001 + BlossomIt(const MaxWeightedMatching& algorithm, int variable)
115.2002 + : _algorithm(&algorithm)
115.2003 + {
115.2004 + _index = _algorithm->_blossom_potential[variable].begin;
115.2005 + _last = _algorithm->_blossom_potential[variable].end;
115.2006 + }
115.2007 +
115.2008 + /// \brief Conversion to \c Node.
115.2009 + ///
115.2010 + /// Conversion to \c Node.
115.2011 + operator Node() const {
115.2012 + return _algorithm->_blossom_node_list[_index];
115.2013 + }
115.2014 +
115.2015 + /// \brief Increment operator.
115.2016 + ///
115.2017 + /// Increment operator.
115.2018 + BlossomIt& operator++() {
115.2019 + ++_index;
115.2020 + return *this;
115.2021 + }
115.2022 +
115.2023 + /// \brief Validity checking
115.2024 + ///
115.2025 + /// Checks whether the iterator is invalid.
115.2026 + bool operator==(Invalid) const { return _index == _last; }
115.2027 +
115.2028 + /// \brief Validity checking
115.2029 + ///
115.2030 + /// Checks whether the iterator is valid.
115.2031 + bool operator!=(Invalid) const { return _index != _last; }
115.2032 +
115.2033 + private:
115.2034 + const MaxWeightedMatching* _algorithm;
115.2035 + int _last;
115.2036 + int _index;
115.2037 + };
115.2038 +
115.2039 + /// @}
115.2040 +
115.2041 + };
115.2042 +
115.2043 + /// \ingroup matching
115.2044 + ///
115.2045 + /// \brief Weighted perfect matching in general graphs
115.2046 + ///
115.2047 + /// This class provides an efficient implementation of Edmond's
115.2048 + /// maximum weighted perfect matching algorithm. The implementation
115.2049 + /// is based on extensive use of priority queues and provides
115.2050 + /// \f$O(nm\log n)\f$ time complexity.
115.2051 + ///
115.2052 + /// The maximum weighted perfect matching problem is to find a subset of
115.2053 + /// the edges in an undirected graph with maximum overall weight for which
115.2054 + /// each node has exactly one incident edge.
115.2055 + /// It can be formulated with the following linear program.
115.2056 + /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
115.2057 + /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
115.2058 + \quad \forall B\in\mathcal{O}\f] */
115.2059 + /// \f[x_e \ge 0\quad \forall e\in E\f]
115.2060 + /// \f[\max \sum_{e\in E}x_ew_e\f]
115.2061 + /// where \f$\delta(X)\f$ is the set of edges incident to a node in
115.2062 + /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
115.2063 + /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
115.2064 + /// subsets of the nodes.
115.2065 + ///
115.2066 + /// The algorithm calculates an optimal matching and a proof of the
115.2067 + /// optimality. The solution of the dual problem can be used to check
115.2068 + /// the result of the algorithm. The dual linear problem is the
115.2069 + /// following.
115.2070 + /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
115.2071 + w_{uv} \quad \forall uv\in E\f] */
115.2072 + /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
115.2073 + /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
115.2074 + \frac{\vert B \vert - 1}{2}z_B\f] */
115.2075 + ///
115.2076 + /// The algorithm can be executed with the run() function.
115.2077 + /// After it the matching (the primal solution) and the dual solution
115.2078 + /// can be obtained using the query functions and the
115.2079 + /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class,
115.2080 + /// which is able to iterate on the nodes of a blossom.
115.2081 + /// If the value type is integer, then the dual solution is multiplied
115.2082 + /// by \ref MaxWeightedMatching::dualScale "4".
115.2083 + ///
115.2084 + /// \tparam GR The undirected graph type the algorithm runs on.
115.2085 + /// \tparam WM The type edge weight map. The default type is
115.2086 + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
115.2087 +#ifdef DOXYGEN
115.2088 + template <typename GR, typename WM>
115.2089 +#else
115.2090 + template <typename GR,
115.2091 + typename WM = typename GR::template EdgeMap<int> >
115.2092 +#endif
115.2093 + class MaxWeightedPerfectMatching {
115.2094 + public:
115.2095 +
115.2096 + /// The graph type of the algorithm
115.2097 + typedef GR Graph;
115.2098 + /// The type of the edge weight map
115.2099 + typedef WM WeightMap;
115.2100 + /// The value type of the edge weights
115.2101 + typedef typename WeightMap::Value Value;
115.2102 +
115.2103 + /// \brief Scaling factor for dual solution
115.2104 + ///
115.2105 + /// Scaling factor for dual solution, it is equal to 4 or 1
115.2106 + /// according to the value type.
115.2107 + static const int dualScale =
115.2108 + std::numeric_limits<Value>::is_integer ? 4 : 1;
115.2109 +
115.2110 + /// The type of the matching map
115.2111 + typedef typename Graph::template NodeMap<typename Graph::Arc>
115.2112 + MatchingMap;
115.2113 +
115.2114 + private:
115.2115 +
115.2116 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
115.2117 +
115.2118 + typedef typename Graph::template NodeMap<Value> NodePotential;
115.2119 + typedef std::vector<Node> BlossomNodeList;
115.2120 +
115.2121 + struct BlossomVariable {
115.2122 + int begin, end;
115.2123 + Value value;
115.2124 +
115.2125 + BlossomVariable(int _begin, int _end, Value _value)
115.2126 + : begin(_begin), end(_end), value(_value) {}
115.2127 +
115.2128 + };
115.2129 +
115.2130 + typedef std::vector<BlossomVariable> BlossomPotential;
115.2131 +
115.2132 + const Graph& _graph;
115.2133 + const WeightMap& _weight;
115.2134 +
115.2135 + MatchingMap* _matching;
115.2136 +
115.2137 + NodePotential* _node_potential;
115.2138 +
115.2139 + BlossomPotential _blossom_potential;
115.2140 + BlossomNodeList _blossom_node_list;
115.2141 +
115.2142 + int _node_num;
115.2143 + int _blossom_num;
115.2144 +
115.2145 + typedef RangeMap<int> IntIntMap;
115.2146 +
115.2147 + enum Status {
115.2148 + EVEN = -1, MATCHED = 0, ODD = 1
115.2149 + };
115.2150 +
115.2151 + typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
115.2152 + struct BlossomData {
115.2153 + int tree;
115.2154 + Status status;
115.2155 + Arc pred, next;
115.2156 + Value pot, offset;
115.2157 + };
115.2158 +
115.2159 + IntNodeMap *_blossom_index;
115.2160 + BlossomSet *_blossom_set;
115.2161 + RangeMap<BlossomData>* _blossom_data;
115.2162 +
115.2163 + IntNodeMap *_node_index;
115.2164 + IntArcMap *_node_heap_index;
115.2165 +
115.2166 + struct NodeData {
115.2167 +
115.2168 + NodeData(IntArcMap& node_heap_index)
115.2169 + : heap(node_heap_index) {}
115.2170 +
115.2171 + int blossom;
115.2172 + Value pot;
115.2173 + BinHeap<Value, IntArcMap> heap;
115.2174 + std::map<int, Arc> heap_index;
115.2175 +
115.2176 + int tree;
115.2177 + };
115.2178 +
115.2179 + RangeMap<NodeData>* _node_data;
115.2180 +
115.2181 + typedef ExtendFindEnum<IntIntMap> TreeSet;
115.2182 +
115.2183 + IntIntMap *_tree_set_index;
115.2184 + TreeSet *_tree_set;
115.2185 +
115.2186 + IntIntMap *_delta2_index;
115.2187 + BinHeap<Value, IntIntMap> *_delta2;
115.2188 +
115.2189 + IntEdgeMap *_delta3_index;
115.2190 + BinHeap<Value, IntEdgeMap> *_delta3;
115.2191 +
115.2192 + IntIntMap *_delta4_index;
115.2193 + BinHeap<Value, IntIntMap> *_delta4;
115.2194 +
115.2195 + Value _delta_sum;
115.2196 +
115.2197 + void createStructures() {
115.2198 + _node_num = countNodes(_graph);
115.2199 + _blossom_num = _node_num * 3 / 2;
115.2200 +
115.2201 + if (!_matching) {
115.2202 + _matching = new MatchingMap(_graph);
115.2203 + }
115.2204 + if (!_node_potential) {
115.2205 + _node_potential = new NodePotential(_graph);
115.2206 + }
115.2207 + if (!_blossom_set) {
115.2208 + _blossom_index = new IntNodeMap(_graph);
115.2209 + _blossom_set = new BlossomSet(*_blossom_index);
115.2210 + _blossom_data = new RangeMap<BlossomData>(_blossom_num);
115.2211 + }
115.2212 +
115.2213 + if (!_node_index) {
115.2214 + _node_index = new IntNodeMap(_graph);
115.2215 + _node_heap_index = new IntArcMap(_graph);
115.2216 + _node_data = new RangeMap<NodeData>(_node_num,
115.2217 + NodeData(*_node_heap_index));
115.2218 + }
115.2219 +
115.2220 + if (!_tree_set) {
115.2221 + _tree_set_index = new IntIntMap(_blossom_num);
115.2222 + _tree_set = new TreeSet(*_tree_set_index);
115.2223 + }
115.2224 + if (!_delta2) {
115.2225 + _delta2_index = new IntIntMap(_blossom_num);
115.2226 + _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
115.2227 + }
115.2228 + if (!_delta3) {
115.2229 + _delta3_index = new IntEdgeMap(_graph);
115.2230 + _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
115.2231 + }
115.2232 + if (!_delta4) {
115.2233 + _delta4_index = new IntIntMap(_blossom_num);
115.2234 + _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
115.2235 + }
115.2236 + }
115.2237 +
115.2238 + void destroyStructures() {
115.2239 + _node_num = countNodes(_graph);
115.2240 + _blossom_num = _node_num * 3 / 2;
115.2241 +
115.2242 + if (_matching) {
115.2243 + delete _matching;
115.2244 + }
115.2245 + if (_node_potential) {
115.2246 + delete _node_potential;
115.2247 + }
115.2248 + if (_blossom_set) {
115.2249 + delete _blossom_index;
115.2250 + delete _blossom_set;
115.2251 + delete _blossom_data;
115.2252 + }
115.2253 +
115.2254 + if (_node_index) {
115.2255 + delete _node_index;
115.2256 + delete _node_heap_index;
115.2257 + delete _node_data;
115.2258 + }
115.2259 +
115.2260 + if (_tree_set) {
115.2261 + delete _tree_set_index;
115.2262 + delete _tree_set;
115.2263 + }
115.2264 + if (_delta2) {
115.2265 + delete _delta2_index;
115.2266 + delete _delta2;
115.2267 + }
115.2268 + if (_delta3) {
115.2269 + delete _delta3_index;
115.2270 + delete _delta3;
115.2271 + }
115.2272 + if (_delta4) {
115.2273 + delete _delta4_index;
115.2274 + delete _delta4;
115.2275 + }
115.2276 + }
115.2277 +
115.2278 + void matchedToEven(int blossom, int tree) {
115.2279 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
115.2280 + _delta2->erase(blossom);
115.2281 + }
115.2282 +
115.2283 + if (!_blossom_set->trivial(blossom)) {
115.2284 + (*_blossom_data)[blossom].pot -=
115.2285 + 2 * (_delta_sum - (*_blossom_data)[blossom].offset);
115.2286 + }
115.2287 +
115.2288 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
115.2289 + n != INVALID; ++n) {
115.2290 +
115.2291 + _blossom_set->increase(n, std::numeric_limits<Value>::max());
115.2292 + int ni = (*_node_index)[n];
115.2293 +
115.2294 + (*_node_data)[ni].heap.clear();
115.2295 + (*_node_data)[ni].heap_index.clear();
115.2296 +
115.2297 + (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
115.2298 +
115.2299 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
115.2300 + Node v = _graph.source(e);
115.2301 + int vb = _blossom_set->find(v);
115.2302 + int vi = (*_node_index)[v];
115.2303 +
115.2304 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
115.2305 + dualScale * _weight[e];
115.2306 +
115.2307 + if ((*_blossom_data)[vb].status == EVEN) {
115.2308 + if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
115.2309 + _delta3->push(e, rw / 2);
115.2310 + }
115.2311 + } else {
115.2312 + typename std::map<int, Arc>::iterator it =
115.2313 + (*_node_data)[vi].heap_index.find(tree);
115.2314 +
115.2315 + if (it != (*_node_data)[vi].heap_index.end()) {
115.2316 + if ((*_node_data)[vi].heap[it->second] > rw) {
115.2317 + (*_node_data)[vi].heap.replace(it->second, e);
115.2318 + (*_node_data)[vi].heap.decrease(e, rw);
115.2319 + it->second = e;
115.2320 + }
115.2321 + } else {
115.2322 + (*_node_data)[vi].heap.push(e, rw);
115.2323 + (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
115.2324 + }
115.2325 +
115.2326 + if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
115.2327 + _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
115.2328 +
115.2329 + if ((*_blossom_data)[vb].status == MATCHED) {
115.2330 + if (_delta2->state(vb) != _delta2->IN_HEAP) {
115.2331 + _delta2->push(vb, _blossom_set->classPrio(vb) -
115.2332 + (*_blossom_data)[vb].offset);
115.2333 + } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
115.2334 + (*_blossom_data)[vb].offset){
115.2335 + _delta2->decrease(vb, _blossom_set->classPrio(vb) -
115.2336 + (*_blossom_data)[vb].offset);
115.2337 + }
115.2338 + }
115.2339 + }
115.2340 + }
115.2341 + }
115.2342 + }
115.2343 + (*_blossom_data)[blossom].offset = 0;
115.2344 + }
115.2345 +
115.2346 + void matchedToOdd(int blossom) {
115.2347 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
115.2348 + _delta2->erase(blossom);
115.2349 + }
115.2350 + (*_blossom_data)[blossom].offset += _delta_sum;
115.2351 + if (!_blossom_set->trivial(blossom)) {
115.2352 + _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
115.2353 + (*_blossom_data)[blossom].offset);
115.2354 + }
115.2355 + }
115.2356 +
115.2357 + void evenToMatched(int blossom, int tree) {
115.2358 + if (!_blossom_set->trivial(blossom)) {
115.2359 + (*_blossom_data)[blossom].pot += 2 * _delta_sum;
115.2360 + }
115.2361 +
115.2362 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
115.2363 + n != INVALID; ++n) {
115.2364 + int ni = (*_node_index)[n];
115.2365 + (*_node_data)[ni].pot -= _delta_sum;
115.2366 +
115.2367 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
115.2368 + Node v = _graph.source(e);
115.2369 + int vb = _blossom_set->find(v);
115.2370 + int vi = (*_node_index)[v];
115.2371 +
115.2372 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
115.2373 + dualScale * _weight[e];
115.2374 +
115.2375 + if (vb == blossom) {
115.2376 + if (_delta3->state(e) == _delta3->IN_HEAP) {
115.2377 + _delta3->erase(e);
115.2378 + }
115.2379 + } else if ((*_blossom_data)[vb].status == EVEN) {
115.2380 +
115.2381 + if (_delta3->state(e) == _delta3->IN_HEAP) {
115.2382 + _delta3->erase(e);
115.2383 + }
115.2384 +
115.2385 + int vt = _tree_set->find(vb);
115.2386 +
115.2387 + if (vt != tree) {
115.2388 +
115.2389 + Arc r = _graph.oppositeArc(e);
115.2390 +
115.2391 + typename std::map<int, Arc>::iterator it =
115.2392 + (*_node_data)[ni].heap_index.find(vt);
115.2393 +
115.2394 + if (it != (*_node_data)[ni].heap_index.end()) {
115.2395 + if ((*_node_data)[ni].heap[it->second] > rw) {
115.2396 + (*_node_data)[ni].heap.replace(it->second, r);
115.2397 + (*_node_data)[ni].heap.decrease(r, rw);
115.2398 + it->second = r;
115.2399 + }
115.2400 + } else {
115.2401 + (*_node_data)[ni].heap.push(r, rw);
115.2402 + (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
115.2403 + }
115.2404 +
115.2405 + if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
115.2406 + _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
115.2407 +
115.2408 + if (_delta2->state(blossom) != _delta2->IN_HEAP) {
115.2409 + _delta2->push(blossom, _blossom_set->classPrio(blossom) -
115.2410 + (*_blossom_data)[blossom].offset);
115.2411 + } else if ((*_delta2)[blossom] >
115.2412 + _blossom_set->classPrio(blossom) -
115.2413 + (*_blossom_data)[blossom].offset){
115.2414 + _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
115.2415 + (*_blossom_data)[blossom].offset);
115.2416 + }
115.2417 + }
115.2418 + }
115.2419 + } else {
115.2420 +
115.2421 + typename std::map<int, Arc>::iterator it =
115.2422 + (*_node_data)[vi].heap_index.find(tree);
115.2423 +
115.2424 + if (it != (*_node_data)[vi].heap_index.end()) {
115.2425 + (*_node_data)[vi].heap.erase(it->second);
115.2426 + (*_node_data)[vi].heap_index.erase(it);
115.2427 + if ((*_node_data)[vi].heap.empty()) {
115.2428 + _blossom_set->increase(v, std::numeric_limits<Value>::max());
115.2429 + } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
115.2430 + _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
115.2431 + }
115.2432 +
115.2433 + if ((*_blossom_data)[vb].status == MATCHED) {
115.2434 + if (_blossom_set->classPrio(vb) ==
115.2435 + std::numeric_limits<Value>::max()) {
115.2436 + _delta2->erase(vb);
115.2437 + } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
115.2438 + (*_blossom_data)[vb].offset) {
115.2439 + _delta2->increase(vb, _blossom_set->classPrio(vb) -
115.2440 + (*_blossom_data)[vb].offset);
115.2441 + }
115.2442 + }
115.2443 + }
115.2444 + }
115.2445 + }
115.2446 + }
115.2447 + }
115.2448 +
115.2449 + void oddToMatched(int blossom) {
115.2450 + (*_blossom_data)[blossom].offset -= _delta_sum;
115.2451 +
115.2452 + if (_blossom_set->classPrio(blossom) !=
115.2453 + std::numeric_limits<Value>::max()) {
115.2454 + _delta2->push(blossom, _blossom_set->classPrio(blossom) -
115.2455 + (*_blossom_data)[blossom].offset);
115.2456 + }
115.2457 +
115.2458 + if (!_blossom_set->trivial(blossom)) {
115.2459 + _delta4->erase(blossom);
115.2460 + }
115.2461 + }
115.2462 +
115.2463 + void oddToEven(int blossom, int tree) {
115.2464 + if (!_blossom_set->trivial(blossom)) {
115.2465 + _delta4->erase(blossom);
115.2466 + (*_blossom_data)[blossom].pot -=
115.2467 + 2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
115.2468 + }
115.2469 +
115.2470 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
115.2471 + n != INVALID; ++n) {
115.2472 + int ni = (*_node_index)[n];
115.2473 +
115.2474 + _blossom_set->increase(n, std::numeric_limits<Value>::max());
115.2475 +
115.2476 + (*_node_data)[ni].heap.clear();
115.2477 + (*_node_data)[ni].heap_index.clear();
115.2478 + (*_node_data)[ni].pot +=
115.2479 + 2 * _delta_sum - (*_blossom_data)[blossom].offset;
115.2480 +
115.2481 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
115.2482 + Node v = _graph.source(e);
115.2483 + int vb = _blossom_set->find(v);
115.2484 + int vi = (*_node_index)[v];
115.2485 +
115.2486 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
115.2487 + dualScale * _weight[e];
115.2488 +
115.2489 + if ((*_blossom_data)[vb].status == EVEN) {
115.2490 + if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
115.2491 + _delta3->push(e, rw / 2);
115.2492 + }
115.2493 + } else {
115.2494 +
115.2495 + typename std::map<int, Arc>::iterator it =
115.2496 + (*_node_data)[vi].heap_index.find(tree);
115.2497 +
115.2498 + if (it != (*_node_data)[vi].heap_index.end()) {
115.2499 + if ((*_node_data)[vi].heap[it->second] > rw) {
115.2500 + (*_node_data)[vi].heap.replace(it->second, e);
115.2501 + (*_node_data)[vi].heap.decrease(e, rw);
115.2502 + it->second = e;
115.2503 + }
115.2504 + } else {
115.2505 + (*_node_data)[vi].heap.push(e, rw);
115.2506 + (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
115.2507 + }
115.2508 +
115.2509 + if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
115.2510 + _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
115.2511 +
115.2512 + if ((*_blossom_data)[vb].status == MATCHED) {
115.2513 + if (_delta2->state(vb) != _delta2->IN_HEAP) {
115.2514 + _delta2->push(vb, _blossom_set->classPrio(vb) -
115.2515 + (*_blossom_data)[vb].offset);
115.2516 + } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
115.2517 + (*_blossom_data)[vb].offset) {
115.2518 + _delta2->decrease(vb, _blossom_set->classPrio(vb) -
115.2519 + (*_blossom_data)[vb].offset);
115.2520 + }
115.2521 + }
115.2522 + }
115.2523 + }
115.2524 + }
115.2525 + }
115.2526 + (*_blossom_data)[blossom].offset = 0;
115.2527 + }
115.2528 +
115.2529 + void alternatePath(int even, int tree) {
115.2530 + int odd;
115.2531 +
115.2532 + evenToMatched(even, tree);
115.2533 + (*_blossom_data)[even].status = MATCHED;
115.2534 +
115.2535 + while ((*_blossom_data)[even].pred != INVALID) {
115.2536 + odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
115.2537 + (*_blossom_data)[odd].status = MATCHED;
115.2538 + oddToMatched(odd);
115.2539 + (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
115.2540 +
115.2541 + even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
115.2542 + (*_blossom_data)[even].status = MATCHED;
115.2543 + evenToMatched(even, tree);
115.2544 + (*_blossom_data)[even].next =
115.2545 + _graph.oppositeArc((*_blossom_data)[odd].pred);
115.2546 + }
115.2547 +
115.2548 + }
115.2549 +
115.2550 + void destroyTree(int tree) {
115.2551 + for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
115.2552 + if ((*_blossom_data)[b].status == EVEN) {
115.2553 + (*_blossom_data)[b].status = MATCHED;
115.2554 + evenToMatched(b, tree);
115.2555 + } else if ((*_blossom_data)[b].status == ODD) {
115.2556 + (*_blossom_data)[b].status = MATCHED;
115.2557 + oddToMatched(b);
115.2558 + }
115.2559 + }
115.2560 + _tree_set->eraseClass(tree);
115.2561 + }
115.2562 +
115.2563 + void augmentOnEdge(const Edge& edge) {
115.2564 +
115.2565 + int left = _blossom_set->find(_graph.u(edge));
115.2566 + int right = _blossom_set->find(_graph.v(edge));
115.2567 +
115.2568 + int left_tree = _tree_set->find(left);
115.2569 + alternatePath(left, left_tree);
115.2570 + destroyTree(left_tree);
115.2571 +
115.2572 + int right_tree = _tree_set->find(right);
115.2573 + alternatePath(right, right_tree);
115.2574 + destroyTree(right_tree);
115.2575 +
115.2576 + (*_blossom_data)[left].next = _graph.direct(edge, true);
115.2577 + (*_blossom_data)[right].next = _graph.direct(edge, false);
115.2578 + }
115.2579 +
115.2580 + void extendOnArc(const Arc& arc) {
115.2581 + int base = _blossom_set->find(_graph.target(arc));
115.2582 + int tree = _tree_set->find(base);
115.2583 +
115.2584 + int odd = _blossom_set->find(_graph.source(arc));
115.2585 + _tree_set->insert(odd, tree);
115.2586 + (*_blossom_data)[odd].status = ODD;
115.2587 + matchedToOdd(odd);
115.2588 + (*_blossom_data)[odd].pred = arc;
115.2589 +
115.2590 + int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
115.2591 + (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
115.2592 + _tree_set->insert(even, tree);
115.2593 + (*_blossom_data)[even].status = EVEN;
115.2594 + matchedToEven(even, tree);
115.2595 + }
115.2596 +
115.2597 + void shrinkOnEdge(const Edge& edge, int tree) {
115.2598 + int nca = -1;
115.2599 + std::vector<int> left_path, right_path;
115.2600 +
115.2601 + {
115.2602 + std::set<int> left_set, right_set;
115.2603 + int left = _blossom_set->find(_graph.u(edge));
115.2604 + left_path.push_back(left);
115.2605 + left_set.insert(left);
115.2606 +
115.2607 + int right = _blossom_set->find(_graph.v(edge));
115.2608 + right_path.push_back(right);
115.2609 + right_set.insert(right);
115.2610 +
115.2611 + while (true) {
115.2612 +
115.2613 + if ((*_blossom_data)[left].pred == INVALID) break;
115.2614 +
115.2615 + left =
115.2616 + _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
115.2617 + left_path.push_back(left);
115.2618 + left =
115.2619 + _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
115.2620 + left_path.push_back(left);
115.2621 +
115.2622 + left_set.insert(left);
115.2623 +
115.2624 + if (right_set.find(left) != right_set.end()) {
115.2625 + nca = left;
115.2626 + break;
115.2627 + }
115.2628 +
115.2629 + if ((*_blossom_data)[right].pred == INVALID) break;
115.2630 +
115.2631 + right =
115.2632 + _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
115.2633 + right_path.push_back(right);
115.2634 + right =
115.2635 + _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
115.2636 + right_path.push_back(right);
115.2637 +
115.2638 + right_set.insert(right);
115.2639 +
115.2640 + if (left_set.find(right) != left_set.end()) {
115.2641 + nca = right;
115.2642 + break;
115.2643 + }
115.2644 +
115.2645 + }
115.2646 +
115.2647 + if (nca == -1) {
115.2648 + if ((*_blossom_data)[left].pred == INVALID) {
115.2649 + nca = right;
115.2650 + while (left_set.find(nca) == left_set.end()) {
115.2651 + nca =
115.2652 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
115.2653 + right_path.push_back(nca);
115.2654 + nca =
115.2655 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
115.2656 + right_path.push_back(nca);
115.2657 + }
115.2658 + } else {
115.2659 + nca = left;
115.2660 + while (right_set.find(nca) == right_set.end()) {
115.2661 + nca =
115.2662 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
115.2663 + left_path.push_back(nca);
115.2664 + nca =
115.2665 + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
115.2666 + left_path.push_back(nca);
115.2667 + }
115.2668 + }
115.2669 + }
115.2670 + }
115.2671 +
115.2672 + std::vector<int> subblossoms;
115.2673 + Arc prev;
115.2674 +
115.2675 + prev = _graph.direct(edge, true);
115.2676 + for (int i = 0; left_path[i] != nca; i += 2) {
115.2677 + subblossoms.push_back(left_path[i]);
115.2678 + (*_blossom_data)[left_path[i]].next = prev;
115.2679 + _tree_set->erase(left_path[i]);
115.2680 +
115.2681 + subblossoms.push_back(left_path[i + 1]);
115.2682 + (*_blossom_data)[left_path[i + 1]].status = EVEN;
115.2683 + oddToEven(left_path[i + 1], tree);
115.2684 + _tree_set->erase(left_path[i + 1]);
115.2685 + prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
115.2686 + }
115.2687 +
115.2688 + int k = 0;
115.2689 + while (right_path[k] != nca) ++k;
115.2690 +
115.2691 + subblossoms.push_back(nca);
115.2692 + (*_blossom_data)[nca].next = prev;
115.2693 +
115.2694 + for (int i = k - 2; i >= 0; i -= 2) {
115.2695 + subblossoms.push_back(right_path[i + 1]);
115.2696 + (*_blossom_data)[right_path[i + 1]].status = EVEN;
115.2697 + oddToEven(right_path[i + 1], tree);
115.2698 + _tree_set->erase(right_path[i + 1]);
115.2699 +
115.2700 + (*_blossom_data)[right_path[i + 1]].next =
115.2701 + (*_blossom_data)[right_path[i + 1]].pred;
115.2702 +
115.2703 + subblossoms.push_back(right_path[i]);
115.2704 + _tree_set->erase(right_path[i]);
115.2705 + }
115.2706 +
115.2707 + int surface =
115.2708 + _blossom_set->join(subblossoms.begin(), subblossoms.end());
115.2709 +
115.2710 + for (int i = 0; i < int(subblossoms.size()); ++i) {
115.2711 + if (!_blossom_set->trivial(subblossoms[i])) {
115.2712 + (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
115.2713 + }
115.2714 + (*_blossom_data)[subblossoms[i]].status = MATCHED;
115.2715 + }
115.2716 +
115.2717 + (*_blossom_data)[surface].pot = -2 * _delta_sum;
115.2718 + (*_blossom_data)[surface].offset = 0;
115.2719 + (*_blossom_data)[surface].status = EVEN;
115.2720 + (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
115.2721 + (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
115.2722 +
115.2723 + _tree_set->insert(surface, tree);
115.2724 + _tree_set->erase(nca);
115.2725 + }
115.2726 +
115.2727 + void splitBlossom(int blossom) {
115.2728 + Arc next = (*_blossom_data)[blossom].next;
115.2729 + Arc pred = (*_blossom_data)[blossom].pred;
115.2730 +
115.2731 + int tree = _tree_set->find(blossom);
115.2732 +
115.2733 + (*_blossom_data)[blossom].status = MATCHED;
115.2734 + oddToMatched(blossom);
115.2735 + if (_delta2->state(blossom) == _delta2->IN_HEAP) {
115.2736 + _delta2->erase(blossom);
115.2737 + }
115.2738 +
115.2739 + std::vector<int> subblossoms;
115.2740 + _blossom_set->split(blossom, std::back_inserter(subblossoms));
115.2741 +
115.2742 + Value offset = (*_blossom_data)[blossom].offset;
115.2743 + int b = _blossom_set->find(_graph.source(pred));
115.2744 + int d = _blossom_set->find(_graph.source(next));
115.2745 +
115.2746 + int ib = -1, id = -1;
115.2747 + for (int i = 0; i < int(subblossoms.size()); ++i) {
115.2748 + if (subblossoms[i] == b) ib = i;
115.2749 + if (subblossoms[i] == d) id = i;
115.2750 +
115.2751 + (*_blossom_data)[subblossoms[i]].offset = offset;
115.2752 + if (!_blossom_set->trivial(subblossoms[i])) {
115.2753 + (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
115.2754 + }
115.2755 + if (_blossom_set->classPrio(subblossoms[i]) !=
115.2756 + std::numeric_limits<Value>::max()) {
115.2757 + _delta2->push(subblossoms[i],
115.2758 + _blossom_set->classPrio(subblossoms[i]) -
115.2759 + (*_blossom_data)[subblossoms[i]].offset);
115.2760 + }
115.2761 + }
115.2762 +
115.2763 + if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
115.2764 + for (int i = (id + 1) % subblossoms.size();
115.2765 + i != ib; i = (i + 2) % subblossoms.size()) {
115.2766 + int sb = subblossoms[i];
115.2767 + int tb = subblossoms[(i + 1) % subblossoms.size()];
115.2768 + (*_blossom_data)[sb].next =
115.2769 + _graph.oppositeArc((*_blossom_data)[tb].next);
115.2770 + }
115.2771 +
115.2772 + for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
115.2773 + int sb = subblossoms[i];
115.2774 + int tb = subblossoms[(i + 1) % subblossoms.size()];
115.2775 + int ub = subblossoms[(i + 2) % subblossoms.size()];
115.2776 +
115.2777 + (*_blossom_data)[sb].status = ODD;
115.2778 + matchedToOdd(sb);
115.2779 + _tree_set->insert(sb, tree);
115.2780 + (*_blossom_data)[sb].pred = pred;
115.2781 + (*_blossom_data)[sb].next =
115.2782 + _graph.oppositeArc((*_blossom_data)[tb].next);
115.2783 +
115.2784 + pred = (*_blossom_data)[ub].next;
115.2785 +
115.2786 + (*_blossom_data)[tb].status = EVEN;
115.2787 + matchedToEven(tb, tree);
115.2788 + _tree_set->insert(tb, tree);
115.2789 + (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
115.2790 + }
115.2791 +
115.2792 + (*_blossom_data)[subblossoms[id]].status = ODD;
115.2793 + matchedToOdd(subblossoms[id]);
115.2794 + _tree_set->insert(subblossoms[id], tree);
115.2795 + (*_blossom_data)[subblossoms[id]].next = next;
115.2796 + (*_blossom_data)[subblossoms[id]].pred = pred;
115.2797 +
115.2798 + } else {
115.2799 +
115.2800 + for (int i = (ib + 1) % subblossoms.size();
115.2801 + i != id; i = (i + 2) % subblossoms.size()) {
115.2802 + int sb = subblossoms[i];
115.2803 + int tb = subblossoms[(i + 1) % subblossoms.size()];
115.2804 + (*_blossom_data)[sb].next =
115.2805 + _graph.oppositeArc((*_blossom_data)[tb].next);
115.2806 + }
115.2807 +
115.2808 + for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
115.2809 + int sb = subblossoms[i];
115.2810 + int tb = subblossoms[(i + 1) % subblossoms.size()];
115.2811 + int ub = subblossoms[(i + 2) % subblossoms.size()];
115.2812 +
115.2813 + (*_blossom_data)[sb].status = ODD;
115.2814 + matchedToOdd(sb);
115.2815 + _tree_set->insert(sb, tree);
115.2816 + (*_blossom_data)[sb].next = next;
115.2817 + (*_blossom_data)[sb].pred =
115.2818 + _graph.oppositeArc((*_blossom_data)[tb].next);
115.2819 +
115.2820 + (*_blossom_data)[tb].status = EVEN;
115.2821 + matchedToEven(tb, tree);
115.2822 + _tree_set->insert(tb, tree);
115.2823 + (*_blossom_data)[tb].pred =
115.2824 + (*_blossom_data)[tb].next =
115.2825 + _graph.oppositeArc((*_blossom_data)[ub].next);
115.2826 + next = (*_blossom_data)[ub].next;
115.2827 + }
115.2828 +
115.2829 + (*_blossom_data)[subblossoms[ib]].status = ODD;
115.2830 + matchedToOdd(subblossoms[ib]);
115.2831 + _tree_set->insert(subblossoms[ib], tree);
115.2832 + (*_blossom_data)[subblossoms[ib]].next = next;
115.2833 + (*_blossom_data)[subblossoms[ib]].pred = pred;
115.2834 + }
115.2835 + _tree_set->erase(blossom);
115.2836 + }
115.2837 +
115.2838 + void extractBlossom(int blossom, const Node& base, const Arc& matching) {
115.2839 + if (_blossom_set->trivial(blossom)) {
115.2840 + int bi = (*_node_index)[base];
115.2841 + Value pot = (*_node_data)[bi].pot;
115.2842 +
115.2843 + (*_matching)[base] = matching;
115.2844 + _blossom_node_list.push_back(base);
115.2845 + (*_node_potential)[base] = pot;
115.2846 + } else {
115.2847 +
115.2848 + Value pot = (*_blossom_data)[blossom].pot;
115.2849 + int bn = _blossom_node_list.size();
115.2850 +
115.2851 + std::vector<int> subblossoms;
115.2852 + _blossom_set->split(blossom, std::back_inserter(subblossoms));
115.2853 + int b = _blossom_set->find(base);
115.2854 + int ib = -1;
115.2855 + for (int i = 0; i < int(subblossoms.size()); ++i) {
115.2856 + if (subblossoms[i] == b) { ib = i; break; }
115.2857 + }
115.2858 +
115.2859 + for (int i = 1; i < int(subblossoms.size()); i += 2) {
115.2860 + int sb = subblossoms[(ib + i) % subblossoms.size()];
115.2861 + int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
115.2862 +
115.2863 + Arc m = (*_blossom_data)[tb].next;
115.2864 + extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
115.2865 + extractBlossom(tb, _graph.source(m), m);
115.2866 + }
115.2867 + extractBlossom(subblossoms[ib], base, matching);
115.2868 +
115.2869 + int en = _blossom_node_list.size();
115.2870 +
115.2871 + _blossom_potential.push_back(BlossomVariable(bn, en, pot));
115.2872 + }
115.2873 + }
115.2874 +
115.2875 + void extractMatching() {
115.2876 + std::vector<int> blossoms;
115.2877 + for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
115.2878 + blossoms.push_back(c);
115.2879 + }
115.2880 +
115.2881 + for (int i = 0; i < int(blossoms.size()); ++i) {
115.2882 +
115.2883 + Value offset = (*_blossom_data)[blossoms[i]].offset;
115.2884 + (*_blossom_data)[blossoms[i]].pot += 2 * offset;
115.2885 + for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
115.2886 + n != INVALID; ++n) {
115.2887 + (*_node_data)[(*_node_index)[n]].pot -= offset;
115.2888 + }
115.2889 +
115.2890 + Arc matching = (*_blossom_data)[blossoms[i]].next;
115.2891 + Node base = _graph.source(matching);
115.2892 + extractBlossom(blossoms[i], base, matching);
115.2893 + }
115.2894 + }
115.2895 +
115.2896 + public:
115.2897 +
115.2898 + /// \brief Constructor
115.2899 + ///
115.2900 + /// Constructor.
115.2901 + MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
115.2902 + : _graph(graph), _weight(weight), _matching(0),
115.2903 + _node_potential(0), _blossom_potential(), _blossom_node_list(),
115.2904 + _node_num(0), _blossom_num(0),
115.2905 +
115.2906 + _blossom_index(0), _blossom_set(0), _blossom_data(0),
115.2907 + _node_index(0), _node_heap_index(0), _node_data(0),
115.2908 + _tree_set_index(0), _tree_set(0),
115.2909 +
115.2910 + _delta2_index(0), _delta2(0),
115.2911 + _delta3_index(0), _delta3(0),
115.2912 + _delta4_index(0), _delta4(0),
115.2913 +
115.2914 + _delta_sum() {}
115.2915 +
115.2916 + ~MaxWeightedPerfectMatching() {
115.2917 + destroyStructures();
115.2918 + }
115.2919 +
115.2920 + /// \name Execution Control
115.2921 + /// The simplest way to execute the algorithm is to use the
115.2922 + /// \ref run() member function.
115.2923 +
115.2924 + ///@{
115.2925 +
115.2926 + /// \brief Initialize the algorithm
115.2927 + ///
115.2928 + /// This function initializes the algorithm.
115.2929 + void init() {
115.2930 + createStructures();
115.2931 +
115.2932 + for (ArcIt e(_graph); e != INVALID; ++e) {
115.2933 + (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
115.2934 + }
115.2935 + for (EdgeIt e(_graph); e != INVALID; ++e) {
115.2936 + (*_delta3_index)[e] = _delta3->PRE_HEAP;
115.2937 + }
115.2938 + for (int i = 0; i < _blossom_num; ++i) {
115.2939 + (*_delta2_index)[i] = _delta2->PRE_HEAP;
115.2940 + (*_delta4_index)[i] = _delta4->PRE_HEAP;
115.2941 + }
115.2942 +
115.2943 + int index = 0;
115.2944 + for (NodeIt n(_graph); n != INVALID; ++n) {
115.2945 + Value max = - std::numeric_limits<Value>::max();
115.2946 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
115.2947 + if (_graph.target(e) == n) continue;
115.2948 + if ((dualScale * _weight[e]) / 2 > max) {
115.2949 + max = (dualScale * _weight[e]) / 2;
115.2950 + }
115.2951 + }
115.2952 + (*_node_index)[n] = index;
115.2953 + (*_node_data)[index].pot = max;
115.2954 + int blossom =
115.2955 + _blossom_set->insert(n, std::numeric_limits<Value>::max());
115.2956 +
115.2957 + _tree_set->insert(blossom);
115.2958 +
115.2959 + (*_blossom_data)[blossom].status = EVEN;
115.2960 + (*_blossom_data)[blossom].pred = INVALID;
115.2961 + (*_blossom_data)[blossom].next = INVALID;
115.2962 + (*_blossom_data)[blossom].pot = 0;
115.2963 + (*_blossom_data)[blossom].offset = 0;
115.2964 + ++index;
115.2965 + }
115.2966 + for (EdgeIt e(_graph); e != INVALID; ++e) {
115.2967 + int si = (*_node_index)[_graph.u(e)];
115.2968 + int ti = (*_node_index)[_graph.v(e)];
115.2969 + if (_graph.u(e) != _graph.v(e)) {
115.2970 + _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
115.2971 + dualScale * _weight[e]) / 2);
115.2972 + }
115.2973 + }
115.2974 + }
115.2975 +
115.2976 + /// \brief Start the algorithm
115.2977 + ///
115.2978 + /// This function starts the algorithm.
115.2979 + ///
115.2980 + /// \pre \ref init() must be called before using this function.
115.2981 + bool start() {
115.2982 + enum OpType {
115.2983 + D2, D3, D4
115.2984 + };
115.2985 +
115.2986 + int unmatched = _node_num;
115.2987 + while (unmatched > 0) {
115.2988 + Value d2 = !_delta2->empty() ?
115.2989 + _delta2->prio() : std::numeric_limits<Value>::max();
115.2990 +
115.2991 + Value d3 = !_delta3->empty() ?
115.2992 + _delta3->prio() : std::numeric_limits<Value>::max();
115.2993 +
115.2994 + Value d4 = !_delta4->empty() ?
115.2995 + _delta4->prio() : std::numeric_limits<Value>::max();
115.2996 +
115.2997 + _delta_sum = d2; OpType ot = D2;
115.2998 + if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
115.2999 + if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
115.3000 +
115.3001 + if (_delta_sum == std::numeric_limits<Value>::max()) {
115.3002 + return false;
115.3003 + }
115.3004 +
115.3005 + switch (ot) {
115.3006 + case D2:
115.3007 + {
115.3008 + int blossom = _delta2->top();
115.3009 + Node n = _blossom_set->classTop(blossom);
115.3010 + Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
115.3011 + extendOnArc(e);
115.3012 + }
115.3013 + break;
115.3014 + case D3:
115.3015 + {
115.3016 + Edge e = _delta3->top();
115.3017 +
115.3018 + int left_blossom = _blossom_set->find(_graph.u(e));
115.3019 + int right_blossom = _blossom_set->find(_graph.v(e));
115.3020 +
115.3021 + if (left_blossom == right_blossom) {
115.3022 + _delta3->pop();
115.3023 + } else {
115.3024 + int left_tree = _tree_set->find(left_blossom);
115.3025 + int right_tree = _tree_set->find(right_blossom);
115.3026 +
115.3027 + if (left_tree == right_tree) {
115.3028 + shrinkOnEdge(e, left_tree);
115.3029 + } else {
115.3030 + augmentOnEdge(e);
115.3031 + unmatched -= 2;
115.3032 + }
115.3033 + }
115.3034 + } break;
115.3035 + case D4:
115.3036 + splitBlossom(_delta4->top());
115.3037 + break;
115.3038 + }
115.3039 + }
115.3040 + extractMatching();
115.3041 + return true;
115.3042 + }
115.3043 +
115.3044 + /// \brief Run the algorithm.
115.3045 + ///
115.3046 + /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
115.3047 + ///
115.3048 + /// \note mwpm.run() is just a shortcut of the following code.
115.3049 + /// \code
115.3050 + /// mwpm.init();
115.3051 + /// mwpm.start();
115.3052 + /// \endcode
115.3053 + bool run() {
115.3054 + init();
115.3055 + return start();
115.3056 + }
115.3057 +
115.3058 + /// @}
115.3059 +
115.3060 + /// \name Primal Solution
115.3061 + /// Functions to get the primal solution, i.e. the maximum weighted
115.3062 + /// perfect matching.\n
115.3063 + /// Either \ref run() or \ref start() function should be called before
115.3064 + /// using them.
115.3065 +
115.3066 + /// @{
115.3067 +
115.3068 + /// \brief Return the weight of the matching.
115.3069 + ///
115.3070 + /// This function returns the weight of the found matching.
115.3071 + ///
115.3072 + /// \pre Either run() or start() must be called before using this function.
115.3073 + Value matchingWeight() const {
115.3074 + Value sum = 0;
115.3075 + for (NodeIt n(_graph); n != INVALID; ++n) {
115.3076 + if ((*_matching)[n] != INVALID) {
115.3077 + sum += _weight[(*_matching)[n]];
115.3078 + }
115.3079 + }
115.3080 + return sum /= 2;
115.3081 + }
115.3082 +
115.3083 + /// \brief Return \c true if the given edge is in the matching.
115.3084 + ///
115.3085 + /// This function returns \c true if the given edge is in the found
115.3086 + /// matching.
115.3087 + ///
115.3088 + /// \pre Either run() or start() must be called before using this function.
115.3089 + bool matching(const Edge& edge) const {
115.3090 + return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
115.3091 + }
115.3092 +
115.3093 + /// \brief Return the matching arc (or edge) incident to the given node.
115.3094 + ///
115.3095 + /// This function returns the matching arc (or edge) incident to the
115.3096 + /// given node in the found matching or \c INVALID if the node is
115.3097 + /// not covered by the matching.
115.3098 + ///
115.3099 + /// \pre Either run() or start() must be called before using this function.
115.3100 + Arc matching(const Node& node) const {
115.3101 + return (*_matching)[node];
115.3102 + }
115.3103 +
115.3104 + /// \brief Return a const reference to the matching map.
115.3105 + ///
115.3106 + /// This function returns a const reference to a node map that stores
115.3107 + /// the matching arc (or edge) incident to each node.
115.3108 + const MatchingMap& matchingMap() const {
115.3109 + return *_matching;
115.3110 + }
115.3111 +
115.3112 + /// \brief Return the mate of the given node.
115.3113 + ///
115.3114 + /// This function returns the mate of the given node in the found
115.3115 + /// matching or \c INVALID if the node is not covered by the matching.
115.3116 + ///
115.3117 + /// \pre Either run() or start() must be called before using this function.
115.3118 + Node mate(const Node& node) const {
115.3119 + return _graph.target((*_matching)[node]);
115.3120 + }
115.3121 +
115.3122 + /// @}
115.3123 +
115.3124 + /// \name Dual Solution
115.3125 + /// Functions to get the dual solution.\n
115.3126 + /// Either \ref run() or \ref start() function should be called before
115.3127 + /// using them.
115.3128 +
115.3129 + /// @{
115.3130 +
115.3131 + /// \brief Return the value of the dual solution.
115.3132 + ///
115.3133 + /// This function returns the value of the dual solution.
115.3134 + /// It should be equal to the primal value scaled by \ref dualScale
115.3135 + /// "dual scale".
115.3136 + ///
115.3137 + /// \pre Either run() or start() must be called before using this function.
115.3138 + Value dualValue() const {
115.3139 + Value sum = 0;
115.3140 + for (NodeIt n(_graph); n != INVALID; ++n) {
115.3141 + sum += nodeValue(n);
115.3142 + }
115.3143 + for (int i = 0; i < blossomNum(); ++i) {
115.3144 + sum += blossomValue(i) * (blossomSize(i) / 2);
115.3145 + }
115.3146 + return sum;
115.3147 + }
115.3148 +
115.3149 + /// \brief Return the dual value (potential) of the given node.
115.3150 + ///
115.3151 + /// This function returns the dual value (potential) of the given node.
115.3152 + ///
115.3153 + /// \pre Either run() or start() must be called before using this function.
115.3154 + Value nodeValue(const Node& n) const {
115.3155 + return (*_node_potential)[n];
115.3156 + }
115.3157 +
115.3158 + /// \brief Return the number of the blossoms in the basis.
115.3159 + ///
115.3160 + /// This function returns the number of the blossoms in the basis.
115.3161 + ///
115.3162 + /// \pre Either run() or start() must be called before using this function.
115.3163 + /// \see BlossomIt
115.3164 + int blossomNum() const {
115.3165 + return _blossom_potential.size();
115.3166 + }
115.3167 +
115.3168 + /// \brief Return the number of the nodes in the given blossom.
115.3169 + ///
115.3170 + /// This function returns the number of the nodes in the given blossom.
115.3171 + ///
115.3172 + /// \pre Either run() or start() must be called before using this function.
115.3173 + /// \see BlossomIt
115.3174 + int blossomSize(int k) const {
115.3175 + return _blossom_potential[k].end - _blossom_potential[k].begin;
115.3176 + }
115.3177 +
115.3178 + /// \brief Return the dual value (ptential) of the given blossom.
115.3179 + ///
115.3180 + /// This function returns the dual value (ptential) of the given blossom.
115.3181 + ///
115.3182 + /// \pre Either run() or start() must be called before using this function.
115.3183 + Value blossomValue(int k) const {
115.3184 + return _blossom_potential[k].value;
115.3185 + }
115.3186 +
115.3187 + /// \brief Iterator for obtaining the nodes of a blossom.
115.3188 + ///
115.3189 + /// This class provides an iterator for obtaining the nodes of the
115.3190 + /// given blossom. It lists a subset of the nodes.
115.3191 + /// Before using this iterator, you must allocate a
115.3192 + /// MaxWeightedPerfectMatching class and execute it.
115.3193 + class BlossomIt {
115.3194 + public:
115.3195 +
115.3196 + /// \brief Constructor.
115.3197 + ///
115.3198 + /// Constructor to get the nodes of the given variable.
115.3199 + ///
115.3200 + /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()"
115.3201 + /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()"
115.3202 + /// must be called before initializing this iterator.
115.3203 + BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
115.3204 + : _algorithm(&algorithm)
115.3205 + {
115.3206 + _index = _algorithm->_blossom_potential[variable].begin;
115.3207 + _last = _algorithm->_blossom_potential[variable].end;
115.3208 + }
115.3209 +
115.3210 + /// \brief Conversion to \c Node.
115.3211 + ///
115.3212 + /// Conversion to \c Node.
115.3213 + operator Node() const {
115.3214 + return _algorithm->_blossom_node_list[_index];
115.3215 + }
115.3216 +
115.3217 + /// \brief Increment operator.
115.3218 + ///
115.3219 + /// Increment operator.
115.3220 + BlossomIt& operator++() {
115.3221 + ++_index;
115.3222 + return *this;
115.3223 + }
115.3224 +
115.3225 + /// \brief Validity checking
115.3226 + ///
115.3227 + /// This function checks whether the iterator is invalid.
115.3228 + bool operator==(Invalid) const { return _index == _last; }
115.3229 +
115.3230 + /// \brief Validity checking
115.3231 + ///
115.3232 + /// This function checks whether the iterator is valid.
115.3233 + bool operator!=(Invalid) const { return _index != _last; }
115.3234 +
115.3235 + private:
115.3236 + const MaxWeightedPerfectMatching* _algorithm;
115.3237 + int _last;
115.3238 + int _index;
115.3239 + };
115.3240 +
115.3241 + /// @}
115.3242 +
115.3243 + };
115.3244 +
115.3245 +} //END OF NAMESPACE LEMON
115.3246 +
115.3247 +#endif //LEMON_MAX_MATCHING_H
116.1 --- a/lemon/math.h Fri Nov 13 12:33:33 2009 +0100
116.2 +++ b/lemon/math.h Thu Dec 10 17:05:35 2009 +0100
116.3 @@ -2,7 +2,7 @@
116.4 *
116.5 * This file is a part of LEMON, a generic C++ optimization library.
116.6 *
116.7 - * Copyright (C) 2003-2008
116.8 + * Copyright (C) 2003-2009
116.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
116.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
116.11 *
116.12 @@ -55,6 +55,15 @@
116.13 /// 1/sqrt(2)
116.14 const long double SQRT1_2 = 0.7071067811865475244008443621048490L;
116.15
116.16 + ///Check whether the parameter is NaN or not
116.17 +
116.18 + ///This function checks whether the parameter is NaN or not.
116.19 + ///Is should be equivalent with std::isnan(), but it is not
116.20 + ///provided by all compilers.
116.21 + inline bool isNaN(double v)
116.22 + {
116.23 + return v!=v;
116.24 + }
116.25
116.26 /// @}
116.27
117.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
117.2 +++ b/lemon/min_cost_arborescence.h Thu Dec 10 17:05:35 2009 +0100
117.3 @@ -0,0 +1,807 @@
117.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
117.5 + *
117.6 + * This file is a part of LEMON, a generic C++ optimization library.
117.7 + *
117.8 + * Copyright (C) 2003-2008
117.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
117.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
117.11 + *
117.12 + * Permission to use, modify and distribute this software is granted
117.13 + * provided that this copyright notice appears in all copies. For
117.14 + * precise terms see the accompanying LICENSE file.
117.15 + *
117.16 + * This software is provided "AS IS" with no warranty of any kind,
117.17 + * express or implied, and with no claim as to its suitability for any
117.18 + * purpose.
117.19 + *
117.20 + */
117.21 +
117.22 +#ifndef LEMON_MIN_COST_ARBORESCENCE_H
117.23 +#define LEMON_MIN_COST_ARBORESCENCE_H
117.24 +
117.25 +///\ingroup spantree
117.26 +///\file
117.27 +///\brief Minimum Cost Arborescence algorithm.
117.28 +
117.29 +#include <vector>
117.30 +
117.31 +#include <lemon/list_graph.h>
117.32 +#include <lemon/bin_heap.h>
117.33 +#include <lemon/assert.h>
117.34 +
117.35 +namespace lemon {
117.36 +
117.37 +
117.38 + /// \brief Default traits class for MinCostArborescence class.
117.39 + ///
117.40 + /// Default traits class for MinCostArborescence class.
117.41 + /// \param GR Digraph type.
117.42 + /// \param CM Type of the cost map.
117.43 + template <class GR, class CM>
117.44 + struct MinCostArborescenceDefaultTraits{
117.45 +
117.46 + /// \brief The digraph type the algorithm runs on.
117.47 + typedef GR Digraph;
117.48 +
117.49 + /// \brief The type of the map that stores the arc costs.
117.50 + ///
117.51 + /// The type of the map that stores the arc costs.
117.52 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
117.53 + typedef CM CostMap;
117.54 +
117.55 + /// \brief The value type of the costs.
117.56 + ///
117.57 + /// The value type of the costs.
117.58 + typedef typename CostMap::Value Value;
117.59 +
117.60 + /// \brief The type of the map that stores which arcs are in the
117.61 + /// arborescence.
117.62 + ///
117.63 + /// The type of the map that stores which arcs are in the
117.64 + /// arborescence. It must conform to the \ref concepts::WriteMap
117.65 + /// "WriteMap" concept, and its value type must be \c bool
117.66 + /// (or convertible). Initially it will be set to \c false on each
117.67 + /// arc, then it will be set on each arborescence arc once.
117.68 + typedef typename Digraph::template ArcMap<bool> ArborescenceMap;
117.69 +
117.70 + /// \brief Instantiates a \c ArborescenceMap.
117.71 + ///
117.72 + /// This function instantiates a \c ArborescenceMap.
117.73 + /// \param digraph The digraph to which we would like to calculate
117.74 + /// the \c ArborescenceMap.
117.75 + static ArborescenceMap *createArborescenceMap(const Digraph &digraph){
117.76 + return new ArborescenceMap(digraph);
117.77 + }
117.78 +
117.79 + /// \brief The type of the \c PredMap
117.80 + ///
117.81 + /// The type of the \c PredMap. It must confrom to the
117.82 + /// \ref concepts::WriteMap "WriteMap" concept, and its value type
117.83 + /// must be the \c Arc type of the digraph.
117.84 + typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
117.85 +
117.86 + /// \brief Instantiates a \c PredMap.
117.87 + ///
117.88 + /// This function instantiates a \c PredMap.
117.89 + /// \param digraph The digraph to which we would like to define the
117.90 + /// \c PredMap.
117.91 + static PredMap *createPredMap(const Digraph &digraph){
117.92 + return new PredMap(digraph);
117.93 + }
117.94 +
117.95 + };
117.96 +
117.97 + /// \ingroup spantree
117.98 + ///
117.99 + /// \brief Minimum Cost Arborescence algorithm class.
117.100 + ///
117.101 + /// This class provides an efficient implementation of the
117.102 + /// Minimum Cost Arborescence algorithm. The arborescence is a tree
117.103 + /// which is directed from a given source node of the digraph. One or
117.104 + /// more sources should be given to the algorithm and it will calculate
117.105 + /// the minimum cost subgraph that is the union of arborescences with the
117.106 + /// given sources and spans all the nodes which are reachable from the
117.107 + /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+e).
117.108 + ///
117.109 + /// The algorithm also provides an optimal dual solution, therefore
117.110 + /// the optimality of the solution can be checked.
117.111 + ///
117.112 + /// \param GR The digraph type the algorithm runs on.
117.113 + /// \param CM A read-only arc map storing the costs of the
117.114 + /// arcs. It is read once for each arc, so the map may involve in
117.115 + /// relatively time consuming process to compute the arc costs if
117.116 + /// it is necessary. The default map type is \ref
117.117 + /// concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
117.118 + /// \param TR Traits class to set various data types used
117.119 + /// by the algorithm. The default traits class is
117.120 + /// \ref MinCostArborescenceDefaultTraits
117.121 + /// "MinCostArborescenceDefaultTraits<GR, CM>".
117.122 +#ifndef DOXYGEN
117.123 + template <typename GR,
117.124 + typename CM = typename GR::template ArcMap<int>,
117.125 + typename TR =
117.126 + MinCostArborescenceDefaultTraits<GR, CM> >
117.127 +#else
117.128 + template <typename GR, typename CM, typedef TR>
117.129 +#endif
117.130 + class MinCostArborescence {
117.131 + public:
117.132 +
117.133 + /// \brief The \ref MinCostArborescenceDefaultTraits "traits class"
117.134 + /// of the algorithm.
117.135 + typedef TR Traits;
117.136 + /// The type of the underlying digraph.
117.137 + typedef typename Traits::Digraph Digraph;
117.138 + /// The type of the map that stores the arc costs.
117.139 + typedef typename Traits::CostMap CostMap;
117.140 + ///The type of the costs of the arcs.
117.141 + typedef typename Traits::Value Value;
117.142 + ///The type of the predecessor map.
117.143 + typedef typename Traits::PredMap PredMap;
117.144 + ///The type of the map that stores which arcs are in the arborescence.
117.145 + typedef typename Traits::ArborescenceMap ArborescenceMap;
117.146 +
117.147 + typedef MinCostArborescence Create;
117.148 +
117.149 + private:
117.150 +
117.151 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
117.152 +
117.153 + struct CostArc {
117.154 +
117.155 + Arc arc;
117.156 + Value value;
117.157 +
117.158 + CostArc() {}
117.159 + CostArc(Arc _arc, Value _value) : arc(_arc), value(_value) {}
117.160 +
117.161 + };
117.162 +
117.163 + const Digraph *_digraph;
117.164 + const CostMap *_cost;
117.165 +
117.166 + PredMap *_pred;
117.167 + bool local_pred;
117.168 +
117.169 + ArborescenceMap *_arborescence;
117.170 + bool local_arborescence;
117.171 +
117.172 + typedef typename Digraph::template ArcMap<int> ArcOrder;
117.173 + ArcOrder *_arc_order;
117.174 +
117.175 + typedef typename Digraph::template NodeMap<int> NodeOrder;
117.176 + NodeOrder *_node_order;
117.177 +
117.178 + typedef typename Digraph::template NodeMap<CostArc> CostArcMap;
117.179 + CostArcMap *_cost_arcs;
117.180 +
117.181 + struct StackLevel {
117.182 +
117.183 + std::vector<CostArc> arcs;
117.184 + int node_level;
117.185 +
117.186 + };
117.187 +
117.188 + std::vector<StackLevel> level_stack;
117.189 + std::vector<Node> queue;
117.190 +
117.191 + typedef std::vector<typename Digraph::Node> DualNodeList;
117.192 +
117.193 + DualNodeList _dual_node_list;
117.194 +
117.195 + struct DualVariable {
117.196 + int begin, end;
117.197 + Value value;
117.198 +
117.199 + DualVariable(int _begin, int _end, Value _value)
117.200 + : begin(_begin), end(_end), value(_value) {}
117.201 +
117.202 + };
117.203 +
117.204 + typedef std::vector<DualVariable> DualVariables;
117.205 +
117.206 + DualVariables _dual_variables;
117.207 +
117.208 + typedef typename Digraph::template NodeMap<int> HeapCrossRef;
117.209 +
117.210 + HeapCrossRef *_heap_cross_ref;
117.211 +
117.212 + typedef BinHeap<int, HeapCrossRef> Heap;
117.213 +
117.214 + Heap *_heap;
117.215 +
117.216 + protected:
117.217 +
117.218 + MinCostArborescence() {}
117.219 +
117.220 + private:
117.221 +
117.222 + void createStructures() {
117.223 + if (!_pred) {
117.224 + local_pred = true;
117.225 + _pred = Traits::createPredMap(*_digraph);
117.226 + }
117.227 + if (!_arborescence) {
117.228 + local_arborescence = true;
117.229 + _arborescence = Traits::createArborescenceMap(*_digraph);
117.230 + }
117.231 + if (!_arc_order) {
117.232 + _arc_order = new ArcOrder(*_digraph);
117.233 + }
117.234 + if (!_node_order) {
117.235 + _node_order = new NodeOrder(*_digraph);
117.236 + }
117.237 + if (!_cost_arcs) {
117.238 + _cost_arcs = new CostArcMap(*_digraph);
117.239 + }
117.240 + if (!_heap_cross_ref) {
117.241 + _heap_cross_ref = new HeapCrossRef(*_digraph, -1);
117.242 + }
117.243 + if (!_heap) {
117.244 + _heap = new Heap(*_heap_cross_ref);
117.245 + }
117.246 + }
117.247 +
117.248 + void destroyStructures() {
117.249 + if (local_arborescence) {
117.250 + delete _arborescence;
117.251 + }
117.252 + if (local_pred) {
117.253 + delete _pred;
117.254 + }
117.255 + if (_arc_order) {
117.256 + delete _arc_order;
117.257 + }
117.258 + if (_node_order) {
117.259 + delete _node_order;
117.260 + }
117.261 + if (_cost_arcs) {
117.262 + delete _cost_arcs;
117.263 + }
117.264 + if (_heap) {
117.265 + delete _heap;
117.266 + }
117.267 + if (_heap_cross_ref) {
117.268 + delete _heap_cross_ref;
117.269 + }
117.270 + }
117.271 +
117.272 + Arc prepare(Node node) {
117.273 + std::vector<Node> nodes;
117.274 + (*_node_order)[node] = _dual_node_list.size();
117.275 + StackLevel level;
117.276 + level.node_level = _dual_node_list.size();
117.277 + _dual_node_list.push_back(node);
117.278 + for (InArcIt it(*_digraph, node); it != INVALID; ++it) {
117.279 + Arc arc = it;
117.280 + Node source = _digraph->source(arc);
117.281 + Value value = (*_cost)[it];
117.282 + if (source == node || (*_node_order)[source] == -3) continue;
117.283 + if ((*_cost_arcs)[source].arc == INVALID) {
117.284 + (*_cost_arcs)[source].arc = arc;
117.285 + (*_cost_arcs)[source].value = value;
117.286 + nodes.push_back(source);
117.287 + } else {
117.288 + if ((*_cost_arcs)[source].value > value) {
117.289 + (*_cost_arcs)[source].arc = arc;
117.290 + (*_cost_arcs)[source].value = value;
117.291 + }
117.292 + }
117.293 + }
117.294 + CostArc minimum = (*_cost_arcs)[nodes[0]];
117.295 + for (int i = 1; i < int(nodes.size()); ++i) {
117.296 + if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
117.297 + minimum = (*_cost_arcs)[nodes[i]];
117.298 + }
117.299 + }
117.300 + (*_arc_order)[minimum.arc] = _dual_variables.size();
117.301 + DualVariable var(_dual_node_list.size() - 1,
117.302 + _dual_node_list.size(), minimum.value);
117.303 + _dual_variables.push_back(var);
117.304 + for (int i = 0; i < int(nodes.size()); ++i) {
117.305 + (*_cost_arcs)[nodes[i]].value -= minimum.value;
117.306 + level.arcs.push_back((*_cost_arcs)[nodes[i]]);
117.307 + (*_cost_arcs)[nodes[i]].arc = INVALID;
117.308 + }
117.309 + level_stack.push_back(level);
117.310 + return minimum.arc;
117.311 + }
117.312 +
117.313 + Arc contract(Node node) {
117.314 + int node_bottom = bottom(node);
117.315 + std::vector<Node> nodes;
117.316 + while (!level_stack.empty() &&
117.317 + level_stack.back().node_level >= node_bottom) {
117.318 + for (int i = 0; i < int(level_stack.back().arcs.size()); ++i) {
117.319 + Arc arc = level_stack.back().arcs[i].arc;
117.320 + Node source = _digraph->source(arc);
117.321 + Value value = level_stack.back().arcs[i].value;
117.322 + if ((*_node_order)[source] >= node_bottom) continue;
117.323 + if ((*_cost_arcs)[source].arc == INVALID) {
117.324 + (*_cost_arcs)[source].arc = arc;
117.325 + (*_cost_arcs)[source].value = value;
117.326 + nodes.push_back(source);
117.327 + } else {
117.328 + if ((*_cost_arcs)[source].value > value) {
117.329 + (*_cost_arcs)[source].arc = arc;
117.330 + (*_cost_arcs)[source].value = value;
117.331 + }
117.332 + }
117.333 + }
117.334 + level_stack.pop_back();
117.335 + }
117.336 + CostArc minimum = (*_cost_arcs)[nodes[0]];
117.337 + for (int i = 1; i < int(nodes.size()); ++i) {
117.338 + if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
117.339 + minimum = (*_cost_arcs)[nodes[i]];
117.340 + }
117.341 + }
117.342 + (*_arc_order)[minimum.arc] = _dual_variables.size();
117.343 + DualVariable var(node_bottom, _dual_node_list.size(), minimum.value);
117.344 + _dual_variables.push_back(var);
117.345 + StackLevel level;
117.346 + level.node_level = node_bottom;
117.347 + for (int i = 0; i < int(nodes.size()); ++i) {
117.348 + (*_cost_arcs)[nodes[i]].value -= minimum.value;
117.349 + level.arcs.push_back((*_cost_arcs)[nodes[i]]);
117.350 + (*_cost_arcs)[nodes[i]].arc = INVALID;
117.351 + }
117.352 + level_stack.push_back(level);
117.353 + return minimum.arc;
117.354 + }
117.355 +
117.356 + int bottom(Node node) {
117.357 + int k = level_stack.size() - 1;
117.358 + while (level_stack[k].node_level > (*_node_order)[node]) {
117.359 + --k;
117.360 + }
117.361 + return level_stack[k].node_level;
117.362 + }
117.363 +
117.364 + void finalize(Arc arc) {
117.365 + Node node = _digraph->target(arc);
117.366 + _heap->push(node, (*_arc_order)[arc]);
117.367 + _pred->set(node, arc);
117.368 + while (!_heap->empty()) {
117.369 + Node source = _heap->top();
117.370 + _heap->pop();
117.371 + (*_node_order)[source] = -1;
117.372 + for (OutArcIt it(*_digraph, source); it != INVALID; ++it) {
117.373 + if ((*_arc_order)[it] < 0) continue;
117.374 + Node target = _digraph->target(it);
117.375 + switch(_heap->state(target)) {
117.376 + case Heap::PRE_HEAP:
117.377 + _heap->push(target, (*_arc_order)[it]);
117.378 + _pred->set(target, it);
117.379 + break;
117.380 + case Heap::IN_HEAP:
117.381 + if ((*_arc_order)[it] < (*_heap)[target]) {
117.382 + _heap->decrease(target, (*_arc_order)[it]);
117.383 + _pred->set(target, it);
117.384 + }
117.385 + break;
117.386 + case Heap::POST_HEAP:
117.387 + break;
117.388 + }
117.389 + }
117.390 + _arborescence->set((*_pred)[source], true);
117.391 + }
117.392 + }
117.393 +
117.394 +
117.395 + public:
117.396 +
117.397 + /// \name Named Template Parameters
117.398 +
117.399 + /// @{
117.400 +
117.401 + template <class T>
117.402 + struct SetArborescenceMapTraits : public Traits {
117.403 + typedef T ArborescenceMap;
117.404 + static ArborescenceMap *createArborescenceMap(const Digraph &)
117.405 + {
117.406 + LEMON_ASSERT(false, "ArborescenceMap is not initialized");
117.407 + return 0; // ignore warnings
117.408 + }
117.409 + };
117.410 +
117.411 + /// \brief \ref named-templ-param "Named parameter" for
117.412 + /// setting \c ArborescenceMap type
117.413 + ///
117.414 + /// \ref named-templ-param "Named parameter" for setting
117.415 + /// \c ArborescenceMap type.
117.416 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept,
117.417 + /// and its value type must be \c bool (or convertible).
117.418 + /// Initially it will be set to \c false on each arc,
117.419 + /// then it will be set on each arborescence arc once.
117.420 + template <class T>
117.421 + struct SetArborescenceMap
117.422 + : public MinCostArborescence<Digraph, CostMap,
117.423 + SetArborescenceMapTraits<T> > {
117.424 + };
117.425 +
117.426 + template <class T>
117.427 + struct SetPredMapTraits : public Traits {
117.428 + typedef T PredMap;
117.429 + static PredMap *createPredMap(const Digraph &)
117.430 + {
117.431 + LEMON_ASSERT(false, "PredMap is not initialized");
117.432 + return 0; // ignore warnings
117.433 + }
117.434 + };
117.435 +
117.436 + /// \brief \ref named-templ-param "Named parameter" for
117.437 + /// setting \c PredMap type
117.438 + ///
117.439 + /// \ref named-templ-param "Named parameter" for setting
117.440 + /// \c PredMap type.
117.441 + /// It must meet the \ref concepts::WriteMap "WriteMap" concept,
117.442 + /// and its value type must be the \c Arc type of the digraph.
117.443 + template <class T>
117.444 + struct SetPredMap
117.445 + : public MinCostArborescence<Digraph, CostMap, SetPredMapTraits<T> > {
117.446 + };
117.447 +
117.448 + /// @}
117.449 +
117.450 + /// \brief Constructor.
117.451 + ///
117.452 + /// \param digraph The digraph the algorithm will run on.
117.453 + /// \param cost The cost map used by the algorithm.
117.454 + MinCostArborescence(const Digraph& digraph, const CostMap& cost)
117.455 + : _digraph(&digraph), _cost(&cost), _pred(0), local_pred(false),
117.456 + _arborescence(0), local_arborescence(false),
117.457 + _arc_order(0), _node_order(0), _cost_arcs(0),
117.458 + _heap_cross_ref(0), _heap(0) {}
117.459 +
117.460 + /// \brief Destructor.
117.461 + ~MinCostArborescence() {
117.462 + destroyStructures();
117.463 + }
117.464 +
117.465 + /// \brief Sets the arborescence map.
117.466 + ///
117.467 + /// Sets the arborescence map.
117.468 + /// \return <tt>(*this)</tt>
117.469 + MinCostArborescence& arborescenceMap(ArborescenceMap& m) {
117.470 + if (local_arborescence) {
117.471 + delete _arborescence;
117.472 + }
117.473 + local_arborescence = false;
117.474 + _arborescence = &m;
117.475 + return *this;
117.476 + }
117.477 +
117.478 + /// \brief Sets the predecessor map.
117.479 + ///
117.480 + /// Sets the predecessor map.
117.481 + /// \return <tt>(*this)</tt>
117.482 + MinCostArborescence& predMap(PredMap& m) {
117.483 + if (local_pred) {
117.484 + delete _pred;
117.485 + }
117.486 + local_pred = false;
117.487 + _pred = &m;
117.488 + return *this;
117.489 + }
117.490 +
117.491 + /// \name Execution Control
117.492 + /// The simplest way to execute the algorithm is to use
117.493 + /// one of the member functions called \c run(...). \n
117.494 + /// If you need more control on the execution,
117.495 + /// first you must call \ref init(), then you can add several
117.496 + /// source nodes with \ref addSource().
117.497 + /// Finally \ref start() will perform the arborescence
117.498 + /// computation.
117.499 +
117.500 + ///@{
117.501 +
117.502 + /// \brief Initializes the internal data structures.
117.503 + ///
117.504 + /// Initializes the internal data structures.
117.505 + ///
117.506 + void init() {
117.507 + createStructures();
117.508 + _heap->clear();
117.509 + for (NodeIt it(*_digraph); it != INVALID; ++it) {
117.510 + (*_cost_arcs)[it].arc = INVALID;
117.511 + (*_node_order)[it] = -3;
117.512 + (*_heap_cross_ref)[it] = Heap::PRE_HEAP;
117.513 + _pred->set(it, INVALID);
117.514 + }
117.515 + for (ArcIt it(*_digraph); it != INVALID; ++it) {
117.516 + _arborescence->set(it, false);
117.517 + (*_arc_order)[it] = -1;
117.518 + }
117.519 + _dual_node_list.clear();
117.520 + _dual_variables.clear();
117.521 + }
117.522 +
117.523 + /// \brief Adds a new source node.
117.524 + ///
117.525 + /// Adds a new source node to the algorithm.
117.526 + void addSource(Node source) {
117.527 + std::vector<Node> nodes;
117.528 + nodes.push_back(source);
117.529 + while (!nodes.empty()) {
117.530 + Node node = nodes.back();
117.531 + nodes.pop_back();
117.532 + for (OutArcIt it(*_digraph, node); it != INVALID; ++it) {
117.533 + Node target = _digraph->target(it);
117.534 + if ((*_node_order)[target] == -3) {
117.535 + (*_node_order)[target] = -2;
117.536 + nodes.push_back(target);
117.537 + queue.push_back(target);
117.538 + }
117.539 + }
117.540 + }
117.541 + (*_node_order)[source] = -1;
117.542 + }
117.543 +
117.544 + /// \brief Processes the next node in the priority queue.
117.545 + ///
117.546 + /// Processes the next node in the priority queue.
117.547 + ///
117.548 + /// \return The processed node.
117.549 + ///
117.550 + /// \warning The queue must not be empty.
117.551 + Node processNextNode() {
117.552 + Node node = queue.back();
117.553 + queue.pop_back();
117.554 + if ((*_node_order)[node] == -2) {
117.555 + Arc arc = prepare(node);
117.556 + Node source = _digraph->source(arc);
117.557 + while ((*_node_order)[source] != -1) {
117.558 + if ((*_node_order)[source] >= 0) {
117.559 + arc = contract(source);
117.560 + } else {
117.561 + arc = prepare(source);
117.562 + }
117.563 + source = _digraph->source(arc);
117.564 + }
117.565 + finalize(arc);
117.566 + level_stack.clear();
117.567 + }
117.568 + return node;
117.569 + }
117.570 +
117.571 + /// \brief Returns the number of the nodes to be processed.
117.572 + ///
117.573 + /// Returns the number of the nodes to be processed in the priority
117.574 + /// queue.
117.575 + int queueSize() const {
117.576 + return queue.size();
117.577 + }
117.578 +
117.579 + /// \brief Returns \c false if there are nodes to be processed.
117.580 + ///
117.581 + /// Returns \c false if there are nodes to be processed.
117.582 + bool emptyQueue() const {
117.583 + return queue.empty();
117.584 + }
117.585 +
117.586 + /// \brief Executes the algorithm.
117.587 + ///
117.588 + /// Executes the algorithm.
117.589 + ///
117.590 + /// \pre init() must be called and at least one node should be added
117.591 + /// with addSource() before using this function.
117.592 + ///
117.593 + ///\note mca.start() is just a shortcut of the following code.
117.594 + ///\code
117.595 + ///while (!mca.emptyQueue()) {
117.596 + /// mca.processNextNode();
117.597 + ///}
117.598 + ///\endcode
117.599 + void start() {
117.600 + while (!emptyQueue()) {
117.601 + processNextNode();
117.602 + }
117.603 + }
117.604 +
117.605 + /// \brief Runs %MinCostArborescence algorithm from node \c s.
117.606 + ///
117.607 + /// This method runs the %MinCostArborescence algorithm from
117.608 + /// a root node \c s.
117.609 + ///
117.610 + /// \note mca.run(s) is just a shortcut of the following code.
117.611 + /// \code
117.612 + /// mca.init();
117.613 + /// mca.addSource(s);
117.614 + /// mca.start();
117.615 + /// \endcode
117.616 + void run(Node s) {
117.617 + init();
117.618 + addSource(s);
117.619 + start();
117.620 + }
117.621 +
117.622 + ///@}
117.623 +
117.624 + /// \name Query Functions
117.625 + /// The result of the %MinCostArborescence algorithm can be obtained
117.626 + /// using these functions.\n
117.627 + /// Either run() or start() must be called before using them.
117.628 +
117.629 + /// @{
117.630 +
117.631 + /// \brief Returns the cost of the arborescence.
117.632 + ///
117.633 + /// Returns the cost of the arborescence.
117.634 + Value arborescenceCost() const {
117.635 + Value sum = 0;
117.636 + for (ArcIt it(*_digraph); it != INVALID; ++it) {
117.637 + if (arborescence(it)) {
117.638 + sum += (*_cost)[it];
117.639 + }
117.640 + }
117.641 + return sum;
117.642 + }
117.643 +
117.644 + /// \brief Returns \c true if the arc is in the arborescence.
117.645 + ///
117.646 + /// Returns \c true if the given arc is in the arborescence.
117.647 + /// \param arc An arc of the digraph.
117.648 + /// \pre \ref run() must be called before using this function.
117.649 + bool arborescence(Arc arc) const {
117.650 + return (*_pred)[_digraph->target(arc)] == arc;
117.651 + }
117.652 +
117.653 + /// \brief Returns a const reference to the arborescence map.
117.654 + ///
117.655 + /// Returns a const reference to the arborescence map.
117.656 + /// \pre \ref run() must be called before using this function.
117.657 + const ArborescenceMap& arborescenceMap() const {
117.658 + return *_arborescence;
117.659 + }
117.660 +
117.661 + /// \brief Returns the predecessor arc of the given node.
117.662 + ///
117.663 + /// Returns the predecessor arc of the given node.
117.664 + /// \pre \ref run() must be called before using this function.
117.665 + Arc pred(Node node) const {
117.666 + return (*_pred)[node];
117.667 + }
117.668 +
117.669 + /// \brief Returns a const reference to the pred map.
117.670 + ///
117.671 + /// Returns a const reference to the pred map.
117.672 + /// \pre \ref run() must be called before using this function.
117.673 + const PredMap& predMap() const {
117.674 + return *_pred;
117.675 + }
117.676 +
117.677 + /// \brief Indicates that a node is reachable from the sources.
117.678 + ///
117.679 + /// Indicates that a node is reachable from the sources.
117.680 + bool reached(Node node) const {
117.681 + return (*_node_order)[node] != -3;
117.682 + }
117.683 +
117.684 + /// \brief Indicates that a node is processed.
117.685 + ///
117.686 + /// Indicates that a node is processed. The arborescence path exists
117.687 + /// from the source to the given node.
117.688 + bool processed(Node node) const {
117.689 + return (*_node_order)[node] == -1;
117.690 + }
117.691 +
117.692 + /// \brief Returns the number of the dual variables in basis.
117.693 + ///
117.694 + /// Returns the number of the dual variables in basis.
117.695 + int dualNum() const {
117.696 + return _dual_variables.size();
117.697 + }
117.698 +
117.699 + /// \brief Returns the value of the dual solution.
117.700 + ///
117.701 + /// Returns the value of the dual solution. It should be
117.702 + /// equal to the arborescence value.
117.703 + Value dualValue() const {
117.704 + Value sum = 0;
117.705 + for (int i = 0; i < int(_dual_variables.size()); ++i) {
117.706 + sum += _dual_variables[i].value;
117.707 + }
117.708 + return sum;
117.709 + }
117.710 +
117.711 + /// \brief Returns the number of the nodes in the dual variable.
117.712 + ///
117.713 + /// Returns the number of the nodes in the dual variable.
117.714 + int dualSize(int k) const {
117.715 + return _dual_variables[k].end - _dual_variables[k].begin;
117.716 + }
117.717 +
117.718 + /// \brief Returns the value of the dual variable.
117.719 + ///
117.720 + /// Returns the the value of the dual variable.
117.721 + Value dualValue(int k) const {
117.722 + return _dual_variables[k].value;
117.723 + }
117.724 +
117.725 + /// \brief LEMON iterator for getting a dual variable.
117.726 + ///
117.727 + /// This class provides a common style LEMON iterator for getting a
117.728 + /// dual variable of \ref MinCostArborescence algorithm.
117.729 + /// It iterates over a subset of the nodes.
117.730 + class DualIt {
117.731 + public:
117.732 +
117.733 + /// \brief Constructor.
117.734 + ///
117.735 + /// Constructor for getting the nodeset of the dual variable
117.736 + /// of \ref MinCostArborescence algorithm.
117.737 + DualIt(const MinCostArborescence& algorithm, int variable)
117.738 + : _algorithm(&algorithm)
117.739 + {
117.740 + _index = _algorithm->_dual_variables[variable].begin;
117.741 + _last = _algorithm->_dual_variables[variable].end;
117.742 + }
117.743 +
117.744 + /// \brief Conversion to \c Node.
117.745 + ///
117.746 + /// Conversion to \c Node.
117.747 + operator Node() const {
117.748 + return _algorithm->_dual_node_list[_index];
117.749 + }
117.750 +
117.751 + /// \brief Increment operator.
117.752 + ///
117.753 + /// Increment operator.
117.754 + DualIt& operator++() {
117.755 + ++_index;
117.756 + return *this;
117.757 + }
117.758 +
117.759 + /// \brief Validity checking
117.760 + ///
117.761 + /// Checks whether the iterator is invalid.
117.762 + bool operator==(Invalid) const {
117.763 + return _index == _last;
117.764 + }
117.765 +
117.766 + /// \brief Validity checking
117.767 + ///
117.768 + /// Checks whether the iterator is valid.
117.769 + bool operator!=(Invalid) const {
117.770 + return _index != _last;
117.771 + }
117.772 +
117.773 + private:
117.774 + const MinCostArborescence* _algorithm;
117.775 + int _index, _last;
117.776 + };
117.777 +
117.778 + /// @}
117.779 +
117.780 + };
117.781 +
117.782 + /// \ingroup spantree
117.783 + ///
117.784 + /// \brief Function type interface for MinCostArborescence algorithm.
117.785 + ///
117.786 + /// Function type interface for MinCostArborescence algorithm.
117.787 + /// \param digraph The digraph the algorithm runs on.
117.788 + /// \param cost An arc map storing the costs.
117.789 + /// \param source The source node of the arborescence.
117.790 + /// \retval arborescence An arc map with \c bool (or convertible) value
117.791 + /// type that stores the arborescence.
117.792 + /// \return The total cost of the arborescence.
117.793 + ///
117.794 + /// \sa MinCostArborescence
117.795 + template <typename Digraph, typename CostMap, typename ArborescenceMap>
117.796 + typename CostMap::Value minCostArborescence(const Digraph& digraph,
117.797 + const CostMap& cost,
117.798 + typename Digraph::Node source,
117.799 + ArborescenceMap& arborescence) {
117.800 + typename MinCostArborescence<Digraph, CostMap>
117.801 + ::template SetArborescenceMap<ArborescenceMap>
117.802 + ::Create mca(digraph, cost);
117.803 + mca.arborescenceMap(arborescence);
117.804 + mca.run(source);
117.805 + return mca.arborescenceCost();
117.806 + }
117.807 +
117.808 +}
117.809 +
117.810 +#endif
118.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
118.2 +++ b/lemon/nauty_reader.h Thu Dec 10 17:05:35 2009 +0100
118.3 @@ -0,0 +1,113 @@
118.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
118.5 + *
118.6 + * This file is a part of LEMON, a generic C++ optimization library.
118.7 + *
118.8 + * Copyright (C) 2003-2009
118.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
118.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
118.11 + *
118.12 + * Permission to use, modify and distribute this software is granted
118.13 + * provided that this copyright notice appears in all copies. For
118.14 + * precise terms see the accompanying LICENSE file.
118.15 + *
118.16 + * This software is provided "AS IS" with no warranty of any kind,
118.17 + * express or implied, and with no claim as to its suitability for any
118.18 + * purpose.
118.19 + *
118.20 + */
118.21 +
118.22 +#ifndef LEMON_NAUTY_READER_H
118.23 +#define LEMON_NAUTY_READER_H
118.24 +
118.25 +#include <vector>
118.26 +#include <iostream>
118.27 +#include <string>
118.28 +
118.29 +/// \ingroup nauty_group
118.30 +/// \file
118.31 +/// \brief Nauty file reader.
118.32 +
118.33 +namespace lemon {
118.34 +
118.35 + /// \ingroup nauty_group
118.36 + ///
118.37 + /// \brief Nauty file reader
118.38 + ///
118.39 + /// The \e geng program is in the \e gtools suite of the nauty
118.40 + /// package. This tool can generate all non-isomorphic undirected
118.41 + /// graphs of several classes with given node number (e.g.
118.42 + /// general, connected, biconnected, triangle-free, 4-cycle-free,
118.43 + /// bipartite and graphs with given edge number and degree
118.44 + /// constraints). This function reads a \e nauty \e graph6 \e format
118.45 + /// line from the given stream and builds it in the given graph.
118.46 + ///
118.47 + /// The site of nauty package: http://cs.anu.edu.au/~bdm/nauty/
118.48 + ///
118.49 + /// For example, the number of all non-isomorphic planar graphs
118.50 + /// can be computed with the following code.
118.51 + ///\code
118.52 + /// int num = 0;
118.53 + /// SmartGraph graph;
118.54 + /// while (readNautyGraph(graph, std::cin)) {
118.55 + /// PlanarityChecking<SmartGraph> pc(graph);
118.56 + /// if (pc.run()) ++num;
118.57 + /// }
118.58 + /// std::cout << "Number of planar graphs: " << num << std::endl;
118.59 + ///\endcode
118.60 + ///
118.61 + /// The nauty files are quite huge, therefore instead of the direct
118.62 + /// file generation pipelining is recommended. For example,
118.63 + ///\code
118.64 + /// ./geng -c 10 | ./num_of_planar_graphs
118.65 + ///\endcode
118.66 + template <typename Graph>
118.67 + std::istream& readNautyGraph(Graph& graph, std::istream& is = std::cin) {
118.68 + graph.clear();
118.69 +
118.70 + std::string line;
118.71 + if (getline(is, line)) {
118.72 + int index = 0;
118.73 +
118.74 + int n;
118.75 +
118.76 + if (line[index] == '>') {
118.77 + index += 10;
118.78 + }
118.79 +
118.80 + char c = line[index++]; c -= 63;
118.81 + if (c != 63) {
118.82 + n = int(c);
118.83 + } else {
118.84 + c = line[index++]; c -= 63;
118.85 + n = (int(c) << 12);
118.86 + c = line[index++]; c -= 63;
118.87 + n |= (int(c) << 6);
118.88 + c = line[index++]; c -= 63;
118.89 + n |= int(c);
118.90 + }
118.91 +
118.92 + std::vector<typename Graph::Node> nodes;
118.93 + for (int i = 0; i < n; ++i) {
118.94 + nodes.push_back(graph.addNode());
118.95 + }
118.96 +
118.97 + int bit = -1;
118.98 + for (int j = 0; j < n; ++j) {
118.99 + for (int i = 0; i < j; ++i) {
118.100 + if (bit == -1) {
118.101 + c = line[index++]; c -= 63;
118.102 + bit = 5;
118.103 + }
118.104 + bool b = (c & (1 << (bit--))) != 0;
118.105 +
118.106 + if (b) {
118.107 + graph.addEdge(nodes[i], nodes[j]);
118.108 + }
118.109 + }
118.110 + }
118.111 + }
118.112 + return is;
118.113 + }
118.114 +}
118.115 +
118.116 +#endif
119.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
119.2 +++ b/lemon/network_simplex.h Thu Dec 10 17:05:35 2009 +0100
119.3 @@ -0,0 +1,1489 @@
119.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
119.5 + *
119.6 + * This file is a part of LEMON, a generic C++ optimization library.
119.7 + *
119.8 + * Copyright (C) 2003-2009
119.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
119.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
119.11 + *
119.12 + * Permission to use, modify and distribute this software is granted
119.13 + * provided that this copyright notice appears in all copies. For
119.14 + * precise terms see the accompanying LICENSE file.
119.15 + *
119.16 + * This software is provided "AS IS" with no warranty of any kind,
119.17 + * express or implied, and with no claim as to its suitability for any
119.18 + * purpose.
119.19 + *
119.20 + */
119.21 +
119.22 +#ifndef LEMON_NETWORK_SIMPLEX_H
119.23 +#define LEMON_NETWORK_SIMPLEX_H
119.24 +
119.25 +/// \ingroup min_cost_flow_algs
119.26 +///
119.27 +/// \file
119.28 +/// \brief Network Simplex algorithm for finding a minimum cost flow.
119.29 +
119.30 +#include <vector>
119.31 +#include <limits>
119.32 +#include <algorithm>
119.33 +
119.34 +#include <lemon/core.h>
119.35 +#include <lemon/math.h>
119.36 +
119.37 +namespace lemon {
119.38 +
119.39 + /// \addtogroup min_cost_flow_algs
119.40 + /// @{
119.41 +
119.42 + /// \brief Implementation of the primal Network Simplex algorithm
119.43 + /// for finding a \ref min_cost_flow "minimum cost flow".
119.44 + ///
119.45 + /// \ref NetworkSimplex implements the primal Network Simplex algorithm
119.46 + /// for finding a \ref min_cost_flow "minimum cost flow".
119.47 + /// This algorithm is a specialized version of the linear programming
119.48 + /// simplex method directly for the minimum cost flow problem.
119.49 + /// It is one of the most efficient solution methods.
119.50 + ///
119.51 + /// In general this class is the fastest implementation available
119.52 + /// in LEMON for the minimum cost flow problem.
119.53 + /// Moreover it supports both directions of the supply/demand inequality
119.54 + /// constraints. For more information see \ref SupplyType.
119.55 + ///
119.56 + /// Most of the parameters of the problem (except for the digraph)
119.57 + /// can be given using separate functions, and the algorithm can be
119.58 + /// executed using the \ref run() function. If some parameters are not
119.59 + /// specified, then default values will be used.
119.60 + ///
119.61 + /// \tparam GR The digraph type the algorithm runs on.
119.62 + /// \tparam V The value type used for flow amounts, capacity bounds
119.63 + /// and supply values in the algorithm. By default it is \c int.
119.64 + /// \tparam C The value type used for costs and potentials in the
119.65 + /// algorithm. By default it is the same as \c V.
119.66 + ///
119.67 + /// \warning Both value types must be signed and all input data must
119.68 + /// be integer.
119.69 + ///
119.70 + /// \note %NetworkSimplex provides five different pivot rule
119.71 + /// implementations, from which the most efficient one is used
119.72 + /// by default. For more information see \ref PivotRule.
119.73 + template <typename GR, typename V = int, typename C = V>
119.74 + class NetworkSimplex
119.75 + {
119.76 + public:
119.77 +
119.78 + /// The type of the flow amounts, capacity bounds and supply values
119.79 + typedef V Value;
119.80 + /// The type of the arc costs
119.81 + typedef C Cost;
119.82 +
119.83 + public:
119.84 +
119.85 + /// \brief Problem type constants for the \c run() function.
119.86 + ///
119.87 + /// Enum type containing the problem type constants that can be
119.88 + /// returned by the \ref run() function of the algorithm.
119.89 + enum ProblemType {
119.90 + /// The problem has no feasible solution (flow).
119.91 + INFEASIBLE,
119.92 + /// The problem has optimal solution (i.e. it is feasible and
119.93 + /// bounded), and the algorithm has found optimal flow and node
119.94 + /// potentials (primal and dual solutions).
119.95 + OPTIMAL,
119.96 + /// The objective function of the problem is unbounded, i.e.
119.97 + /// there is a directed cycle having negative total cost and
119.98 + /// infinite upper bound.
119.99 + UNBOUNDED
119.100 + };
119.101 +
119.102 + /// \brief Constants for selecting the type of the supply constraints.
119.103 + ///
119.104 + /// Enum type containing constants for selecting the supply type,
119.105 + /// i.e. the direction of the inequalities in the supply/demand
119.106 + /// constraints of the \ref min_cost_flow "minimum cost flow problem".
119.107 + ///
119.108 + /// The default supply type is \c GEQ, the \c LEQ type can be
119.109 + /// selected using \ref supplyType().
119.110 + /// The equality form is a special case of both supply types.
119.111 + enum SupplyType {
119.112 + /// This option means that there are <em>"greater or equal"</em>
119.113 + /// supply/demand constraints in the definition of the problem.
119.114 + GEQ,
119.115 + /// This option means that there are <em>"less or equal"</em>
119.116 + /// supply/demand constraints in the definition of the problem.
119.117 + LEQ
119.118 + };
119.119 +
119.120 + /// \brief Constants for selecting the pivot rule.
119.121 + ///
119.122 + /// Enum type containing constants for selecting the pivot rule for
119.123 + /// the \ref run() function.
119.124 + ///
119.125 + /// \ref NetworkSimplex provides five different pivot rule
119.126 + /// implementations that significantly affect the running time
119.127 + /// of the algorithm.
119.128 + /// By default \ref BLOCK_SEARCH "Block Search" is used, which
119.129 + /// proved to be the most efficient and the most robust on various
119.130 + /// test inputs according to our benchmark tests.
119.131 + /// However another pivot rule can be selected using the \ref run()
119.132 + /// function with the proper parameter.
119.133 + enum PivotRule {
119.134 +
119.135 + /// The First Eligible pivot rule.
119.136 + /// The next eligible arc is selected in a wraparound fashion
119.137 + /// in every iteration.
119.138 + FIRST_ELIGIBLE,
119.139 +
119.140 + /// The Best Eligible pivot rule.
119.141 + /// The best eligible arc is selected in every iteration.
119.142 + BEST_ELIGIBLE,
119.143 +
119.144 + /// The Block Search pivot rule.
119.145 + /// A specified number of arcs are examined in every iteration
119.146 + /// in a wraparound fashion and the best eligible arc is selected
119.147 + /// from this block.
119.148 + BLOCK_SEARCH,
119.149 +
119.150 + /// The Candidate List pivot rule.
119.151 + /// In a major iteration a candidate list is built from eligible arcs
119.152 + /// in a wraparound fashion and in the following minor iterations
119.153 + /// the best eligible arc is selected from this list.
119.154 + CANDIDATE_LIST,
119.155 +
119.156 + /// The Altering Candidate List pivot rule.
119.157 + /// It is a modified version of the Candidate List method.
119.158 + /// It keeps only the several best eligible arcs from the former
119.159 + /// candidate list and extends this list in every iteration.
119.160 + ALTERING_LIST
119.161 + };
119.162 +
119.163 + private:
119.164 +
119.165 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
119.166 +
119.167 + typedef std::vector<Arc> ArcVector;
119.168 + typedef std::vector<Node> NodeVector;
119.169 + typedef std::vector<int> IntVector;
119.170 + typedef std::vector<bool> BoolVector;
119.171 + typedef std::vector<Value> ValueVector;
119.172 + typedef std::vector<Cost> CostVector;
119.173 +
119.174 + // State constants for arcs
119.175 + enum ArcStateEnum {
119.176 + STATE_UPPER = -1,
119.177 + STATE_TREE = 0,
119.178 + STATE_LOWER = 1
119.179 + };
119.180 +
119.181 + private:
119.182 +
119.183 + // Data related to the underlying digraph
119.184 + const GR &_graph;
119.185 + int _node_num;
119.186 + int _arc_num;
119.187 + int _all_arc_num;
119.188 + int _search_arc_num;
119.189 +
119.190 + // Parameters of the problem
119.191 + bool _have_lower;
119.192 + SupplyType _stype;
119.193 + Value _sum_supply;
119.194 +
119.195 + // Data structures for storing the digraph
119.196 + IntNodeMap _node_id;
119.197 + IntArcMap _arc_id;
119.198 + IntVector _source;
119.199 + IntVector _target;
119.200 +
119.201 + // Node and arc data
119.202 + ValueVector _lower;
119.203 + ValueVector _upper;
119.204 + ValueVector _cap;
119.205 + CostVector _cost;
119.206 + ValueVector _supply;
119.207 + ValueVector _flow;
119.208 + CostVector _pi;
119.209 +
119.210 + // Data for storing the spanning tree structure
119.211 + IntVector _parent;
119.212 + IntVector _pred;
119.213 + IntVector _thread;
119.214 + IntVector _rev_thread;
119.215 + IntVector _succ_num;
119.216 + IntVector _last_succ;
119.217 + IntVector _dirty_revs;
119.218 + BoolVector _forward;
119.219 + IntVector _state;
119.220 + int _root;
119.221 +
119.222 + // Temporary data used in the current pivot iteration
119.223 + int in_arc, join, u_in, v_in, u_out, v_out;
119.224 + int first, second, right, last;
119.225 + int stem, par_stem, new_stem;
119.226 + Value delta;
119.227 +
119.228 + public:
119.229 +
119.230 + /// \brief Constant for infinite upper bounds (capacities).
119.231 + ///
119.232 + /// Constant for infinite upper bounds (capacities).
119.233 + /// It is \c std::numeric_limits<Value>::infinity() if available,
119.234 + /// \c std::numeric_limits<Value>::max() otherwise.
119.235 + const Value INF;
119.236 +
119.237 + private:
119.238 +
119.239 + // Implementation of the First Eligible pivot rule
119.240 + class FirstEligiblePivotRule
119.241 + {
119.242 + private:
119.243 +
119.244 + // References to the NetworkSimplex class
119.245 + const IntVector &_source;
119.246 + const IntVector &_target;
119.247 + const CostVector &_cost;
119.248 + const IntVector &_state;
119.249 + const CostVector &_pi;
119.250 + int &_in_arc;
119.251 + int _search_arc_num;
119.252 +
119.253 + // Pivot rule data
119.254 + int _next_arc;
119.255 +
119.256 + public:
119.257 +
119.258 + // Constructor
119.259 + FirstEligiblePivotRule(NetworkSimplex &ns) :
119.260 + _source(ns._source), _target(ns._target),
119.261 + _cost(ns._cost), _state(ns._state), _pi(ns._pi),
119.262 + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
119.263 + _next_arc(0)
119.264 + {}
119.265 +
119.266 + // Find next entering arc
119.267 + bool findEnteringArc() {
119.268 + Cost c;
119.269 + for (int e = _next_arc; e < _search_arc_num; ++e) {
119.270 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
119.271 + if (c < 0) {
119.272 + _in_arc = e;
119.273 + _next_arc = e + 1;
119.274 + return true;
119.275 + }
119.276 + }
119.277 + for (int e = 0; e < _next_arc; ++e) {
119.278 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
119.279 + if (c < 0) {
119.280 + _in_arc = e;
119.281 + _next_arc = e + 1;
119.282 + return true;
119.283 + }
119.284 + }
119.285 + return false;
119.286 + }
119.287 +
119.288 + }; //class FirstEligiblePivotRule
119.289 +
119.290 +
119.291 + // Implementation of the Best Eligible pivot rule
119.292 + class BestEligiblePivotRule
119.293 + {
119.294 + private:
119.295 +
119.296 + // References to the NetworkSimplex class
119.297 + const IntVector &_source;
119.298 + const IntVector &_target;
119.299 + const CostVector &_cost;
119.300 + const IntVector &_state;
119.301 + const CostVector &_pi;
119.302 + int &_in_arc;
119.303 + int _search_arc_num;
119.304 +
119.305 + public:
119.306 +
119.307 + // Constructor
119.308 + BestEligiblePivotRule(NetworkSimplex &ns) :
119.309 + _source(ns._source), _target(ns._target),
119.310 + _cost(ns._cost), _state(ns._state), _pi(ns._pi),
119.311 + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num)
119.312 + {}
119.313 +
119.314 + // Find next entering arc
119.315 + bool findEnteringArc() {
119.316 + Cost c, min = 0;
119.317 + for (int e = 0; e < _search_arc_num; ++e) {
119.318 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
119.319 + if (c < min) {
119.320 + min = c;
119.321 + _in_arc = e;
119.322 + }
119.323 + }
119.324 + return min < 0;
119.325 + }
119.326 +
119.327 + }; //class BestEligiblePivotRule
119.328 +
119.329 +
119.330 + // Implementation of the Block Search pivot rule
119.331 + class BlockSearchPivotRule
119.332 + {
119.333 + private:
119.334 +
119.335 + // References to the NetworkSimplex class
119.336 + const IntVector &_source;
119.337 + const IntVector &_target;
119.338 + const CostVector &_cost;
119.339 + const IntVector &_state;
119.340 + const CostVector &_pi;
119.341 + int &_in_arc;
119.342 + int _search_arc_num;
119.343 +
119.344 + // Pivot rule data
119.345 + int _block_size;
119.346 + int _next_arc;
119.347 +
119.348 + public:
119.349 +
119.350 + // Constructor
119.351 + BlockSearchPivotRule(NetworkSimplex &ns) :
119.352 + _source(ns._source), _target(ns._target),
119.353 + _cost(ns._cost), _state(ns._state), _pi(ns._pi),
119.354 + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
119.355 + _next_arc(0)
119.356 + {
119.357 + // The main parameters of the pivot rule
119.358 + const double BLOCK_SIZE_FACTOR = 0.5;
119.359 + const int MIN_BLOCK_SIZE = 10;
119.360 +
119.361 + _block_size = std::max( int(BLOCK_SIZE_FACTOR *
119.362 + std::sqrt(double(_search_arc_num))),
119.363 + MIN_BLOCK_SIZE );
119.364 + }
119.365 +
119.366 + // Find next entering arc
119.367 + bool findEnteringArc() {
119.368 + Cost c, min = 0;
119.369 + int cnt = _block_size;
119.370 + int e, min_arc = _next_arc;
119.371 + for (e = _next_arc; e < _search_arc_num; ++e) {
119.372 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
119.373 + if (c < min) {
119.374 + min = c;
119.375 + min_arc = e;
119.376 + }
119.377 + if (--cnt == 0) {
119.378 + if (min < 0) break;
119.379 + cnt = _block_size;
119.380 + }
119.381 + }
119.382 + if (min == 0 || cnt > 0) {
119.383 + for (e = 0; e < _next_arc; ++e) {
119.384 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
119.385 + if (c < min) {
119.386 + min = c;
119.387 + min_arc = e;
119.388 + }
119.389 + if (--cnt == 0) {
119.390 + if (min < 0) break;
119.391 + cnt = _block_size;
119.392 + }
119.393 + }
119.394 + }
119.395 + if (min >= 0) return false;
119.396 + _in_arc = min_arc;
119.397 + _next_arc = e;
119.398 + return true;
119.399 + }
119.400 +
119.401 + }; //class BlockSearchPivotRule
119.402 +
119.403 +
119.404 + // Implementation of the Candidate List pivot rule
119.405 + class CandidateListPivotRule
119.406 + {
119.407 + private:
119.408 +
119.409 + // References to the NetworkSimplex class
119.410 + const IntVector &_source;
119.411 + const IntVector &_target;
119.412 + const CostVector &_cost;
119.413 + const IntVector &_state;
119.414 + const CostVector &_pi;
119.415 + int &_in_arc;
119.416 + int _search_arc_num;
119.417 +
119.418 + // Pivot rule data
119.419 + IntVector _candidates;
119.420 + int _list_length, _minor_limit;
119.421 + int _curr_length, _minor_count;
119.422 + int _next_arc;
119.423 +
119.424 + public:
119.425 +
119.426 + /// Constructor
119.427 + CandidateListPivotRule(NetworkSimplex &ns) :
119.428 + _source(ns._source), _target(ns._target),
119.429 + _cost(ns._cost), _state(ns._state), _pi(ns._pi),
119.430 + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
119.431 + _next_arc(0)
119.432 + {
119.433 + // The main parameters of the pivot rule
119.434 + const double LIST_LENGTH_FACTOR = 1.0;
119.435 + const int MIN_LIST_LENGTH = 10;
119.436 + const double MINOR_LIMIT_FACTOR = 0.1;
119.437 + const int MIN_MINOR_LIMIT = 3;
119.438 +
119.439 + _list_length = std::max( int(LIST_LENGTH_FACTOR *
119.440 + std::sqrt(double(_search_arc_num))),
119.441 + MIN_LIST_LENGTH );
119.442 + _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
119.443 + MIN_MINOR_LIMIT );
119.444 + _curr_length = _minor_count = 0;
119.445 + _candidates.resize(_list_length);
119.446 + }
119.447 +
119.448 + /// Find next entering arc
119.449 + bool findEnteringArc() {
119.450 + Cost min, c;
119.451 + int e, min_arc = _next_arc;
119.452 + if (_curr_length > 0 && _minor_count < _minor_limit) {
119.453 + // Minor iteration: select the best eligible arc from the
119.454 + // current candidate list
119.455 + ++_minor_count;
119.456 + min = 0;
119.457 + for (int i = 0; i < _curr_length; ++i) {
119.458 + e = _candidates[i];
119.459 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
119.460 + if (c < min) {
119.461 + min = c;
119.462 + min_arc = e;
119.463 + }
119.464 + if (c >= 0) {
119.465 + _candidates[i--] = _candidates[--_curr_length];
119.466 + }
119.467 + }
119.468 + if (min < 0) {
119.469 + _in_arc = min_arc;
119.470 + return true;
119.471 + }
119.472 + }
119.473 +
119.474 + // Major iteration: build a new candidate list
119.475 + min = 0;
119.476 + _curr_length = 0;
119.477 + for (e = _next_arc; e < _search_arc_num; ++e) {
119.478 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
119.479 + if (c < 0) {
119.480 + _candidates[_curr_length++] = e;
119.481 + if (c < min) {
119.482 + min = c;
119.483 + min_arc = e;
119.484 + }
119.485 + if (_curr_length == _list_length) break;
119.486 + }
119.487 + }
119.488 + if (_curr_length < _list_length) {
119.489 + for (e = 0; e < _next_arc; ++e) {
119.490 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
119.491 + if (c < 0) {
119.492 + _candidates[_curr_length++] = e;
119.493 + if (c < min) {
119.494 + min = c;
119.495 + min_arc = e;
119.496 + }
119.497 + if (_curr_length == _list_length) break;
119.498 + }
119.499 + }
119.500 + }
119.501 + if (_curr_length == 0) return false;
119.502 + _minor_count = 1;
119.503 + _in_arc = min_arc;
119.504 + _next_arc = e;
119.505 + return true;
119.506 + }
119.507 +
119.508 + }; //class CandidateListPivotRule
119.509 +
119.510 +
119.511 + // Implementation of the Altering Candidate List pivot rule
119.512 + class AlteringListPivotRule
119.513 + {
119.514 + private:
119.515 +
119.516 + // References to the NetworkSimplex class
119.517 + const IntVector &_source;
119.518 + const IntVector &_target;
119.519 + const CostVector &_cost;
119.520 + const IntVector &_state;
119.521 + const CostVector &_pi;
119.522 + int &_in_arc;
119.523 + int _search_arc_num;
119.524 +
119.525 + // Pivot rule data
119.526 + int _block_size, _head_length, _curr_length;
119.527 + int _next_arc;
119.528 + IntVector _candidates;
119.529 + CostVector _cand_cost;
119.530 +
119.531 + // Functor class to compare arcs during sort of the candidate list
119.532 + class SortFunc
119.533 + {
119.534 + private:
119.535 + const CostVector &_map;
119.536 + public:
119.537 + SortFunc(const CostVector &map) : _map(map) {}
119.538 + bool operator()(int left, int right) {
119.539 + return _map[left] > _map[right];
119.540 + }
119.541 + };
119.542 +
119.543 + SortFunc _sort_func;
119.544 +
119.545 + public:
119.546 +
119.547 + // Constructor
119.548 + AlteringListPivotRule(NetworkSimplex &ns) :
119.549 + _source(ns._source), _target(ns._target),
119.550 + _cost(ns._cost), _state(ns._state), _pi(ns._pi),
119.551 + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
119.552 + _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
119.553 + {
119.554 + // The main parameters of the pivot rule
119.555 + const double BLOCK_SIZE_FACTOR = 1.5;
119.556 + const int MIN_BLOCK_SIZE = 10;
119.557 + const double HEAD_LENGTH_FACTOR = 0.1;
119.558 + const int MIN_HEAD_LENGTH = 3;
119.559 +
119.560 + _block_size = std::max( int(BLOCK_SIZE_FACTOR *
119.561 + std::sqrt(double(_search_arc_num))),
119.562 + MIN_BLOCK_SIZE );
119.563 + _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
119.564 + MIN_HEAD_LENGTH );
119.565 + _candidates.resize(_head_length + _block_size);
119.566 + _curr_length = 0;
119.567 + }
119.568 +
119.569 + // Find next entering arc
119.570 + bool findEnteringArc() {
119.571 + // Check the current candidate list
119.572 + int e;
119.573 + for (int i = 0; i < _curr_length; ++i) {
119.574 + e = _candidates[i];
119.575 + _cand_cost[e] = _state[e] *
119.576 + (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
119.577 + if (_cand_cost[e] >= 0) {
119.578 + _candidates[i--] = _candidates[--_curr_length];
119.579 + }
119.580 + }
119.581 +
119.582 + // Extend the list
119.583 + int cnt = _block_size;
119.584 + int last_arc = 0;
119.585 + int limit = _head_length;
119.586 +
119.587 + for (int e = _next_arc; e < _search_arc_num; ++e) {
119.588 + _cand_cost[e] = _state[e] *
119.589 + (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
119.590 + if (_cand_cost[e] < 0) {
119.591 + _candidates[_curr_length++] = e;
119.592 + last_arc = e;
119.593 + }
119.594 + if (--cnt == 0) {
119.595 + if (_curr_length > limit) break;
119.596 + limit = 0;
119.597 + cnt = _block_size;
119.598 + }
119.599 + }
119.600 + if (_curr_length <= limit) {
119.601 + for (int e = 0; e < _next_arc; ++e) {
119.602 + _cand_cost[e] = _state[e] *
119.603 + (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
119.604 + if (_cand_cost[e] < 0) {
119.605 + _candidates[_curr_length++] = e;
119.606 + last_arc = e;
119.607 + }
119.608 + if (--cnt == 0) {
119.609 + if (_curr_length > limit) break;
119.610 + limit = 0;
119.611 + cnt = _block_size;
119.612 + }
119.613 + }
119.614 + }
119.615 + if (_curr_length == 0) return false;
119.616 + _next_arc = last_arc + 1;
119.617 +
119.618 + // Make heap of the candidate list (approximating a partial sort)
119.619 + make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
119.620 + _sort_func );
119.621 +
119.622 + // Pop the first element of the heap
119.623 + _in_arc = _candidates[0];
119.624 + pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
119.625 + _sort_func );
119.626 + _curr_length = std::min(_head_length, _curr_length - 1);
119.627 + return true;
119.628 + }
119.629 +
119.630 + }; //class AlteringListPivotRule
119.631 +
119.632 + public:
119.633 +
119.634 + /// \brief Constructor.
119.635 + ///
119.636 + /// The constructor of the class.
119.637 + ///
119.638 + /// \param graph The digraph the algorithm runs on.
119.639 + NetworkSimplex(const GR& graph) :
119.640 + _graph(graph), _node_id(graph), _arc_id(graph),
119.641 + INF(std::numeric_limits<Value>::has_infinity ?
119.642 + std::numeric_limits<Value>::infinity() :
119.643 + std::numeric_limits<Value>::max())
119.644 + {
119.645 + // Check the value types
119.646 + LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
119.647 + "The flow type of NetworkSimplex must be signed");
119.648 + LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
119.649 + "The cost type of NetworkSimplex must be signed");
119.650 +
119.651 + // Resize vectors
119.652 + _node_num = countNodes(_graph);
119.653 + _arc_num = countArcs(_graph);
119.654 + int all_node_num = _node_num + 1;
119.655 + int max_arc_num = _arc_num + 2 * _node_num;
119.656 +
119.657 + _source.resize(max_arc_num);
119.658 + _target.resize(max_arc_num);
119.659 +
119.660 + _lower.resize(_arc_num);
119.661 + _upper.resize(_arc_num);
119.662 + _cap.resize(max_arc_num);
119.663 + _cost.resize(max_arc_num);
119.664 + _supply.resize(all_node_num);
119.665 + _flow.resize(max_arc_num);
119.666 + _pi.resize(all_node_num);
119.667 +
119.668 + _parent.resize(all_node_num);
119.669 + _pred.resize(all_node_num);
119.670 + _forward.resize(all_node_num);
119.671 + _thread.resize(all_node_num);
119.672 + _rev_thread.resize(all_node_num);
119.673 + _succ_num.resize(all_node_num);
119.674 + _last_succ.resize(all_node_num);
119.675 + _state.resize(max_arc_num);
119.676 +
119.677 + // Copy the graph (store the arcs in a mixed order)
119.678 + int i = 0;
119.679 + for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
119.680 + _node_id[n] = i;
119.681 + }
119.682 + int k = std::max(int(std::sqrt(double(_arc_num))), 10);
119.683 + i = 0;
119.684 + for (ArcIt a(_graph); a != INVALID; ++a) {
119.685 + _arc_id[a] = i;
119.686 + _source[i] = _node_id[_graph.source(a)];
119.687 + _target[i] = _node_id[_graph.target(a)];
119.688 + if ((i += k) >= _arc_num) i = (i % k) + 1;
119.689 + }
119.690 +
119.691 + // Initialize maps
119.692 + for (int i = 0; i != _node_num; ++i) {
119.693 + _supply[i] = 0;
119.694 + }
119.695 + for (int i = 0; i != _arc_num; ++i) {
119.696 + _lower[i] = 0;
119.697 + _upper[i] = INF;
119.698 + _cost[i] = 1;
119.699 + }
119.700 + _have_lower = false;
119.701 + _stype = GEQ;
119.702 + }
119.703 +
119.704 + /// \name Parameters
119.705 + /// The parameters of the algorithm can be specified using these
119.706 + /// functions.
119.707 +
119.708 + /// @{
119.709 +
119.710 + /// \brief Set the lower bounds on the arcs.
119.711 + ///
119.712 + /// This function sets the lower bounds on the arcs.
119.713 + /// If it is not used before calling \ref run(), the lower bounds
119.714 + /// will be set to zero on all arcs.
119.715 + ///
119.716 + /// \param map An arc map storing the lower bounds.
119.717 + /// Its \c Value type must be convertible to the \c Value type
119.718 + /// of the algorithm.
119.719 + ///
119.720 + /// \return <tt>(*this)</tt>
119.721 + template <typename LowerMap>
119.722 + NetworkSimplex& lowerMap(const LowerMap& map) {
119.723 + _have_lower = true;
119.724 + for (ArcIt a(_graph); a != INVALID; ++a) {
119.725 + _lower[_arc_id[a]] = map[a];
119.726 + }
119.727 + return *this;
119.728 + }
119.729 +
119.730 + /// \brief Set the upper bounds (capacities) on the arcs.
119.731 + ///
119.732 + /// This function sets the upper bounds (capacities) on the arcs.
119.733 + /// If it is not used before calling \ref run(), the upper bounds
119.734 + /// will be set to \ref INF on all arcs (i.e. the flow value will be
119.735 + /// unbounded from above on each arc).
119.736 + ///
119.737 + /// \param map An arc map storing the upper bounds.
119.738 + /// Its \c Value type must be convertible to the \c Value type
119.739 + /// of the algorithm.
119.740 + ///
119.741 + /// \return <tt>(*this)</tt>
119.742 + template<typename UpperMap>
119.743 + NetworkSimplex& upperMap(const UpperMap& map) {
119.744 + for (ArcIt a(_graph); a != INVALID; ++a) {
119.745 + _upper[_arc_id[a]] = map[a];
119.746 + }
119.747 + return *this;
119.748 + }
119.749 +
119.750 + /// \brief Set the costs of the arcs.
119.751 + ///
119.752 + /// This function sets the costs of the arcs.
119.753 + /// If it is not used before calling \ref run(), the costs
119.754 + /// will be set to \c 1 on all arcs.
119.755 + ///
119.756 + /// \param map An arc map storing the costs.
119.757 + /// Its \c Value type must be convertible to the \c Cost type
119.758 + /// of the algorithm.
119.759 + ///
119.760 + /// \return <tt>(*this)</tt>
119.761 + template<typename CostMap>
119.762 + NetworkSimplex& costMap(const CostMap& map) {
119.763 + for (ArcIt a(_graph); a != INVALID; ++a) {
119.764 + _cost[_arc_id[a]] = map[a];
119.765 + }
119.766 + return *this;
119.767 + }
119.768 +
119.769 + /// \brief Set the supply values of the nodes.
119.770 + ///
119.771 + /// This function sets the supply values of the nodes.
119.772 + /// If neither this function nor \ref stSupply() is used before
119.773 + /// calling \ref run(), the supply of each node will be set to zero.
119.774 + /// (It makes sense only if non-zero lower bounds are given.)
119.775 + ///
119.776 + /// \param map A node map storing the supply values.
119.777 + /// Its \c Value type must be convertible to the \c Value type
119.778 + /// of the algorithm.
119.779 + ///
119.780 + /// \return <tt>(*this)</tt>
119.781 + template<typename SupplyMap>
119.782 + NetworkSimplex& supplyMap(const SupplyMap& map) {
119.783 + for (NodeIt n(_graph); n != INVALID; ++n) {
119.784 + _supply[_node_id[n]] = map[n];
119.785 + }
119.786 + return *this;
119.787 + }
119.788 +
119.789 + /// \brief Set single source and target nodes and a supply value.
119.790 + ///
119.791 + /// This function sets a single source node and a single target node
119.792 + /// and the required flow value.
119.793 + /// If neither this function nor \ref supplyMap() is used before
119.794 + /// calling \ref run(), the supply of each node will be set to zero.
119.795 + /// (It makes sense only if non-zero lower bounds are given.)
119.796 + ///
119.797 + /// Using this function has the same effect as using \ref supplyMap()
119.798 + /// with such a map in which \c k is assigned to \c s, \c -k is
119.799 + /// assigned to \c t and all other nodes have zero supply value.
119.800 + ///
119.801 + /// \param s The source node.
119.802 + /// \param t The target node.
119.803 + /// \param k The required amount of flow from node \c s to node \c t
119.804 + /// (i.e. the supply of \c s and the demand of \c t).
119.805 + ///
119.806 + /// \return <tt>(*this)</tt>
119.807 + NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
119.808 + for (int i = 0; i != _node_num; ++i) {
119.809 + _supply[i] = 0;
119.810 + }
119.811 + _supply[_node_id[s]] = k;
119.812 + _supply[_node_id[t]] = -k;
119.813 + return *this;
119.814 + }
119.815 +
119.816 + /// \brief Set the type of the supply constraints.
119.817 + ///
119.818 + /// This function sets the type of the supply/demand constraints.
119.819 + /// If it is not used before calling \ref run(), the \ref GEQ supply
119.820 + /// type will be used.
119.821 + ///
119.822 + /// For more information see \ref SupplyType.
119.823 + ///
119.824 + /// \return <tt>(*this)</tt>
119.825 + NetworkSimplex& supplyType(SupplyType supply_type) {
119.826 + _stype = supply_type;
119.827 + return *this;
119.828 + }
119.829 +
119.830 + /// @}
119.831 +
119.832 + /// \name Execution Control
119.833 + /// The algorithm can be executed using \ref run().
119.834 +
119.835 + /// @{
119.836 +
119.837 + /// \brief Run the algorithm.
119.838 + ///
119.839 + /// This function runs the algorithm.
119.840 + /// The paramters can be specified using functions \ref lowerMap(),
119.841 + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
119.842 + /// \ref supplyType().
119.843 + /// For example,
119.844 + /// \code
119.845 + /// NetworkSimplex<ListDigraph> ns(graph);
119.846 + /// ns.lowerMap(lower).upperMap(upper).costMap(cost)
119.847 + /// .supplyMap(sup).run();
119.848 + /// \endcode
119.849 + ///
119.850 + /// This function can be called more than once. All the parameters
119.851 + /// that have been given are kept for the next call, unless
119.852 + /// \ref reset() is called, thus only the modified parameters
119.853 + /// have to be set again. See \ref reset() for examples.
119.854 + /// However the underlying digraph must not be modified after this
119.855 + /// class have been constructed, since it copies and extends the graph.
119.856 + ///
119.857 + /// \param pivot_rule The pivot rule that will be used during the
119.858 + /// algorithm. For more information see \ref PivotRule.
119.859 + ///
119.860 + /// \return \c INFEASIBLE if no feasible flow exists,
119.861 + /// \n \c OPTIMAL if the problem has optimal solution
119.862 + /// (i.e. it is feasible and bounded), and the algorithm has found
119.863 + /// optimal flow and node potentials (primal and dual solutions),
119.864 + /// \n \c UNBOUNDED if the objective function of the problem is
119.865 + /// unbounded, i.e. there is a directed cycle having negative total
119.866 + /// cost and infinite upper bound.
119.867 + ///
119.868 + /// \see ProblemType, PivotRule
119.869 + ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
119.870 + if (!init()) return INFEASIBLE;
119.871 + return start(pivot_rule);
119.872 + }
119.873 +
119.874 + /// \brief Reset all the parameters that have been given before.
119.875 + ///
119.876 + /// This function resets all the paramaters that have been given
119.877 + /// before using functions \ref lowerMap(), \ref upperMap(),
119.878 + /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
119.879 + ///
119.880 + /// It is useful for multiple run() calls. If this function is not
119.881 + /// used, all the parameters given before are kept for the next
119.882 + /// \ref run() call.
119.883 + /// However the underlying digraph must not be modified after this
119.884 + /// class have been constructed, since it copies and extends the graph.
119.885 + ///
119.886 + /// For example,
119.887 + /// \code
119.888 + /// NetworkSimplex<ListDigraph> ns(graph);
119.889 + ///
119.890 + /// // First run
119.891 + /// ns.lowerMap(lower).upperMap(upper).costMap(cost)
119.892 + /// .supplyMap(sup).run();
119.893 + ///
119.894 + /// // Run again with modified cost map (reset() is not called,
119.895 + /// // so only the cost map have to be set again)
119.896 + /// cost[e] += 100;
119.897 + /// ns.costMap(cost).run();
119.898 + ///
119.899 + /// // Run again from scratch using reset()
119.900 + /// // (the lower bounds will be set to zero on all arcs)
119.901 + /// ns.reset();
119.902 + /// ns.upperMap(capacity).costMap(cost)
119.903 + /// .supplyMap(sup).run();
119.904 + /// \endcode
119.905 + ///
119.906 + /// \return <tt>(*this)</tt>
119.907 + NetworkSimplex& reset() {
119.908 + for (int i = 0; i != _node_num; ++i) {
119.909 + _supply[i] = 0;
119.910 + }
119.911 + for (int i = 0; i != _arc_num; ++i) {
119.912 + _lower[i] = 0;
119.913 + _upper[i] = INF;
119.914 + _cost[i] = 1;
119.915 + }
119.916 + _have_lower = false;
119.917 + _stype = GEQ;
119.918 + return *this;
119.919 + }
119.920 +
119.921 + /// @}
119.922 +
119.923 + /// \name Query Functions
119.924 + /// The results of the algorithm can be obtained using these
119.925 + /// functions.\n
119.926 + /// The \ref run() function must be called before using them.
119.927 +
119.928 + /// @{
119.929 +
119.930 + /// \brief Return the total cost of the found flow.
119.931 + ///
119.932 + /// This function returns the total cost of the found flow.
119.933 + /// Its complexity is O(e).
119.934 + ///
119.935 + /// \note The return type of the function can be specified as a
119.936 + /// template parameter. For example,
119.937 + /// \code
119.938 + /// ns.totalCost<double>();
119.939 + /// \endcode
119.940 + /// It is useful if the total cost cannot be stored in the \c Cost
119.941 + /// type of the algorithm, which is the default return type of the
119.942 + /// function.
119.943 + ///
119.944 + /// \pre \ref run() must be called before using this function.
119.945 + template <typename Number>
119.946 + Number totalCost() const {
119.947 + Number c = 0;
119.948 + for (ArcIt a(_graph); a != INVALID; ++a) {
119.949 + int i = _arc_id[a];
119.950 + c += Number(_flow[i]) * Number(_cost[i]);
119.951 + }
119.952 + return c;
119.953 + }
119.954 +
119.955 +#ifndef DOXYGEN
119.956 + Cost totalCost() const {
119.957 + return totalCost<Cost>();
119.958 + }
119.959 +#endif
119.960 +
119.961 + /// \brief Return the flow on the given arc.
119.962 + ///
119.963 + /// This function returns the flow on the given arc.
119.964 + ///
119.965 + /// \pre \ref run() must be called before using this function.
119.966 + Value flow(const Arc& a) const {
119.967 + return _flow[_arc_id[a]];
119.968 + }
119.969 +
119.970 + /// \brief Return the flow map (the primal solution).
119.971 + ///
119.972 + /// This function copies the flow value on each arc into the given
119.973 + /// map. The \c Value type of the algorithm must be convertible to
119.974 + /// the \c Value type of the map.
119.975 + ///
119.976 + /// \pre \ref run() must be called before using this function.
119.977 + template <typename FlowMap>
119.978 + void flowMap(FlowMap &map) const {
119.979 + for (ArcIt a(_graph); a != INVALID; ++a) {
119.980 + map.set(a, _flow[_arc_id[a]]);
119.981 + }
119.982 + }
119.983 +
119.984 + /// \brief Return the potential (dual value) of the given node.
119.985 + ///
119.986 + /// This function returns the potential (dual value) of the
119.987 + /// given node.
119.988 + ///
119.989 + /// \pre \ref run() must be called before using this function.
119.990 + Cost potential(const Node& n) const {
119.991 + return _pi[_node_id[n]];
119.992 + }
119.993 +
119.994 + /// \brief Return the potential map (the dual solution).
119.995 + ///
119.996 + /// This function copies the potential (dual value) of each node
119.997 + /// into the given map.
119.998 + /// The \c Cost type of the algorithm must be convertible to the
119.999 + /// \c Value type of the map.
119.1000 + ///
119.1001 + /// \pre \ref run() must be called before using this function.
119.1002 + template <typename PotentialMap>
119.1003 + void potentialMap(PotentialMap &map) const {
119.1004 + for (NodeIt n(_graph); n != INVALID; ++n) {
119.1005 + map.set(n, _pi[_node_id[n]]);
119.1006 + }
119.1007 + }
119.1008 +
119.1009 + /// @}
119.1010 +
119.1011 + private:
119.1012 +
119.1013 + // Initialize internal data structures
119.1014 + bool init() {
119.1015 + if (_node_num == 0) return false;
119.1016 +
119.1017 + // Check the sum of supply values
119.1018 + _sum_supply = 0;
119.1019 + for (int i = 0; i != _node_num; ++i) {
119.1020 + _sum_supply += _supply[i];
119.1021 + }
119.1022 + if ( !((_stype == GEQ && _sum_supply <= 0) ||
119.1023 + (_stype == LEQ && _sum_supply >= 0)) ) return false;
119.1024 +
119.1025 + // Remove non-zero lower bounds
119.1026 + if (_have_lower) {
119.1027 + for (int i = 0; i != _arc_num; ++i) {
119.1028 + Value c = _lower[i];
119.1029 + if (c >= 0) {
119.1030 + _cap[i] = _upper[i] < INF ? _upper[i] - c : INF;
119.1031 + } else {
119.1032 + _cap[i] = _upper[i] < INF + c ? _upper[i] - c : INF;
119.1033 + }
119.1034 + _supply[_source[i]] -= c;
119.1035 + _supply[_target[i]] += c;
119.1036 + }
119.1037 + } else {
119.1038 + for (int i = 0; i != _arc_num; ++i) {
119.1039 + _cap[i] = _upper[i];
119.1040 + }
119.1041 + }
119.1042 +
119.1043 + // Initialize artifical cost
119.1044 + Cost ART_COST;
119.1045 + if (std::numeric_limits<Cost>::is_exact) {
119.1046 + ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
119.1047 + } else {
119.1048 + ART_COST = std::numeric_limits<Cost>::min();
119.1049 + for (int i = 0; i != _arc_num; ++i) {
119.1050 + if (_cost[i] > ART_COST) ART_COST = _cost[i];
119.1051 + }
119.1052 + ART_COST = (ART_COST + 1) * _node_num;
119.1053 + }
119.1054 +
119.1055 + // Initialize arc maps
119.1056 + for (int i = 0; i != _arc_num; ++i) {
119.1057 + _flow[i] = 0;
119.1058 + _state[i] = STATE_LOWER;
119.1059 + }
119.1060 +
119.1061 + // Set data for the artificial root node
119.1062 + _root = _node_num;
119.1063 + _parent[_root] = -1;
119.1064 + _pred[_root] = -1;
119.1065 + _thread[_root] = 0;
119.1066 + _rev_thread[0] = _root;
119.1067 + _succ_num[_root] = _node_num + 1;
119.1068 + _last_succ[_root] = _root - 1;
119.1069 + _supply[_root] = -_sum_supply;
119.1070 + _pi[_root] = 0;
119.1071 +
119.1072 + // Add artificial arcs and initialize the spanning tree data structure
119.1073 + if (_sum_supply == 0) {
119.1074 + // EQ supply constraints
119.1075 + _search_arc_num = _arc_num;
119.1076 + _all_arc_num = _arc_num + _node_num;
119.1077 + for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
119.1078 + _parent[u] = _root;
119.1079 + _pred[u] = e;
119.1080 + _thread[u] = u + 1;
119.1081 + _rev_thread[u + 1] = u;
119.1082 + _succ_num[u] = 1;
119.1083 + _last_succ[u] = u;
119.1084 + _cap[e] = INF;
119.1085 + _state[e] = STATE_TREE;
119.1086 + if (_supply[u] >= 0) {
119.1087 + _forward[u] = true;
119.1088 + _pi[u] = 0;
119.1089 + _source[e] = u;
119.1090 + _target[e] = _root;
119.1091 + _flow[e] = _supply[u];
119.1092 + _cost[e] = 0;
119.1093 + } else {
119.1094 + _forward[u] = false;
119.1095 + _pi[u] = ART_COST;
119.1096 + _source[e] = _root;
119.1097 + _target[e] = u;
119.1098 + _flow[e] = -_supply[u];
119.1099 + _cost[e] = ART_COST;
119.1100 + }
119.1101 + }
119.1102 + }
119.1103 + else if (_sum_supply > 0) {
119.1104 + // LEQ supply constraints
119.1105 + _search_arc_num = _arc_num + _node_num;
119.1106 + int f = _arc_num + _node_num;
119.1107 + for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
119.1108 + _parent[u] = _root;
119.1109 + _thread[u] = u + 1;
119.1110 + _rev_thread[u + 1] = u;
119.1111 + _succ_num[u] = 1;
119.1112 + _last_succ[u] = u;
119.1113 + if (_supply[u] >= 0) {
119.1114 + _forward[u] = true;
119.1115 + _pi[u] = 0;
119.1116 + _pred[u] = e;
119.1117 + _source[e] = u;
119.1118 + _target[e] = _root;
119.1119 + _cap[e] = INF;
119.1120 + _flow[e] = _supply[u];
119.1121 + _cost[e] = 0;
119.1122 + _state[e] = STATE_TREE;
119.1123 + } else {
119.1124 + _forward[u] = false;
119.1125 + _pi[u] = ART_COST;
119.1126 + _pred[u] = f;
119.1127 + _source[f] = _root;
119.1128 + _target[f] = u;
119.1129 + _cap[f] = INF;
119.1130 + _flow[f] = -_supply[u];
119.1131 + _cost[f] = ART_COST;
119.1132 + _state[f] = STATE_TREE;
119.1133 + _source[e] = u;
119.1134 + _target[e] = _root;
119.1135 + _cap[e] = INF;
119.1136 + _flow[e] = 0;
119.1137 + _cost[e] = 0;
119.1138 + _state[e] = STATE_LOWER;
119.1139 + ++f;
119.1140 + }
119.1141 + }
119.1142 + _all_arc_num = f;
119.1143 + }
119.1144 + else {
119.1145 + // GEQ supply constraints
119.1146 + _search_arc_num = _arc_num + _node_num;
119.1147 + int f = _arc_num + _node_num;
119.1148 + for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
119.1149 + _parent[u] = _root;
119.1150 + _thread[u] = u + 1;
119.1151 + _rev_thread[u + 1] = u;
119.1152 + _succ_num[u] = 1;
119.1153 + _last_succ[u] = u;
119.1154 + if (_supply[u] <= 0) {
119.1155 + _forward[u] = false;
119.1156 + _pi[u] = 0;
119.1157 + _pred[u] = e;
119.1158 + _source[e] = _root;
119.1159 + _target[e] = u;
119.1160 + _cap[e] = INF;
119.1161 + _flow[e] = -_supply[u];
119.1162 + _cost[e] = 0;
119.1163 + _state[e] = STATE_TREE;
119.1164 + } else {
119.1165 + _forward[u] = true;
119.1166 + _pi[u] = -ART_COST;
119.1167 + _pred[u] = f;
119.1168 + _source[f] = u;
119.1169 + _target[f] = _root;
119.1170 + _cap[f] = INF;
119.1171 + _flow[f] = _supply[u];
119.1172 + _state[f] = STATE_TREE;
119.1173 + _cost[f] = ART_COST;
119.1174 + _source[e] = _root;
119.1175 + _target[e] = u;
119.1176 + _cap[e] = INF;
119.1177 + _flow[e] = 0;
119.1178 + _cost[e] = 0;
119.1179 + _state[e] = STATE_LOWER;
119.1180 + ++f;
119.1181 + }
119.1182 + }
119.1183 + _all_arc_num = f;
119.1184 + }
119.1185 +
119.1186 + return true;
119.1187 + }
119.1188 +
119.1189 + // Find the join node
119.1190 + void findJoinNode() {
119.1191 + int u = _source[in_arc];
119.1192 + int v = _target[in_arc];
119.1193 + while (u != v) {
119.1194 + if (_succ_num[u] < _succ_num[v]) {
119.1195 + u = _parent[u];
119.1196 + } else {
119.1197 + v = _parent[v];
119.1198 + }
119.1199 + }
119.1200 + join = u;
119.1201 + }
119.1202 +
119.1203 + // Find the leaving arc of the cycle and returns true if the
119.1204 + // leaving arc is not the same as the entering arc
119.1205 + bool findLeavingArc() {
119.1206 + // Initialize first and second nodes according to the direction
119.1207 + // of the cycle
119.1208 + if (_state[in_arc] == STATE_LOWER) {
119.1209 + first = _source[in_arc];
119.1210 + second = _target[in_arc];
119.1211 + } else {
119.1212 + first = _target[in_arc];
119.1213 + second = _source[in_arc];
119.1214 + }
119.1215 + delta = _cap[in_arc];
119.1216 + int result = 0;
119.1217 + Value d;
119.1218 + int e;
119.1219 +
119.1220 + // Search the cycle along the path form the first node to the root
119.1221 + for (int u = first; u != join; u = _parent[u]) {
119.1222 + e = _pred[u];
119.1223 + d = _forward[u] ?
119.1224 + _flow[e] : (_cap[e] == INF ? INF : _cap[e] - _flow[e]);
119.1225 + if (d < delta) {
119.1226 + delta = d;
119.1227 + u_out = u;
119.1228 + result = 1;
119.1229 + }
119.1230 + }
119.1231 + // Search the cycle along the path form the second node to the root
119.1232 + for (int u = second; u != join; u = _parent[u]) {
119.1233 + e = _pred[u];
119.1234 + d = _forward[u] ?
119.1235 + (_cap[e] == INF ? INF : _cap[e] - _flow[e]) : _flow[e];
119.1236 + if (d <= delta) {
119.1237 + delta = d;
119.1238 + u_out = u;
119.1239 + result = 2;
119.1240 + }
119.1241 + }
119.1242 +
119.1243 + if (result == 1) {
119.1244 + u_in = first;
119.1245 + v_in = second;
119.1246 + } else {
119.1247 + u_in = second;
119.1248 + v_in = first;
119.1249 + }
119.1250 + return result != 0;
119.1251 + }
119.1252 +
119.1253 + // Change _flow and _state vectors
119.1254 + void changeFlow(bool change) {
119.1255 + // Augment along the cycle
119.1256 + if (delta > 0) {
119.1257 + Value val = _state[in_arc] * delta;
119.1258 + _flow[in_arc] += val;
119.1259 + for (int u = _source[in_arc]; u != join; u = _parent[u]) {
119.1260 + _flow[_pred[u]] += _forward[u] ? -val : val;
119.1261 + }
119.1262 + for (int u = _target[in_arc]; u != join; u = _parent[u]) {
119.1263 + _flow[_pred[u]] += _forward[u] ? val : -val;
119.1264 + }
119.1265 + }
119.1266 + // Update the state of the entering and leaving arcs
119.1267 + if (change) {
119.1268 + _state[in_arc] = STATE_TREE;
119.1269 + _state[_pred[u_out]] =
119.1270 + (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
119.1271 + } else {
119.1272 + _state[in_arc] = -_state[in_arc];
119.1273 + }
119.1274 + }
119.1275 +
119.1276 + // Update the tree structure
119.1277 + void updateTreeStructure() {
119.1278 + int u, w;
119.1279 + int old_rev_thread = _rev_thread[u_out];
119.1280 + int old_succ_num = _succ_num[u_out];
119.1281 + int old_last_succ = _last_succ[u_out];
119.1282 + v_out = _parent[u_out];
119.1283 +
119.1284 + u = _last_succ[u_in]; // the last successor of u_in
119.1285 + right = _thread[u]; // the node after it
119.1286 +
119.1287 + // Handle the case when old_rev_thread equals to v_in
119.1288 + // (it also means that join and v_out coincide)
119.1289 + if (old_rev_thread == v_in) {
119.1290 + last = _thread[_last_succ[u_out]];
119.1291 + } else {
119.1292 + last = _thread[v_in];
119.1293 + }
119.1294 +
119.1295 + // Update _thread and _parent along the stem nodes (i.e. the nodes
119.1296 + // between u_in and u_out, whose parent have to be changed)
119.1297 + _thread[v_in] = stem = u_in;
119.1298 + _dirty_revs.clear();
119.1299 + _dirty_revs.push_back(v_in);
119.1300 + par_stem = v_in;
119.1301 + while (stem != u_out) {
119.1302 + // Insert the next stem node into the thread list
119.1303 + new_stem = _parent[stem];
119.1304 + _thread[u] = new_stem;
119.1305 + _dirty_revs.push_back(u);
119.1306 +
119.1307 + // Remove the subtree of stem from the thread list
119.1308 + w = _rev_thread[stem];
119.1309 + _thread[w] = right;
119.1310 + _rev_thread[right] = w;
119.1311 +
119.1312 + // Change the parent node and shift stem nodes
119.1313 + _parent[stem] = par_stem;
119.1314 + par_stem = stem;
119.1315 + stem = new_stem;
119.1316 +
119.1317 + // Update u and right
119.1318 + u = _last_succ[stem] == _last_succ[par_stem] ?
119.1319 + _rev_thread[par_stem] : _last_succ[stem];
119.1320 + right = _thread[u];
119.1321 + }
119.1322 + _parent[u_out] = par_stem;
119.1323 + _thread[u] = last;
119.1324 + _rev_thread[last] = u;
119.1325 + _last_succ[u_out] = u;
119.1326 +
119.1327 + // Remove the subtree of u_out from the thread list except for
119.1328 + // the case when old_rev_thread equals to v_in
119.1329 + // (it also means that join and v_out coincide)
119.1330 + if (old_rev_thread != v_in) {
119.1331 + _thread[old_rev_thread] = right;
119.1332 + _rev_thread[right] = old_rev_thread;
119.1333 + }
119.1334 +
119.1335 + // Update _rev_thread using the new _thread values
119.1336 + for (int i = 0; i < int(_dirty_revs.size()); ++i) {
119.1337 + u = _dirty_revs[i];
119.1338 + _rev_thread[_thread[u]] = u;
119.1339 + }
119.1340 +
119.1341 + // Update _pred, _forward, _last_succ and _succ_num for the
119.1342 + // stem nodes from u_out to u_in
119.1343 + int tmp_sc = 0, tmp_ls = _last_succ[u_out];
119.1344 + u = u_out;
119.1345 + while (u != u_in) {
119.1346 + w = _parent[u];
119.1347 + _pred[u] = _pred[w];
119.1348 + _forward[u] = !_forward[w];
119.1349 + tmp_sc += _succ_num[u] - _succ_num[w];
119.1350 + _succ_num[u] = tmp_sc;
119.1351 + _last_succ[w] = tmp_ls;
119.1352 + u = w;
119.1353 + }
119.1354 + _pred[u_in] = in_arc;
119.1355 + _forward[u_in] = (u_in == _source[in_arc]);
119.1356 + _succ_num[u_in] = old_succ_num;
119.1357 +
119.1358 + // Set limits for updating _last_succ form v_in and v_out
119.1359 + // towards the root
119.1360 + int up_limit_in = -1;
119.1361 + int up_limit_out = -1;
119.1362 + if (_last_succ[join] == v_in) {
119.1363 + up_limit_out = join;
119.1364 + } else {
119.1365 + up_limit_in = join;
119.1366 + }
119.1367 +
119.1368 + // Update _last_succ from v_in towards the root
119.1369 + for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
119.1370 + u = _parent[u]) {
119.1371 + _last_succ[u] = _last_succ[u_out];
119.1372 + }
119.1373 + // Update _last_succ from v_out towards the root
119.1374 + if (join != old_rev_thread && v_in != old_rev_thread) {
119.1375 + for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
119.1376 + u = _parent[u]) {
119.1377 + _last_succ[u] = old_rev_thread;
119.1378 + }
119.1379 + } else {
119.1380 + for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
119.1381 + u = _parent[u]) {
119.1382 + _last_succ[u] = _last_succ[u_out];
119.1383 + }
119.1384 + }
119.1385 +
119.1386 + // Update _succ_num from v_in to join
119.1387 + for (u = v_in; u != join; u = _parent[u]) {
119.1388 + _succ_num[u] += old_succ_num;
119.1389 + }
119.1390 + // Update _succ_num from v_out to join
119.1391 + for (u = v_out; u != join; u = _parent[u]) {
119.1392 + _succ_num[u] -= old_succ_num;
119.1393 + }
119.1394 + }
119.1395 +
119.1396 + // Update potentials
119.1397 + void updatePotential() {
119.1398 + Cost sigma = _forward[u_in] ?
119.1399 + _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
119.1400 + _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
119.1401 + // Update potentials in the subtree, which has been moved
119.1402 + int end = _thread[_last_succ[u_in]];
119.1403 + for (int u = u_in; u != end; u = _thread[u]) {
119.1404 + _pi[u] += sigma;
119.1405 + }
119.1406 + }
119.1407 +
119.1408 + // Execute the algorithm
119.1409 + ProblemType start(PivotRule pivot_rule) {
119.1410 + // Select the pivot rule implementation
119.1411 + switch (pivot_rule) {
119.1412 + case FIRST_ELIGIBLE:
119.1413 + return start<FirstEligiblePivotRule>();
119.1414 + case BEST_ELIGIBLE:
119.1415 + return start<BestEligiblePivotRule>();
119.1416 + case BLOCK_SEARCH:
119.1417 + return start<BlockSearchPivotRule>();
119.1418 + case CANDIDATE_LIST:
119.1419 + return start<CandidateListPivotRule>();
119.1420 + case ALTERING_LIST:
119.1421 + return start<AlteringListPivotRule>();
119.1422 + }
119.1423 + return INFEASIBLE; // avoid warning
119.1424 + }
119.1425 +
119.1426 + template <typename PivotRuleImpl>
119.1427 + ProblemType start() {
119.1428 + PivotRuleImpl pivot(*this);
119.1429 +
119.1430 + // Execute the Network Simplex algorithm
119.1431 + while (pivot.findEnteringArc()) {
119.1432 + findJoinNode();
119.1433 + bool change = findLeavingArc();
119.1434 + if (delta >= INF) return UNBOUNDED;
119.1435 + changeFlow(change);
119.1436 + if (change) {
119.1437 + updateTreeStructure();
119.1438 + updatePotential();
119.1439 + }
119.1440 + }
119.1441 +
119.1442 + // Check feasibility
119.1443 + for (int e = _search_arc_num; e != _all_arc_num; ++e) {
119.1444 + if (_flow[e] != 0) return INFEASIBLE;
119.1445 + }
119.1446 +
119.1447 + // Transform the solution and the supply map to the original form
119.1448 + if (_have_lower) {
119.1449 + for (int i = 0; i != _arc_num; ++i) {
119.1450 + Value c = _lower[i];
119.1451 + if (c != 0) {
119.1452 + _flow[i] += c;
119.1453 + _supply[_source[i]] += c;
119.1454 + _supply[_target[i]] -= c;
119.1455 + }
119.1456 + }
119.1457 + }
119.1458 +
119.1459 + // Shift potentials to meet the requirements of the GEQ/LEQ type
119.1460 + // optimality conditions
119.1461 + if (_sum_supply == 0) {
119.1462 + if (_stype == GEQ) {
119.1463 + Cost max_pot = std::numeric_limits<Cost>::min();
119.1464 + for (int i = 0; i != _node_num; ++i) {
119.1465 + if (_pi[i] > max_pot) max_pot = _pi[i];
119.1466 + }
119.1467 + if (max_pot > 0) {
119.1468 + for (int i = 0; i != _node_num; ++i)
119.1469 + _pi[i] -= max_pot;
119.1470 + }
119.1471 + } else {
119.1472 + Cost min_pot = std::numeric_limits<Cost>::max();
119.1473 + for (int i = 0; i != _node_num; ++i) {
119.1474 + if (_pi[i] < min_pot) min_pot = _pi[i];
119.1475 + }
119.1476 + if (min_pot < 0) {
119.1477 + for (int i = 0; i != _node_num; ++i)
119.1478 + _pi[i] -= min_pot;
119.1479 + }
119.1480 + }
119.1481 + }
119.1482 +
119.1483 + return OPTIMAL;
119.1484 + }
119.1485 +
119.1486 + }; //class NetworkSimplex
119.1487 +
119.1488 + ///@}
119.1489 +
119.1490 +} //namespace lemon
119.1491 +
119.1492 +#endif //LEMON_NETWORK_SIMPLEX_H
120.1 --- a/lemon/path.h Fri Nov 13 12:33:33 2009 +0100
120.2 +++ b/lemon/path.h Thu Dec 10 17:05:35 2009 +0100
120.3 @@ -2,7 +2,7 @@
120.4 *
120.5 * This file is a part of LEMON, a generic C++ optimization library.
120.6 *
120.7 - * Copyright (C) 2003-2008
120.8 + * Copyright (C) 2003-2009
120.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
120.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
120.11 *
120.12 @@ -40,7 +40,7 @@
120.13 /// \brief A structure for representing directed paths in a digraph.
120.14 ///
120.15 /// A structure for representing directed path in a digraph.
120.16 - /// \tparam _Digraph The digraph type in which the path is.
120.17 + /// \tparam GR The digraph type in which the path is.
120.18 ///
120.19 /// In a sense, the path can be treated as a list of arcs. The
120.20 /// lemon path type stores just this list. As a consequence, it
120.21 @@ -52,11 +52,11 @@
120.22 /// insertion and erase is done in O(1) (amortized) time. The
120.23 /// implementation uses two vectors for storing the front and back
120.24 /// insertions.
120.25 - template <typename _Digraph>
120.26 + template <typename GR>
120.27 class Path {
120.28 public:
120.29
120.30 - typedef _Digraph Digraph;
120.31 + typedef GR Digraph;
120.32 typedef typename Digraph::Arc Arc;
120.33
120.34 /// \brief Default constructor
120.35 @@ -137,7 +137,7 @@
120.36
120.37 /// \brief The nth arc.
120.38 ///
120.39 - /// \pre n is in the [0..length() - 1] range
120.40 + /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
120.41 const Arc& nth(int n) const {
120.42 return n < int(head.size()) ? *(head.rbegin() + n) :
120.43 *(tail.begin() + (n - head.size()));
120.44 @@ -145,7 +145,7 @@
120.45
120.46 /// \brief Initialize arc iterator to point to the nth arc
120.47 ///
120.48 - /// \pre n is in the [0..length() - 1] range
120.49 + /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
120.50 ArcIt nthIt(int n) const {
120.51 return ArcIt(*this, n);
120.52 }
120.53 @@ -228,7 +228,7 @@
120.54 /// \brief A structure for representing directed paths in a digraph.
120.55 ///
120.56 /// A structure for representing directed path in a digraph.
120.57 - /// \tparam _Digraph The digraph type in which the path is.
120.58 + /// \tparam GR The digraph type in which the path is.
120.59 ///
120.60 /// In a sense, the path can be treated as a list of arcs. The
120.61 /// lemon path type stores just this list. As a consequence it
120.62 @@ -240,11 +240,11 @@
120.63 /// erasure is amortized O(1) time. This implementation is faster
120.64 /// then the \c Path type because it use just one vector for the
120.65 /// arcs.
120.66 - template <typename _Digraph>
120.67 + template <typename GR>
120.68 class SimplePath {
120.69 public:
120.70
120.71 - typedef _Digraph Digraph;
120.72 + typedef GR Digraph;
120.73 typedef typename Digraph::Arc Arc;
120.74
120.75 /// \brief Default constructor
120.76 @@ -329,7 +329,7 @@
120.77
120.78 /// \brief The nth arc.
120.79 ///
120.80 - /// \pre n is in the [0..length() - 1] range
120.81 + /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
120.82 const Arc& nth(int n) const {
120.83 return data[n];
120.84 }
120.85 @@ -392,7 +392,7 @@
120.86 /// \brief A structure for representing directed paths in a digraph.
120.87 ///
120.88 /// A structure for representing directed path in a digraph.
120.89 - /// \tparam _Digraph The digraph type in which the path is.
120.90 + /// \tparam GR The digraph type in which the path is.
120.91 ///
120.92 /// In a sense, the path can be treated as a list of arcs. The
120.93 /// lemon path type stores just this list. As a consequence it
120.94 @@ -404,11 +404,11 @@
120.95 /// of the arc in the path. The length can be computed in O(n)
120.96 /// time. The front and back insertion and erasure is O(1) time
120.97 /// and it can be splited and spliced in O(1) time.
120.98 - template <typename _Digraph>
120.99 + template <typename GR>
120.100 class ListPath {
120.101 public:
120.102
120.103 - typedef _Digraph Digraph;
120.104 + typedef GR Digraph;
120.105 typedef typename Digraph::Arc Arc;
120.106
120.107 protected:
120.108 @@ -507,7 +507,7 @@
120.109 /// \brief The nth arc.
120.110 ///
120.111 /// This function looks for the nth arc in O(n) time.
120.112 - /// \pre n is in the [0..length() - 1] range
120.113 + /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
120.114 const Arc& nth(int n) const {
120.115 Node *node = first;
120.116 for (int i = 0; i < n; ++i) {
120.117 @@ -732,7 +732,7 @@
120.118 /// \brief A structure for representing directed paths in a digraph.
120.119 ///
120.120 /// A structure for representing directed path in a digraph.
120.121 - /// \tparam _Digraph The digraph type in which the path is.
120.122 + /// \tparam GR The digraph type in which the path is.
120.123 ///
120.124 /// In a sense, the path can be treated as a list of arcs. The
120.125 /// lemon path type stores just this list. As a consequence it
120.126 @@ -746,11 +746,11 @@
120.127 /// Being the the most memory efficient path type in LEMON,
120.128 /// it is intented to be
120.129 /// used when you want to store a large number of paths.
120.130 - template <typename _Digraph>
120.131 + template <typename GR>
120.132 class StaticPath {
120.133 public:
120.134
120.135 - typedef _Digraph Digraph;
120.136 + typedef GR Digraph;
120.137 typedef typename Digraph::Arc Arc;
120.138
120.139 /// \brief Default constructor
120.140 @@ -833,7 +833,7 @@
120.141
120.142 /// \brief The nth arc.
120.143 ///
120.144 - /// \pre n is in the [0..length() - 1] range
120.145 + /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
120.146 const Arc& nth(int n) const {
120.147 return arcs[n];
120.148 }
121.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
121.2 +++ b/lemon/preflow.h Thu Dec 10 17:05:35 2009 +0100
121.3 @@ -0,0 +1,965 @@
121.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
121.5 + *
121.6 + * This file is a part of LEMON, a generic C++ optimization library.
121.7 + *
121.8 + * Copyright (C) 2003-2009
121.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
121.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
121.11 + *
121.12 + * Permission to use, modify and distribute this software is granted
121.13 + * provided that this copyright notice appears in all copies. For
121.14 + * precise terms see the accompanying LICENSE file.
121.15 + *
121.16 + * This software is provided "AS IS" with no warranty of any kind,
121.17 + * express or implied, and with no claim as to its suitability for any
121.18 + * purpose.
121.19 + *
121.20 + */
121.21 +
121.22 +#ifndef LEMON_PREFLOW_H
121.23 +#define LEMON_PREFLOW_H
121.24 +
121.25 +#include <lemon/tolerance.h>
121.26 +#include <lemon/elevator.h>
121.27 +
121.28 +/// \file
121.29 +/// \ingroup max_flow
121.30 +/// \brief Implementation of the preflow algorithm.
121.31 +
121.32 +namespace lemon {
121.33 +
121.34 + /// \brief Default traits class of Preflow class.
121.35 + ///
121.36 + /// Default traits class of Preflow class.
121.37 + /// \tparam GR Digraph type.
121.38 + /// \tparam CAP Capacity map type.
121.39 + template <typename GR, typename CAP>
121.40 + struct PreflowDefaultTraits {
121.41 +
121.42 + /// \brief The type of the digraph the algorithm runs on.
121.43 + typedef GR Digraph;
121.44 +
121.45 + /// \brief The type of the map that stores the arc capacities.
121.46 + ///
121.47 + /// The type of the map that stores the arc capacities.
121.48 + /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
121.49 + typedef CAP CapacityMap;
121.50 +
121.51 + /// \brief The type of the flow values.
121.52 + typedef typename CapacityMap::Value Value;
121.53 +
121.54 + /// \brief The type of the map that stores the flow values.
121.55 + ///
121.56 + /// The type of the map that stores the flow values.
121.57 + /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
121.58 + typedef typename Digraph::template ArcMap<Value> FlowMap;
121.59 +
121.60 + /// \brief Instantiates a FlowMap.
121.61 + ///
121.62 + /// This function instantiates a \ref FlowMap.
121.63 + /// \param digraph The digraph for which we would like to define
121.64 + /// the flow map.
121.65 + static FlowMap* createFlowMap(const Digraph& digraph) {
121.66 + return new FlowMap(digraph);
121.67 + }
121.68 +
121.69 + /// \brief The elevator type used by Preflow algorithm.
121.70 + ///
121.71 + /// The elevator type used by Preflow algorithm.
121.72 + ///
121.73 + /// \sa Elevator
121.74 + /// \sa LinkedElevator
121.75 + typedef LinkedElevator<Digraph, typename Digraph::Node> Elevator;
121.76 +
121.77 + /// \brief Instantiates an Elevator.
121.78 + ///
121.79 + /// This function instantiates an \ref Elevator.
121.80 + /// \param digraph The digraph for which we would like to define
121.81 + /// the elevator.
121.82 + /// \param max_level The maximum level of the elevator.
121.83 + static Elevator* createElevator(const Digraph& digraph, int max_level) {
121.84 + return new Elevator(digraph, max_level);
121.85 + }
121.86 +
121.87 + /// \brief The tolerance used by the algorithm
121.88 + ///
121.89 + /// The tolerance used by the algorithm to handle inexact computation.
121.90 + typedef lemon::Tolerance<Value> Tolerance;
121.91 +
121.92 + };
121.93 +
121.94 +
121.95 + /// \ingroup max_flow
121.96 + ///
121.97 + /// \brief %Preflow algorithm class.
121.98 + ///
121.99 + /// This class provides an implementation of Goldberg-Tarjan's \e preflow
121.100 + /// \e push-relabel algorithm producing a \ref max_flow
121.101 + /// "flow of maximum value" in a digraph.
121.102 + /// The preflow algorithms are the fastest known maximum
121.103 + /// flow algorithms. The current implementation use a mixture of the
121.104 + /// \e "highest label" and the \e "bound decrease" heuristics.
121.105 + /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
121.106 + ///
121.107 + /// The algorithm consists of two phases. After the first phase
121.108 + /// the maximum flow value and the minimum cut is obtained. The
121.109 + /// second phase constructs a feasible maximum flow on each arc.
121.110 + ///
121.111 + /// \tparam GR The type of the digraph the algorithm runs on.
121.112 + /// \tparam CAP The type of the capacity map. The default map
121.113 + /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
121.114 +#ifdef DOXYGEN
121.115 + template <typename GR, typename CAP, typename TR>
121.116 +#else
121.117 + template <typename GR,
121.118 + typename CAP = typename GR::template ArcMap<int>,
121.119 + typename TR = PreflowDefaultTraits<GR, CAP> >
121.120 +#endif
121.121 + class Preflow {
121.122 + public:
121.123 +
121.124 + ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
121.125 + typedef TR Traits;
121.126 + ///The type of the digraph the algorithm runs on.
121.127 + typedef typename Traits::Digraph Digraph;
121.128 + ///The type of the capacity map.
121.129 + typedef typename Traits::CapacityMap CapacityMap;
121.130 + ///The type of the flow values.
121.131 + typedef typename Traits::Value Value;
121.132 +
121.133 + ///The type of the flow map.
121.134 + typedef typename Traits::FlowMap FlowMap;
121.135 + ///The type of the elevator.
121.136 + typedef typename Traits::Elevator Elevator;
121.137 + ///The type of the tolerance.
121.138 + typedef typename Traits::Tolerance Tolerance;
121.139 +
121.140 + private:
121.141 +
121.142 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
121.143 +
121.144 + const Digraph& _graph;
121.145 + const CapacityMap* _capacity;
121.146 +
121.147 + int _node_num;
121.148 +
121.149 + Node _source, _target;
121.150 +
121.151 + FlowMap* _flow;
121.152 + bool _local_flow;
121.153 +
121.154 + Elevator* _level;
121.155 + bool _local_level;
121.156 +
121.157 + typedef typename Digraph::template NodeMap<Value> ExcessMap;
121.158 + ExcessMap* _excess;
121.159 +
121.160 + Tolerance _tolerance;
121.161 +
121.162 + bool _phase;
121.163 +
121.164 +
121.165 + void createStructures() {
121.166 + _node_num = countNodes(_graph);
121.167 +
121.168 + if (!_flow) {
121.169 + _flow = Traits::createFlowMap(_graph);
121.170 + _local_flow = true;
121.171 + }
121.172 + if (!_level) {
121.173 + _level = Traits::createElevator(_graph, _node_num);
121.174 + _local_level = true;
121.175 + }
121.176 + if (!_excess) {
121.177 + _excess = new ExcessMap(_graph);
121.178 + }
121.179 + }
121.180 +
121.181 + void destroyStructures() {
121.182 + if (_local_flow) {
121.183 + delete _flow;
121.184 + }
121.185 + if (_local_level) {
121.186 + delete _level;
121.187 + }
121.188 + if (_excess) {
121.189 + delete _excess;
121.190 + }
121.191 + }
121.192 +
121.193 + public:
121.194 +
121.195 + typedef Preflow Create;
121.196 +
121.197 + ///\name Named Template Parameters
121.198 +
121.199 + ///@{
121.200 +
121.201 + template <typename T>
121.202 + struct SetFlowMapTraits : public Traits {
121.203 + typedef T FlowMap;
121.204 + static FlowMap *createFlowMap(const Digraph&) {
121.205 + LEMON_ASSERT(false, "FlowMap is not initialized");
121.206 + return 0; // ignore warnings
121.207 + }
121.208 + };
121.209 +
121.210 + /// \brief \ref named-templ-param "Named parameter" for setting
121.211 + /// FlowMap type
121.212 + ///
121.213 + /// \ref named-templ-param "Named parameter" for setting FlowMap
121.214 + /// type.
121.215 + template <typename T>
121.216 + struct SetFlowMap
121.217 + : public Preflow<Digraph, CapacityMap, SetFlowMapTraits<T> > {
121.218 + typedef Preflow<Digraph, CapacityMap,
121.219 + SetFlowMapTraits<T> > Create;
121.220 + };
121.221 +
121.222 + template <typename T>
121.223 + struct SetElevatorTraits : public Traits {
121.224 + typedef T Elevator;
121.225 + static Elevator *createElevator(const Digraph&, int) {
121.226 + LEMON_ASSERT(false, "Elevator is not initialized");
121.227 + return 0; // ignore warnings
121.228 + }
121.229 + };
121.230 +
121.231 + /// \brief \ref named-templ-param "Named parameter" for setting
121.232 + /// Elevator type
121.233 + ///
121.234 + /// \ref named-templ-param "Named parameter" for setting Elevator
121.235 + /// type. If this named parameter is used, then an external
121.236 + /// elevator object must be passed to the algorithm using the
121.237 + /// \ref elevator(Elevator&) "elevator()" function before calling
121.238 + /// \ref run() or \ref init().
121.239 + /// \sa SetStandardElevator
121.240 + template <typename T>
121.241 + struct SetElevator
121.242 + : public Preflow<Digraph, CapacityMap, SetElevatorTraits<T> > {
121.243 + typedef Preflow<Digraph, CapacityMap,
121.244 + SetElevatorTraits<T> > Create;
121.245 + };
121.246 +
121.247 + template <typename T>
121.248 + struct SetStandardElevatorTraits : public Traits {
121.249 + typedef T Elevator;
121.250 + static Elevator *createElevator(const Digraph& digraph, int max_level) {
121.251 + return new Elevator(digraph, max_level);
121.252 + }
121.253 + };
121.254 +
121.255 + /// \brief \ref named-templ-param "Named parameter" for setting
121.256 + /// Elevator type with automatic allocation
121.257 + ///
121.258 + /// \ref named-templ-param "Named parameter" for setting Elevator
121.259 + /// type with automatic allocation.
121.260 + /// The Elevator should have standard constructor interface to be
121.261 + /// able to automatically created by the algorithm (i.e. the
121.262 + /// digraph and the maximum level should be passed to it).
121.263 + /// However an external elevator object could also be passed to the
121.264 + /// algorithm with the \ref elevator(Elevator&) "elevator()" function
121.265 + /// before calling \ref run() or \ref init().
121.266 + /// \sa SetElevator
121.267 + template <typename T>
121.268 + struct SetStandardElevator
121.269 + : public Preflow<Digraph, CapacityMap,
121.270 + SetStandardElevatorTraits<T> > {
121.271 + typedef Preflow<Digraph, CapacityMap,
121.272 + SetStandardElevatorTraits<T> > Create;
121.273 + };
121.274 +
121.275 + /// @}
121.276 +
121.277 + protected:
121.278 +
121.279 + Preflow() {}
121.280 +
121.281 + public:
121.282 +
121.283 +
121.284 + /// \brief The constructor of the class.
121.285 + ///
121.286 + /// The constructor of the class.
121.287 + /// \param digraph The digraph the algorithm runs on.
121.288 + /// \param capacity The capacity of the arcs.
121.289 + /// \param source The source node.
121.290 + /// \param target The target node.
121.291 + Preflow(const Digraph& digraph, const CapacityMap& capacity,
121.292 + Node source, Node target)
121.293 + : _graph(digraph), _capacity(&capacity),
121.294 + _node_num(0), _source(source), _target(target),
121.295 + _flow(0), _local_flow(false),
121.296 + _level(0), _local_level(false),
121.297 + _excess(0), _tolerance(), _phase() {}
121.298 +
121.299 + /// \brief Destructor.
121.300 + ///
121.301 + /// Destructor.
121.302 + ~Preflow() {
121.303 + destroyStructures();
121.304 + }
121.305 +
121.306 + /// \brief Sets the capacity map.
121.307 + ///
121.308 + /// Sets the capacity map.
121.309 + /// \return <tt>(*this)</tt>
121.310 + Preflow& capacityMap(const CapacityMap& map) {
121.311 + _capacity = ↦
121.312 + return *this;
121.313 + }
121.314 +
121.315 + /// \brief Sets the flow map.
121.316 + ///
121.317 + /// Sets the flow map.
121.318 + /// If you don't use this function before calling \ref run() or
121.319 + /// \ref init(), an instance will be allocated automatically.
121.320 + /// The destructor deallocates this automatically allocated map,
121.321 + /// of course.
121.322 + /// \return <tt>(*this)</tt>
121.323 + Preflow& flowMap(FlowMap& map) {
121.324 + if (_local_flow) {
121.325 + delete _flow;
121.326 + _local_flow = false;
121.327 + }
121.328 + _flow = ↦
121.329 + return *this;
121.330 + }
121.331 +
121.332 + /// \brief Sets the source node.
121.333 + ///
121.334 + /// Sets the source node.
121.335 + /// \return <tt>(*this)</tt>
121.336 + Preflow& source(const Node& node) {
121.337 + _source = node;
121.338 + return *this;
121.339 + }
121.340 +
121.341 + /// \brief Sets the target node.
121.342 + ///
121.343 + /// Sets the target node.
121.344 + /// \return <tt>(*this)</tt>
121.345 + Preflow& target(const Node& node) {
121.346 + _target = node;
121.347 + return *this;
121.348 + }
121.349 +
121.350 + /// \brief Sets the elevator used by algorithm.
121.351 + ///
121.352 + /// Sets the elevator used by algorithm.
121.353 + /// If you don't use this function before calling \ref run() or
121.354 + /// \ref init(), an instance will be allocated automatically.
121.355 + /// The destructor deallocates this automatically allocated elevator,
121.356 + /// of course.
121.357 + /// \return <tt>(*this)</tt>
121.358 + Preflow& elevator(Elevator& elevator) {
121.359 + if (_local_level) {
121.360 + delete _level;
121.361 + _local_level = false;
121.362 + }
121.363 + _level = &elevator;
121.364 + return *this;
121.365 + }
121.366 +
121.367 + /// \brief Returns a const reference to the elevator.
121.368 + ///
121.369 + /// Returns a const reference to the elevator.
121.370 + ///
121.371 + /// \pre Either \ref run() or \ref init() must be called before
121.372 + /// using this function.
121.373 + const Elevator& elevator() const {
121.374 + return *_level;
121.375 + }
121.376 +
121.377 + /// \brief Sets the tolerance used by algorithm.
121.378 + ///
121.379 + /// Sets the tolerance used by algorithm.
121.380 + Preflow& tolerance(const Tolerance& tolerance) const {
121.381 + _tolerance = tolerance;
121.382 + return *this;
121.383 + }
121.384 +
121.385 + /// \brief Returns a const reference to the tolerance.
121.386 + ///
121.387 + /// Returns a const reference to the tolerance.
121.388 + const Tolerance& tolerance() const {
121.389 + return tolerance;
121.390 + }
121.391 +
121.392 + /// \name Execution Control
121.393 + /// The simplest way to execute the preflow algorithm is to use
121.394 + /// \ref run() or \ref runMinCut().\n
121.395 + /// If you need more control on the initial solution or the execution,
121.396 + /// first you have to call one of the \ref init() functions, then
121.397 + /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
121.398 +
121.399 + ///@{
121.400 +
121.401 + /// \brief Initializes the internal data structures.
121.402 + ///
121.403 + /// Initializes the internal data structures and sets the initial
121.404 + /// flow to zero on each arc.
121.405 + void init() {
121.406 + createStructures();
121.407 +
121.408 + _phase = true;
121.409 + for (NodeIt n(_graph); n != INVALID; ++n) {
121.410 + (*_excess)[n] = 0;
121.411 + }
121.412 +
121.413 + for (ArcIt e(_graph); e != INVALID; ++e) {
121.414 + _flow->set(e, 0);
121.415 + }
121.416 +
121.417 + typename Digraph::template NodeMap<bool> reached(_graph, false);
121.418 +
121.419 + _level->initStart();
121.420 + _level->initAddItem(_target);
121.421 +
121.422 + std::vector<Node> queue;
121.423 + reached[_source] = true;
121.424 +
121.425 + queue.push_back(_target);
121.426 + reached[_target] = true;
121.427 + while (!queue.empty()) {
121.428 + _level->initNewLevel();
121.429 + std::vector<Node> nqueue;
121.430 + for (int i = 0; i < int(queue.size()); ++i) {
121.431 + Node n = queue[i];
121.432 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
121.433 + Node u = _graph.source(e);
121.434 + if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
121.435 + reached[u] = true;
121.436 + _level->initAddItem(u);
121.437 + nqueue.push_back(u);
121.438 + }
121.439 + }
121.440 + }
121.441 + queue.swap(nqueue);
121.442 + }
121.443 + _level->initFinish();
121.444 +
121.445 + for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
121.446 + if (_tolerance.positive((*_capacity)[e])) {
121.447 + Node u = _graph.target(e);
121.448 + if ((*_level)[u] == _level->maxLevel()) continue;
121.449 + _flow->set(e, (*_capacity)[e]);
121.450 + (*_excess)[u] += (*_capacity)[e];
121.451 + if (u != _target && !_level->active(u)) {
121.452 + _level->activate(u);
121.453 + }
121.454 + }
121.455 + }
121.456 + }
121.457 +
121.458 + /// \brief Initializes the internal data structures using the
121.459 + /// given flow map.
121.460 + ///
121.461 + /// Initializes the internal data structures and sets the initial
121.462 + /// flow to the given \c flowMap. The \c flowMap should contain a
121.463 + /// flow or at least a preflow, i.e. at each node excluding the
121.464 + /// source node the incoming flow should greater or equal to the
121.465 + /// outgoing flow.
121.466 + /// \return \c false if the given \c flowMap is not a preflow.
121.467 + template <typename FlowMap>
121.468 + bool init(const FlowMap& flowMap) {
121.469 + createStructures();
121.470 +
121.471 + for (ArcIt e(_graph); e != INVALID; ++e) {
121.472 + _flow->set(e, flowMap[e]);
121.473 + }
121.474 +
121.475 + for (NodeIt n(_graph); n != INVALID; ++n) {
121.476 + Value excess = 0;
121.477 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
121.478 + excess += (*_flow)[e];
121.479 + }
121.480 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
121.481 + excess -= (*_flow)[e];
121.482 + }
121.483 + if (excess < 0 && n != _source) return false;
121.484 + (*_excess)[n] = excess;
121.485 + }
121.486 +
121.487 + typename Digraph::template NodeMap<bool> reached(_graph, false);
121.488 +
121.489 + _level->initStart();
121.490 + _level->initAddItem(_target);
121.491 +
121.492 + std::vector<Node> queue;
121.493 + reached[_source] = true;
121.494 +
121.495 + queue.push_back(_target);
121.496 + reached[_target] = true;
121.497 + while (!queue.empty()) {
121.498 + _level->initNewLevel();
121.499 + std::vector<Node> nqueue;
121.500 + for (int i = 0; i < int(queue.size()); ++i) {
121.501 + Node n = queue[i];
121.502 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
121.503 + Node u = _graph.source(e);
121.504 + if (!reached[u] &&
121.505 + _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
121.506 + reached[u] = true;
121.507 + _level->initAddItem(u);
121.508 + nqueue.push_back(u);
121.509 + }
121.510 + }
121.511 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
121.512 + Node v = _graph.target(e);
121.513 + if (!reached[v] && _tolerance.positive((*_flow)[e])) {
121.514 + reached[v] = true;
121.515 + _level->initAddItem(v);
121.516 + nqueue.push_back(v);
121.517 + }
121.518 + }
121.519 + }
121.520 + queue.swap(nqueue);
121.521 + }
121.522 + _level->initFinish();
121.523 +
121.524 + for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
121.525 + Value rem = (*_capacity)[e] - (*_flow)[e];
121.526 + if (_tolerance.positive(rem)) {
121.527 + Node u = _graph.target(e);
121.528 + if ((*_level)[u] == _level->maxLevel()) continue;
121.529 + _flow->set(e, (*_capacity)[e]);
121.530 + (*_excess)[u] += rem;
121.531 + if (u != _target && !_level->active(u)) {
121.532 + _level->activate(u);
121.533 + }
121.534 + }
121.535 + }
121.536 + for (InArcIt e(_graph, _source); e != INVALID; ++e) {
121.537 + Value rem = (*_flow)[e];
121.538 + if (_tolerance.positive(rem)) {
121.539 + Node v = _graph.source(e);
121.540 + if ((*_level)[v] == _level->maxLevel()) continue;
121.541 + _flow->set(e, 0);
121.542 + (*_excess)[v] += rem;
121.543 + if (v != _target && !_level->active(v)) {
121.544 + _level->activate(v);
121.545 + }
121.546 + }
121.547 + }
121.548 + return true;
121.549 + }
121.550 +
121.551 + /// \brief Starts the first phase of the preflow algorithm.
121.552 + ///
121.553 + /// The preflow algorithm consists of two phases, this method runs
121.554 + /// the first phase. After the first phase the maximum flow value
121.555 + /// and a minimum value cut can already be computed, although a
121.556 + /// maximum flow is not yet obtained. So after calling this method
121.557 + /// \ref flowValue() returns the value of a maximum flow and \ref
121.558 + /// minCut() returns a minimum cut.
121.559 + /// \pre One of the \ref init() functions must be called before
121.560 + /// using this function.
121.561 + void startFirstPhase() {
121.562 + _phase = true;
121.563 +
121.564 + Node n = _level->highestActive();
121.565 + int level = _level->highestActiveLevel();
121.566 + while (n != INVALID) {
121.567 + int num = _node_num;
121.568 +
121.569 + while (num > 0 && n != INVALID) {
121.570 + Value excess = (*_excess)[n];
121.571 + int new_level = _level->maxLevel();
121.572 +
121.573 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
121.574 + Value rem = (*_capacity)[e] - (*_flow)[e];
121.575 + if (!_tolerance.positive(rem)) continue;
121.576 + Node v = _graph.target(e);
121.577 + if ((*_level)[v] < level) {
121.578 + if (!_level->active(v) && v != _target) {
121.579 + _level->activate(v);
121.580 + }
121.581 + if (!_tolerance.less(rem, excess)) {
121.582 + _flow->set(e, (*_flow)[e] + excess);
121.583 + (*_excess)[v] += excess;
121.584 + excess = 0;
121.585 + goto no_more_push_1;
121.586 + } else {
121.587 + excess -= rem;
121.588 + (*_excess)[v] += rem;
121.589 + _flow->set(e, (*_capacity)[e]);
121.590 + }
121.591 + } else if (new_level > (*_level)[v]) {
121.592 + new_level = (*_level)[v];
121.593 + }
121.594 + }
121.595 +
121.596 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
121.597 + Value rem = (*_flow)[e];
121.598 + if (!_tolerance.positive(rem)) continue;
121.599 + Node v = _graph.source(e);
121.600 + if ((*_level)[v] < level) {
121.601 + if (!_level->active(v) && v != _target) {
121.602 + _level->activate(v);
121.603 + }
121.604 + if (!_tolerance.less(rem, excess)) {
121.605 + _flow->set(e, (*_flow)[e] - excess);
121.606 + (*_excess)[v] += excess;
121.607 + excess = 0;
121.608 + goto no_more_push_1;
121.609 + } else {
121.610 + excess -= rem;
121.611 + (*_excess)[v] += rem;
121.612 + _flow->set(e, 0);
121.613 + }
121.614 + } else if (new_level > (*_level)[v]) {
121.615 + new_level = (*_level)[v];
121.616 + }
121.617 + }
121.618 +
121.619 + no_more_push_1:
121.620 +
121.621 + (*_excess)[n] = excess;
121.622 +
121.623 + if (excess != 0) {
121.624 + if (new_level + 1 < _level->maxLevel()) {
121.625 + _level->liftHighestActive(new_level + 1);
121.626 + } else {
121.627 + _level->liftHighestActiveToTop();
121.628 + }
121.629 + if (_level->emptyLevel(level)) {
121.630 + _level->liftToTop(level);
121.631 + }
121.632 + } else {
121.633 + _level->deactivate(n);
121.634 + }
121.635 +
121.636 + n = _level->highestActive();
121.637 + level = _level->highestActiveLevel();
121.638 + --num;
121.639 + }
121.640 +
121.641 + num = _node_num * 20;
121.642 + while (num > 0 && n != INVALID) {
121.643 + Value excess = (*_excess)[n];
121.644 + int new_level = _level->maxLevel();
121.645 +
121.646 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
121.647 + Value rem = (*_capacity)[e] - (*_flow)[e];
121.648 + if (!_tolerance.positive(rem)) continue;
121.649 + Node v = _graph.target(e);
121.650 + if ((*_level)[v] < level) {
121.651 + if (!_level->active(v) && v != _target) {
121.652 + _level->activate(v);
121.653 + }
121.654 + if (!_tolerance.less(rem, excess)) {
121.655 + _flow->set(e, (*_flow)[e] + excess);
121.656 + (*_excess)[v] += excess;
121.657 + excess = 0;
121.658 + goto no_more_push_2;
121.659 + } else {
121.660 + excess -= rem;
121.661 + (*_excess)[v] += rem;
121.662 + _flow->set(e, (*_capacity)[e]);
121.663 + }
121.664 + } else if (new_level > (*_level)[v]) {
121.665 + new_level = (*_level)[v];
121.666 + }
121.667 + }
121.668 +
121.669 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
121.670 + Value rem = (*_flow)[e];
121.671 + if (!_tolerance.positive(rem)) continue;
121.672 + Node v = _graph.source(e);
121.673 + if ((*_level)[v] < level) {
121.674 + if (!_level->active(v) && v != _target) {
121.675 + _level->activate(v);
121.676 + }
121.677 + if (!_tolerance.less(rem, excess)) {
121.678 + _flow->set(e, (*_flow)[e] - excess);
121.679 + (*_excess)[v] += excess;
121.680 + excess = 0;
121.681 + goto no_more_push_2;
121.682 + } else {
121.683 + excess -= rem;
121.684 + (*_excess)[v] += rem;
121.685 + _flow->set(e, 0);
121.686 + }
121.687 + } else if (new_level > (*_level)[v]) {
121.688 + new_level = (*_level)[v];
121.689 + }
121.690 + }
121.691 +
121.692 + no_more_push_2:
121.693 +
121.694 + (*_excess)[n] = excess;
121.695 +
121.696 + if (excess != 0) {
121.697 + if (new_level + 1 < _level->maxLevel()) {
121.698 + _level->liftActiveOn(level, new_level + 1);
121.699 + } else {
121.700 + _level->liftActiveToTop(level);
121.701 + }
121.702 + if (_level->emptyLevel(level)) {
121.703 + _level->liftToTop(level);
121.704 + }
121.705 + } else {
121.706 + _level->deactivate(n);
121.707 + }
121.708 +
121.709 + while (level >= 0 && _level->activeFree(level)) {
121.710 + --level;
121.711 + }
121.712 + if (level == -1) {
121.713 + n = _level->highestActive();
121.714 + level = _level->highestActiveLevel();
121.715 + } else {
121.716 + n = _level->activeOn(level);
121.717 + }
121.718 + --num;
121.719 + }
121.720 + }
121.721 + }
121.722 +
121.723 + /// \brief Starts the second phase of the preflow algorithm.
121.724 + ///
121.725 + /// The preflow algorithm consists of two phases, this method runs
121.726 + /// the second phase. After calling one of the \ref init() functions
121.727 + /// and \ref startFirstPhase() and then \ref startSecondPhase(),
121.728 + /// \ref flowMap() returns a maximum flow, \ref flowValue() returns the
121.729 + /// value of a maximum flow, \ref minCut() returns a minimum cut
121.730 + /// \pre One of the \ref init() functions and \ref startFirstPhase()
121.731 + /// must be called before using this function.
121.732 + void startSecondPhase() {
121.733 + _phase = false;
121.734 +
121.735 + typename Digraph::template NodeMap<bool> reached(_graph);
121.736 + for (NodeIt n(_graph); n != INVALID; ++n) {
121.737 + reached[n] = (*_level)[n] < _level->maxLevel();
121.738 + }
121.739 +
121.740 + _level->initStart();
121.741 + _level->initAddItem(_source);
121.742 +
121.743 + std::vector<Node> queue;
121.744 + queue.push_back(_source);
121.745 + reached[_source] = true;
121.746 +
121.747 + while (!queue.empty()) {
121.748 + _level->initNewLevel();
121.749 + std::vector<Node> nqueue;
121.750 + for (int i = 0; i < int(queue.size()); ++i) {
121.751 + Node n = queue[i];
121.752 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
121.753 + Node v = _graph.target(e);
121.754 + if (!reached[v] && _tolerance.positive((*_flow)[e])) {
121.755 + reached[v] = true;
121.756 + _level->initAddItem(v);
121.757 + nqueue.push_back(v);
121.758 + }
121.759 + }
121.760 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
121.761 + Node u = _graph.source(e);
121.762 + if (!reached[u] &&
121.763 + _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
121.764 + reached[u] = true;
121.765 + _level->initAddItem(u);
121.766 + nqueue.push_back(u);
121.767 + }
121.768 + }
121.769 + }
121.770 + queue.swap(nqueue);
121.771 + }
121.772 + _level->initFinish();
121.773 +
121.774 + for (NodeIt n(_graph); n != INVALID; ++n) {
121.775 + if (!reached[n]) {
121.776 + _level->dirtyTopButOne(n);
121.777 + } else if ((*_excess)[n] > 0 && _target != n) {
121.778 + _level->activate(n);
121.779 + }
121.780 + }
121.781 +
121.782 + Node n;
121.783 + while ((n = _level->highestActive()) != INVALID) {
121.784 + Value excess = (*_excess)[n];
121.785 + int level = _level->highestActiveLevel();
121.786 + int new_level = _level->maxLevel();
121.787 +
121.788 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
121.789 + Value rem = (*_capacity)[e] - (*_flow)[e];
121.790 + if (!_tolerance.positive(rem)) continue;
121.791 + Node v = _graph.target(e);
121.792 + if ((*_level)[v] < level) {
121.793 + if (!_level->active(v) && v != _source) {
121.794 + _level->activate(v);
121.795 + }
121.796 + if (!_tolerance.less(rem, excess)) {
121.797 + _flow->set(e, (*_flow)[e] + excess);
121.798 + (*_excess)[v] += excess;
121.799 + excess = 0;
121.800 + goto no_more_push;
121.801 + } else {
121.802 + excess -= rem;
121.803 + (*_excess)[v] += rem;
121.804 + _flow->set(e, (*_capacity)[e]);
121.805 + }
121.806 + } else if (new_level > (*_level)[v]) {
121.807 + new_level = (*_level)[v];
121.808 + }
121.809 + }
121.810 +
121.811 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
121.812 + Value rem = (*_flow)[e];
121.813 + if (!_tolerance.positive(rem)) continue;
121.814 + Node v = _graph.source(e);
121.815 + if ((*_level)[v] < level) {
121.816 + if (!_level->active(v) && v != _source) {
121.817 + _level->activate(v);
121.818 + }
121.819 + if (!_tolerance.less(rem, excess)) {
121.820 + _flow->set(e, (*_flow)[e] - excess);
121.821 + (*_excess)[v] += excess;
121.822 + excess = 0;
121.823 + goto no_more_push;
121.824 + } else {
121.825 + excess -= rem;
121.826 + (*_excess)[v] += rem;
121.827 + _flow->set(e, 0);
121.828 + }
121.829 + } else if (new_level > (*_level)[v]) {
121.830 + new_level = (*_level)[v];
121.831 + }
121.832 + }
121.833 +
121.834 + no_more_push:
121.835 +
121.836 + (*_excess)[n] = excess;
121.837 +
121.838 + if (excess != 0) {
121.839 + if (new_level + 1 < _level->maxLevel()) {
121.840 + _level->liftHighestActive(new_level + 1);
121.841 + } else {
121.842 + // Calculation error
121.843 + _level->liftHighestActiveToTop();
121.844 + }
121.845 + if (_level->emptyLevel(level)) {
121.846 + // Calculation error
121.847 + _level->liftToTop(level);
121.848 + }
121.849 + } else {
121.850 + _level->deactivate(n);
121.851 + }
121.852 +
121.853 + }
121.854 + }
121.855 +
121.856 + /// \brief Runs the preflow algorithm.
121.857 + ///
121.858 + /// Runs the preflow algorithm.
121.859 + /// \note pf.run() is just a shortcut of the following code.
121.860 + /// \code
121.861 + /// pf.init();
121.862 + /// pf.startFirstPhase();
121.863 + /// pf.startSecondPhase();
121.864 + /// \endcode
121.865 + void run() {
121.866 + init();
121.867 + startFirstPhase();
121.868 + startSecondPhase();
121.869 + }
121.870 +
121.871 + /// \brief Runs the preflow algorithm to compute the minimum cut.
121.872 + ///
121.873 + /// Runs the preflow algorithm to compute the minimum cut.
121.874 + /// \note pf.runMinCut() is just a shortcut of the following code.
121.875 + /// \code
121.876 + /// pf.init();
121.877 + /// pf.startFirstPhase();
121.878 + /// \endcode
121.879 + void runMinCut() {
121.880 + init();
121.881 + startFirstPhase();
121.882 + }
121.883 +
121.884 + /// @}
121.885 +
121.886 + /// \name Query Functions
121.887 + /// The results of the preflow algorithm can be obtained using these
121.888 + /// functions.\n
121.889 + /// Either one of the \ref run() "run*()" functions or one of the
121.890 + /// \ref startFirstPhase() "start*()" functions should be called
121.891 + /// before using them.
121.892 +
121.893 + ///@{
121.894 +
121.895 + /// \brief Returns the value of the maximum flow.
121.896 + ///
121.897 + /// Returns the value of the maximum flow by returning the excess
121.898 + /// of the target node. This value equals to the value of
121.899 + /// the maximum flow already after the first phase of the algorithm.
121.900 + ///
121.901 + /// \pre Either \ref run() or \ref init() must be called before
121.902 + /// using this function.
121.903 + Value flowValue() const {
121.904 + return (*_excess)[_target];
121.905 + }
121.906 +
121.907 + /// \brief Returns the flow value on the given arc.
121.908 + ///
121.909 + /// Returns the flow value on the given arc. This method can
121.910 + /// be called after the second phase of the algorithm.
121.911 + ///
121.912 + /// \pre Either \ref run() or \ref init() must be called before
121.913 + /// using this function.
121.914 + Value flow(const Arc& arc) const {
121.915 + return (*_flow)[arc];
121.916 + }
121.917 +
121.918 + /// \brief Returns a const reference to the flow map.
121.919 + ///
121.920 + /// Returns a const reference to the arc map storing the found flow.
121.921 + /// This method can be called after the second phase of the algorithm.
121.922 + ///
121.923 + /// \pre Either \ref run() or \ref init() must be called before
121.924 + /// using this function.
121.925 + const FlowMap& flowMap() const {
121.926 + return *_flow;
121.927 + }
121.928 +
121.929 + /// \brief Returns \c true when the node is on the source side of the
121.930 + /// minimum cut.
121.931 + ///
121.932 + /// Returns true when the node is on the source side of the found
121.933 + /// minimum cut. This method can be called both after running \ref
121.934 + /// startFirstPhase() and \ref startSecondPhase().
121.935 + ///
121.936 + /// \pre Either \ref run() or \ref init() must be called before
121.937 + /// using this function.
121.938 + bool minCut(const Node& node) const {
121.939 + return ((*_level)[node] == _level->maxLevel()) == _phase;
121.940 + }
121.941 +
121.942 + /// \brief Gives back a minimum value cut.
121.943 + ///
121.944 + /// Sets \c cutMap to the characteristic vector of a minimum value
121.945 + /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
121.946 + /// node map with \c bool (or convertible) value type.
121.947 + ///
121.948 + /// This method can be called both after running \ref startFirstPhase()
121.949 + /// and \ref startSecondPhase(). The result after the second phase
121.950 + /// could be slightly different if inexact computation is used.
121.951 + ///
121.952 + /// \note This function calls \ref minCut() for each node, so it runs in
121.953 + /// O(n) time.
121.954 + ///
121.955 + /// \pre Either \ref run() or \ref init() must be called before
121.956 + /// using this function.
121.957 + template <typename CutMap>
121.958 + void minCutMap(CutMap& cutMap) const {
121.959 + for (NodeIt n(_graph); n != INVALID; ++n) {
121.960 + cutMap.set(n, minCut(n));
121.961 + }
121.962 + }
121.963 +
121.964 + /// @}
121.965 + };
121.966 +}
121.967 +
121.968 +#endif
122.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
122.2 +++ b/lemon/radix_heap.h Thu Dec 10 17:05:35 2009 +0100
122.3 @@ -0,0 +1,433 @@
122.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
122.5 + *
122.6 + * This file is a part of LEMON, a generic C++ optimization library.
122.7 + *
122.8 + * Copyright (C) 2003-2009
122.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
122.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
122.11 + *
122.12 + * Permission to use, modify and distribute this software is granted
122.13 + * provided that this copyright notice appears in all copies. For
122.14 + * precise terms see the accompanying LICENSE file.
122.15 + *
122.16 + * This software is provided "AS IS" with no warranty of any kind,
122.17 + * express or implied, and with no claim as to its suitability for any
122.18 + * purpose.
122.19 + *
122.20 + */
122.21 +
122.22 +#ifndef LEMON_RADIX_HEAP_H
122.23 +#define LEMON_RADIX_HEAP_H
122.24 +
122.25 +///\ingroup auxdat
122.26 +///\file
122.27 +///\brief Radix Heap implementation.
122.28 +
122.29 +#include <vector>
122.30 +#include <lemon/error.h>
122.31 +
122.32 +namespace lemon {
122.33 +
122.34 +
122.35 + /// \ingroup auxdata
122.36 + ///
122.37 + /// \brief A Radix Heap implementation.
122.38 + ///
122.39 + /// This class implements the \e radix \e heap data structure. A \e heap
122.40 + /// is a data structure for storing items with specified values called \e
122.41 + /// priorities in such a way that finding the item with minimum priority is
122.42 + /// efficient. This heap type can store only items with \e int priority.
122.43 + /// In a heap one can change the priority of an item, add or erase an
122.44 + /// item, but the priority cannot be decreased under the last removed
122.45 + /// item's priority.
122.46 + ///
122.47 + /// \param IM A read and writable Item int map, used internally
122.48 + /// to handle the cross references.
122.49 + ///
122.50 + /// \see BinHeap
122.51 + /// \see Dijkstra
122.52 + template <typename IM>
122.53 + class RadixHeap {
122.54 +
122.55 + public:
122.56 + typedef typename IM::Key Item;
122.57 + typedef int Prio;
122.58 + typedef IM ItemIntMap;
122.59 +
122.60 + /// \brief Exception thrown by RadixHeap.
122.61 + ///
122.62 + /// This Exception is thrown when a smaller priority
122.63 + /// is inserted into the \e RadixHeap then the last time erased.
122.64 + /// \see RadixHeap
122.65 +
122.66 + class UnderFlowPriorityError : public Exception {
122.67 + public:
122.68 + virtual const char* what() const throw() {
122.69 + return "lemon::RadixHeap::UnderFlowPriorityError";
122.70 + }
122.71 + };
122.72 +
122.73 + /// \brief Type to represent the items states.
122.74 + ///
122.75 + /// Each Item element have a state associated to it. It may be "in heap",
122.76 + /// "pre heap" or "post heap". The latter two are indifferent from the
122.77 + /// heap's point of view, but may be useful to the user.
122.78 + ///
122.79 + /// The ItemIntMap \e should be initialized in such way that it maps
122.80 + /// PRE_HEAP (-1) to any element to be put in the heap...
122.81 + enum State {
122.82 + IN_HEAP = 0,
122.83 + PRE_HEAP = -1,
122.84 + POST_HEAP = -2
122.85 + };
122.86 +
122.87 + private:
122.88 +
122.89 + struct RadixItem {
122.90 + int prev, next, box;
122.91 + Item item;
122.92 + int prio;
122.93 + RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
122.94 + };
122.95 +
122.96 + struct RadixBox {
122.97 + int first;
122.98 + int min, size;
122.99 + RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
122.100 + };
122.101 +
122.102 + std::vector<RadixItem> data;
122.103 + std::vector<RadixBox> boxes;
122.104 +
122.105 + ItemIntMap &_iim;
122.106 +
122.107 +
122.108 + public:
122.109 + /// \brief The constructor.
122.110 + ///
122.111 + /// The constructor.
122.112 + ///
122.113 + /// \param map It should be given to the constructor, since it is used
122.114 + /// internally to handle the cross references. The value of the map
122.115 + /// should be PRE_HEAP (-1) for each element.
122.116 + ///
122.117 + /// \param minimal The initial minimal value of the heap.
122.118 + /// \param capacity It determines the initial capacity of the heap.
122.119 + RadixHeap(ItemIntMap &map, int minimal = 0, int capacity = 0)
122.120 + : _iim(map) {
122.121 + boxes.push_back(RadixBox(minimal, 1));
122.122 + boxes.push_back(RadixBox(minimal + 1, 1));
122.123 + while (lower(boxes.size() - 1, capacity + minimal - 1)) {
122.124 + extend();
122.125 + }
122.126 + }
122.127 +
122.128 + /// The number of items stored in the heap.
122.129 + ///
122.130 + /// \brief Returns the number of items stored in the heap.
122.131 + int size() const { return data.size(); }
122.132 + /// \brief Checks if the heap stores no items.
122.133 + ///
122.134 + /// Returns \c true if and only if the heap stores no items.
122.135 + bool empty() const { return data.empty(); }
122.136 +
122.137 + /// \brief Make empty this heap.
122.138 + ///
122.139 + /// Make empty this heap. It does not change the cross reference
122.140 + /// map. If you want to reuse a heap what is not surely empty you
122.141 + /// should first clear the heap and after that you should set the
122.142 + /// cross reference map for each item to \c PRE_HEAP.
122.143 + void clear(int minimal = 0, int capacity = 0) {
122.144 + data.clear(); boxes.clear();
122.145 + boxes.push_back(RadixBox(minimal, 1));
122.146 + boxes.push_back(RadixBox(minimal + 1, 1));
122.147 + while (lower(boxes.size() - 1, capacity + minimal - 1)) {
122.148 + extend();
122.149 + }
122.150 + }
122.151 +
122.152 + private:
122.153 +
122.154 + bool upper(int box, Prio pr) {
122.155 + return pr < boxes[box].min;
122.156 + }
122.157 +
122.158 + bool lower(int box, Prio pr) {
122.159 + return pr >= boxes[box].min + boxes[box].size;
122.160 + }
122.161 +
122.162 + /// \brief Remove item from the box list.
122.163 + void remove(int index) {
122.164 + if (data[index].prev >= 0) {
122.165 + data[data[index].prev].next = data[index].next;
122.166 + } else {
122.167 + boxes[data[index].box].first = data[index].next;
122.168 + }
122.169 + if (data[index].next >= 0) {
122.170 + data[data[index].next].prev = data[index].prev;
122.171 + }
122.172 + }
122.173 +
122.174 + /// \brief Insert item into the box list.
122.175 + void insert(int box, int index) {
122.176 + if (boxes[box].first == -1) {
122.177 + boxes[box].first = index;
122.178 + data[index].next = data[index].prev = -1;
122.179 + } else {
122.180 + data[index].next = boxes[box].first;
122.181 + data[boxes[box].first].prev = index;
122.182 + data[index].prev = -1;
122.183 + boxes[box].first = index;
122.184 + }
122.185 + data[index].box = box;
122.186 + }
122.187 +
122.188 + /// \brief Add a new box to the box list.
122.189 + void extend() {
122.190 + int min = boxes.back().min + boxes.back().size;
122.191 + int bs = 2 * boxes.back().size;
122.192 + boxes.push_back(RadixBox(min, bs));
122.193 + }
122.194 +
122.195 + /// \brief Move an item up into the proper box.
122.196 + void bubble_up(int index) {
122.197 + if (!lower(data[index].box, data[index].prio)) return;
122.198 + remove(index);
122.199 + int box = findUp(data[index].box, data[index].prio);
122.200 + insert(box, index);
122.201 + }
122.202 +
122.203 + /// \brief Find up the proper box for the item with the given prio.
122.204 + int findUp(int start, int pr) {
122.205 + while (lower(start, pr)) {
122.206 + if (++start == int(boxes.size())) {
122.207 + extend();
122.208 + }
122.209 + }
122.210 + return start;
122.211 + }
122.212 +
122.213 + /// \brief Move an item down into the proper box.
122.214 + void bubble_down(int index) {
122.215 + if (!upper(data[index].box, data[index].prio)) return;
122.216 + remove(index);
122.217 + int box = findDown(data[index].box, data[index].prio);
122.218 + insert(box, index);
122.219 + }
122.220 +
122.221 + /// \brief Find up the proper box for the item with the given prio.
122.222 + int findDown(int start, int pr) {
122.223 + while (upper(start, pr)) {
122.224 + if (--start < 0) throw UnderFlowPriorityError();
122.225 + }
122.226 + return start;
122.227 + }
122.228 +
122.229 + /// \brief Find the first not empty box.
122.230 + int findFirst() {
122.231 + int first = 0;
122.232 + while (boxes[first].first == -1) ++first;
122.233 + return first;
122.234 + }
122.235 +
122.236 + /// \brief Gives back the minimal prio of the box.
122.237 + int minValue(int box) {
122.238 + int min = data[boxes[box].first].prio;
122.239 + for (int k = boxes[box].first; k != -1; k = data[k].next) {
122.240 + if (data[k].prio < min) min = data[k].prio;
122.241 + }
122.242 + return min;
122.243 + }
122.244 +
122.245 + /// \brief Rearrange the items of the heap and makes the
122.246 + /// first box not empty.
122.247 + void moveDown() {
122.248 + int box = findFirst();
122.249 + if (box == 0) return;
122.250 + int min = minValue(box);
122.251 + for (int i = 0; i <= box; ++i) {
122.252 + boxes[i].min = min;
122.253 + min += boxes[i].size;
122.254 + }
122.255 + int curr = boxes[box].first, next;
122.256 + while (curr != -1) {
122.257 + next = data[curr].next;
122.258 + bubble_down(curr);
122.259 + curr = next;
122.260 + }
122.261 + }
122.262 +
122.263 + void relocate_last(int index) {
122.264 + if (index != int(data.size()) - 1) {
122.265 + data[index] = data.back();
122.266 + if (data[index].prev != -1) {
122.267 + data[data[index].prev].next = index;
122.268 + } else {
122.269 + boxes[data[index].box].first = index;
122.270 + }
122.271 + if (data[index].next != -1) {
122.272 + data[data[index].next].prev = index;
122.273 + }
122.274 + _iim[data[index].item] = index;
122.275 + }
122.276 + data.pop_back();
122.277 + }
122.278 +
122.279 + public:
122.280 +
122.281 + /// \brief Insert an item into the heap with the given priority.
122.282 + ///
122.283 + /// Adds \c i to the heap with priority \c p.
122.284 + /// \param i The item to insert.
122.285 + /// \param p The priority of the item.
122.286 + void push(const Item &i, const Prio &p) {
122.287 + int n = data.size();
122.288 + _iim.set(i, n);
122.289 + data.push_back(RadixItem(i, p));
122.290 + while (lower(boxes.size() - 1, p)) {
122.291 + extend();
122.292 + }
122.293 + int box = findDown(boxes.size() - 1, p);
122.294 + insert(box, n);
122.295 + }
122.296 +
122.297 + /// \brief Returns the item with minimum priority.
122.298 + ///
122.299 + /// This method returns the item with minimum priority.
122.300 + /// \pre The heap must be nonempty.
122.301 + Item top() const {
122.302 + const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
122.303 + return data[boxes[0].first].item;
122.304 + }
122.305 +
122.306 + /// \brief Returns the minimum priority.
122.307 + ///
122.308 + /// It returns the minimum priority.
122.309 + /// \pre The heap must be nonempty.
122.310 + Prio prio() const {
122.311 + const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
122.312 + return data[boxes[0].first].prio;
122.313 + }
122.314 +
122.315 + /// \brief Deletes the item with minimum priority.
122.316 + ///
122.317 + /// This method deletes the item with minimum priority.
122.318 + /// \pre The heap must be non-empty.
122.319 + void pop() {
122.320 + moveDown();
122.321 + int index = boxes[0].first;
122.322 + _iim[data[index].item] = POST_HEAP;
122.323 + remove(index);
122.324 + relocate_last(index);
122.325 + }
122.326 +
122.327 + /// \brief Deletes \c i from the heap.
122.328 + ///
122.329 + /// This method deletes item \c i from the heap, if \c i was
122.330 + /// already stored in the heap.
122.331 + /// \param i The item to erase.
122.332 + void erase(const Item &i) {
122.333 + int index = _iim[i];
122.334 + _iim[i] = POST_HEAP;
122.335 + remove(index);
122.336 + relocate_last(index);
122.337 + }
122.338 +
122.339 + /// \brief Returns the priority of \c i.
122.340 + ///
122.341 + /// This function returns the priority of item \c i.
122.342 + /// \pre \c i must be in the heap.
122.343 + /// \param i The item.
122.344 + Prio operator[](const Item &i) const {
122.345 + int idx = _iim[i];
122.346 + return data[idx].prio;
122.347 + }
122.348 +
122.349 + /// \brief \c i gets to the heap with priority \c p independently
122.350 + /// if \c i was already there.
122.351 + ///
122.352 + /// This method calls \ref push(\c i, \c p) if \c i is not stored
122.353 + /// in the heap and sets the priority of \c i to \c p otherwise.
122.354 + /// It may throw an \e UnderFlowPriorityException.
122.355 + /// \param i The item.
122.356 + /// \param p The priority.
122.357 + void set(const Item &i, const Prio &p) {
122.358 + int idx = _iim[i];
122.359 + if( idx < 0 ) {
122.360 + push(i, p);
122.361 + }
122.362 + else if( p >= data[idx].prio ) {
122.363 + data[idx].prio = p;
122.364 + bubble_up(idx);
122.365 + } else {
122.366 + data[idx].prio = p;
122.367 + bubble_down(idx);
122.368 + }
122.369 + }
122.370 +
122.371 +
122.372 + /// \brief Decreases the priority of \c i to \c p.
122.373 + ///
122.374 + /// This method decreases the priority of item \c i to \c p.
122.375 + /// \pre \c i must be stored in the heap with priority at least \c p, and
122.376 + /// \c should be greater or equal to the last removed item's priority.
122.377 + /// \param i The item.
122.378 + /// \param p The priority.
122.379 + void decrease(const Item &i, const Prio &p) {
122.380 + int idx = _iim[i];
122.381 + data[idx].prio = p;
122.382 + bubble_down(idx);
122.383 + }
122.384 +
122.385 + /// \brief Increases the priority of \c i to \c p.
122.386 + ///
122.387 + /// This method sets the priority of item \c i to \c p.
122.388 + /// \pre \c i must be stored in the heap with priority at most \c p
122.389 + /// \param i The item.
122.390 + /// \param p The priority.
122.391 + void increase(const Item &i, const Prio &p) {
122.392 + int idx = _iim[i];
122.393 + data[idx].prio = p;
122.394 + bubble_up(idx);
122.395 + }
122.396 +
122.397 + /// \brief Returns if \c item is in, has already been in, or has
122.398 + /// never been in the heap.
122.399 + ///
122.400 + /// This method returns PRE_HEAP if \c item has never been in the
122.401 + /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
122.402 + /// otherwise. In the latter case it is possible that \c item will
122.403 + /// get back to the heap again.
122.404 + /// \param i The item.
122.405 + State state(const Item &i) const {
122.406 + int s = _iim[i];
122.407 + if( s >= 0 ) s = 0;
122.408 + return State(s);
122.409 + }
122.410 +
122.411 + /// \brief Sets the state of the \c item in the heap.
122.412 + ///
122.413 + /// Sets the state of the \c item in the heap. It can be used to
122.414 + /// manually clear the heap when it is important to achive the
122.415 + /// better time complexity.
122.416 + /// \param i The item.
122.417 + /// \param st The state. It should not be \c IN_HEAP.
122.418 + void state(const Item& i, State st) {
122.419 + switch (st) {
122.420 + case POST_HEAP:
122.421 + case PRE_HEAP:
122.422 + if (state(i) == IN_HEAP) {
122.423 + erase(i);
122.424 + }
122.425 + _iim[i] = st;
122.426 + break;
122.427 + case IN_HEAP:
122.428 + break;
122.429 + }
122.430 + }
122.431 +
122.432 + }; // class RadixHeap
122.433 +
122.434 +} // namespace lemon
122.435 +
122.436 +#endif // LEMON_RADIX_HEAP_H
123.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
123.2 +++ b/lemon/radix_sort.h Thu Dec 10 17:05:35 2009 +0100
123.3 @@ -0,0 +1,487 @@
123.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
123.5 + *
123.6 + * This file is a part of LEMON, a generic C++ optimization library.
123.7 + *
123.8 + * Copyright (C) 2003-2009
123.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
123.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
123.11 + *
123.12 + * Permission to use, modify and distribute this software is granted
123.13 + * provided that this copyright notice appears in all copies. For
123.14 + * precise terms see the accompanying LICENSE file.
123.15 + *
123.16 + * This software is provided "AS IS" with no warranty of any kind,
123.17 + * express or implied, and with no claim as to its suitability for any
123.18 + * purpose.
123.19 + *
123.20 + */
123.21 +
123.22 +#ifndef RADIX_SORT_H
123.23 +#define RADIX_SORT_H
123.24 +
123.25 +/// \ingroup auxalg
123.26 +/// \file
123.27 +/// \brief Radix sort
123.28 +///
123.29 +/// Linear time sorting algorithms
123.30 +
123.31 +#include <vector>
123.32 +#include <limits>
123.33 +#include <iterator>
123.34 +#include <algorithm>
123.35 +
123.36 +namespace lemon {
123.37 +
123.38 + namespace _radix_sort_bits {
123.39 +
123.40 + template <typename Value>
123.41 + struct Identity {
123.42 + const Value& operator()(const Value& val) {
123.43 + return val;
123.44 + }
123.45 + };
123.46 +
123.47 +
123.48 + template <typename Value, typename Iterator, typename Functor>
123.49 + Iterator radixSortPartition(Iterator first, Iterator last,
123.50 + Functor functor, Value mask) {
123.51 + while (first != last && !(functor(*first) & mask)) {
123.52 + ++first;
123.53 + }
123.54 + if (first == last) {
123.55 + return first;
123.56 + }
123.57 + --last;
123.58 + while (first != last && (functor(*last) & mask)) {
123.59 + --last;
123.60 + }
123.61 + if (first == last) {
123.62 + return first;
123.63 + }
123.64 + std::iter_swap(first, last);
123.65 + ++first;
123.66 + if (!(first < last)) {
123.67 + return first;
123.68 + }
123.69 + while (true) {
123.70 + while (!(functor(*first) & mask)) {
123.71 + ++first;
123.72 + }
123.73 + --last;
123.74 + while (functor(*last) & mask) {
123.75 + --last;
123.76 + }
123.77 + if (!(first < last)) {
123.78 + return first;
123.79 + }
123.80 + std::iter_swap(first, last);
123.81 + ++first;
123.82 + }
123.83 + }
123.84 +
123.85 + template <typename Iterator, typename Functor>
123.86 + Iterator radixSortSignPartition(Iterator first, Iterator last,
123.87 + Functor functor) {
123.88 + while (first != last && functor(*first) < 0) {
123.89 + ++first;
123.90 + }
123.91 + if (first == last) {
123.92 + return first;
123.93 + }
123.94 + --last;
123.95 + while (first != last && functor(*last) >= 0) {
123.96 + --last;
123.97 + }
123.98 + if (first == last) {
123.99 + return first;
123.100 + }
123.101 + std::iter_swap(first, last);
123.102 + ++first;
123.103 + if (!(first < last)) {
123.104 + return first;
123.105 + }
123.106 + while (true) {
123.107 + while (functor(*first) < 0) {
123.108 + ++first;
123.109 + }
123.110 + --last;
123.111 + while (functor(*last) >= 0) {
123.112 + --last;
123.113 + }
123.114 + if (!(first < last)) {
123.115 + return first;
123.116 + }
123.117 + std::iter_swap(first, last);
123.118 + ++first;
123.119 + }
123.120 + }
123.121 +
123.122 + template <typename Value, typename Iterator, typename Functor>
123.123 + void radixIntroSort(Iterator first, Iterator last,
123.124 + Functor functor, Value mask) {
123.125 + while (mask != 0 && last - first > 1) {
123.126 + Iterator cut = radixSortPartition(first, last, functor, mask);
123.127 + mask >>= 1;
123.128 + radixIntroSort(first, cut, functor, mask);
123.129 + first = cut;
123.130 + }
123.131 + }
123.132 +
123.133 + template <typename Value, typename Iterator, typename Functor>
123.134 + void radixSignedSort(Iterator first, Iterator last, Functor functor) {
123.135 +
123.136 + Iterator cut = radixSortSignPartition(first, last, functor);
123.137 +
123.138 + Value mask;
123.139 + int max_digit;
123.140 + Iterator it;
123.141 +
123.142 + mask = ~0; max_digit = 0;
123.143 + for (it = first; it != cut; ++it) {
123.144 + while ((mask & functor(*it)) != mask) {
123.145 + ++max_digit;
123.146 + mask <<= 1;
123.147 + }
123.148 + }
123.149 + radixIntroSort(first, cut, functor, 1 << max_digit);
123.150 +
123.151 + mask = 0; max_digit = 0;
123.152 + for (it = cut; it != last; ++it) {
123.153 + while ((mask | functor(*it)) != mask) {
123.154 + ++max_digit;
123.155 + mask <<= 1; mask |= 1;
123.156 + }
123.157 + }
123.158 + radixIntroSort(cut, last, functor, 1 << max_digit);
123.159 + }
123.160 +
123.161 + template <typename Value, typename Iterator, typename Functor>
123.162 + void radixUnsignedSort(Iterator first, Iterator last, Functor functor) {
123.163 +
123.164 + Value mask = 0;
123.165 + int max_digit = 0;
123.166 +
123.167 + Iterator it;
123.168 + for (it = first; it != last; ++it) {
123.169 + while ((mask | functor(*it)) != mask) {
123.170 + ++max_digit;
123.171 + mask <<= 1; mask |= 1;
123.172 + }
123.173 + }
123.174 + radixIntroSort(first, last, functor, 1 << max_digit);
123.175 + }
123.176 +
123.177 +
123.178 + template <typename Value,
123.179 + bool sign = std::numeric_limits<Value>::is_signed >
123.180 + struct RadixSortSelector {
123.181 + template <typename Iterator, typename Functor>
123.182 + static void sort(Iterator first, Iterator last, Functor functor) {
123.183 + radixSignedSort<Value>(first, last, functor);
123.184 + }
123.185 + };
123.186 +
123.187 + template <typename Value>
123.188 + struct RadixSortSelector<Value, false> {
123.189 + template <typename Iterator, typename Functor>
123.190 + static void sort(Iterator first, Iterator last, Functor functor) {
123.191 + radixUnsignedSort<Value>(first, last, functor);
123.192 + }
123.193 + };
123.194 +
123.195 + }
123.196 +
123.197 + /// \ingroup auxalg
123.198 + ///
123.199 + /// \brief Sorts the STL compatible range into ascending order.
123.200 + ///
123.201 + /// The \c radixSort sorts an STL compatible range into ascending
123.202 + /// order. The radix sort algorithm can sort items which are mapped
123.203 + /// to integers with an adaptable unary function \c functor and the
123.204 + /// order will be ascending according to these mapped values.
123.205 + ///
123.206 + /// It is also possible to use a normal function instead
123.207 + /// of the functor object. If the functor is not given it will use
123.208 + /// the identity function instead.
123.209 + ///
123.210 + /// This is a special quick sort algorithm where the pivot
123.211 + /// values to split the items are choosen to be 2<sup>k</sup>
123.212 + /// for each \c k.
123.213 + /// Therefore, the time complexity of the algorithm is O(log(c)*n) and
123.214 + /// it uses O(log(c)) additional space, where \c c is the maximal value
123.215 + /// and \c n is the number of the items in the container.
123.216 + ///
123.217 + /// \param first The begin of the given range.
123.218 + /// \param last The end of the given range.
123.219 + /// \param functor An adaptible unary function or a normal function
123.220 + /// which maps the items to any integer type which can be either
123.221 + /// signed or unsigned.
123.222 + ///
123.223 + /// \sa stableRadixSort()
123.224 + template <typename Iterator, typename Functor>
123.225 + void radixSort(Iterator first, Iterator last, Functor functor) {
123.226 + using namespace _radix_sort_bits;
123.227 + typedef typename Functor::result_type Value;
123.228 + RadixSortSelector<Value>::sort(first, last, functor);
123.229 + }
123.230 +
123.231 + template <typename Iterator, typename Value, typename Key>
123.232 + void radixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
123.233 + using namespace _radix_sort_bits;
123.234 + RadixSortSelector<Value>::sort(first, last, functor);
123.235 + }
123.236 +
123.237 + template <typename Iterator, typename Value, typename Key>
123.238 + void radixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
123.239 + using namespace _radix_sort_bits;
123.240 + RadixSortSelector<Value>::sort(first, last, functor);
123.241 + }
123.242 +
123.243 + template <typename Iterator, typename Value, typename Key>
123.244 + void radixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
123.245 + using namespace _radix_sort_bits;
123.246 + RadixSortSelector<Value>::sort(first, last, functor);
123.247 + }
123.248 +
123.249 + template <typename Iterator, typename Value, typename Key>
123.250 + void radixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
123.251 + using namespace _radix_sort_bits;
123.252 + RadixSortSelector<Value>::sort(first, last, functor);
123.253 + }
123.254 +
123.255 + template <typename Iterator>
123.256 + void radixSort(Iterator first, Iterator last) {
123.257 + using namespace _radix_sort_bits;
123.258 + typedef typename std::iterator_traits<Iterator>::value_type Value;
123.259 + RadixSortSelector<Value>::sort(first, last, Identity<Value>());
123.260 + }
123.261 +
123.262 + namespace _radix_sort_bits {
123.263 +
123.264 + template <typename Value>
123.265 + unsigned char valueByte(Value value, int byte) {
123.266 + return value >> (std::numeric_limits<unsigned char>::digits * byte);
123.267 + }
123.268 +
123.269 + template <typename Functor, typename Key>
123.270 + void stableRadixIntroSort(Key *first, Key *last, Key *target,
123.271 + int byte, Functor functor) {
123.272 + const int size =
123.273 + unsigned(std::numeric_limits<unsigned char>::max()) + 1;
123.274 + std::vector<int> counter(size);
123.275 + for (int i = 0; i < size; ++i) {
123.276 + counter[i] = 0;
123.277 + }
123.278 + Key *it = first;
123.279 + while (first != last) {
123.280 + ++counter[valueByte(functor(*first), byte)];
123.281 + ++first;
123.282 + }
123.283 + int prev, num = 0;
123.284 + for (int i = 0; i < size; ++i) {
123.285 + prev = num;
123.286 + num += counter[i];
123.287 + counter[i] = prev;
123.288 + }
123.289 + while (it != last) {
123.290 + target[counter[valueByte(functor(*it), byte)]++] = *it;
123.291 + ++it;
123.292 + }
123.293 + }
123.294 +
123.295 + template <typename Functor, typename Key>
123.296 + void signedStableRadixIntroSort(Key *first, Key *last, Key *target,
123.297 + int byte, Functor functor) {
123.298 + const int size =
123.299 + unsigned(std::numeric_limits<unsigned char>::max()) + 1;
123.300 + std::vector<int> counter(size);
123.301 + for (int i = 0; i < size; ++i) {
123.302 + counter[i] = 0;
123.303 + }
123.304 + Key *it = first;
123.305 + while (first != last) {
123.306 + counter[valueByte(functor(*first), byte)]++;
123.307 + ++first;
123.308 + }
123.309 + int prev, num = 0;
123.310 + for (int i = size / 2; i < size; ++i) {
123.311 + prev = num;
123.312 + num += counter[i];
123.313 + counter[i] = prev;
123.314 + }
123.315 + for (int i = 0; i < size / 2; ++i) {
123.316 + prev = num;
123.317 + num += counter[i];
123.318 + counter[i] = prev;
123.319 + }
123.320 + while (it != last) {
123.321 + target[counter[valueByte(functor(*it), byte)]++] = *it;
123.322 + ++it;
123.323 + }
123.324 + }
123.325 +
123.326 +
123.327 + template <typename Value, typename Iterator, typename Functor>
123.328 + void stableRadixSignedSort(Iterator first, Iterator last, Functor functor) {
123.329 + if (first == last) return;
123.330 + typedef typename std::iterator_traits<Iterator>::value_type Key;
123.331 + typedef std::allocator<Key> Allocator;
123.332 + Allocator allocator;
123.333 +
123.334 + int length = std::distance(first, last);
123.335 + Key* buffer = allocator.allocate(2 * length);
123.336 + try {
123.337 + bool dir = true;
123.338 + std::copy(first, last, buffer);
123.339 + for (int i = 0; i < int(sizeof(Value)) - 1; ++i) {
123.340 + if (dir) {
123.341 + stableRadixIntroSort(buffer, buffer + length, buffer + length,
123.342 + i, functor);
123.343 + } else {
123.344 + stableRadixIntroSort(buffer + length, buffer + 2 * length, buffer,
123.345 + i, functor);
123.346 + }
123.347 + dir = !dir;
123.348 + }
123.349 + if (dir) {
123.350 + signedStableRadixIntroSort(buffer, buffer + length, buffer + length,
123.351 + sizeof(Value) - 1, functor);
123.352 + std::copy(buffer + length, buffer + 2 * length, first);
123.353 + } else {
123.354 + signedStableRadixIntroSort(buffer + length, buffer + 2 * length,
123.355 + buffer, sizeof(Value) - 1, functor);
123.356 + std::copy(buffer, buffer + length, first);
123.357 + }
123.358 + } catch (...) {
123.359 + allocator.deallocate(buffer, 2 * length);
123.360 + throw;
123.361 + }
123.362 + allocator.deallocate(buffer, 2 * length);
123.363 + }
123.364 +
123.365 + template <typename Value, typename Iterator, typename Functor>
123.366 + void stableRadixUnsignedSort(Iterator first, Iterator last,
123.367 + Functor functor) {
123.368 + if (first == last) return;
123.369 + typedef typename std::iterator_traits<Iterator>::value_type Key;
123.370 + typedef std::allocator<Key> Allocator;
123.371 + Allocator allocator;
123.372 +
123.373 + int length = std::distance(first, last);
123.374 + Key *buffer = allocator.allocate(2 * length);
123.375 + try {
123.376 + bool dir = true;
123.377 + std::copy(first, last, buffer);
123.378 + for (int i = 0; i < int(sizeof(Value)); ++i) {
123.379 + if (dir) {
123.380 + stableRadixIntroSort(buffer, buffer + length,
123.381 + buffer + length, i, functor);
123.382 + } else {
123.383 + stableRadixIntroSort(buffer + length, buffer + 2 * length,
123.384 + buffer, i, functor);
123.385 + }
123.386 + dir = !dir;
123.387 + }
123.388 + if (dir) {
123.389 + std::copy(buffer, buffer + length, first);
123.390 + } else {
123.391 + std::copy(buffer + length, buffer + 2 * length, first);
123.392 + }
123.393 + } catch (...) {
123.394 + allocator.deallocate(buffer, 2 * length);
123.395 + throw;
123.396 + }
123.397 + allocator.deallocate(buffer, 2 * length);
123.398 + }
123.399 +
123.400 +
123.401 +
123.402 + template <typename Value,
123.403 + bool sign = std::numeric_limits<Value>::is_signed >
123.404 + struct StableRadixSortSelector {
123.405 + template <typename Iterator, typename Functor>
123.406 + static void sort(Iterator first, Iterator last, Functor functor) {
123.407 + stableRadixSignedSort<Value>(first, last, functor);
123.408 + }
123.409 + };
123.410 +
123.411 + template <typename Value>
123.412 + struct StableRadixSortSelector<Value, false> {
123.413 + template <typename Iterator, typename Functor>
123.414 + static void sort(Iterator first, Iterator last, Functor functor) {
123.415 + stableRadixUnsignedSort<Value>(first, last, functor);
123.416 + }
123.417 + };
123.418 +
123.419 + }
123.420 +
123.421 + /// \ingroup auxalg
123.422 + ///
123.423 + /// \brief Sorts the STL compatible range into ascending order in a stable
123.424 + /// way.
123.425 + ///
123.426 + /// This function sorts an STL compatible range into ascending
123.427 + /// order according to an integer mapping in the same as radixSort() does.
123.428 + ///
123.429 + /// This sorting algorithm is stable, i.e. the order of two equal
123.430 + /// elements remains the same after the sorting.
123.431 + ///
123.432 + /// This sort algorithm use a radix forward sort on the
123.433 + /// bytes of the integer number. The algorithm sorts the items
123.434 + /// byte-by-byte. First, it counts how many times a byte value occurs
123.435 + /// in the container, then it copies the corresponding items to
123.436 + /// another container in asceding order in O(n) time.
123.437 + ///
123.438 + /// The time complexity of the algorithm is O(log(c)*n) and
123.439 + /// it uses O(n) additional space, where \c c is the
123.440 + /// maximal value and \c n is the number of the items in the
123.441 + /// container.
123.442 + ///
123.443 +
123.444 + /// \param first The begin of the given range.
123.445 + /// \param last The end of the given range.
123.446 + /// \param functor An adaptible unary function or a normal function
123.447 + /// which maps the items to any integer type which can be either
123.448 + /// signed or unsigned.
123.449 + /// \sa radixSort()
123.450 + template <typename Iterator, typename Functor>
123.451 + void stableRadixSort(Iterator first, Iterator last, Functor functor) {
123.452 + using namespace _radix_sort_bits;
123.453 + typedef typename Functor::result_type Value;
123.454 + StableRadixSortSelector<Value>::sort(first, last, functor);
123.455 + }
123.456 +
123.457 + template <typename Iterator, typename Value, typename Key>
123.458 + void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
123.459 + using namespace _radix_sort_bits;
123.460 + StableRadixSortSelector<Value>::sort(first, last, functor);
123.461 + }
123.462 +
123.463 + template <typename Iterator, typename Value, typename Key>
123.464 + void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
123.465 + using namespace _radix_sort_bits;
123.466 + StableRadixSortSelector<Value>::sort(first, last, functor);
123.467 + }
123.468 +
123.469 + template <typename Iterator, typename Value, typename Key>
123.470 + void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
123.471 + using namespace _radix_sort_bits;
123.472 + StableRadixSortSelector<Value>::sort(first, last, functor);
123.473 + }
123.474 +
123.475 + template <typename Iterator, typename Value, typename Key>
123.476 + void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
123.477 + using namespace _radix_sort_bits;
123.478 + StableRadixSortSelector<Value>::sort(first, last, functor);
123.479 + }
123.480 +
123.481 + template <typename Iterator>
123.482 + void stableRadixSort(Iterator first, Iterator last) {
123.483 + using namespace _radix_sort_bits;
123.484 + typedef typename std::iterator_traits<Iterator>::value_type Value;
123.485 + StableRadixSortSelector<Value>::sort(first, last, Identity<Value>());
123.486 + }
123.487 +
123.488 +}
123.489 +
123.490 +#endif
124.1 --- a/lemon/random.cc Fri Nov 13 12:33:33 2009 +0100
124.2 +++ b/lemon/random.cc Thu Dec 10 17:05:35 2009 +0100
124.3 @@ -2,7 +2,7 @@
124.4 *
124.5 * This file is a part of LEMON, a generic C++ optimization library.
124.6 *
124.7 - * Copyright (C) 2003-2008
124.8 + * Copyright (C) 2003-2009
124.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
124.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
124.11 *
125.1 --- a/lemon/random.h Fri Nov 13 12:33:33 2009 +0100
125.2 +++ b/lemon/random.h Thu Dec 10 17:05:35 2009 +0100
125.3 @@ -2,7 +2,7 @@
125.4 *
125.5 * This file is a part of LEMON, a generic C++ optimization library.
125.6 *
125.7 - * Copyright (C) 2003-2008
125.8 + * Copyright (C) 2003-2009
125.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
125.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
125.11 *
125.12 @@ -530,10 +530,6 @@
125.13 ///
125.14 /// @{
125.15
125.16 - ///\name Initialization
125.17 - ///
125.18 - /// @{
125.19 -
125.20 /// \brief Default constructor
125.21 ///
125.22 /// Constructor with constant seeding.
125.23 @@ -607,7 +603,7 @@
125.24 /// By default, this function calls the \c seedFromFile() member
125.25 /// function with the <tt>/dev/urandom</tt> file. If it does not success,
125.26 /// it uses the \c seedFromTime().
125.27 - /// \return Currently always true.
125.28 + /// \return Currently always \c true.
125.29 bool seed() {
125.30 #ifndef WIN32
125.31 if (seedFromFile("/dev/urandom", 0)) return true;
125.32 @@ -628,7 +624,7 @@
125.33 /// entropy).
125.34 /// \param file The source file
125.35 /// \param offset The offset, from the file read.
125.36 - /// \return True when the seeding successes.
125.37 + /// \return \c true when the seeding successes.
125.38 #ifndef WIN32
125.39 bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
125.40 #else
125.41 @@ -649,7 +645,7 @@
125.42 /// Seding from process id and time. This function uses the
125.43 /// current process id and the current time for initialize the
125.44 /// random sequence.
125.45 - /// \return Currently always true.
125.46 + /// \return Currently always \c true.
125.47 bool seedFromTime() {
125.48 #ifndef WIN32
125.49 timeval tv;
125.50 @@ -663,7 +659,7 @@
125.51
125.52 /// @}
125.53
125.54 - ///\name Uniform distributions
125.55 + ///\name Uniform Distributions
125.56 ///
125.57 /// @{
125.58
125.59 @@ -680,12 +676,6 @@
125.60 return real<double>();
125.61 }
125.62
125.63 - /// @}
125.64 -
125.65 - ///\name Uniform distributions
125.66 - ///
125.67 - /// @{
125.68 -
125.69 /// \brief Returns a random real number from the range [0, 1)
125.70 ///
125.71 /// It returns a random double from the range [0, 1).
125.72 @@ -741,8 +731,6 @@
125.73 return _random_bits::IntConversion<Number, Word>::convert(core);
125.74 }
125.75
125.76 - /// @}
125.77 -
125.78 unsigned int uinteger() {
125.79 return uinteger<unsigned int>();
125.80 }
125.81 @@ -774,21 +762,20 @@
125.82
125.83 /// @}
125.84
125.85 - ///\name Non-uniform distributions
125.86 + ///\name Non-uniform Distributions
125.87 ///
125.88 -
125.89 ///@{
125.90
125.91 - /// \brief Returns a random bool
125.92 + /// \brief Returns a random bool with given probability of true result.
125.93 ///
125.94 /// It returns a random bool with given probability of true result.
125.95 bool boolean(double p) {
125.96 return operator()() < p;
125.97 }
125.98
125.99 - /// Standard Gauss distribution
125.100 + /// Standard normal (Gauss) distribution
125.101
125.102 - /// Standard Gauss distribution.
125.103 + /// Standard normal (Gauss) distribution.
125.104 /// \note The Cartesian form of the Box-Muller
125.105 /// transformation is used to generate a random normal distribution.
125.106 double gauss()
125.107 @@ -801,15 +788,55 @@
125.108 } while(S>=1);
125.109 return std::sqrt(-2*std::log(S)/S)*V1;
125.110 }
125.111 - /// Gauss distribution with given mean and standard deviation
125.112 + /// Normal (Gauss) distribution with given mean and standard deviation
125.113
125.114 - /// Gauss distribution with given mean and standard deviation.
125.115 + /// Normal (Gauss) distribution with given mean and standard deviation.
125.116 /// \sa gauss()
125.117 double gauss(double mean,double std_dev)
125.118 {
125.119 return gauss()*std_dev+mean;
125.120 }
125.121
125.122 + /// Lognormal distribution
125.123 +
125.124 + /// Lognormal distribution. The parameters are the mean and the standard
125.125 + /// deviation of <tt>exp(X)</tt>.
125.126 + ///
125.127 + double lognormal(double n_mean,double n_std_dev)
125.128 + {
125.129 + return std::exp(gauss(n_mean,n_std_dev));
125.130 + }
125.131 + /// Lognormal distribution
125.132 +
125.133 + /// Lognormal distribution. The parameter is an <tt>std::pair</tt> of
125.134 + /// the mean and the standard deviation of <tt>exp(X)</tt>.
125.135 + ///
125.136 + double lognormal(const std::pair<double,double> ¶ms)
125.137 + {
125.138 + return std::exp(gauss(params.first,params.second));
125.139 + }
125.140 + /// Compute the lognormal parameters from mean and standard deviation
125.141 +
125.142 + /// This function computes the lognormal parameters from mean and
125.143 + /// standard deviation. The return value can direcly be passed to
125.144 + /// lognormal().
125.145 + std::pair<double,double> lognormalParamsFromMD(double mean,
125.146 + double std_dev)
125.147 + {
125.148 + double fr=std_dev/mean;
125.149 + fr*=fr;
125.150 + double lg=std::log(1+fr);
125.151 + return std::pair<double,double>(std::log(mean)-lg/2.0,std::sqrt(lg));
125.152 + }
125.153 + /// Lognormal distribution with given mean and standard deviation
125.154 +
125.155 + /// Lognormal distribution with given mean and standard deviation.
125.156 + ///
125.157 + double lognormalMD(double mean,double std_dev)
125.158 + {
125.159 + return lognormal(lognormalParamsFromMD(mean,std_dev));
125.160 + }
125.161 +
125.162 /// Exponential distribution with given mean
125.163
125.164 /// This function generates an exponential distribution random number
125.165 @@ -911,9 +938,8 @@
125.166
125.167 ///@}
125.168
125.169 - ///\name Two dimensional distributions
125.170 + ///\name Two Dimensional Distributions
125.171 ///
125.172 -
125.173 ///@{
125.174
125.175 /// Uniform distribution on the full unit circle
125.176 @@ -930,7 +956,7 @@
125.177 } while(V1*V1+V2*V2>=1);
125.178 return dim2::Point<double>(V1,V2);
125.179 }
125.180 - /// A kind of two dimensional Gauss distribution
125.181 + /// A kind of two dimensional normal (Gauss) distribution
125.182
125.183 /// This function provides a turning symmetric two-dimensional distribution.
125.184 /// Both coordinates are of standard normal distribution, but they are not
126.1 --- a/lemon/smart_graph.h Fri Nov 13 12:33:33 2009 +0100
126.2 +++ b/lemon/smart_graph.h Thu Dec 10 17:05:35 2009 +0100
126.3 @@ -2,7 +2,7 @@
126.4 *
126.5 * This file is a part of LEMON, a generic C++ optimization library.
126.6 *
126.7 - * Copyright (C) 2003-2008
126.8 + * Copyright (C) 2003-2009
126.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
126.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
126.11 *
126.12 @@ -55,7 +55,7 @@
126.13
126.14 public:
126.15
126.16 - typedef SmartDigraphBase Graph;
126.17 + typedef SmartDigraphBase Digraph;
126.18
126.19 class Node;
126.20 class Arc;
126.21 @@ -67,7 +67,7 @@
126.22 : nodes(_g.nodes), arcs(_g.arcs) { }
126.23
126.24 typedef True NodeNumTag;
126.25 - typedef True EdgeNumTag;
126.26 + typedef True ArcNumTag;
126.27
126.28 int nodeNum() const { return nodes.size(); }
126.29 int arcNum() const { return arcs.size(); }
126.30 @@ -191,14 +191,10 @@
126.31 ///It is also quite memory efficient, but at the price
126.32 ///that <b> it does support only limited (only stack-like)
126.33 ///node and arc deletions</b>.
126.34 - ///It conforms to the \ref concepts::Digraph "Digraph concept" with
126.35 - ///an important extra feature that its maps are real \ref
126.36 - ///concepts::ReferenceMap "reference map"s.
126.37 + ///It fully conforms to the \ref concepts::Digraph "Digraph concept".
126.38 ///
126.39 ///\sa concepts::Digraph.
126.40 class SmartDigraph : public ExtendedSmartDigraphBase {
126.41 - public:
126.42 -
126.43 typedef ExtendedSmartDigraphBase Parent;
126.44
126.45 private:
126.46 @@ -225,15 +221,15 @@
126.47
126.48 ///Add a new node to the digraph.
126.49
126.50 - /// \return the new node.
126.51 - ///
126.52 + /// Add a new node to the digraph.
126.53 + /// \return The new node.
126.54 Node addNode() { return Parent::addNode(); }
126.55
126.56 ///Add a new arc to the digraph.
126.57
126.58 ///Add a new arc to the digraph with source node \c s
126.59 ///and target node \c t.
126.60 - ///\return the new arc.
126.61 + ///\return The new arc.
126.62 Arc addArc(const Node& s, const Node& t) {
126.63 return Parent::addArc(s, t);
126.64 }
126.65 @@ -305,7 +301,9 @@
126.66 Node b = addNode();
126.67 nodes[b._id].first_out=nodes[n._id].first_out;
126.68 nodes[n._id].first_out=-1;
126.69 - for(int i=nodes[b._id].first_out;i!=-1;i++) arcs[i].source=b._id;
126.70 + for(int i=nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) {
126.71 + arcs[i].source=b._id;
126.72 + }
126.73 if(connect) addArc(n,b);
126.74 return b;
126.75 }
126.76 @@ -420,7 +418,7 @@
126.77
126.78 public:
126.79
126.80 - typedef SmartGraphBase Digraph;
126.81 + typedef SmartGraphBase Graph;
126.82
126.83 class Node;
126.84 class Arc;
126.85 @@ -464,8 +462,8 @@
126.86 explicit Arc(int id) { _id = id;}
126.87
126.88 public:
126.89 - operator Edge() const {
126.90 - return _id != -1 ? edgeFromId(_id / 2) : INVALID;
126.91 + operator Edge() const {
126.92 + return _id != -1 ? edgeFromId(_id / 2) : INVALID;
126.93 }
126.94
126.95 Arc() {}
126.96 @@ -480,6 +478,13 @@
126.97 SmartGraphBase()
126.98 : nodes(), arcs() {}
126.99
126.100 + typedef True NodeNumTag;
126.101 + typedef True EdgeNumTag;
126.102 + typedef True ArcNumTag;
126.103 +
126.104 + int nodeNum() const { return nodes.size(); }
126.105 + int edgeNum() const { return arcs.size() / 2; }
126.106 + int arcNum() const { return arcs.size(); }
126.107
126.108 int maxNodeId() const { return nodes.size()-1; }
126.109 int maxEdgeId() const { return arcs.size() / 2 - 1; }
126.110 @@ -620,16 +625,12 @@
126.111 /// It is also quite memory efficient, but at the price
126.112 /// that <b> it does support only limited (only stack-like)
126.113 /// node and arc deletions</b>.
126.114 - /// Except from this it conforms to
126.115 - /// the \ref concepts::Graph "Graph concept".
126.116 - ///
126.117 - /// It also has an
126.118 - /// important extra feature that
126.119 - /// its maps are real \ref concepts::ReferenceMap "reference map"s.
126.120 + /// It fully conforms to the \ref concepts::Graph "Graph concept".
126.121 ///
126.122 /// \sa concepts::Graph.
126.123 - ///
126.124 class SmartGraph : public ExtendedSmartGraphBase {
126.125 + typedef ExtendedSmartGraphBase Parent;
126.126 +
126.127 private:
126.128
126.129 ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
126.130 @@ -647,8 +648,6 @@
126.131
126.132 public:
126.133
126.134 - typedef ExtendedSmartGraphBase Parent;
126.135 -
126.136 /// Constructor
126.137
126.138 /// Constructor.
126.139 @@ -657,15 +656,15 @@
126.140
126.141 ///Add a new node to the graph.
126.142
126.143 - /// \return the new node.
126.144 - ///
126.145 + /// Add a new node to the graph.
126.146 + /// \return The new node.
126.147 Node addNode() { return Parent::addNode(); }
126.148
126.149 ///Add a new edge to the graph.
126.150
126.151 ///Add a new edge to the graph with node \c s
126.152 ///and \c t.
126.153 - ///\return the new edge.
126.154 + ///\return The new edge.
126.155 Edge addEdge(const Node& s, const Node& t) {
126.156 return Parent::addEdge(s, t);
126.157 }
126.158 @@ -728,8 +727,8 @@
126.159 dir.push_back(arcFromId(n));
126.160 dir.push_back(arcFromId(n-1));
126.161 Parent::notifier(Arc()).erase(dir);
126.162 - nodes[arcs[n].target].first_out=arcs[n].next_out;
126.163 - nodes[arcs[n-1].target].first_out=arcs[n-1].next_out;
126.164 + nodes[arcs[n-1].target].first_out=arcs[n].next_out;
126.165 + nodes[arcs[n].target].first_out=arcs[n-1].next_out;
126.166 arcs.pop_back();
126.167 arcs.pop_back();
126.168 }
127.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
127.2 +++ b/lemon/soplex.cc Thu Dec 10 17:05:35 2009 +0100
127.3 @@ -0,0 +1,452 @@
127.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
127.5 + *
127.6 + * This file is a part of LEMON, a generic C++ optimization library.
127.7 + *
127.8 + * Copyright (C) 2003-2008
127.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
127.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
127.11 + *
127.12 + * Permission to use, modify and distribute this software is granted
127.13 + * provided that this copyright notice appears in all copies. For
127.14 + * precise terms see the accompanying LICENSE file.
127.15 + *
127.16 + * This software is provided "AS IS" with no warranty of any kind,
127.17 + * express or implied, and with no claim as to its suitability for any
127.18 + * purpose.
127.19 + *
127.20 + */
127.21 +
127.22 +#include <iostream>
127.23 +#include <lemon/soplex.h>
127.24 +
127.25 +#include <soplex.h>
127.26 +#include <spxout.h>
127.27 +
127.28 +
127.29 +///\file
127.30 +///\brief Implementation of the LEMON-SOPLEX lp solver interface.
127.31 +namespace lemon {
127.32 +
127.33 + SoplexLp::SoplexLp() {
127.34 + soplex = new soplex::SoPlex;
127.35 + messageLevel(MESSAGE_NOTHING);
127.36 + }
127.37 +
127.38 + SoplexLp::~SoplexLp() {
127.39 + delete soplex;
127.40 + }
127.41 +
127.42 + SoplexLp::SoplexLp(const SoplexLp& lp) {
127.43 + rows = lp.rows;
127.44 + cols = lp.cols;
127.45 +
127.46 + soplex = new soplex::SoPlex;
127.47 + (*static_cast<soplex::SPxLP*>(soplex)) = *(lp.soplex);
127.48 +
127.49 + _col_names = lp._col_names;
127.50 + _col_names_ref = lp._col_names_ref;
127.51 +
127.52 + _row_names = lp._row_names;
127.53 + _row_names_ref = lp._row_names_ref;
127.54 +
127.55 + messageLevel(MESSAGE_NOTHING);
127.56 + }
127.57 +
127.58 + void SoplexLp::_clear_temporals() {
127.59 + _primal_values.clear();
127.60 + _dual_values.clear();
127.61 + }
127.62 +
127.63 + SoplexLp* SoplexLp::newSolver() const {
127.64 + SoplexLp* newlp = new SoplexLp();
127.65 + return newlp;
127.66 + }
127.67 +
127.68 + SoplexLp* SoplexLp::cloneSolver() const {
127.69 + SoplexLp* newlp = new SoplexLp(*this);
127.70 + return newlp;
127.71 + }
127.72 +
127.73 + const char* SoplexLp::_solverName() const { return "SoplexLp"; }
127.74 +
127.75 + int SoplexLp::_addCol() {
127.76 + soplex::LPCol c;
127.77 + c.setLower(-soplex::infinity);
127.78 + c.setUpper(soplex::infinity);
127.79 + soplex->addCol(c);
127.80 +
127.81 + _col_names.push_back(std::string());
127.82 +
127.83 + return soplex->nCols() - 1;
127.84 + }
127.85 +
127.86 + int SoplexLp::_addRow() {
127.87 + soplex::LPRow r;
127.88 + r.setLhs(-soplex::infinity);
127.89 + r.setRhs(soplex::infinity);
127.90 + soplex->addRow(r);
127.91 +
127.92 + _row_names.push_back(std::string());
127.93 +
127.94 + return soplex->nRows() - 1;
127.95 + }
127.96 +
127.97 +
127.98 + void SoplexLp::_eraseCol(int i) {
127.99 + soplex->removeCol(i);
127.100 + _col_names_ref.erase(_col_names[i]);
127.101 + _col_names[i] = _col_names.back();
127.102 + _col_names_ref[_col_names.back()] = i;
127.103 + _col_names.pop_back();
127.104 + }
127.105 +
127.106 + void SoplexLp::_eraseRow(int i) {
127.107 + soplex->removeRow(i);
127.108 + _row_names_ref.erase(_row_names[i]);
127.109 + _row_names[i] = _row_names.back();
127.110 + _row_names_ref[_row_names.back()] = i;
127.111 + _row_names.pop_back();
127.112 + }
127.113 +
127.114 + void SoplexLp::_eraseColId(int i) {
127.115 + cols.eraseIndex(i);
127.116 + cols.relocateIndex(i, cols.maxIndex());
127.117 + }
127.118 + void SoplexLp::_eraseRowId(int i) {
127.119 + rows.eraseIndex(i);
127.120 + rows.relocateIndex(i, rows.maxIndex());
127.121 + }
127.122 +
127.123 + void SoplexLp::_getColName(int c, std::string &name) const {
127.124 + name = _col_names[c];
127.125 + }
127.126 +
127.127 + void SoplexLp::_setColName(int c, const std::string &name) {
127.128 + _col_names_ref.erase(_col_names[c]);
127.129 + _col_names[c] = name;
127.130 + if (!name.empty()) {
127.131 + _col_names_ref.insert(std::make_pair(name, c));
127.132 + }
127.133 + }
127.134 +
127.135 + int SoplexLp::_colByName(const std::string& name) const {
127.136 + std::map<std::string, int>::const_iterator it =
127.137 + _col_names_ref.find(name);
127.138 + if (it != _col_names_ref.end()) {
127.139 + return it->second;
127.140 + } else {
127.141 + return -1;
127.142 + }
127.143 + }
127.144 +
127.145 + void SoplexLp::_getRowName(int r, std::string &name) const {
127.146 + name = _row_names[r];
127.147 + }
127.148 +
127.149 + void SoplexLp::_setRowName(int r, const std::string &name) {
127.150 + _row_names_ref.erase(_row_names[r]);
127.151 + _row_names[r] = name;
127.152 + if (!name.empty()) {
127.153 + _row_names_ref.insert(std::make_pair(name, r));
127.154 + }
127.155 + }
127.156 +
127.157 + int SoplexLp::_rowByName(const std::string& name) const {
127.158 + std::map<std::string, int>::const_iterator it =
127.159 + _row_names_ref.find(name);
127.160 + if (it != _row_names_ref.end()) {
127.161 + return it->second;
127.162 + } else {
127.163 + return -1;
127.164 + }
127.165 + }
127.166 +
127.167 +
127.168 + void SoplexLp::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
127.169 + for (int j = 0; j < soplex->nCols(); ++j) {
127.170 + soplex->changeElement(i, j, 0.0);
127.171 + }
127.172 + for(ExprIterator it = b; it != e; ++it) {
127.173 + soplex->changeElement(i, it->first, it->second);
127.174 + }
127.175 + }
127.176 +
127.177 + void SoplexLp::_getRowCoeffs(int i, InsertIterator b) const {
127.178 + const soplex::SVector& vec = soplex->rowVector(i);
127.179 + for (int k = 0; k < vec.size(); ++k) {
127.180 + *b = std::make_pair(vec.index(k), vec.value(k));
127.181 + ++b;
127.182 + }
127.183 + }
127.184 +
127.185 + void SoplexLp::_setColCoeffs(int j, ExprIterator b, ExprIterator e) {
127.186 + for (int i = 0; i < soplex->nRows(); ++i) {
127.187 + soplex->changeElement(i, j, 0.0);
127.188 + }
127.189 + for(ExprIterator it = b; it != e; ++it) {
127.190 + soplex->changeElement(it->first, j, it->second);
127.191 + }
127.192 + }
127.193 +
127.194 + void SoplexLp::_getColCoeffs(int i, InsertIterator b) const {
127.195 + const soplex::SVector& vec = soplex->colVector(i);
127.196 + for (int k = 0; k < vec.size(); ++k) {
127.197 + *b = std::make_pair(vec.index(k), vec.value(k));
127.198 + ++b;
127.199 + }
127.200 + }
127.201 +
127.202 + void SoplexLp::_setCoeff(int i, int j, Value value) {
127.203 + soplex->changeElement(i, j, value);
127.204 + }
127.205 +
127.206 + SoplexLp::Value SoplexLp::_getCoeff(int i, int j) const {
127.207 + return soplex->rowVector(i)[j];
127.208 + }
127.209 +
127.210 + void SoplexLp::_setColLowerBound(int i, Value value) {
127.211 + LEMON_ASSERT(value != INF, "Invalid bound");
127.212 + soplex->changeLower(i, value != -INF ? value : -soplex::infinity);
127.213 + }
127.214 +
127.215 + SoplexLp::Value SoplexLp::_getColLowerBound(int i) const {
127.216 + double value = soplex->lower(i);
127.217 + return value != -soplex::infinity ? value : -INF;
127.218 + }
127.219 +
127.220 + void SoplexLp::_setColUpperBound(int i, Value value) {
127.221 + LEMON_ASSERT(value != -INF, "Invalid bound");
127.222 + soplex->changeUpper(i, value != INF ? value : soplex::infinity);
127.223 + }
127.224 +
127.225 + SoplexLp::Value SoplexLp::_getColUpperBound(int i) const {
127.226 + double value = soplex->upper(i);
127.227 + return value != soplex::infinity ? value : INF;
127.228 + }
127.229 +
127.230 + void SoplexLp::_setRowLowerBound(int i, Value lb) {
127.231 + LEMON_ASSERT(lb != INF, "Invalid bound");
127.232 + soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity, soplex->rhs(i));
127.233 + }
127.234 +
127.235 + SoplexLp::Value SoplexLp::_getRowLowerBound(int i) const {
127.236 + double res = soplex->lhs(i);
127.237 + return res == -soplex::infinity ? -INF : res;
127.238 + }
127.239 +
127.240 + void SoplexLp::_setRowUpperBound(int i, Value ub) {
127.241 + LEMON_ASSERT(ub != -INF, "Invalid bound");
127.242 + soplex->changeRange(i, soplex->lhs(i), ub != INF ? ub : soplex::infinity);
127.243 + }
127.244 +
127.245 + SoplexLp::Value SoplexLp::_getRowUpperBound(int i) const {
127.246 + double res = soplex->rhs(i);
127.247 + return res == soplex::infinity ? INF : res;
127.248 + }
127.249 +
127.250 + void SoplexLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
127.251 + for (int j = 0; j < soplex->nCols(); ++j) {
127.252 + soplex->changeObj(j, 0.0);
127.253 + }
127.254 + for (ExprIterator it = b; it != e; ++it) {
127.255 + soplex->changeObj(it->first, it->second);
127.256 + }
127.257 + }
127.258 +
127.259 + void SoplexLp::_getObjCoeffs(InsertIterator b) const {
127.260 + for (int j = 0; j < soplex->nCols(); ++j) {
127.261 + Value coef = soplex->obj(j);
127.262 + if (coef != 0.0) {
127.263 + *b = std::make_pair(j, coef);
127.264 + ++b;
127.265 + }
127.266 + }
127.267 + }
127.268 +
127.269 + void SoplexLp::_setObjCoeff(int i, Value obj_coef) {
127.270 + soplex->changeObj(i, obj_coef);
127.271 + }
127.272 +
127.273 + SoplexLp::Value SoplexLp::_getObjCoeff(int i) const {
127.274 + return soplex->obj(i);
127.275 + }
127.276 +
127.277 + SoplexLp::SolveExitStatus SoplexLp::_solve() {
127.278 +
127.279 + _clear_temporals();
127.280 +
127.281 + _applyMessageLevel();
127.282 +
127.283 + soplex::SPxSolver::Status status = soplex->solve();
127.284 +
127.285 + switch (status) {
127.286 + case soplex::SPxSolver::OPTIMAL:
127.287 + case soplex::SPxSolver::INFEASIBLE:
127.288 + case soplex::SPxSolver::UNBOUNDED:
127.289 + return SOLVED;
127.290 + default:
127.291 + return UNSOLVED;
127.292 + }
127.293 + }
127.294 +
127.295 + SoplexLp::Value SoplexLp::_getPrimal(int i) const {
127.296 + if (_primal_values.empty()) {
127.297 + _primal_values.resize(soplex->nCols());
127.298 + soplex::Vector pv(_primal_values.size(), &_primal_values.front());
127.299 + soplex->getPrimal(pv);
127.300 + }
127.301 + return _primal_values[i];
127.302 + }
127.303 +
127.304 + SoplexLp::Value SoplexLp::_getDual(int i) const {
127.305 + if (_dual_values.empty()) {
127.306 + _dual_values.resize(soplex->nRows());
127.307 + soplex::Vector dv(_dual_values.size(), &_dual_values.front());
127.308 + soplex->getDual(dv);
127.309 + }
127.310 + return _dual_values[i];
127.311 + }
127.312 +
127.313 + SoplexLp::Value SoplexLp::_getPrimalValue() const {
127.314 + return soplex->objValue();
127.315 + }
127.316 +
127.317 + SoplexLp::VarStatus SoplexLp::_getColStatus(int i) const {
127.318 + switch (soplex->getBasisColStatus(i)) {
127.319 + case soplex::SPxSolver::BASIC:
127.320 + return BASIC;
127.321 + case soplex::SPxSolver::ON_UPPER:
127.322 + return UPPER;
127.323 + case soplex::SPxSolver::ON_LOWER:
127.324 + return LOWER;
127.325 + case soplex::SPxSolver::FIXED:
127.326 + return FIXED;
127.327 + case soplex::SPxSolver::ZERO:
127.328 + return FREE;
127.329 + default:
127.330 + LEMON_ASSERT(false, "Wrong column status");
127.331 + return VarStatus();
127.332 + }
127.333 + }
127.334 +
127.335 + SoplexLp::VarStatus SoplexLp::_getRowStatus(int i) const {
127.336 + switch (soplex->getBasisRowStatus(i)) {
127.337 + case soplex::SPxSolver::BASIC:
127.338 + return BASIC;
127.339 + case soplex::SPxSolver::ON_UPPER:
127.340 + return UPPER;
127.341 + case soplex::SPxSolver::ON_LOWER:
127.342 + return LOWER;
127.343 + case soplex::SPxSolver::FIXED:
127.344 + return FIXED;
127.345 + case soplex::SPxSolver::ZERO:
127.346 + return FREE;
127.347 + default:
127.348 + LEMON_ASSERT(false, "Wrong row status");
127.349 + return VarStatus();
127.350 + }
127.351 + }
127.352 +
127.353 + SoplexLp::Value SoplexLp::_getPrimalRay(int i) const {
127.354 + if (_primal_ray.empty()) {
127.355 + _primal_ray.resize(soplex->nCols());
127.356 + soplex::Vector pv(_primal_ray.size(), &_primal_ray.front());
127.357 + soplex->getDualfarkas(pv);
127.358 + }
127.359 + return _primal_ray[i];
127.360 + }
127.361 +
127.362 + SoplexLp::Value SoplexLp::_getDualRay(int i) const {
127.363 + if (_dual_ray.empty()) {
127.364 + _dual_ray.resize(soplex->nRows());
127.365 + soplex::Vector dv(_dual_ray.size(), &_dual_ray.front());
127.366 + soplex->getDualfarkas(dv);
127.367 + }
127.368 + return _dual_ray[i];
127.369 + }
127.370 +
127.371 + SoplexLp::ProblemType SoplexLp::_getPrimalType() const {
127.372 + switch (soplex->status()) {
127.373 + case soplex::SPxSolver::OPTIMAL:
127.374 + return OPTIMAL;
127.375 + case soplex::SPxSolver::UNBOUNDED:
127.376 + return UNBOUNDED;
127.377 + case soplex::SPxSolver::INFEASIBLE:
127.378 + return INFEASIBLE;
127.379 + default:
127.380 + return UNDEFINED;
127.381 + }
127.382 + }
127.383 +
127.384 + SoplexLp::ProblemType SoplexLp::_getDualType() const {
127.385 + switch (soplex->status()) {
127.386 + case soplex::SPxSolver::OPTIMAL:
127.387 + return OPTIMAL;
127.388 + case soplex::SPxSolver::UNBOUNDED:
127.389 + return UNBOUNDED;
127.390 + case soplex::SPxSolver::INFEASIBLE:
127.391 + return INFEASIBLE;
127.392 + default:
127.393 + return UNDEFINED;
127.394 + }
127.395 + }
127.396 +
127.397 + void SoplexLp::_setSense(Sense sense) {
127.398 + switch (sense) {
127.399 + case MIN:
127.400 + soplex->changeSense(soplex::SPxSolver::MINIMIZE);
127.401 + break;
127.402 + case MAX:
127.403 + soplex->changeSense(soplex::SPxSolver::MAXIMIZE);
127.404 + }
127.405 + }
127.406 +
127.407 + SoplexLp::Sense SoplexLp::_getSense() const {
127.408 + switch (soplex->spxSense()) {
127.409 + case soplex::SPxSolver::MAXIMIZE:
127.410 + return MAX;
127.411 + case soplex::SPxSolver::MINIMIZE:
127.412 + return MIN;
127.413 + default:
127.414 + LEMON_ASSERT(false, "Wrong sense.");
127.415 + return SoplexLp::Sense();
127.416 + }
127.417 + }
127.418 +
127.419 + void SoplexLp::_clear() {
127.420 + soplex->clear();
127.421 + _col_names.clear();
127.422 + _col_names_ref.clear();
127.423 + _row_names.clear();
127.424 + _row_names_ref.clear();
127.425 + cols.clear();
127.426 + rows.clear();
127.427 + _clear_temporals();
127.428 + }
127.429 +
127.430 + void SoplexLp::_messageLevel(MessageLevel level) {
127.431 + switch (level) {
127.432 + case MESSAGE_NOTHING:
127.433 + _message_level = -1;
127.434 + break;
127.435 + case MESSAGE_ERROR:
127.436 + _message_level = soplex::SPxOut::ERROR;
127.437 + break;
127.438 + case MESSAGE_WARNING:
127.439 + _message_level = soplex::SPxOut::WARNING;
127.440 + break;
127.441 + case MESSAGE_NORMAL:
127.442 + _message_level = soplex::SPxOut::INFO2;
127.443 + break;
127.444 + case MESSAGE_VERBOSE:
127.445 + _message_level = soplex::SPxOut::DEBUG;
127.446 + break;
127.447 + }
127.448 + }
127.449 +
127.450 + void SoplexLp::_applyMessageLevel() {
127.451 + soplex::Param::setVerbose(_message_level);
127.452 + }
127.453 +
127.454 +} //namespace lemon
127.455 +
128.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
128.2 +++ b/lemon/soplex.h Thu Dec 10 17:05:35 2009 +0100
128.3 @@ -0,0 +1,157 @@
128.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
128.5 + *
128.6 + * This file is a part of LEMON, a generic C++ optimization library.
128.7 + *
128.8 + * Copyright (C) 2003-2008
128.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
128.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
128.11 + *
128.12 + * Permission to use, modify and distribute this software is granted
128.13 + * provided that this copyright notice appears in all copies. For
128.14 + * precise terms see the accompanying LICENSE file.
128.15 + *
128.16 + * This software is provided "AS IS" with no warranty of any kind,
128.17 + * express or implied, and with no claim as to its suitability for any
128.18 + * purpose.
128.19 + *
128.20 + */
128.21 +
128.22 +#ifndef LEMON_SOPLEX_H
128.23 +#define LEMON_SOPLEX_H
128.24 +
128.25 +///\file
128.26 +///\brief Header of the LEMON-SOPLEX lp solver interface.
128.27 +
128.28 +#include <vector>
128.29 +#include <string>
128.30 +
128.31 +#include <lemon/lp_base.h>
128.32 +
128.33 +// Forward declaration
128.34 +namespace soplex {
128.35 + class SoPlex;
128.36 +}
128.37 +
128.38 +namespace lemon {
128.39 +
128.40 + /// \ingroup lp_group
128.41 + ///
128.42 + /// \brief Interface for the SOPLEX solver
128.43 + ///
128.44 + /// This class implements an interface for the SoPlex LP solver.
128.45 + /// The SoPlex library is an object oriented lp solver library
128.46 + /// developed at the Konrad-Zuse-Zentrum für Informationstechnik
128.47 + /// Berlin (ZIB). You can find detailed information about it at the
128.48 + /// <tt>http://soplex.zib.de</tt> address.
128.49 + class SoplexLp : public LpSolver {
128.50 + private:
128.51 +
128.52 + soplex::SoPlex* soplex;
128.53 +
128.54 + std::vector<std::string> _col_names;
128.55 + std::map<std::string, int> _col_names_ref;
128.56 +
128.57 + std::vector<std::string> _row_names;
128.58 + std::map<std::string, int> _row_names_ref;
128.59 +
128.60 + private:
128.61 +
128.62 + // these values cannot be retrieved element by element
128.63 + mutable std::vector<Value> _primal_values;
128.64 + mutable std::vector<Value> _dual_values;
128.65 +
128.66 + mutable std::vector<Value> _primal_ray;
128.67 + mutable std::vector<Value> _dual_ray;
128.68 +
128.69 + void _clear_temporals();
128.70 +
128.71 + public:
128.72 +
128.73 + /// \e
128.74 + SoplexLp();
128.75 + /// \e
128.76 + SoplexLp(const SoplexLp&);
128.77 + /// \e
128.78 + ~SoplexLp();
128.79 + /// \e
128.80 + virtual SoplexLp* newSolver() const;
128.81 + /// \e
128.82 + virtual SoplexLp* cloneSolver() const;
128.83 +
128.84 + protected:
128.85 +
128.86 + virtual const char* _solverName() const;
128.87 +
128.88 + virtual int _addCol();
128.89 + virtual int _addRow();
128.90 +
128.91 + virtual void _eraseCol(int i);
128.92 + virtual void _eraseRow(int i);
128.93 +
128.94 + virtual void _eraseColId(int i);
128.95 + virtual void _eraseRowId(int i);
128.96 +
128.97 + virtual void _getColName(int col, std::string& name) const;
128.98 + virtual void _setColName(int col, const std::string& name);
128.99 + virtual int _colByName(const std::string& name) const;
128.100 +
128.101 + virtual void _getRowName(int row, std::string& name) const;
128.102 + virtual void _setRowName(int row, const std::string& name);
128.103 + virtual int _rowByName(const std::string& name) const;
128.104 +
128.105 + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
128.106 + virtual void _getRowCoeffs(int i, InsertIterator b) const;
128.107 +
128.108 + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
128.109 + virtual void _getColCoeffs(int i, InsertIterator b) const;
128.110 +
128.111 + virtual void _setCoeff(int row, int col, Value value);
128.112 + virtual Value _getCoeff(int row, int col) const;
128.113 +
128.114 + virtual void _setColLowerBound(int i, Value value);
128.115 + virtual Value _getColLowerBound(int i) const;
128.116 + virtual void _setColUpperBound(int i, Value value);
128.117 + virtual Value _getColUpperBound(int i) const;
128.118 +
128.119 + virtual void _setRowLowerBound(int i, Value value);
128.120 + virtual Value _getRowLowerBound(int i) const;
128.121 + virtual void _setRowUpperBound(int i, Value value);
128.122 + virtual Value _getRowUpperBound(int i) const;
128.123 +
128.124 + virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
128.125 + virtual void _getObjCoeffs(InsertIterator b) const;
128.126 +
128.127 + virtual void _setObjCoeff(int i, Value obj_coef);
128.128 + virtual Value _getObjCoeff(int i) const;
128.129 +
128.130 + virtual void _setSense(Sense sense);
128.131 + virtual Sense _getSense() const;
128.132 +
128.133 + virtual SolveExitStatus _solve();
128.134 + virtual Value _getPrimal(int i) const;
128.135 + virtual Value _getDual(int i) const;
128.136 +
128.137 + virtual Value _getPrimalValue() const;
128.138 +
128.139 + virtual Value _getPrimalRay(int i) const;
128.140 + virtual Value _getDualRay(int i) const;
128.141 +
128.142 + virtual VarStatus _getColStatus(int i) const;
128.143 + virtual VarStatus _getRowStatus(int i) const;
128.144 +
128.145 + virtual ProblemType _getPrimalType() const;
128.146 + virtual ProblemType _getDualType() const;
128.147 +
128.148 + virtual void _clear();
128.149 +
128.150 + void _messageLevel(MessageLevel m);
128.151 + void _applyMessageLevel();
128.152 +
128.153 + int _message_level;
128.154 +
128.155 + };
128.156 +
128.157 +} //END OF NAMESPACE LEMON
128.158 +
128.159 +#endif //LEMON_SOPLEX_H
128.160 +
129.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
129.2 +++ b/lemon/suurballe.h Thu Dec 10 17:05:35 2009 +0100
129.3 @@ -0,0 +1,535 @@
129.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
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 + */
129.21 +
129.22 +#ifndef LEMON_SUURBALLE_H
129.23 +#define LEMON_SUURBALLE_H
129.24 +
129.25 +///\ingroup shortest_path
129.26 +///\file
129.27 +///\brief An algorithm for finding arc-disjoint paths between two
129.28 +/// nodes having minimum total length.
129.29 +
129.30 +#include <vector>
129.31 +#include <limits>
129.32 +#include <lemon/bin_heap.h>
129.33 +#include <lemon/path.h>
129.34 +#include <lemon/list_graph.h>
129.35 +#include <lemon/maps.h>
129.36 +
129.37 +namespace lemon {
129.38 +
129.39 + /// \addtogroup shortest_path
129.40 + /// @{
129.41 +
129.42 + /// \brief Algorithm for finding arc-disjoint paths between two nodes
129.43 + /// having minimum total length.
129.44 + ///
129.45 + /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
129.46 + /// finding arc-disjoint paths having minimum total length (cost)
129.47 + /// from a given source node to a given target node in a digraph.
129.48 + ///
129.49 + /// Note that this problem is a special case of the \ref min_cost_flow
129.50 + /// "minimum cost flow problem". This implementation is actually an
129.51 + /// efficient specialized version of the \ref CapacityScaling
129.52 + /// "Successive Shortest Path" algorithm directly for this problem.
129.53 + /// Therefore this class provides query functions for flow values and
129.54 + /// node potentials (the dual solution) just like the minimum cost flow
129.55 + /// algorithms.
129.56 + ///
129.57 + /// \tparam GR The digraph type the algorithm runs on.
129.58 + /// \tparam LEN The type of the length map.
129.59 + /// The default value is <tt>GR::ArcMap<int></tt>.
129.60 + ///
129.61 + /// \warning Length values should be \e non-negative \e integers.
129.62 + ///
129.63 + /// \note For finding node-disjoint paths this algorithm can be used
129.64 + /// along with the \ref SplitNodes adaptor.
129.65 +#ifdef DOXYGEN
129.66 + template <typename GR, typename LEN>
129.67 +#else
129.68 + template < typename GR,
129.69 + typename LEN = typename GR::template ArcMap<int> >
129.70 +#endif
129.71 + class Suurballe
129.72 + {
129.73 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
129.74 +
129.75 + typedef ConstMap<Arc, int> ConstArcMap;
129.76 + typedef typename GR::template NodeMap<Arc> PredMap;
129.77 +
129.78 + public:
129.79 +
129.80 + /// The type of the digraph the algorithm runs on.
129.81 + typedef GR Digraph;
129.82 + /// The type of the length map.
129.83 + typedef LEN LengthMap;
129.84 + /// The type of the lengths.
129.85 + typedef typename LengthMap::Value Length;
129.86 +#ifdef DOXYGEN
129.87 + /// The type of the flow map.
129.88 + typedef GR::ArcMap<int> FlowMap;
129.89 + /// The type of the potential map.
129.90 + typedef GR::NodeMap<Length> PotentialMap;
129.91 +#else
129.92 + /// The type of the flow map.
129.93 + typedef typename Digraph::template ArcMap<int> FlowMap;
129.94 + /// The type of the potential map.
129.95 + typedef typename Digraph::template NodeMap<Length> PotentialMap;
129.96 +#endif
129.97 +
129.98 + /// The type of the path structures.
129.99 + typedef SimplePath<GR> Path;
129.100 +
129.101 + private:
129.102 +
129.103 + // ResidualDijkstra is a special implementation of the
129.104 + // Dijkstra algorithm for finding shortest paths in the
129.105 + // residual network with respect to the reduced arc lengths
129.106 + // and modifying the node potentials according to the
129.107 + // distance of the nodes.
129.108 + class ResidualDijkstra
129.109 + {
129.110 + typedef typename Digraph::template NodeMap<int> HeapCrossRef;
129.111 + typedef BinHeap<Length, HeapCrossRef> Heap;
129.112 +
129.113 + private:
129.114 +
129.115 + // The digraph the algorithm runs on
129.116 + const Digraph &_graph;
129.117 +
129.118 + // The main maps
129.119 + const FlowMap &_flow;
129.120 + const LengthMap &_length;
129.121 + PotentialMap &_potential;
129.122 +
129.123 + // The distance map
129.124 + PotentialMap _dist;
129.125 + // The pred arc map
129.126 + PredMap &_pred;
129.127 + // The processed (i.e. permanently labeled) nodes
129.128 + std::vector<Node> _proc_nodes;
129.129 +
129.130 + Node _s;
129.131 + Node _t;
129.132 +
129.133 + public:
129.134 +
129.135 + /// Constructor.
129.136 + ResidualDijkstra( const Digraph &graph,
129.137 + const FlowMap &flow,
129.138 + const LengthMap &length,
129.139 + PotentialMap &potential,
129.140 + PredMap &pred,
129.141 + Node s, Node t ) :
129.142 + _graph(graph), _flow(flow), _length(length), _potential(potential),
129.143 + _dist(graph), _pred(pred), _s(s), _t(t) {}
129.144 +
129.145 + /// \brief Run the algorithm. It returns \c true if a path is found
129.146 + /// from the source node to the target node.
129.147 + bool run() {
129.148 + HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
129.149 + Heap heap(heap_cross_ref);
129.150 + heap.push(_s, 0);
129.151 + _pred[_s] = INVALID;
129.152 + _proc_nodes.clear();
129.153 +
129.154 + // Process nodes
129.155 + while (!heap.empty() && heap.top() != _t) {
129.156 + Node u = heap.top(), v;
129.157 + Length d = heap.prio() + _potential[u], nd;
129.158 + _dist[u] = heap.prio();
129.159 + heap.pop();
129.160 + _proc_nodes.push_back(u);
129.161 +
129.162 + // Traverse outgoing arcs
129.163 + for (OutArcIt e(_graph, u); e != INVALID; ++e) {
129.164 + if (_flow[e] == 0) {
129.165 + v = _graph.target(e);
129.166 + switch(heap.state(v)) {
129.167 + case Heap::PRE_HEAP:
129.168 + heap.push(v, d + _length[e] - _potential[v]);
129.169 + _pred[v] = e;
129.170 + break;
129.171 + case Heap::IN_HEAP:
129.172 + nd = d + _length[e] - _potential[v];
129.173 + if (nd < heap[v]) {
129.174 + heap.decrease(v, nd);
129.175 + _pred[v] = e;
129.176 + }
129.177 + break;
129.178 + case Heap::POST_HEAP:
129.179 + break;
129.180 + }
129.181 + }
129.182 + }
129.183 +
129.184 + // Traverse incoming arcs
129.185 + for (InArcIt e(_graph, u); e != INVALID; ++e) {
129.186 + if (_flow[e] == 1) {
129.187 + v = _graph.source(e);
129.188 + switch(heap.state(v)) {
129.189 + case Heap::PRE_HEAP:
129.190 + heap.push(v, d - _length[e] - _potential[v]);
129.191 + _pred[v] = e;
129.192 + break;
129.193 + case Heap::IN_HEAP:
129.194 + nd = d - _length[e] - _potential[v];
129.195 + if (nd < heap[v]) {
129.196 + heap.decrease(v, nd);
129.197 + _pred[v] = e;
129.198 + }
129.199 + break;
129.200 + case Heap::POST_HEAP:
129.201 + break;
129.202 + }
129.203 + }
129.204 + }
129.205 + }
129.206 + if (heap.empty()) return false;
129.207 +
129.208 + // Update potentials of processed nodes
129.209 + Length t_dist = heap.prio();
129.210 + for (int i = 0; i < int(_proc_nodes.size()); ++i)
129.211 + _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
129.212 + return true;
129.213 + }
129.214 +
129.215 + }; //class ResidualDijkstra
129.216 +
129.217 + private:
129.218 +
129.219 + // The digraph the algorithm runs on
129.220 + const Digraph &_graph;
129.221 + // The length map
129.222 + const LengthMap &_length;
129.223 +
129.224 + // Arc map of the current flow
129.225 + FlowMap *_flow;
129.226 + bool _local_flow;
129.227 + // Node map of the current potentials
129.228 + PotentialMap *_potential;
129.229 + bool _local_potential;
129.230 +
129.231 + // The source node
129.232 + Node _source;
129.233 + // The target node
129.234 + Node _target;
129.235 +
129.236 + // Container to store the found paths
129.237 + std::vector< SimplePath<Digraph> > paths;
129.238 + int _path_num;
129.239 +
129.240 + // The pred arc map
129.241 + PredMap _pred;
129.242 + // Implementation of the Dijkstra algorithm for finding augmenting
129.243 + // shortest paths in the residual network
129.244 + ResidualDijkstra *_dijkstra;
129.245 +
129.246 + public:
129.247 +
129.248 + /// \brief Constructor.
129.249 + ///
129.250 + /// Constructor.
129.251 + ///
129.252 + /// \param graph The digraph the algorithm runs on.
129.253 + /// \param length The length (cost) values of the arcs.
129.254 + Suurballe( const Digraph &graph,
129.255 + const LengthMap &length ) :
129.256 + _graph(graph), _length(length), _flow(0), _local_flow(false),
129.257 + _potential(0), _local_potential(false), _pred(graph)
129.258 + {
129.259 + LEMON_ASSERT(std::numeric_limits<Length>::is_integer,
129.260 + "The length type of Suurballe must be integer");
129.261 + }
129.262 +
129.263 + /// Destructor.
129.264 + ~Suurballe() {
129.265 + if (_local_flow) delete _flow;
129.266 + if (_local_potential) delete _potential;
129.267 + delete _dijkstra;
129.268 + }
129.269 +
129.270 + /// \brief Set the flow map.
129.271 + ///
129.272 + /// This function sets the flow map.
129.273 + /// If it is not used before calling \ref run() or \ref init(),
129.274 + /// an instance will be allocated automatically. The destructor
129.275 + /// deallocates this automatically allocated map, of course.
129.276 + ///
129.277 + /// The found flow contains only 0 and 1 values, since it is the
129.278 + /// union of the found arc-disjoint paths.
129.279 + ///
129.280 + /// \return <tt>(*this)</tt>
129.281 + Suurballe& flowMap(FlowMap &map) {
129.282 + if (_local_flow) {
129.283 + delete _flow;
129.284 + _local_flow = false;
129.285 + }
129.286 + _flow = ↦
129.287 + return *this;
129.288 + }
129.289 +
129.290 + /// \brief Set the potential map.
129.291 + ///
129.292 + /// This function sets the potential map.
129.293 + /// If it is not used before calling \ref run() or \ref init(),
129.294 + /// an instance will be allocated automatically. The destructor
129.295 + /// deallocates this automatically allocated map, of course.
129.296 + ///
129.297 + /// The node potentials provide the dual solution of the underlying
129.298 + /// \ref min_cost_flow "minimum cost flow problem".
129.299 + ///
129.300 + /// \return <tt>(*this)</tt>
129.301 + Suurballe& potentialMap(PotentialMap &map) {
129.302 + if (_local_potential) {
129.303 + delete _potential;
129.304 + _local_potential = false;
129.305 + }
129.306 + _potential = ↦
129.307 + return *this;
129.308 + }
129.309 +
129.310 + /// \name Execution Control
129.311 + /// The simplest way to execute the algorithm is to call the run()
129.312 + /// function.
129.313 + /// \n
129.314 + /// If you only need the flow that is the union of the found
129.315 + /// arc-disjoint paths, you may call init() and findFlow().
129.316 +
129.317 + /// @{
129.318 +
129.319 + /// \brief Run the algorithm.
129.320 + ///
129.321 + /// This function runs the algorithm.
129.322 + ///
129.323 + /// \param s The source node.
129.324 + /// \param t The target node.
129.325 + /// \param k The number of paths to be found.
129.326 + ///
129.327 + /// \return \c k if there are at least \c k arc-disjoint paths from
129.328 + /// \c s to \c t in the digraph. Otherwise it returns the number of
129.329 + /// arc-disjoint paths found.
129.330 + ///
129.331 + /// \note Apart from the return value, <tt>s.run(s, t, k)</tt> is
129.332 + /// just a shortcut of the following code.
129.333 + /// \code
129.334 + /// s.init(s);
129.335 + /// s.findFlow(t, k);
129.336 + /// s.findPaths();
129.337 + /// \endcode
129.338 + int run(const Node& s, const Node& t, int k = 2) {
129.339 + init(s);
129.340 + findFlow(t, k);
129.341 + findPaths();
129.342 + return _path_num;
129.343 + }
129.344 +
129.345 + /// \brief Initialize the algorithm.
129.346 + ///
129.347 + /// This function initializes the algorithm.
129.348 + ///
129.349 + /// \param s The source node.
129.350 + void init(const Node& s) {
129.351 + _source = s;
129.352 +
129.353 + // Initialize maps
129.354 + if (!_flow) {
129.355 + _flow = new FlowMap(_graph);
129.356 + _local_flow = true;
129.357 + }
129.358 + if (!_potential) {
129.359 + _potential = new PotentialMap(_graph);
129.360 + _local_potential = true;
129.361 + }
129.362 + for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
129.363 + for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
129.364 + }
129.365 +
129.366 + /// \brief Execute the algorithm to find an optimal flow.
129.367 + ///
129.368 + /// This function executes the successive shortest path algorithm to
129.369 + /// find a minimum cost flow, which is the union of \c k (or less)
129.370 + /// arc-disjoint paths.
129.371 + ///
129.372 + /// \param t The target node.
129.373 + /// \param k The number of paths to be found.
129.374 + ///
129.375 + /// \return \c k if there are at least \c k arc-disjoint paths from
129.376 + /// the source node to the given node \c t in the digraph.
129.377 + /// Otherwise it returns the number of arc-disjoint paths found.
129.378 + ///
129.379 + /// \pre \ref init() must be called before using this function.
129.380 + int findFlow(const Node& t, int k = 2) {
129.381 + _target = t;
129.382 + _dijkstra =
129.383 + new ResidualDijkstra( _graph, *_flow, _length, *_potential, _pred,
129.384 + _source, _target );
129.385 +
129.386 + // Find shortest paths
129.387 + _path_num = 0;
129.388 + while (_path_num < k) {
129.389 + // Run Dijkstra
129.390 + if (!_dijkstra->run()) break;
129.391 + ++_path_num;
129.392 +
129.393 + // Set the flow along the found shortest path
129.394 + Node u = _target;
129.395 + Arc e;
129.396 + while ((e = _pred[u]) != INVALID) {
129.397 + if (u == _graph.target(e)) {
129.398 + (*_flow)[e] = 1;
129.399 + u = _graph.source(e);
129.400 + } else {
129.401 + (*_flow)[e] = 0;
129.402 + u = _graph.target(e);
129.403 + }
129.404 + }
129.405 + }
129.406 + return _path_num;
129.407 + }
129.408 +
129.409 + /// \brief Compute the paths from the flow.
129.410 + ///
129.411 + /// This function computes the paths from the found minimum cost flow,
129.412 + /// which is the union of some arc-disjoint paths.
129.413 + ///
129.414 + /// \pre \ref init() and \ref findFlow() must be called before using
129.415 + /// this function.
129.416 + void findPaths() {
129.417 + FlowMap res_flow(_graph);
129.418 + for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
129.419 +
129.420 + paths.clear();
129.421 + paths.resize(_path_num);
129.422 + for (int i = 0; i < _path_num; ++i) {
129.423 + Node n = _source;
129.424 + while (n != _target) {
129.425 + OutArcIt e(_graph, n);
129.426 + for ( ; res_flow[e] == 0; ++e) ;
129.427 + n = _graph.target(e);
129.428 + paths[i].addBack(e);
129.429 + res_flow[e] = 0;
129.430 + }
129.431 + }
129.432 + }
129.433 +
129.434 + /// @}
129.435 +
129.436 + /// \name Query Functions
129.437 + /// The results of the algorithm can be obtained using these
129.438 + /// functions.
129.439 + /// \n The algorithm should be executed before using them.
129.440 +
129.441 + /// @{
129.442 +
129.443 + /// \brief Return the total length of the found paths.
129.444 + ///
129.445 + /// This function returns the total length of the found paths, i.e.
129.446 + /// the total cost of the found flow.
129.447 + /// The complexity of the function is O(e).
129.448 + ///
129.449 + /// \pre \ref run() or \ref findFlow() must be called before using
129.450 + /// this function.
129.451 + Length totalLength() const {
129.452 + Length c = 0;
129.453 + for (ArcIt e(_graph); e != INVALID; ++e)
129.454 + c += (*_flow)[e] * _length[e];
129.455 + return c;
129.456 + }
129.457 +
129.458 + /// \brief Return the flow value on the given arc.
129.459 + ///
129.460 + /// This function returns the flow value on the given arc.
129.461 + /// It is \c 1 if the arc is involved in one of the found arc-disjoint
129.462 + /// paths, otherwise it is \c 0.
129.463 + ///
129.464 + /// \pre \ref run() or \ref findFlow() must be called before using
129.465 + /// this function.
129.466 + int flow(const Arc& arc) const {
129.467 + return (*_flow)[arc];
129.468 + }
129.469 +
129.470 + /// \brief Return a const reference to an arc map storing the
129.471 + /// found flow.
129.472 + ///
129.473 + /// This function returns a const reference to an arc map storing
129.474 + /// the flow that is the union of the found arc-disjoint paths.
129.475 + ///
129.476 + /// \pre \ref run() or \ref findFlow() must be called before using
129.477 + /// this function.
129.478 + const FlowMap& flowMap() const {
129.479 + return *_flow;
129.480 + }
129.481 +
129.482 + /// \brief Return the potential of the given node.
129.483 + ///
129.484 + /// This function returns the potential of the given node.
129.485 + /// The node potentials provide the dual solution of the
129.486 + /// underlying \ref min_cost_flow "minimum cost flow problem".
129.487 + ///
129.488 + /// \pre \ref run() or \ref findFlow() must be called before using
129.489 + /// this function.
129.490 + Length potential(const Node& node) const {
129.491 + return (*_potential)[node];
129.492 + }
129.493 +
129.494 + /// \brief Return a const reference to a node map storing the
129.495 + /// found potentials (the dual solution).
129.496 + ///
129.497 + /// This function returns a const reference to a node map storing
129.498 + /// the found potentials that provide the dual solution of the
129.499 + /// underlying \ref min_cost_flow "minimum cost flow problem".
129.500 + ///
129.501 + /// \pre \ref run() or \ref findFlow() must be called before using
129.502 + /// this function.
129.503 + const PotentialMap& potentialMap() const {
129.504 + return *_potential;
129.505 + }
129.506 +
129.507 + /// \brief Return the number of the found paths.
129.508 + ///
129.509 + /// This function returns the number of the found paths.
129.510 + ///
129.511 + /// \pre \ref run() or \ref findFlow() must be called before using
129.512 + /// this function.
129.513 + int pathNum() const {
129.514 + return _path_num;
129.515 + }
129.516 +
129.517 + /// \brief Return a const reference to the specified path.
129.518 + ///
129.519 + /// This function returns a const reference to the specified path.
129.520 + ///
129.521 + /// \param i The function returns the <tt>i</tt>-th path.
129.522 + /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
129.523 + ///
129.524 + /// \pre \ref run() or \ref findPaths() must be called before using
129.525 + /// this function.
129.526 + Path path(int i) const {
129.527 + return paths[i];
129.528 + }
129.529 +
129.530 + /// @}
129.531 +
129.532 + }; //class Suurballe
129.533 +
129.534 + ///@}
129.535 +
129.536 +} //namespace lemon
129.537 +
129.538 +#endif //LEMON_SUURBALLE_H
130.1 --- a/lemon/time_measure.h Fri Nov 13 12:33:33 2009 +0100
130.2 +++ b/lemon/time_measure.h Thu Dec 10 17:05:35 2009 +0100
130.3 @@ -2,7 +2,7 @@
130.4 *
130.5 * This file is a part of LEMON, a generic C++ optimization library.
130.6 *
130.7 - * Copyright (C) 2003-2008
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 @@ -287,7 +287,7 @@
130.13 ///
130.14 Timer(bool run=true) :_running(run) {_reset();}
130.15
130.16 - ///\name Control the state of the timer
130.17 + ///\name Control the State of the Timer
130.18 ///Basically a Timer can be either running or stopped,
130.19 ///but it provides a bit finer control on the execution.
130.20 ///The \ref lemon::Timer "Timer" also counts the number of
130.21 @@ -395,7 +395,7 @@
130.22
130.23 ///@}
130.24
130.25 - ///\name Query Functions for the ellapsed time
130.26 + ///\name Query Functions for the Ellapsed Time
130.27
130.28 ///@{
130.29
131.1 --- a/lemon/tolerance.h Fri Nov 13 12:33:33 2009 +0100
131.2 +++ b/lemon/tolerance.h Thu Dec 10 17:05:35 2009 +0100
131.3 @@ -2,7 +2,7 @@
131.4 *
131.5 * This file is a part of LEMON, a generic C++ optimization library.
131.6 *
131.7 - * Copyright (C) 2003-2008
131.8 + * Copyright (C) 2003-2009
131.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
131.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
131.11 *
132.1 --- a/lemon/unionfind.h Fri Nov 13 12:33:33 2009 +0100
132.2 +++ b/lemon/unionfind.h Thu Dec 10 17:05:35 2009 +0100
132.3 @@ -2,7 +2,7 @@
132.4 *
132.5 * This file is a part of LEMON, a generic C++ optimization library.
132.6 *
132.7 - * Copyright (C) 2003-2008
132.8 + * Copyright (C) 2003-2009
132.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
132.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
132.11 *
132.12 @@ -51,11 +51,13 @@
132.13 ///
132.14 /// \pre You need to add all the elements by the \ref insert()
132.15 /// method.
132.16 - template <typename _ItemIntMap>
132.17 + template <typename IM>
132.18 class UnionFind {
132.19 public:
132.20
132.21 - typedef _ItemIntMap ItemIntMap;
132.22 + ///\e
132.23 + typedef IM ItemIntMap;
132.24 + ///\e
132.25 typedef typename ItemIntMap::Key Item;
132.26
132.27 private:
132.28 @@ -170,11 +172,13 @@
132.29 /// \pre You need to add all the elements by the \ref insert()
132.30 /// method.
132.31 ///
132.32 - template <typename _ItemIntMap>
132.33 + template <typename IM>
132.34 class UnionFindEnum {
132.35 public:
132.36
132.37 - typedef _ItemIntMap ItemIntMap;
132.38 + ///\e
132.39 + typedef IM ItemIntMap;
132.40 + ///\e
132.41 typedef typename ItemIntMap::Key Item;
132.42
132.43 private:
132.44 @@ -627,11 +631,13 @@
132.45 ///
132.46 /// \pre You need to add all the elements by the \ref insert()
132.47 /// method.
132.48 - template <typename _ItemIntMap>
132.49 + template <typename IM>
132.50 class ExtendFindEnum {
132.51 public:
132.52
132.53 - typedef _ItemIntMap ItemIntMap;
132.54 + ///\e
132.55 + typedef IM ItemIntMap;
132.56 + ///\e
132.57 typedef typename ItemIntMap::Key Item;
132.58
132.59 private:
132.60 @@ -948,18 +954,18 @@
132.61 ///
132.62 /// \pre You need to add all the elements by the \ref insert()
132.63 /// method.
132.64 - ///
132.65 - template <typename _Value, typename _ItemIntMap,
132.66 - typename _Comp = std::less<_Value> >
132.67 + template <typename V, typename IM, typename Comp = std::less<V> >
132.68 class HeapUnionFind {
132.69 public:
132.70
132.71 - typedef _Value Value;
132.72 - typedef typename _ItemIntMap::Key Item;
132.73 -
132.74 - typedef _ItemIntMap ItemIntMap;
132.75 -
132.76 - typedef _Comp Comp;
132.77 + ///\e
132.78 + typedef V Value;
132.79 + ///\e
132.80 + typedef typename IM::Key Item;
132.81 + ///\e
132.82 + typedef IM ItemIntMap;
132.83 + ///\e
132.84 + typedef Comp Compare;
132.85
132.86 private:
132.87
132.88 @@ -1189,7 +1195,7 @@
132.89 int ld = nodes[nodes[jd].next].left;
132.90 popLeft(nodes[jd].next);
132.91 pushRight(jd, ld);
132.92 - if (less(ld, nodes[jd].left) ||
132.93 + if (less(ld, nodes[jd].left) ||
132.94 nodes[ld].item == nodes[pd].item) {
132.95 nodes[jd].item = nodes[ld].item;
132.96 nodes[jd].prio = nodes[ld].prio;
132.97 @@ -1601,7 +1607,7 @@
132.98
132.99 /// \brief Gives back the priority of the current item.
132.100 ///
132.101 - /// \return Gives back the priority of the current item.
132.102 + /// Gives back the priority of the current item.
132.103 const Value& operator[](const Item& item) const {
132.104 return nodes[index[item]].prio;
132.105 }
132.106 @@ -1646,7 +1652,7 @@
132.107
132.108 /// \brief Gives back the minimum priority of the class.
132.109 ///
132.110 - /// \return Gives back the minimum priority of the class.
132.111 + /// Gives back the minimum priority of the class.
132.112 const Value& classPrio(int cls) const {
132.113 return nodes[~(classes[cls].parent)].prio;
132.114 }
132.115 @@ -1660,9 +1666,9 @@
132.116
132.117 /// \brief Gives back a representant item of the class.
132.118 ///
132.119 + /// Gives back a representant item of the class.
132.120 /// The representant is indpendent from the priorities of the
132.121 /// items.
132.122 - /// \return Gives back a representant item of the class.
132.123 const Item& classRep(int id) const {
132.124 int parent = classes[id].parent;
132.125 return nodes[parent >= 0 ? classes[id].depth : leftNode(id)].item;
133.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
133.2 +++ b/m4/lx_check_coin.m4 Thu Dec 10 17:05:35 2009 +0100
133.3 @@ -0,0 +1,136 @@
133.4 +AC_DEFUN([LX_CHECK_COIN],
133.5 +[
133.6 + AC_ARG_WITH([coin],
133.7 +AS_HELP_STRING([--with-coin@<:@=PREFIX@:>@], [search for CLP under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
133.8 +AS_HELP_STRING([--without-coin], [disable checking for CLP]),
133.9 + [], [with_coin=yes])
133.10 +
133.11 + AC_ARG_WITH([coin-includedir],
133.12 +AS_HELP_STRING([--with-coin-includedir=DIR], [search for CLP headers in DIR]),
133.13 + [], [with_coin_includedir=no])
133.14 +
133.15 + AC_ARG_WITH([coin-libdir],
133.16 +AS_HELP_STRING([--with-coin-libdir=DIR], [search for CLP libraries in DIR]),
133.17 + [], [with_coin_libdir=no])
133.18 +
133.19 + lx_clp_found=no
133.20 + if test x"$with_coin" != x"no"; then
133.21 + AC_MSG_CHECKING([for CLP])
133.22 +
133.23 + if test x"$with_coin_includedir" != x"no"; then
133.24 + CLP_CXXFLAGS="-I$with_coin_includedir"
133.25 + elif test x"$with_coin" != x"yes"; then
133.26 + CLP_CXXFLAGS="-I$with_coin/include"
133.27 + fi
133.28 +
133.29 + if test x"$with_coin_libdir" != x"no"; then
133.30 + CLP_LDFLAGS="-L$with_coin_libdir"
133.31 + elif test x"$with_coin" != x"yes"; then
133.32 + CLP_LDFLAGS="-L$with_coin/lib"
133.33 + fi
133.34 + CLP_LIBS="-lClp -lCoinUtils -lm"
133.35 +
133.36 + lx_save_cxxflags="$CXXFLAGS"
133.37 + lx_save_ldflags="$LDFLAGS"
133.38 + lx_save_libs="$LIBS"
133.39 + CXXFLAGS="$CLP_CXXFLAGS"
133.40 + LDFLAGS="$CLP_LDFLAGS"
133.41 + LIBS="$CLP_LIBS"
133.42 +
133.43 + lx_clp_test_prog='
133.44 + #include <coin/ClpModel.hpp>
133.45 +
133.46 + int main(int argc, char** argv)
133.47 + {
133.48 + ClpModel clp;
133.49 + return 0;
133.50 + }'
133.51 +
133.52 + AC_LANG_PUSH(C++)
133.53 + AC_LINK_IFELSE([$lx_clp_test_prog], [lx_clp_found=yes], [lx_clp_found=no])
133.54 + AC_LANG_POP(C++)
133.55 +
133.56 + CXXFLAGS="$lx_save_cxxflags"
133.57 + LDFLAGS="$lx_save_ldflags"
133.58 + LIBS="$lx_save_libs"
133.59 +
133.60 + if test x"$lx_clp_found" = x"yes"; then
133.61 + AC_DEFINE([LEMON_HAVE_CLP], [1], [Define to 1 if you have CLP.])
133.62 + lx_lp_found=yes
133.63 + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
133.64 + AC_MSG_RESULT([yes])
133.65 + else
133.66 + CLP_CXXFLAGS=""
133.67 + CLP_LDFLAGS=""
133.68 + CLP_LIBS=""
133.69 + AC_MSG_RESULT([no])
133.70 + fi
133.71 + fi
133.72 + CLP_LIBS="$CLP_LDFLAGS $CLP_LIBS"
133.73 + AC_SUBST(CLP_CXXFLAGS)
133.74 + AC_SUBST(CLP_LIBS)
133.75 + AM_CONDITIONAL([HAVE_CLP], [test x"$lx_clp_found" = x"yes"])
133.76 +
133.77 +
133.78 + lx_cbc_found=no
133.79 + if test x"$lx_clp_found" = x"yes"; then
133.80 + if test x"$with_coin" != x"no"; then
133.81 + AC_MSG_CHECKING([for CBC])
133.82 +
133.83 + if test x"$with_coin_includedir" != x"no"; then
133.84 + CBC_CXXFLAGS="-I$with_coin_includedir"
133.85 + elif test x"$with_coin" != x"yes"; then
133.86 + CBC_CXXFLAGS="-I$with_coin/include"
133.87 + fi
133.88 +
133.89 + if test x"$with_coin_libdir" != x"no"; then
133.90 + CBC_LDFLAGS="-L$with_coin_libdir"
133.91 + elif test x"$with_coin" != x"yes"; then
133.92 + CBC_LDFLAGS="-L$with_coin/lib"
133.93 + fi
133.94 + CBC_LIBS="-lOsi -lCbc -lOsiCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
133.95 +
133.96 + lx_save_cxxflags="$CXXFLAGS"
133.97 + lx_save_ldflags="$LDFLAGS"
133.98 + lx_save_libs="$LIBS"
133.99 + CXXFLAGS="$CBC_CXXFLAGS"
133.100 + LDFLAGS="$CBC_LDFLAGS"
133.101 + LIBS="$CBC_LIBS"
133.102 +
133.103 + lx_cbc_test_prog='
133.104 + #include <coin/CbcModel.hpp>
133.105 +
133.106 + int main(int argc, char** argv)
133.107 + {
133.108 + CbcModel cbc;
133.109 + return 0;
133.110 + }'
133.111 +
133.112 + AC_LANG_PUSH(C++)
133.113 + AC_LINK_IFELSE([$lx_cbc_test_prog], [lx_cbc_found=yes], [lx_cbc_found=no])
133.114 + AC_LANG_POP(C++)
133.115 +
133.116 + CXXFLAGS="$lx_save_cxxflags"
133.117 + LDFLAGS="$lx_save_ldflags"
133.118 + LIBS="$lx_save_libs"
133.119 +
133.120 + if test x"$lx_cbc_found" = x"yes"; then
133.121 + AC_DEFINE([LEMON_HAVE_CBC], [1], [Define to 1 if you have CBC.])
133.122 + lx_lp_found=yes
133.123 + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
133.124 + lx_mip_found=yes
133.125 + AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
133.126 + AC_MSG_RESULT([yes])
133.127 + else
133.128 + CBC_CXXFLAGS=""
133.129 + CBC_LDFLAGS=""
133.130 + CBC_LIBS=""
133.131 + AC_MSG_RESULT([no])
133.132 + fi
133.133 + fi
133.134 + fi
133.135 + CBC_LIBS="$CBC_LDFLAGS $CBC_LIBS"
133.136 + AC_SUBST(CBC_CXXFLAGS)
133.137 + AC_SUBST(CBC_LIBS)
133.138 + AM_CONDITIONAL([HAVE_CBC], [test x"$lx_cbc_found" = x"yes"])
133.139 +])
134.1 --- a/m4/lx_check_cplex.m4 Fri Nov 13 12:33:33 2009 +0100
134.2 +++ b/m4/lx_check_cplex.m4 Thu Dec 10 17:05:35 2009 +0100
134.3 @@ -62,6 +62,10 @@
134.4
134.5 if test x"$lx_cplex_found" = x"yes"; then
134.6 AC_DEFINE([LEMON_HAVE_CPLEX], [1], [Define to 1 if you have CPLEX.])
134.7 + lx_lp_found=yes
134.8 + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
134.9 + lx_mip_found=yes
134.10 + AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
134.11 AC_MSG_RESULT([yes])
134.12 else
134.13 CPLEX_CFLAGS=""
135.1 --- a/m4/lx_check_glpk.m4 Fri Nov 13 12:33:33 2009 +0100
135.2 +++ b/m4/lx_check_glpk.m4 Thu Dec 10 17:05:35 2009 +0100
135.3 @@ -42,6 +42,11 @@
135.4 #include <glpk.h>
135.5 }
135.6
135.7 + #if (GLP_MAJOR_VERSION < 4) \
135.8 + || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION < 33)
135.9 + #error Supported GLPK versions: 4.33 or above
135.10 + #endif
135.11 +
135.12 int main(int argc, char** argv)
135.13 {
135.14 LPX *lp;
135.15 @@ -60,6 +65,10 @@
135.16
135.17 if test x"$lx_glpk_found" = x"yes"; then
135.18 AC_DEFINE([LEMON_HAVE_GLPK], [1], [Define to 1 if you have GLPK.])
135.19 + lx_lp_found=yes
135.20 + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
135.21 + lx_mip_found=yes
135.22 + AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
135.23 AC_MSG_RESULT([yes])
135.24 else
135.25 GLPK_CFLAGS=""
136.1 --- a/m4/lx_check_soplex.m4 Fri Nov 13 12:33:33 2009 +0100
136.2 +++ b/m4/lx_check_soplex.m4 Thu Dec 10 17:05:35 2009 +0100
136.3 @@ -20,7 +20,7 @@
136.4 if test x"$with_soplex_includedir" != x"no"; then
136.5 SOPLEX_CXXFLAGS="-I$with_soplex_includedir"
136.6 elif test x"$with_soplex" != x"yes"; then
136.7 - SOPLEX_CXXFLAGS="-I$with_soplex/include"
136.8 + SOPLEX_CXXFLAGS="-I$with_soplex/src"
136.9 fi
136.10
136.11 if test x"$with_soplex_libdir" != x"no"; then
136.12 @@ -38,7 +38,7 @@
136.13 LIBS="$SOPLEX_LIBS"
136.14
136.15 lx_soplex_test_prog='
136.16 - #include <soplex/soplex.h>
136.17 + #include <soplex.h>
136.18
136.19 int main(int argc, char** argv)
136.20 {
136.21 @@ -56,6 +56,8 @@
136.22
136.23 if test x"$lx_soplex_found" = x"yes"; then
136.24 AC_DEFINE([LEMON_HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.])
136.25 + lx_lp_found=yes
136.26 + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
136.27 AC_MSG_RESULT([yes])
136.28 else
136.29 SOPLEX_CXXFLAGS=""
137.1 --- a/scripts/chg-len.py Fri Nov 13 12:33:33 2009 +0100
137.2 +++ b/scripts/chg-len.py Thu Dec 10 17:05:35 2009 +0100
137.3 @@ -1,7 +1,11 @@
137.4 #! /usr/bin/env python
137.5
137.6 import sys
137.7 -import os
137.8 +
137.9 +from mercurial import ui, hg
137.10 +from mercurial import util
137.11 +
137.12 +util.rcpath = lambda : []
137.13
137.14 if len(sys.argv)>1 and sys.argv[1] in ["-h","--help"]:
137.15 print """
137.16 @@ -9,32 +13,20 @@
137.17 in the revision graph from revison 0 to the current one.
137.18 """
137.19 exit(0)
137.20 -plist = os.popen("HGRCPATH='' hg parents --template='{rev}\n'").readlines()
137.21 -if len(plist)>1:
137.22 - print "You are in the process of merging"
137.23 - exit(1)
137.24 -PAR = int(plist[0])
137.25
137.26 -f = os.popen("HGRCPATH='' hg log -r 0:tip --template='{rev} {parents}\n'").\
137.27 - readlines()
137.28 -REV = -1
137.29 -lengths=[]
137.30 -for l in f:
137.31 - REV+=1
137.32 - s = l.split()
137.33 - rev = int(s[0])
137.34 - if REV != rev:
137.35 - print "Something is seriously wrong"
137.36 - exit(1)
137.37 - if len(s) == 1:
137.38 - par1 = par2 = rev - 1
137.39 - elif len(s) == 2:
137.40 - par1 = par2 = int(s[1].split(":")[0])
137.41 +u = ui.ui()
137.42 +r = hg.repository(u, ".")
137.43 +N = r.changectx(".").rev()
137.44 +lengths=[0]*(N+1)
137.45 +for i in range(N+1):
137.46 + p=r.changectx(i).parents()
137.47 + if p[0]:
137.48 + p0=lengths[p[0].rev()]
137.49 else:
137.50 - par1 = int(s[1].split(":")[0])
137.51 - par2 = int(s[2].split(":")[0])
137.52 - if rev == 0:
137.53 - lengths.append(0)
137.54 + p0=-1
137.55 + if len(p)>1 and p[1]:
137.56 + p1=lengths[p[1].rev()]
137.57 else:
137.58 - lengths.append(max(lengths[par1],lengths[par2])+1)
137.59 -print lengths[PAR]
137.60 + p1=-1
137.61 + lengths[i]=max(p0,p1)+1
137.62 +print lengths[N]
138.1 --- a/scripts/mk-release.sh Fri Nov 13 12:33:33 2009 +0100
138.2 +++ b/scripts/mk-release.sh Thu Dec 10 17:05:35 2009 +0100
138.3 @@ -14,7 +14,7 @@
138.4 echo '*****************************************************************'
138.5
138.6 autoreconf -vif
138.7 -./configure --enable-demo
138.8 +./configure
138.9
138.10 make
138.11 make html
139.1 --- a/scripts/unify-sources.sh Fri Nov 13 12:33:33 2009 +0100
139.2 +++ b/scripts/unify-sources.sh Thu Dec 10 17:05:35 2009 +0100
139.3 @@ -1,17 +1,206 @@
139.4 #!/bin/bash
139.5
139.6 -YEAR=`date +2003-%Y`
139.7 +YEAR=`date +%Y`
139.8 HGROOT=`hg root`
139.9
139.10 -function update_header() {
139.11 +function hg_year() {
139.12 + if [ -n "$(hg st $1)" ]; then
139.13 + echo $YEAR
139.14 + else
139.15 + hg log -l 1 --template='{date|isodate}\n' $1 |
139.16 + cut -d '-' -f 1
139.17 + fi
139.18 +}
139.19 +
139.20 +# file enumaration modes
139.21 +
139.22 +function all_files() {
139.23 + hg status -a -m -c |
139.24 + cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
139.25 + while read file; do echo $HGROOT/$file; done
139.26 +}
139.27 +
139.28 +function modified_files() {
139.29 + hg status -a -m |
139.30 + cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
139.31 + while read file; do echo $HGROOT/$file; done
139.32 +}
139.33 +
139.34 +function changed_files() {
139.35 + {
139.36 + if [ -n "$HG_PARENT1" ]
139.37 + then
139.38 + hg status --rev $HG_PARENT1:$HG_NODE -a -m
139.39 + fi
139.40 + if [ -n "$HG_PARENT2" ]
139.41 + then
139.42 + hg status --rev $HG_PARENT2:$HG_NODE -a -m
139.43 + fi
139.44 + } | cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
139.45 + sort | uniq |
139.46 + while read file; do echo $HGROOT/$file; done
139.47 +}
139.48 +
139.49 +function given_files() {
139.50 + for file in $GIVEN_FILES
139.51 + do
139.52 + echo $file
139.53 + done
139.54 +}
139.55 +
139.56 +# actions
139.57 +
139.58 +function update_action() {
139.59 + if ! diff -q $1 $2 >/dev/null
139.60 + then
139.61 + echo -n " [$3 updated]"
139.62 + rm $2
139.63 + mv $1 $2
139.64 + CHANGED=YES
139.65 + fi
139.66 +}
139.67 +
139.68 +function update_warning() {
139.69 + echo -n " [$2 warning]"
139.70 + WARNED=YES
139.71 +}
139.72 +
139.73 +function update_init() {
139.74 + echo Update source files...
139.75 + TOTAL_FILES=0
139.76 + CHANGED_FILES=0
139.77 + WARNED_FILES=0
139.78 +}
139.79 +
139.80 +function update_done() {
139.81 + echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
139.82 + echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
139.83 +}
139.84 +
139.85 +function update_begin() {
139.86 + ((TOTAL_FILES++))
139.87 + CHANGED=NO
139.88 + WARNED=NO
139.89 +}
139.90 +
139.91 +function update_end() {
139.92 + if [ $CHANGED == YES ]
139.93 + then
139.94 + ((++CHANGED_FILES))
139.95 + fi
139.96 + if [ $WARNED == YES ]
139.97 + then
139.98 + ((++WARNED_FILES))
139.99 + fi
139.100 +}
139.101 +
139.102 +function check_action() {
139.103 + if [ "$3" == 'tabs' ]
139.104 + then
139.105 + if echo $2 | grep -q -v -E 'Makefile\.am$'
139.106 + then
139.107 + PATTERN=$(echo -e '\t')
139.108 + else
139.109 + PATTERN=' '
139.110 + fi
139.111 + elif [ "$3" == 'trailing spaces' ]
139.112 + then
139.113 + PATTERN='\ +$'
139.114 + else
139.115 + PATTERN='*'
139.116 + fi
139.117 +
139.118 + if ! diff -q $1 $2 >/dev/null
139.119 + then
139.120 + if [ "$PATTERN" == '*' ]
139.121 + then
139.122 + diff $1 $2 | grep '^[0-9]' | sed "s|^\(.*\)c.*$|$2:\1: check failed: $3|g" |
139.123 + sed "s/:\([0-9]*\),\([0-9]*\):\(.*\)$/:\1:\3 (until line \2)/g"
139.124 + else
139.125 + grep -n -E "$PATTERN" $2 | sed "s|^\([0-9]*\):.*$|$2:\1: check failed: $3|g"
139.126 + fi
139.127 + FAILED=YES
139.128 + fi
139.129 +}
139.130 +
139.131 +function check_warning() {
139.132 + if [ "$2" == 'long lines' ]
139.133 + then
139.134 + grep -n -E '.{81,}' $1 | sed "s|^\([0-9]*\):.*$|$1:\1: warning: $2|g"
139.135 + else
139.136 + echo "$1: warning: $2"
139.137 + fi
139.138 + WARNED=YES
139.139 +}
139.140 +
139.141 +function check_init() {
139.142 + echo Check source files...
139.143 + FAILED_FILES=0
139.144 + WARNED_FILES=0
139.145 + TOTAL_FILES=0
139.146 +}
139.147 +
139.148 +function check_done() {
139.149 + echo $FAILED_FILES out of $TOTAL_FILES files has been failed.
139.150 + echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
139.151 +
139.152 + if [ $WARNED_FILES -gt 0 -o $FAILED_FILES -gt 0 ]
139.153 + then
139.154 + if [ "$WARNING" == 'INTERACTIVE' ]
139.155 + then
139.156 + echo -n "Are the files with errors/warnings acceptable? (yes/no) "
139.157 + while read answer
139.158 + do
139.159 + if [ "$answer" == 'yes' ]
139.160 + then
139.161 + return 0
139.162 + elif [ "$answer" == 'no' ]
139.163 + then
139.164 + return 1
139.165 + fi
139.166 + echo -n "Are the files with errors/warnings acceptable? (yes/no) "
139.167 + done
139.168 + elif [ "$WARNING" == 'WERROR' ]
139.169 + then
139.170 + return 1
139.171 + fi
139.172 + fi
139.173 +}
139.174 +
139.175 +function check_begin() {
139.176 + ((TOTAL_FILES++))
139.177 + FAILED=NO
139.178 + WARNED=NO
139.179 +}
139.180 +
139.181 +function check_end() {
139.182 + if [ $FAILED == YES ]
139.183 + then
139.184 + ((++FAILED_FILES))
139.185 + fi
139.186 + if [ $WARNED == YES ]
139.187 + then
139.188 + ((++WARNED_FILES))
139.189 + fi
139.190 +}
139.191 +
139.192 +
139.193 +
139.194 +# checks
139.195 +
139.196 +function header_check() {
139.197 + if echo $1 | grep -q -E 'Makefile\.am$'
139.198 + then
139.199 + return
139.200 + fi
139.201 +
139.202 TMP_FILE=`mktemp`
139.203 - FILE_NAME=$1
139.204
139.205 (echo "/* -*- mode: C++; indent-tabs-mode: nil; -*-
139.206 *
139.207 * This file is a part of LEMON, a generic C++ optimization library.
139.208 *
139.209 - * Copyright (C) "$YEAR"
139.210 + * Copyright (C) 2003-"$(hg_year $1)"
139.211 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
139.212 * (Egervary Research Group on Combinatorial Optimization, EGRES).
139.213 *
139.214 @@ -25,110 +214,163 @@
139.215 *
139.216 */
139.217 "
139.218 - awk 'BEGIN { pm=0; }
139.219 + awk 'BEGIN { pm=0; }
139.220 pm==3 { print }
139.221 /\/\* / && pm==0 { pm=1;}
139.222 /[^:blank:]/ && (pm==0 || pm==2) { pm=3; print;}
139.223 /\*\// && pm==1 { pm=2;}
139.224 ' $1
139.225 - ) >$TMP_FILE
139.226 + ) >$TMP_FILE
139.227
139.228 - HEADER_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
139.229 -
139.230 - rm $FILE_NAME
139.231 - mv $TMP_FILE $FILE_NAME
139.232 + "$ACTION"_action "$TMP_FILE" "$1" header
139.233 }
139.234
139.235 -function update_tabs() {
139.236 +function tabs_check() {
139.237 + if echo $1 | grep -q -v -E 'Makefile\.am$'
139.238 + then
139.239 + OLD_PATTERN=$(echo -e '\t')
139.240 + NEW_PATTERN=' '
139.241 + else
139.242 + OLD_PATTERN=' '
139.243 + NEW_PATTERN=$(echo -e '\t')
139.244 + fi
139.245 TMP_FILE=`mktemp`
139.246 - FILE_NAME=$1
139.247 + cat $1 | sed -e "s/$OLD_PATTERN/$NEW_PATTERN/g" >$TMP_FILE
139.248
139.249 - cat $1 |
139.250 - sed -e 's/\t/ /g' >$TMP_FILE
139.251 -
139.252 - TABS_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
139.253 -
139.254 - rm $FILE_NAME
139.255 - mv $TMP_FILE $FILE_NAME
139.256 + "$ACTION"_action "$TMP_FILE" "$1" 'tabs'
139.257 }
139.258
139.259 -function remove_trailing_space() {
139.260 +function spaces_check() {
139.261 TMP_FILE=`mktemp`
139.262 - FILE_NAME=$1
139.263 + cat $1 | sed -e 's/ \+$//g' >$TMP_FILE
139.264
139.265 - cat $1 |
139.266 - sed -e 's/ \+$//g' >$TMP_FILE
139.267 -
139.268 - SPACES_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
139.269 -
139.270 - rm $FILE_NAME
139.271 - mv $TMP_FILE $FILE_NAME
139.272 + "$ACTION"_action "$TMP_FILE" "$1" 'trailing spaces'
139.273 }
139.274
139.275 -function long_line_test() {
139.276 - cat $1 |grep -q -E '.{81,}'
139.277 -}
139.278 -
139.279 -function update_file() {
139.280 - echo -n ' update' $i ...
139.281 -
139.282 - update_header $1
139.283 - update_tabs $1
139.284 - remove_trailing_space $1
139.285 -
139.286 - CHANGED=NO;
139.287 - if [[ $HEADER_CH = YES ]];
139.288 +function long_lines_check() {
139.289 + if cat $1 | grep -q -E '.{81,}'
139.290 then
139.291 - echo -n ' [header updated]'
139.292 - CHANGED=YES;
139.293 - fi
139.294 - if [[ $TABS_CH = YES ]];
139.295 - then
139.296 - echo -n ' [tabs removed]'
139.297 - CHANGED=YES;
139.298 - fi
139.299 - if [[ $SPACES_CH = YES ]];
139.300 - then
139.301 - echo -n ' [trailing spaces removed]'
139.302 - CHANGED=YES;
139.303 - fi
139.304 - if long_line_test $1 ;
139.305 - then
139.306 - echo -n ' [LONG LINES]'
139.307 - ((LONG_LINE_FILES++))
139.308 - fi
139.309 - echo
139.310 - if [[ $CHANGED = YES ]];
139.311 - then
139.312 - ((CHANGED_FILES++))
139.313 + "$ACTION"_warning $1 'long lines'
139.314 fi
139.315 }
139.316
139.317 -CHANGED_FILES=0
139.318 -TOTAL_FILES=0
139.319 -LONG_LINE_FILES=0
139.320 -if [ $# == 0 ]; then
139.321 - echo Update all source files...
139.322 - for i in `hg manifest|grep -E '\.(cc|h|dox)$'`
139.323 +# process the file
139.324 +
139.325 +function process_file() {
139.326 + if [ "$ACTION" == 'update' ]
139.327 + then
139.328 + echo -n " $ACTION $1..."
139.329 + else
139.330 + echo " $ACTION $1..."
139.331 + fi
139.332 +
139.333 + CHECKING="header tabs spaces long_lines"
139.334 +
139.335 + "$ACTION"_begin $1
139.336 + for check in $CHECKING
139.337 do
139.338 - update_file $HGROOT/$i
139.339 - ((TOTAL_FILES++))
139.340 + "$check"_check $1
139.341 done
139.342 - echo ' done.'
139.343 -else
139.344 - for i in $*
139.345 + "$ACTION"_end $1
139.346 + if [ "$ACTION" == 'update' ]
139.347 + then
139.348 + echo
139.349 + fi
139.350 +}
139.351 +
139.352 +function process_all {
139.353 + "$ACTION"_init
139.354 + while read file
139.355 do
139.356 - update_file $i
139.357 - ((TOTAL_FILES++))
139.358 - done
139.359 + process_file $file
139.360 + done < <($FILES)
139.361 + "$ACTION"_done
139.362 +}
139.363 +
139.364 +while [ $# -gt 0 ]
139.365 +do
139.366 +
139.367 + if [ "$1" == '--help' ] || [ "$1" == '-h' ]
139.368 + then
139.369 + echo -n \
139.370 +"Usage:
139.371 + $0 [OPTIONS] [files]
139.372 +Options:
139.373 + --dry-run|-n
139.374 + Check the files, but do not modify them.
139.375 + --interactive|-i
139.376 + If --dry-run is specified and the checker emits warnings,
139.377 + then the user is asked if the warnings should be considered
139.378 + errors.
139.379 + --werror|-w
139.380 + Make all warnings into errors.
139.381 + --all|-a
139.382 + Check all source files in the repository.
139.383 + --modified|-m
139.384 + Check only the modified (and new) source files. This option is
139.385 + useful to check the modification before making a commit.
139.386 + --changed|-c
139.387 + Check only the changed source files compared to the parent(s) of
139.388 + the current hg node. This option is useful as hg hook script.
139.389 + To automatically check all your changes before making a commit,
139.390 + add the following section to the appropriate .hg/hgrc file.
139.391 +
139.392 + [hooks]
139.393 + pretxncommit.checksources = scripts/unify-sources.sh -c -n -i
139.394 +
139.395 + --help|-h
139.396 + Print this help message.
139.397 + files
139.398 + The files to check/unify. If no file names are given, the modified
139.399 + source files will be checked/unified (just like using the
139.400 + --modified|-m option).
139.401 +"
139.402 + exit 0
139.403 + elif [ "$1" == '--dry-run' ] || [ "$1" == '-n' ]
139.404 + then
139.405 + [ -n "$ACTION" ] && echo "Conflicting action options" >&2 && exit 1
139.406 + ACTION=check
139.407 + elif [ "$1" == "--all" ] || [ "$1" == '-a' ]
139.408 + then
139.409 + [ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
139.410 + FILES=all_files
139.411 + elif [ "$1" == "--changed" ] || [ "$1" == '-c' ]
139.412 + then
139.413 + [ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
139.414 + FILES=changed_files
139.415 + elif [ "$1" == "--modified" ] || [ "$1" == '-m' ]
139.416 + then
139.417 + [ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
139.418 + FILES=modified_files
139.419 + elif [ "$1" == "--interactive" ] || [ "$1" == "-i" ]
139.420 + then
139.421 + [ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
139.422 + WARNING='INTERACTIVE'
139.423 + elif [ "$1" == "--werror" ] || [ "$1" == "-w" ]
139.424 + then
139.425 + [ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
139.426 + WARNING='WERROR'
139.427 + elif [ $(echo x$1 | cut -c 2) == '-' ]
139.428 + then
139.429 + echo "Invalid option $1" >&2 && exit 1
139.430 + else
139.431 + [ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
139.432 + GIVEN_FILES=$@
139.433 + FILES=given_files
139.434 + break
139.435 + fi
139.436 +
139.437 + shift
139.438 +done
139.439 +
139.440 +if [ -z $FILES ]
139.441 +then
139.442 + FILES=modified_files
139.443 fi
139.444 -echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
139.445 -if [[ $LONG_LINE_FILES -gt 1 ]]; then
139.446 - echo
139.447 - echo WARNING: $LONG_LINE_FILES files contains long lines!
139.448 - echo
139.449 -elif [[ $LONG_LINE_FILES -gt 0 ]]; then
139.450 - echo
139.451 - echo WARNING: a file contains long lines!
139.452 - echo
139.453 +
139.454 +if [ -z $ACTION ]
139.455 +then
139.456 + ACTION=update
139.457 fi
139.458 +
139.459 +process_all
140.1 --- a/test/CMakeLists.txt Fri Nov 13 12:33:33 2009 +0100
140.2 +++ b/test/CMakeLists.txt Thu Dec 10 17:05:35 2009 +0100
140.3 @@ -1,31 +1,119 @@
140.4 INCLUDE_DIRECTORIES(
140.5 - ${CMAKE_SOURCE_DIR}
140.6 + ${PROJECT_SOURCE_DIR}
140.7 ${PROJECT_BINARY_DIR}
140.8 )
140.9
140.10 -LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
140.11 +LINK_DIRECTORIES(
140.12 + ${PROJECT_BINARY_DIR}/lemon
140.13 +)
140.14
140.15 SET(TESTS
140.16 + adaptors_test
140.17 bfs_test
140.18 + circulation_test
140.19 + connectivity_test
140.20 counter_test
140.21 dfs_test
140.22 digraph_test
140.23 dijkstra_test
140.24 dim_test
140.25 + edge_set_test
140.26 error_test
140.27 + euler_test
140.28 + gomory_hu_test
140.29 graph_copy_test
140.30 graph_test
140.31 graph_utils_test
140.32 + hao_orlin_test
140.33 heap_test
140.34 kruskal_test
140.35 maps_test
140.36 + matching_test
140.37 + min_cost_arborescence_test
140.38 + min_cost_flow_test
140.39 + path_test
140.40 + preflow_test
140.41 + radix_sort_test
140.42 random_test
140.43 - path_test
140.44 + suurballe_test
140.45 time_measure_test
140.46 - unionfind_test)
140.47 + unionfind_test
140.48 +)
140.49 +
140.50 +IF(LEMON_HAVE_LP)
140.51 + ADD_EXECUTABLE(lp_test lp_test.cc)
140.52 + SET(LP_TEST_LIBS lemon)
140.53 +
140.54 + IF(LEMON_HAVE_GLPK)
140.55 + SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
140.56 + ENDIF()
140.57 + IF(LEMON_HAVE_CPLEX)
140.58 + SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
140.59 + ENDIF()
140.60 + IF(LEMON_HAVE_CLP)
140.61 + SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
140.62 + ENDIF()
140.63 +
140.64 + TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
140.65 + ADD_TEST(lp_test lp_test)
140.66 +
140.67 + IF(WIN32 AND LEMON_HAVE_GLPK)
140.68 + GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
140.69 + GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
140.70 + ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
140.71 + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
140.72 + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
140.73 + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
140.74 + )
140.75 + ENDIF()
140.76 +
140.77 + IF(WIN32 AND LEMON_HAVE_CPLEX)
140.78 + GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
140.79 + GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
140.80 + ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
140.81 + COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
140.82 + )
140.83 + ENDIF()
140.84 +ENDIF()
140.85 +
140.86 +IF(LEMON_HAVE_MIP)
140.87 + ADD_EXECUTABLE(mip_test mip_test.cc)
140.88 + SET(MIP_TEST_LIBS lemon)
140.89 +
140.90 + IF(LEMON_HAVE_GLPK)
140.91 + SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
140.92 + ENDIF()
140.93 + IF(LEMON_HAVE_CPLEX)
140.94 + SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
140.95 + ENDIF()
140.96 + IF(LEMON_HAVE_CBC)
140.97 + SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
140.98 + ENDIF()
140.99 +
140.100 + TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
140.101 + ADD_TEST(mip_test mip_test)
140.102 +
140.103 + IF(WIN32 AND LEMON_HAVE_GLPK)
140.104 + GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
140.105 + GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
140.106 + ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
140.107 + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
140.108 + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
140.109 + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
140.110 + )
140.111 + ENDIF()
140.112 +
140.113 + IF(WIN32 AND LEMON_HAVE_CPLEX)
140.114 + GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
140.115 + GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
140.116 + ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
140.117 + COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
140.118 + )
140.119 + ENDIF()
140.120 +ENDIF()
140.121
140.122 FOREACH(TEST_NAME ${TESTS})
140.123 ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
140.124 TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
140.125 ADD_TEST(${TEST_NAME} ${TEST_NAME})
140.126 -ENDFOREACH(TEST_NAME)
140.127 +ENDFOREACH()
141.1 --- a/test/Makefile.am Fri Nov 13 12:33:33 2009 +0100
141.2 +++ b/test/Makefile.am Thu Dec 10 17:05:35 2009 +0100
141.3 @@ -3,46 +3,83 @@
141.4
141.5 noinst_HEADERS += \
141.6 test/graph_test.h \
141.7 - test/test_tools.h
141.8 + test/test_tools.h
141.9
141.10 check_PROGRAMS += \
141.11 + test/adaptors_test \
141.12 test/bfs_test \
141.13 - test/counter_test \
141.14 + test/circulation_test \
141.15 + test/connectivity_test \
141.16 + test/counter_test \
141.17 test/dfs_test \
141.18 test/digraph_test \
141.19 test/dijkstra_test \
141.20 - test/dim_test \
141.21 + test/dim_test \
141.22 + test/edge_set_test \
141.23 test/error_test \
141.24 + test/euler_test \
141.25 + test/gomory_hu_test \
141.26 test/graph_copy_test \
141.27 test/graph_test \
141.28 test/graph_utils_test \
141.29 + test/hao_orlin_test \
141.30 test/heap_test \
141.31 test/kruskal_test \
141.32 - test/maps_test \
141.33 - test/random_test \
141.34 - test/path_test \
141.35 - test/test_tools_fail \
141.36 - test/test_tools_pass \
141.37 - test/time_measure_test \
141.38 + test/maps_test \
141.39 + test/matching_test \
141.40 + test/min_cost_arborescence_test \
141.41 + test/min_cost_flow_test \
141.42 + test/path_test \
141.43 + test/preflow_test \
141.44 + test/radix_sort_test \
141.45 + test/random_test \
141.46 + test/suurballe_test \
141.47 + test/test_tools_fail \
141.48 + test/test_tools_pass \
141.49 + test/time_measure_test \
141.50 test/unionfind_test
141.51
141.52 +test_test_tools_pass_DEPENDENCIES = demo
141.53 +
141.54 +if HAVE_LP
141.55 +check_PROGRAMS += test/lp_test
141.56 +endif HAVE_LP
141.57 +if HAVE_MIP
141.58 +check_PROGRAMS += test/mip_test
141.59 +endif HAVE_MIP
141.60 +
141.61 TESTS += $(check_PROGRAMS)
141.62 XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
141.63
141.64 +test_adaptors_test_SOURCES = test/adaptors_test.cc
141.65 test_bfs_test_SOURCES = test/bfs_test.cc
141.66 +test_circulation_test_SOURCES = test/circulation_test.cc
141.67 test_counter_test_SOURCES = test/counter_test.cc
141.68 +test_connectivity_test_SOURCES = test/connectivity_test.cc
141.69 test_dfs_test_SOURCES = test/dfs_test.cc
141.70 test_digraph_test_SOURCES = test/digraph_test.cc
141.71 test_dijkstra_test_SOURCES = test/dijkstra_test.cc
141.72 test_dim_test_SOURCES = test/dim_test.cc
141.73 +test_edge_set_test_SOURCES = test/edge_set_test.cc
141.74 test_error_test_SOURCES = test/error_test.cc
141.75 +test_euler_test_SOURCES = test/euler_test.cc
141.76 +test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
141.77 test_graph_copy_test_SOURCES = test/graph_copy_test.cc
141.78 test_graph_test_SOURCES = test/graph_test.cc
141.79 test_graph_utils_test_SOURCES = test/graph_utils_test.cc
141.80 test_heap_test_SOURCES = test/heap_test.cc
141.81 test_kruskal_test_SOURCES = test/kruskal_test.cc
141.82 +test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
141.83 +test_lp_test_SOURCES = test/lp_test.cc
141.84 test_maps_test_SOURCES = test/maps_test.cc
141.85 +test_mip_test_SOURCES = test/mip_test.cc
141.86 +test_matching_test_SOURCES = test/matching_test.cc
141.87 +test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
141.88 +test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
141.89 test_path_test_SOURCES = test/path_test.cc
141.90 +test_preflow_test_SOURCES = test/preflow_test.cc
141.91 +test_radix_sort_test_SOURCES = test/radix_sort_test.cc
141.92 +test_suurballe_test_SOURCES = test/suurballe_test.cc
141.93 test_random_test_SOURCES = test/random_test.cc
141.94 test_test_tools_fail_SOURCES = test/test_tools_fail.cc
141.95 test_test_tools_pass_SOURCES = test/test_tools_pass.cc
142.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
142.2 +++ b/test/adaptors_test.cc Thu Dec 10 17:05:35 2009 +0100
142.3 @@ -0,0 +1,1486 @@
142.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
142.5 + *
142.6 + * This file is a part of LEMON, a generic C++ optimization library.
142.7 + *
142.8 + * Copyright (C) 2003-2009
142.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
142.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
142.11 + *
142.12 + * Permission to use, modify and distribute this software is granted
142.13 + * provided that this copyright notice appears in all copies. For
142.14 + * precise terms see the accompanying LICENSE file.
142.15 + *
142.16 + * This software is provided "AS IS" with no warranty of any kind,
142.17 + * express or implied, and with no claim as to its suitability for any
142.18 + * purpose.
142.19 + *
142.20 + */
142.21 +
142.22 +#include <iostream>
142.23 +#include <limits>
142.24 +
142.25 +#include <lemon/list_graph.h>
142.26 +#include <lemon/grid_graph.h>
142.27 +#include <lemon/bfs.h>
142.28 +#include <lemon/path.h>
142.29 +
142.30 +#include <lemon/concepts/digraph.h>
142.31 +#include <lemon/concepts/graph.h>
142.32 +#include <lemon/concepts/graph_components.h>
142.33 +#include <lemon/concepts/maps.h>
142.34 +#include <lemon/concept_check.h>
142.35 +
142.36 +#include <lemon/adaptors.h>
142.37 +
142.38 +#include "test/test_tools.h"
142.39 +#include "test/graph_test.h"
142.40 +
142.41 +using namespace lemon;
142.42 +
142.43 +void checkReverseDigraph() {
142.44 + // Check concepts
142.45 + checkConcept<concepts::Digraph, ReverseDigraph<concepts::Digraph> >();
142.46 + checkConcept<concepts::Digraph, ReverseDigraph<ListDigraph> >();
142.47 + checkConcept<concepts::AlterableDigraphComponent<>,
142.48 + ReverseDigraph<ListDigraph> >();
142.49 + checkConcept<concepts::ExtendableDigraphComponent<>,
142.50 + ReverseDigraph<ListDigraph> >();
142.51 + checkConcept<concepts::ErasableDigraphComponent<>,
142.52 + ReverseDigraph<ListDigraph> >();
142.53 + checkConcept<concepts::ClearableDigraphComponent<>,
142.54 + ReverseDigraph<ListDigraph> >();
142.55 +
142.56 + // Create a digraph and an adaptor
142.57 + typedef ListDigraph Digraph;
142.58 + typedef ReverseDigraph<Digraph> Adaptor;
142.59 +
142.60 + Digraph digraph;
142.61 + Adaptor adaptor(digraph);
142.62 +
142.63 + // Add nodes and arcs to the original digraph
142.64 + Digraph::Node n1 = digraph.addNode();
142.65 + Digraph::Node n2 = digraph.addNode();
142.66 + Digraph::Node n3 = digraph.addNode();
142.67 +
142.68 + Digraph::Arc a1 = digraph.addArc(n1, n2);
142.69 + Digraph::Arc a2 = digraph.addArc(n1, n3);
142.70 + Digraph::Arc a3 = digraph.addArc(n2, n3);
142.71 +
142.72 + // Check the adaptor
142.73 + checkGraphNodeList(adaptor, 3);
142.74 + checkGraphArcList(adaptor, 3);
142.75 + checkGraphConArcList(adaptor, 3);
142.76 +
142.77 + checkGraphOutArcList(adaptor, n1, 0);
142.78 + checkGraphOutArcList(adaptor, n2, 1);
142.79 + checkGraphOutArcList(adaptor, n3, 2);
142.80 +
142.81 + checkGraphInArcList(adaptor, n1, 2);
142.82 + checkGraphInArcList(adaptor, n2, 1);
142.83 + checkGraphInArcList(adaptor, n3, 0);
142.84 +
142.85 + checkNodeIds(adaptor);
142.86 + checkArcIds(adaptor);
142.87 +
142.88 + checkGraphNodeMap(adaptor);
142.89 + checkGraphArcMap(adaptor);
142.90 +
142.91 + // Check the orientation of the arcs
142.92 + for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
142.93 + check(adaptor.source(a) == digraph.target(a), "Wrong reverse");
142.94 + check(adaptor.target(a) == digraph.source(a), "Wrong reverse");
142.95 + }
142.96 +
142.97 + // Add and erase nodes and arcs in the digraph through the adaptor
142.98 + Adaptor::Node n4 = adaptor.addNode();
142.99 +
142.100 + Adaptor::Arc a4 = adaptor.addArc(n4, n3);
142.101 + Adaptor::Arc a5 = adaptor.addArc(n2, n4);
142.102 + Adaptor::Arc a6 = adaptor.addArc(n2, n4);
142.103 + Adaptor::Arc a7 = adaptor.addArc(n1, n4);
142.104 + Adaptor::Arc a8 = adaptor.addArc(n1, n2);
142.105 +
142.106 + adaptor.erase(a1);
142.107 + adaptor.erase(n3);
142.108 +
142.109 + // Check the adaptor
142.110 + checkGraphNodeList(adaptor, 3);
142.111 + checkGraphArcList(adaptor, 4);
142.112 + checkGraphConArcList(adaptor, 4);
142.113 +
142.114 + checkGraphOutArcList(adaptor, n1, 2);
142.115 + checkGraphOutArcList(adaptor, n2, 2);
142.116 + checkGraphOutArcList(adaptor, n4, 0);
142.117 +
142.118 + checkGraphInArcList(adaptor, n1, 0);
142.119 + checkGraphInArcList(adaptor, n2, 1);
142.120 + checkGraphInArcList(adaptor, n4, 3);
142.121 +
142.122 + checkNodeIds(adaptor);
142.123 + checkArcIds(adaptor);
142.124 +
142.125 + checkGraphNodeMap(adaptor);
142.126 + checkGraphArcMap(adaptor);
142.127 +
142.128 + // Check the digraph
142.129 + checkGraphNodeList(digraph, 3);
142.130 + checkGraphArcList(digraph, 4);
142.131 + checkGraphConArcList(digraph, 4);
142.132 +
142.133 + checkGraphOutArcList(digraph, n1, 0);
142.134 + checkGraphOutArcList(digraph, n2, 1);
142.135 + checkGraphOutArcList(digraph, n4, 3);
142.136 +
142.137 + checkGraphInArcList(digraph, n1, 2);
142.138 + checkGraphInArcList(digraph, n2, 2);
142.139 + checkGraphInArcList(digraph, n4, 0);
142.140 +
142.141 + checkNodeIds(digraph);
142.142 + checkArcIds(digraph);
142.143 +
142.144 + checkGraphNodeMap(digraph);
142.145 + checkGraphArcMap(digraph);
142.146 +
142.147 + // Check the conversion of nodes and arcs
142.148 + Digraph::Node nd = n4;
142.149 + nd = n4;
142.150 + Adaptor::Node na = n1;
142.151 + na = n2;
142.152 + Digraph::Arc ad = a4;
142.153 + ad = a5;
142.154 + Adaptor::Arc aa = a1;
142.155 + aa = a2;
142.156 +}
142.157 +
142.158 +void checkSubDigraph() {
142.159 + // Check concepts
142.160 + checkConcept<concepts::Digraph, SubDigraph<concepts::Digraph> >();
142.161 + checkConcept<concepts::Digraph, SubDigraph<ListDigraph> >();
142.162 + checkConcept<concepts::AlterableDigraphComponent<>,
142.163 + SubDigraph<ListDigraph> >();
142.164 + checkConcept<concepts::ExtendableDigraphComponent<>,
142.165 + SubDigraph<ListDigraph> >();
142.166 + checkConcept<concepts::ErasableDigraphComponent<>,
142.167 + SubDigraph<ListDigraph> >();
142.168 + checkConcept<concepts::ClearableDigraphComponent<>,
142.169 + SubDigraph<ListDigraph> >();
142.170 +
142.171 + // Create a digraph and an adaptor
142.172 + typedef ListDigraph Digraph;
142.173 + typedef Digraph::NodeMap<bool> NodeFilter;
142.174 + typedef Digraph::ArcMap<bool> ArcFilter;
142.175 + typedef SubDigraph<Digraph, NodeFilter, ArcFilter> Adaptor;
142.176 +
142.177 + Digraph digraph;
142.178 + NodeFilter node_filter(digraph);
142.179 + ArcFilter arc_filter(digraph);
142.180 + Adaptor adaptor(digraph, node_filter, arc_filter);
142.181 +
142.182 + // Add nodes and arcs to the original digraph and the adaptor
142.183 + Digraph::Node n1 = digraph.addNode();
142.184 + Digraph::Node n2 = digraph.addNode();
142.185 + Adaptor::Node n3 = adaptor.addNode();
142.186 +
142.187 + node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
142.188 +
142.189 + Digraph::Arc a1 = digraph.addArc(n1, n2);
142.190 + Digraph::Arc a2 = digraph.addArc(n1, n3);
142.191 + Adaptor::Arc a3 = adaptor.addArc(n2, n3);
142.192 +
142.193 + arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
142.194 +
142.195 + checkGraphNodeList(adaptor, 3);
142.196 + checkGraphArcList(adaptor, 3);
142.197 + checkGraphConArcList(adaptor, 3);
142.198 +
142.199 + checkGraphOutArcList(adaptor, n1, 2);
142.200 + checkGraphOutArcList(adaptor, n2, 1);
142.201 + checkGraphOutArcList(adaptor, n3, 0);
142.202 +
142.203 + checkGraphInArcList(adaptor, n1, 0);
142.204 + checkGraphInArcList(adaptor, n2, 1);
142.205 + checkGraphInArcList(adaptor, n3, 2);
142.206 +
142.207 + checkNodeIds(adaptor);
142.208 + checkArcIds(adaptor);
142.209 +
142.210 + checkGraphNodeMap(adaptor);
142.211 + checkGraphArcMap(adaptor);
142.212 +
142.213 + // Hide an arc
142.214 + adaptor.status(a2, false);
142.215 + adaptor.disable(a3);
142.216 + if (!adaptor.status(a3)) adaptor.enable(a3);
142.217 +
142.218 + checkGraphNodeList(adaptor, 3);
142.219 + checkGraphArcList(adaptor, 2);
142.220 + checkGraphConArcList(adaptor, 2);
142.221 +
142.222 + checkGraphOutArcList(adaptor, n1, 1);
142.223 + checkGraphOutArcList(adaptor, n2, 1);
142.224 + checkGraphOutArcList(adaptor, n3, 0);
142.225 +
142.226 + checkGraphInArcList(adaptor, n1, 0);
142.227 + checkGraphInArcList(adaptor, n2, 1);
142.228 + checkGraphInArcList(adaptor, n3, 1);
142.229 +
142.230 + checkNodeIds(adaptor);
142.231 + checkArcIds(adaptor);
142.232 +
142.233 + checkGraphNodeMap(adaptor);
142.234 + checkGraphArcMap(adaptor);
142.235 +
142.236 + // Hide a node
142.237 + adaptor.status(n1, false);
142.238 + adaptor.disable(n3);
142.239 + if (!adaptor.status(n3)) adaptor.enable(n3);
142.240 +
142.241 + checkGraphNodeList(adaptor, 2);
142.242 + checkGraphArcList(adaptor, 1);
142.243 + checkGraphConArcList(adaptor, 1);
142.244 +
142.245 + checkGraphOutArcList(adaptor, n2, 1);
142.246 + checkGraphOutArcList(adaptor, n3, 0);
142.247 +
142.248 + checkGraphInArcList(adaptor, n2, 0);
142.249 + checkGraphInArcList(adaptor, n3, 1);
142.250 +
142.251 + checkNodeIds(adaptor);
142.252 + checkArcIds(adaptor);
142.253 +
142.254 + checkGraphNodeMap(adaptor);
142.255 + checkGraphArcMap(adaptor);
142.256 +
142.257 + // Hide all nodes and arcs
142.258 + node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
142.259 + arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
142.260 +
142.261 + checkGraphNodeList(adaptor, 0);
142.262 + checkGraphArcList(adaptor, 0);
142.263 + checkGraphConArcList(adaptor, 0);
142.264 +
142.265 + checkNodeIds(adaptor);
142.266 + checkArcIds(adaptor);
142.267 +
142.268 + checkGraphNodeMap(adaptor);
142.269 + checkGraphArcMap(adaptor);
142.270 +
142.271 + // Check the conversion of nodes and arcs
142.272 + Digraph::Node nd = n3;
142.273 + nd = n3;
142.274 + Adaptor::Node na = n1;
142.275 + na = n2;
142.276 + Digraph::Arc ad = a3;
142.277 + ad = a3;
142.278 + Adaptor::Arc aa = a1;
142.279 + aa = a2;
142.280 +}
142.281 +
142.282 +void checkFilterNodes1() {
142.283 + // Check concepts
142.284 + checkConcept<concepts::Digraph, FilterNodes<concepts::Digraph> >();
142.285 + checkConcept<concepts::Digraph, FilterNodes<ListDigraph> >();
142.286 + checkConcept<concepts::AlterableDigraphComponent<>,
142.287 + FilterNodes<ListDigraph> >();
142.288 + checkConcept<concepts::ExtendableDigraphComponent<>,
142.289 + FilterNodes<ListDigraph> >();
142.290 + checkConcept<concepts::ErasableDigraphComponent<>,
142.291 + FilterNodes<ListDigraph> >();
142.292 + checkConcept<concepts::ClearableDigraphComponent<>,
142.293 + FilterNodes<ListDigraph> >();
142.294 +
142.295 + // Create a digraph and an adaptor
142.296 + typedef ListDigraph Digraph;
142.297 + typedef Digraph::NodeMap<bool> NodeFilter;
142.298 + typedef FilterNodes<Digraph, NodeFilter> Adaptor;
142.299 +
142.300 + Digraph digraph;
142.301 + NodeFilter node_filter(digraph);
142.302 + Adaptor adaptor(digraph, node_filter);
142.303 +
142.304 + // Add nodes and arcs to the original digraph and the adaptor
142.305 + Digraph::Node n1 = digraph.addNode();
142.306 + Digraph::Node n2 = digraph.addNode();
142.307 + Adaptor::Node n3 = adaptor.addNode();
142.308 +
142.309 + node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
142.310 +
142.311 + Digraph::Arc a1 = digraph.addArc(n1, n2);
142.312 + Digraph::Arc a2 = digraph.addArc(n1, n3);
142.313 + Adaptor::Arc a3 = adaptor.addArc(n2, n3);
142.314 +
142.315 + checkGraphNodeList(adaptor, 3);
142.316 + checkGraphArcList(adaptor, 3);
142.317 + checkGraphConArcList(adaptor, 3);
142.318 +
142.319 + checkGraphOutArcList(adaptor, n1, 2);
142.320 + checkGraphOutArcList(adaptor, n2, 1);
142.321 + checkGraphOutArcList(adaptor, n3, 0);
142.322 +
142.323 + checkGraphInArcList(adaptor, n1, 0);
142.324 + checkGraphInArcList(adaptor, n2, 1);
142.325 + checkGraphInArcList(adaptor, n3, 2);
142.326 +
142.327 + checkNodeIds(adaptor);
142.328 + checkArcIds(adaptor);
142.329 +
142.330 + checkGraphNodeMap(adaptor);
142.331 + checkGraphArcMap(adaptor);
142.332 +
142.333 + // Hide a node
142.334 + adaptor.status(n1, false);
142.335 + adaptor.disable(n3);
142.336 + if (!adaptor.status(n3)) adaptor.enable(n3);
142.337 +
142.338 + checkGraphNodeList(adaptor, 2);
142.339 + checkGraphArcList(adaptor, 1);
142.340 + checkGraphConArcList(adaptor, 1);
142.341 +
142.342 + checkGraphOutArcList(adaptor, n2, 1);
142.343 + checkGraphOutArcList(adaptor, n3, 0);
142.344 +
142.345 + checkGraphInArcList(adaptor, n2, 0);
142.346 + checkGraphInArcList(adaptor, n3, 1);
142.347 +
142.348 + checkNodeIds(adaptor);
142.349 + checkArcIds(adaptor);
142.350 +
142.351 + checkGraphNodeMap(adaptor);
142.352 + checkGraphArcMap(adaptor);
142.353 +
142.354 + // Hide all nodes
142.355 + node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
142.356 +
142.357 + checkGraphNodeList(adaptor, 0);
142.358 + checkGraphArcList(adaptor, 0);
142.359 + checkGraphConArcList(adaptor, 0);
142.360 +
142.361 + checkNodeIds(adaptor);
142.362 + checkArcIds(adaptor);
142.363 +
142.364 + checkGraphNodeMap(adaptor);
142.365 + checkGraphArcMap(adaptor);
142.366 +
142.367 + // Check the conversion of nodes and arcs
142.368 + Digraph::Node nd = n3;
142.369 + nd = n3;
142.370 + Adaptor::Node na = n1;
142.371 + na = n2;
142.372 + Digraph::Arc ad = a3;
142.373 + ad = a3;
142.374 + Adaptor::Arc aa = a1;
142.375 + aa = a2;
142.376 +}
142.377 +
142.378 +void checkFilterArcs() {
142.379 + // Check concepts
142.380 + checkConcept<concepts::Digraph, FilterArcs<concepts::Digraph> >();
142.381 + checkConcept<concepts::Digraph, FilterArcs<ListDigraph> >();
142.382 + checkConcept<concepts::AlterableDigraphComponent<>,
142.383 + FilterArcs<ListDigraph> >();
142.384 + checkConcept<concepts::ExtendableDigraphComponent<>,
142.385 + FilterArcs<ListDigraph> >();
142.386 + checkConcept<concepts::ErasableDigraphComponent<>,
142.387 + FilterArcs<ListDigraph> >();
142.388 + checkConcept<concepts::ClearableDigraphComponent<>,
142.389 + FilterArcs<ListDigraph> >();
142.390 +
142.391 + // Create a digraph and an adaptor
142.392 + typedef ListDigraph Digraph;
142.393 + typedef Digraph::ArcMap<bool> ArcFilter;
142.394 + typedef FilterArcs<Digraph, ArcFilter> Adaptor;
142.395 +
142.396 + Digraph digraph;
142.397 + ArcFilter arc_filter(digraph);
142.398 + Adaptor adaptor(digraph, arc_filter);
142.399 +
142.400 + // Add nodes and arcs to the original digraph and the adaptor
142.401 + Digraph::Node n1 = digraph.addNode();
142.402 + Digraph::Node n2 = digraph.addNode();
142.403 + Adaptor::Node n3 = adaptor.addNode();
142.404 +
142.405 + Digraph::Arc a1 = digraph.addArc(n1, n2);
142.406 + Digraph::Arc a2 = digraph.addArc(n1, n3);
142.407 + Adaptor::Arc a3 = adaptor.addArc(n2, n3);
142.408 +
142.409 + arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
142.410 +
142.411 + checkGraphNodeList(adaptor, 3);
142.412 + checkGraphArcList(adaptor, 3);
142.413 + checkGraphConArcList(adaptor, 3);
142.414 +
142.415 + checkGraphOutArcList(adaptor, n1, 2);
142.416 + checkGraphOutArcList(adaptor, n2, 1);
142.417 + checkGraphOutArcList(adaptor, n3, 0);
142.418 +
142.419 + checkGraphInArcList(adaptor, n1, 0);
142.420 + checkGraphInArcList(adaptor, n2, 1);
142.421 + checkGraphInArcList(adaptor, n3, 2);
142.422 +
142.423 + checkNodeIds(adaptor);
142.424 + checkArcIds(adaptor);
142.425 +
142.426 + checkGraphNodeMap(adaptor);
142.427 + checkGraphArcMap(adaptor);
142.428 +
142.429 + // Hide an arc
142.430 + adaptor.status(a2, false);
142.431 + adaptor.disable(a3);
142.432 + if (!adaptor.status(a3)) adaptor.enable(a3);
142.433 +
142.434 + checkGraphNodeList(adaptor, 3);
142.435 + checkGraphArcList(adaptor, 2);
142.436 + checkGraphConArcList(adaptor, 2);
142.437 +
142.438 + checkGraphOutArcList(adaptor, n1, 1);
142.439 + checkGraphOutArcList(adaptor, n2, 1);
142.440 + checkGraphOutArcList(adaptor, n3, 0);
142.441 +
142.442 + checkGraphInArcList(adaptor, n1, 0);
142.443 + checkGraphInArcList(adaptor, n2, 1);
142.444 + checkGraphInArcList(adaptor, n3, 1);
142.445 +
142.446 + checkNodeIds(adaptor);
142.447 + checkArcIds(adaptor);
142.448 +
142.449 + checkGraphNodeMap(adaptor);
142.450 + checkGraphArcMap(adaptor);
142.451 +
142.452 + // Hide all arcs
142.453 + arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
142.454 +
142.455 + checkGraphNodeList(adaptor, 3);
142.456 + checkGraphArcList(adaptor, 0);
142.457 + checkGraphConArcList(adaptor, 0);
142.458 +
142.459 + checkNodeIds(adaptor);
142.460 + checkArcIds(adaptor);
142.461 +
142.462 + checkGraphNodeMap(adaptor);
142.463 + checkGraphArcMap(adaptor);
142.464 +
142.465 + // Check the conversion of nodes and arcs
142.466 + Digraph::Node nd = n3;
142.467 + nd = n3;
142.468 + Adaptor::Node na = n1;
142.469 + na = n2;
142.470 + Digraph::Arc ad = a3;
142.471 + ad = a3;
142.472 + Adaptor::Arc aa = a1;
142.473 + aa = a2;
142.474 +}
142.475 +
142.476 +void checkUndirector() {
142.477 + // Check concepts
142.478 + checkConcept<concepts::Graph, Undirector<concepts::Digraph> >();
142.479 + checkConcept<concepts::Graph, Undirector<ListDigraph> >();
142.480 + checkConcept<concepts::AlterableGraphComponent<>,
142.481 + Undirector<ListDigraph> >();
142.482 + checkConcept<concepts::ExtendableGraphComponent<>,
142.483 + Undirector<ListDigraph> >();
142.484 + checkConcept<concepts::ErasableGraphComponent<>,
142.485 + Undirector<ListDigraph> >();
142.486 + checkConcept<concepts::ClearableGraphComponent<>,
142.487 + Undirector<ListDigraph> >();
142.488 +
142.489 +
142.490 + // Create a digraph and an adaptor
142.491 + typedef ListDigraph Digraph;
142.492 + typedef Undirector<Digraph> Adaptor;
142.493 +
142.494 + Digraph digraph;
142.495 + Adaptor adaptor(digraph);
142.496 +
142.497 + // Add nodes and arcs/edges to the original digraph and the adaptor
142.498 + Digraph::Node n1 = digraph.addNode();
142.499 + Digraph::Node n2 = digraph.addNode();
142.500 + Adaptor::Node n3 = adaptor.addNode();
142.501 +
142.502 + Digraph::Arc a1 = digraph.addArc(n1, n2);
142.503 + Digraph::Arc a2 = digraph.addArc(n1, n3);
142.504 + Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
142.505 +
142.506 + // Check the original digraph
142.507 + checkGraphNodeList(digraph, 3);
142.508 + checkGraphArcList(digraph, 3);
142.509 + checkGraphConArcList(digraph, 3);
142.510 +
142.511 + checkGraphOutArcList(digraph, n1, 2);
142.512 + checkGraphOutArcList(digraph, n2, 1);
142.513 + checkGraphOutArcList(digraph, n3, 0);
142.514 +
142.515 + checkGraphInArcList(digraph, n1, 0);
142.516 + checkGraphInArcList(digraph, n2, 1);
142.517 + checkGraphInArcList(digraph, n3, 2);
142.518 +
142.519 + checkNodeIds(digraph);
142.520 + checkArcIds(digraph);
142.521 +
142.522 + checkGraphNodeMap(digraph);
142.523 + checkGraphArcMap(digraph);
142.524 +
142.525 + // Check the adaptor
142.526 + checkGraphNodeList(adaptor, 3);
142.527 + checkGraphArcList(adaptor, 6);
142.528 + checkGraphEdgeList(adaptor, 3);
142.529 + checkGraphConArcList(adaptor, 6);
142.530 + checkGraphConEdgeList(adaptor, 3);
142.531 +
142.532 + checkGraphIncEdgeArcLists(adaptor, n1, 2);
142.533 + checkGraphIncEdgeArcLists(adaptor, n2, 2);
142.534 + checkGraphIncEdgeArcLists(adaptor, n3, 2);
142.535 +
142.536 + checkNodeIds(adaptor);
142.537 + checkArcIds(adaptor);
142.538 + checkEdgeIds(adaptor);
142.539 +
142.540 + checkGraphNodeMap(adaptor);
142.541 + checkGraphArcMap(adaptor);
142.542 + checkGraphEdgeMap(adaptor);
142.543 +
142.544 + // Check the edges of the adaptor
142.545 + for (Adaptor::EdgeIt e(adaptor); e != INVALID; ++e) {
142.546 + check(adaptor.u(e) == digraph.source(e), "Wrong undir");
142.547 + check(adaptor.v(e) == digraph.target(e), "Wrong undir");
142.548 + }
142.549 +
142.550 + // Check CombinedArcMap
142.551 + typedef Adaptor::CombinedArcMap
142.552 + <Digraph::ArcMap<int>, Digraph::ArcMap<int> > IntCombinedMap;
142.553 + typedef Adaptor::CombinedArcMap
142.554 + <Digraph::ArcMap<bool>, Digraph::ArcMap<bool> > BoolCombinedMap;
142.555 + checkConcept<concepts::ReferenceMap<Adaptor::Arc, int, int&, const int&>,
142.556 + IntCombinedMap>();
142.557 + checkConcept<concepts::ReferenceMap<Adaptor::Arc, bool, bool&, const bool&>,
142.558 + BoolCombinedMap>();
142.559 +
142.560 + Digraph::ArcMap<int> fw_map(digraph), bk_map(digraph);
142.561 + for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
142.562 + fw_map[a] = digraph.id(a);
142.563 + bk_map[a] = -digraph.id(a);
142.564 + }
142.565 +
142.566 + Adaptor::CombinedArcMap<Digraph::ArcMap<int>, Digraph::ArcMap<int> >
142.567 + comb_map(fw_map, bk_map);
142.568 + for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
142.569 + if (adaptor.source(a) == digraph.source(a)) {
142.570 + check(comb_map[a] == fw_map[a], "Wrong combined map");
142.571 + } else {
142.572 + check(comb_map[a] == bk_map[a], "Wrong combined map");
142.573 + }
142.574 + }
142.575 +
142.576 + // Check the conversion of nodes and arcs/edges
142.577 + Digraph::Node nd = n3;
142.578 + nd = n3;
142.579 + Adaptor::Node na = n1;
142.580 + na = n2;
142.581 + Digraph::Arc ad = e3;
142.582 + ad = e3;
142.583 + Adaptor::Edge ea = a1;
142.584 + ea = a2;
142.585 +}
142.586 +
142.587 +void checkResidualDigraph() {
142.588 + // Check concepts
142.589 + checkConcept<concepts::Digraph, ResidualDigraph<concepts::Digraph> >();
142.590 + checkConcept<concepts::Digraph, ResidualDigraph<ListDigraph> >();
142.591 +
142.592 + // Create a digraph and an adaptor
142.593 + typedef ListDigraph Digraph;
142.594 + typedef Digraph::ArcMap<int> IntArcMap;
142.595 + typedef ResidualDigraph<Digraph, IntArcMap> Adaptor;
142.596 +
142.597 + Digraph digraph;
142.598 + IntArcMap capacity(digraph), flow(digraph);
142.599 + Adaptor adaptor(digraph, capacity, flow);
142.600 +
142.601 + Digraph::Node n1 = digraph.addNode();
142.602 + Digraph::Node n2 = digraph.addNode();
142.603 + Digraph::Node n3 = digraph.addNode();
142.604 + Digraph::Node n4 = digraph.addNode();
142.605 +
142.606 + Digraph::Arc a1 = digraph.addArc(n1, n2);
142.607 + Digraph::Arc a2 = digraph.addArc(n1, n3);
142.608 + Digraph::Arc a3 = digraph.addArc(n1, n4);
142.609 + Digraph::Arc a4 = digraph.addArc(n2, n3);
142.610 + Digraph::Arc a5 = digraph.addArc(n2, n4);
142.611 + Digraph::Arc a6 = digraph.addArc(n3, n4);
142.612 +
142.613 + capacity[a1] = 8;
142.614 + capacity[a2] = 6;
142.615 + capacity[a3] = 4;
142.616 + capacity[a4] = 4;
142.617 + capacity[a5] = 6;
142.618 + capacity[a6] = 10;
142.619 +
142.620 + // Check the adaptor with various flow values
142.621 + for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
142.622 + flow[a] = 0;
142.623 + }
142.624 +
142.625 + checkGraphNodeList(adaptor, 4);
142.626 + checkGraphArcList(adaptor, 6);
142.627 + checkGraphConArcList(adaptor, 6);
142.628 +
142.629 + checkGraphOutArcList(adaptor, n1, 3);
142.630 + checkGraphOutArcList(adaptor, n2, 2);
142.631 + checkGraphOutArcList(adaptor, n3, 1);
142.632 + checkGraphOutArcList(adaptor, n4, 0);
142.633 +
142.634 + checkGraphInArcList(adaptor, n1, 0);
142.635 + checkGraphInArcList(adaptor, n2, 1);
142.636 + checkGraphInArcList(adaptor, n3, 2);
142.637 + checkGraphInArcList(adaptor, n4, 3);
142.638 +
142.639 + for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
142.640 + flow[a] = capacity[a] / 2;
142.641 + }
142.642 +
142.643 + checkGraphNodeList(adaptor, 4);
142.644 + checkGraphArcList(adaptor, 12);
142.645 + checkGraphConArcList(adaptor, 12);
142.646 +
142.647 + checkGraphOutArcList(adaptor, n1, 3);
142.648 + checkGraphOutArcList(adaptor, n2, 3);
142.649 + checkGraphOutArcList(adaptor, n3, 3);
142.650 + checkGraphOutArcList(adaptor, n4, 3);
142.651 +
142.652 + checkGraphInArcList(adaptor, n1, 3);
142.653 + checkGraphInArcList(adaptor, n2, 3);
142.654 + checkGraphInArcList(adaptor, n3, 3);
142.655 + checkGraphInArcList(adaptor, n4, 3);
142.656 +
142.657 + checkNodeIds(adaptor);
142.658 + checkArcIds(adaptor);
142.659 +
142.660 + checkGraphNodeMap(adaptor);
142.661 + checkGraphArcMap(adaptor);
142.662 +
142.663 + for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
142.664 + flow[a] = capacity[a];
142.665 + }
142.666 +
142.667 + checkGraphNodeList(adaptor, 4);
142.668 + checkGraphArcList(adaptor, 6);
142.669 + checkGraphConArcList(adaptor, 6);
142.670 +
142.671 + checkGraphOutArcList(adaptor, n1, 0);
142.672 + checkGraphOutArcList(adaptor, n2, 1);
142.673 + checkGraphOutArcList(adaptor, n3, 2);
142.674 + checkGraphOutArcList(adaptor, n4, 3);
142.675 +
142.676 + checkGraphInArcList(adaptor, n1, 3);
142.677 + checkGraphInArcList(adaptor, n2, 2);
142.678 + checkGraphInArcList(adaptor, n3, 1);
142.679 + checkGraphInArcList(adaptor, n4, 0);
142.680 +
142.681 + // Saturate all backward arcs
142.682 + // (set the flow to zero on all forward arcs)
142.683 + for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
142.684 + if (adaptor.backward(a))
142.685 + adaptor.augment(a, adaptor.residualCapacity(a));
142.686 + }
142.687 +
142.688 + checkGraphNodeList(adaptor, 4);
142.689 + checkGraphArcList(adaptor, 6);
142.690 + checkGraphConArcList(adaptor, 6);
142.691 +
142.692 + checkGraphOutArcList(adaptor, n1, 3);
142.693 + checkGraphOutArcList(adaptor, n2, 2);
142.694 + checkGraphOutArcList(adaptor, n3, 1);
142.695 + checkGraphOutArcList(adaptor, n4, 0);
142.696 +
142.697 + checkGraphInArcList(adaptor, n1, 0);
142.698 + checkGraphInArcList(adaptor, n2, 1);
142.699 + checkGraphInArcList(adaptor, n3, 2);
142.700 + checkGraphInArcList(adaptor, n4, 3);
142.701 +
142.702 + // Find maximum flow by augmenting along shortest paths
142.703 + int flow_value = 0;
142.704 + Adaptor::ResidualCapacity res_cap(adaptor);
142.705 + while (true) {
142.706 +
142.707 + Bfs<Adaptor> bfs(adaptor);
142.708 + bfs.run(n1, n4);
142.709 +
142.710 + if (!bfs.reached(n4)) break;
142.711 +
142.712 + Path<Adaptor> p = bfs.path(n4);
142.713 +
142.714 + int min = std::numeric_limits<int>::max();
142.715 + for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
142.716 + if (res_cap[a] < min) min = res_cap[a];
142.717 + }
142.718 +
142.719 + for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
142.720 + adaptor.augment(a, min);
142.721 + }
142.722 + flow_value += min;
142.723 + }
142.724 +
142.725 + check(flow_value == 18, "Wrong flow with res graph adaptor");
142.726 +
142.727 + // Check forward() and backward()
142.728 + for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
142.729 + check(adaptor.forward(a) != adaptor.backward(a),
142.730 + "Wrong forward() or backward()");
142.731 + check((adaptor.forward(a) && adaptor.forward(Digraph::Arc(a)) == a) ||
142.732 + (adaptor.backward(a) && adaptor.backward(Digraph::Arc(a)) == a),
142.733 + "Wrong forward() or backward()");
142.734 + }
142.735 +
142.736 + // Check the conversion of nodes and arcs
142.737 + Digraph::Node nd = Adaptor::NodeIt(adaptor);
142.738 + nd = ++Adaptor::NodeIt(adaptor);
142.739 + Adaptor::Node na = n1;
142.740 + na = n2;
142.741 + Digraph::Arc ad = Adaptor::ArcIt(adaptor);
142.742 + ad = ++Adaptor::ArcIt(adaptor);
142.743 +}
142.744 +
142.745 +void checkSplitNodes() {
142.746 + // Check concepts
142.747 + checkConcept<concepts::Digraph, SplitNodes<concepts::Digraph> >();
142.748 + checkConcept<concepts::Digraph, SplitNodes<ListDigraph> >();
142.749 +
142.750 + // Create a digraph and an adaptor
142.751 + typedef ListDigraph Digraph;
142.752 + typedef SplitNodes<Digraph> Adaptor;
142.753 +
142.754 + Digraph digraph;
142.755 + Adaptor adaptor(digraph);
142.756 +
142.757 + Digraph::Node n1 = digraph.addNode();
142.758 + Digraph::Node n2 = digraph.addNode();
142.759 + Digraph::Node n3 = digraph.addNode();
142.760 +
142.761 + Digraph::Arc a1 = digraph.addArc(n1, n2);
142.762 + Digraph::Arc a2 = digraph.addArc(n1, n3);
142.763 + Digraph::Arc a3 = digraph.addArc(n2, n3);
142.764 +
142.765 + checkGraphNodeList(adaptor, 6);
142.766 + checkGraphArcList(adaptor, 6);
142.767 + checkGraphConArcList(adaptor, 6);
142.768 +
142.769 + checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
142.770 + checkGraphOutArcList(adaptor, adaptor.outNode(n1), 2);
142.771 + checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
142.772 + checkGraphOutArcList(adaptor, adaptor.outNode(n2), 1);
142.773 + checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
142.774 + checkGraphOutArcList(adaptor, adaptor.outNode(n3), 0);
142.775 +
142.776 + checkGraphInArcList(adaptor, adaptor.inNode(n1), 0);
142.777 + checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
142.778 + checkGraphInArcList(adaptor, adaptor.inNode(n2), 1);
142.779 + checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
142.780 + checkGraphInArcList(adaptor, adaptor.inNode(n3), 2);
142.781 + checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
142.782 +
142.783 + checkNodeIds(adaptor);
142.784 + checkArcIds(adaptor);
142.785 +
142.786 + checkGraphNodeMap(adaptor);
142.787 + checkGraphArcMap(adaptor);
142.788 +
142.789 + // Check split
142.790 + for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
142.791 + if (adaptor.origArc(a)) {
142.792 + Digraph::Arc oa = a;
142.793 + check(adaptor.source(a) == adaptor.outNode(digraph.source(oa)),
142.794 + "Wrong split");
142.795 + check(adaptor.target(a) == adaptor.inNode(digraph.target(oa)),
142.796 + "Wrong split");
142.797 + } else {
142.798 + Digraph::Node on = a;
142.799 + check(adaptor.source(a) == adaptor.inNode(on), "Wrong split");
142.800 + check(adaptor.target(a) == adaptor.outNode(on), "Wrong split");
142.801 + }
142.802 + }
142.803 +
142.804 + // Check combined node map
142.805 + typedef Adaptor::CombinedNodeMap
142.806 + <Digraph::NodeMap<int>, Digraph::NodeMap<int> > IntCombinedNodeMap;
142.807 + typedef Adaptor::CombinedNodeMap
142.808 + <Digraph::NodeMap<bool>, Digraph::NodeMap<bool> > BoolCombinedNodeMap;
142.809 + checkConcept<concepts::ReferenceMap<Adaptor::Node, int, int&, const int&>,
142.810 + IntCombinedNodeMap>();
142.811 +//checkConcept<concepts::ReferenceMap<Adaptor::Node, bool, bool&, const bool&>,
142.812 +// BoolCombinedNodeMap>();
142.813 + checkConcept<concepts::ReadWriteMap<Adaptor::Node, bool>,
142.814 + BoolCombinedNodeMap>();
142.815 +
142.816 + Digraph::NodeMap<int> in_map(digraph), out_map(digraph);
142.817 + for (Digraph::NodeIt n(digraph); n != INVALID; ++n) {
142.818 + in_map[n] = digraph.id(n);
142.819 + out_map[n] = -digraph.id(n);
142.820 + }
142.821 +
142.822 + Adaptor::CombinedNodeMap<Digraph::NodeMap<int>, Digraph::NodeMap<int> >
142.823 + node_map(in_map, out_map);
142.824 + for (Adaptor::NodeIt n(adaptor); n != INVALID; ++n) {
142.825 + if (adaptor.inNode(n)) {
142.826 + check(node_map[n] == in_map[n], "Wrong combined node map");
142.827 + } else {
142.828 + check(node_map[n] == out_map[n], "Wrong combined node map");
142.829 + }
142.830 + }
142.831 +
142.832 + // Check combined arc map
142.833 + typedef Adaptor::CombinedArcMap
142.834 + <Digraph::ArcMap<int>, Digraph::NodeMap<int> > IntCombinedArcMap;
142.835 + typedef Adaptor::CombinedArcMap
142.836 + <Digraph::ArcMap<bool>, Digraph::NodeMap<bool> > BoolCombinedArcMap;
142.837 + checkConcept<concepts::ReferenceMap<Adaptor::Arc, int, int&, const int&>,
142.838 + IntCombinedArcMap>();
142.839 +//checkConcept<concepts::ReferenceMap<Adaptor::Arc, bool, bool&, const bool&>,
142.840 +// BoolCombinedArcMap>();
142.841 + checkConcept<concepts::ReadWriteMap<Adaptor::Arc, bool>,
142.842 + BoolCombinedArcMap>();
142.843 +
142.844 + Digraph::ArcMap<int> a_map(digraph);
142.845 + for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
142.846 + a_map[a] = digraph.id(a);
142.847 + }
142.848 +
142.849 + Adaptor::CombinedArcMap<Digraph::ArcMap<int>, Digraph::NodeMap<int> >
142.850 + arc_map(a_map, out_map);
142.851 + for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
142.852 + check(arc_map[adaptor.arc(a)] == a_map[a], "Wrong combined arc map");
142.853 + }
142.854 + for (Digraph::NodeIt n(digraph); n != INVALID; ++n) {
142.855 + check(arc_map[adaptor.arc(n)] == out_map[n], "Wrong combined arc map");
142.856 + }
142.857 +
142.858 + // Check the conversion of nodes
142.859 + Digraph::Node nd = adaptor.inNode(n1);
142.860 + check (nd == n1, "Wrong node conversion");
142.861 + nd = adaptor.outNode(n2);
142.862 + check (nd == n2, "Wrong node conversion");
142.863 +}
142.864 +
142.865 +void checkSubGraph() {
142.866 + // Check concepts
142.867 + checkConcept<concepts::Graph, SubGraph<concepts::Graph> >();
142.868 + checkConcept<concepts::Graph, SubGraph<ListGraph> >();
142.869 + checkConcept<concepts::AlterableGraphComponent<>,
142.870 + SubGraph<ListGraph> >();
142.871 + checkConcept<concepts::ExtendableGraphComponent<>,
142.872 + SubGraph<ListGraph> >();
142.873 + checkConcept<concepts::ErasableGraphComponent<>,
142.874 + SubGraph<ListGraph> >();
142.875 + checkConcept<concepts::ClearableGraphComponent<>,
142.876 + SubGraph<ListGraph> >();
142.877 +
142.878 + // Create a graph and an adaptor
142.879 + typedef ListGraph Graph;
142.880 + typedef Graph::NodeMap<bool> NodeFilter;
142.881 + typedef Graph::EdgeMap<bool> EdgeFilter;
142.882 + typedef SubGraph<Graph, NodeFilter, EdgeFilter> Adaptor;
142.883 +
142.884 + Graph graph;
142.885 + NodeFilter node_filter(graph);
142.886 + EdgeFilter edge_filter(graph);
142.887 + Adaptor adaptor(graph, node_filter, edge_filter);
142.888 +
142.889 + // Add nodes and edges to the original graph and the adaptor
142.890 + Graph::Node n1 = graph.addNode();
142.891 + Graph::Node n2 = graph.addNode();
142.892 + Adaptor::Node n3 = adaptor.addNode();
142.893 + Adaptor::Node n4 = adaptor.addNode();
142.894 +
142.895 + node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
142.896 +
142.897 + Graph::Edge e1 = graph.addEdge(n1, n2);
142.898 + Graph::Edge e2 = graph.addEdge(n1, n3);
142.899 + Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
142.900 + Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
142.901 +
142.902 + edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
142.903 +
142.904 + checkGraphNodeList(adaptor, 4);
142.905 + checkGraphArcList(adaptor, 8);
142.906 + checkGraphEdgeList(adaptor, 4);
142.907 + checkGraphConArcList(adaptor, 8);
142.908 + checkGraphConEdgeList(adaptor, 4);
142.909 +
142.910 + checkGraphIncEdgeArcLists(adaptor, n1, 2);
142.911 + checkGraphIncEdgeArcLists(adaptor, n2, 2);
142.912 + checkGraphIncEdgeArcLists(adaptor, n3, 3);
142.913 + checkGraphIncEdgeArcLists(adaptor, n4, 1);
142.914 +
142.915 + checkNodeIds(adaptor);
142.916 + checkArcIds(adaptor);
142.917 + checkEdgeIds(adaptor);
142.918 +
142.919 + checkGraphNodeMap(adaptor);
142.920 + checkGraphArcMap(adaptor);
142.921 + checkGraphEdgeMap(adaptor);
142.922 +
142.923 + // Hide an edge
142.924 + adaptor.status(e2, false);
142.925 + adaptor.disable(e3);
142.926 + if (!adaptor.status(e3)) adaptor.enable(e3);
142.927 +
142.928 + checkGraphNodeList(adaptor, 4);
142.929 + checkGraphArcList(adaptor, 6);
142.930 + checkGraphEdgeList(adaptor, 3);
142.931 + checkGraphConArcList(adaptor, 6);
142.932 + checkGraphConEdgeList(adaptor, 3);
142.933 +
142.934 + checkGraphIncEdgeArcLists(adaptor, n1, 1);
142.935 + checkGraphIncEdgeArcLists(adaptor, n2, 2);
142.936 + checkGraphIncEdgeArcLists(adaptor, n3, 2);
142.937 + checkGraphIncEdgeArcLists(adaptor, n4, 1);
142.938 +
142.939 + checkNodeIds(adaptor);
142.940 + checkArcIds(adaptor);
142.941 + checkEdgeIds(adaptor);
142.942 +
142.943 + checkGraphNodeMap(adaptor);
142.944 + checkGraphArcMap(adaptor);
142.945 + checkGraphEdgeMap(adaptor);
142.946 +
142.947 + // Hide a node
142.948 + adaptor.status(n1, false);
142.949 + adaptor.disable(n3);
142.950 + if (!adaptor.status(n3)) adaptor.enable(n3);
142.951 +
142.952 + checkGraphNodeList(adaptor, 3);
142.953 + checkGraphArcList(adaptor, 4);
142.954 + checkGraphEdgeList(adaptor, 2);
142.955 + checkGraphConArcList(adaptor, 4);
142.956 + checkGraphConEdgeList(adaptor, 2);
142.957 +
142.958 + checkGraphIncEdgeArcLists(adaptor, n2, 1);
142.959 + checkGraphIncEdgeArcLists(adaptor, n3, 2);
142.960 + checkGraphIncEdgeArcLists(adaptor, n4, 1);
142.961 +
142.962 + checkNodeIds(adaptor);
142.963 + checkArcIds(adaptor);
142.964 + checkEdgeIds(adaptor);
142.965 +
142.966 + checkGraphNodeMap(adaptor);
142.967 + checkGraphArcMap(adaptor);
142.968 + checkGraphEdgeMap(adaptor);
142.969 +
142.970 + // Hide all nodes and edges
142.971 + node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
142.972 + edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
142.973 +
142.974 + checkGraphNodeList(adaptor, 0);
142.975 + checkGraphArcList(adaptor, 0);
142.976 + checkGraphEdgeList(adaptor, 0);
142.977 + checkGraphConArcList(adaptor, 0);
142.978 + checkGraphConEdgeList(adaptor, 0);
142.979 +
142.980 + checkNodeIds(adaptor);
142.981 + checkArcIds(adaptor);
142.982 + checkEdgeIds(adaptor);
142.983 +
142.984 + checkGraphNodeMap(adaptor);
142.985 + checkGraphArcMap(adaptor);
142.986 + checkGraphEdgeMap(adaptor);
142.987 +
142.988 + // Check the conversion of nodes and edges
142.989 + Graph::Node ng = n3;
142.990 + ng = n4;
142.991 + Adaptor::Node na = n1;
142.992 + na = n2;
142.993 + Graph::Edge eg = e3;
142.994 + eg = e4;
142.995 + Adaptor::Edge ea = e1;
142.996 + ea = e2;
142.997 +}
142.998 +
142.999 +void checkFilterNodes2() {
142.1000 + // Check concepts
142.1001 + checkConcept<concepts::Graph, FilterNodes<concepts::Graph> >();
142.1002 + checkConcept<concepts::Graph, FilterNodes<ListGraph> >();
142.1003 + checkConcept<concepts::AlterableGraphComponent<>,
142.1004 + FilterNodes<ListGraph> >();
142.1005 + checkConcept<concepts::ExtendableGraphComponent<>,
142.1006 + FilterNodes<ListGraph> >();
142.1007 + checkConcept<concepts::ErasableGraphComponent<>,
142.1008 + FilterNodes<ListGraph> >();
142.1009 + checkConcept<concepts::ClearableGraphComponent<>,
142.1010 + FilterNodes<ListGraph> >();
142.1011 +
142.1012 + // Create a graph and an adaptor
142.1013 + typedef ListGraph Graph;
142.1014 + typedef Graph::NodeMap<bool> NodeFilter;
142.1015 + typedef FilterNodes<Graph, NodeFilter> Adaptor;
142.1016 +
142.1017 + // Add nodes and edges to the original graph and the adaptor
142.1018 + Graph graph;
142.1019 + NodeFilter node_filter(graph);
142.1020 + Adaptor adaptor(graph, node_filter);
142.1021 +
142.1022 + Graph::Node n1 = graph.addNode();
142.1023 + Graph::Node n2 = graph.addNode();
142.1024 + Adaptor::Node n3 = adaptor.addNode();
142.1025 + Adaptor::Node n4 = adaptor.addNode();
142.1026 +
142.1027 + node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
142.1028 +
142.1029 + Graph::Edge e1 = graph.addEdge(n1, n2);
142.1030 + Graph::Edge e2 = graph.addEdge(n1, n3);
142.1031 + Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
142.1032 + Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
142.1033 +
142.1034 + checkGraphNodeList(adaptor, 4);
142.1035 + checkGraphArcList(adaptor, 8);
142.1036 + checkGraphEdgeList(adaptor, 4);
142.1037 + checkGraphConArcList(adaptor, 8);
142.1038 + checkGraphConEdgeList(adaptor, 4);
142.1039 +
142.1040 + checkGraphIncEdgeArcLists(adaptor, n1, 2);
142.1041 + checkGraphIncEdgeArcLists(adaptor, n2, 2);
142.1042 + checkGraphIncEdgeArcLists(adaptor, n3, 3);
142.1043 + checkGraphIncEdgeArcLists(adaptor, n4, 1);
142.1044 +
142.1045 + checkNodeIds(adaptor);
142.1046 + checkArcIds(adaptor);
142.1047 + checkEdgeIds(adaptor);
142.1048 +
142.1049 + checkGraphNodeMap(adaptor);
142.1050 + checkGraphArcMap(adaptor);
142.1051 + checkGraphEdgeMap(adaptor);
142.1052 +
142.1053 + // Hide a node
142.1054 + adaptor.status(n1, false);
142.1055 + adaptor.disable(n3);
142.1056 + if (!adaptor.status(n3)) adaptor.enable(n3);
142.1057 +
142.1058 + checkGraphNodeList(adaptor, 3);
142.1059 + checkGraphArcList(adaptor, 4);
142.1060 + checkGraphEdgeList(adaptor, 2);
142.1061 + checkGraphConArcList(adaptor, 4);
142.1062 + checkGraphConEdgeList(adaptor, 2);
142.1063 +
142.1064 + checkGraphIncEdgeArcLists(adaptor, n2, 1);
142.1065 + checkGraphIncEdgeArcLists(adaptor, n3, 2);
142.1066 + checkGraphIncEdgeArcLists(adaptor, n4, 1);
142.1067 +
142.1068 + checkNodeIds(adaptor);
142.1069 + checkArcIds(adaptor);
142.1070 + checkEdgeIds(adaptor);
142.1071 +
142.1072 + checkGraphNodeMap(adaptor);
142.1073 + checkGraphArcMap(adaptor);
142.1074 + checkGraphEdgeMap(adaptor);
142.1075 +
142.1076 + // Hide all nodes
142.1077 + node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
142.1078 +
142.1079 + checkGraphNodeList(adaptor, 0);
142.1080 + checkGraphArcList(adaptor, 0);
142.1081 + checkGraphEdgeList(adaptor, 0);
142.1082 + checkGraphConArcList(adaptor, 0);
142.1083 + checkGraphConEdgeList(adaptor, 0);
142.1084 +
142.1085 + checkNodeIds(adaptor);
142.1086 + checkArcIds(adaptor);
142.1087 + checkEdgeIds(adaptor);
142.1088 +
142.1089 + checkGraphNodeMap(adaptor);
142.1090 + checkGraphArcMap(adaptor);
142.1091 + checkGraphEdgeMap(adaptor);
142.1092 +
142.1093 + // Check the conversion of nodes and edges
142.1094 + Graph::Node ng = n3;
142.1095 + ng = n4;
142.1096 + Adaptor::Node na = n1;
142.1097 + na = n2;
142.1098 + Graph::Edge eg = e3;
142.1099 + eg = e4;
142.1100 + Adaptor::Edge ea = e1;
142.1101 + ea = e2;
142.1102 +}
142.1103 +
142.1104 +void checkFilterEdges() {
142.1105 + // Check concepts
142.1106 + checkConcept<concepts::Graph, FilterEdges<concepts::Graph> >();
142.1107 + checkConcept<concepts::Graph, FilterEdges<ListGraph> >();
142.1108 + checkConcept<concepts::AlterableGraphComponent<>,
142.1109 + FilterEdges<ListGraph> >();
142.1110 + checkConcept<concepts::ExtendableGraphComponent<>,
142.1111 + FilterEdges<ListGraph> >();
142.1112 + checkConcept<concepts::ErasableGraphComponent<>,
142.1113 + FilterEdges<ListGraph> >();
142.1114 + checkConcept<concepts::ClearableGraphComponent<>,
142.1115 + FilterEdges<ListGraph> >();
142.1116 +
142.1117 + // Create a graph and an adaptor
142.1118 + typedef ListGraph Graph;
142.1119 + typedef Graph::EdgeMap<bool> EdgeFilter;
142.1120 + typedef FilterEdges<Graph, EdgeFilter> Adaptor;
142.1121 +
142.1122 + Graph graph;
142.1123 + EdgeFilter edge_filter(graph);
142.1124 + Adaptor adaptor(graph, edge_filter);
142.1125 +
142.1126 + // Add nodes and edges to the original graph and the adaptor
142.1127 + Graph::Node n1 = graph.addNode();
142.1128 + Graph::Node n2 = graph.addNode();
142.1129 + Adaptor::Node n3 = adaptor.addNode();
142.1130 + Adaptor::Node n4 = adaptor.addNode();
142.1131 +
142.1132 + Graph::Edge e1 = graph.addEdge(n1, n2);
142.1133 + Graph::Edge e2 = graph.addEdge(n1, n3);
142.1134 + Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
142.1135 + Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
142.1136 +
142.1137 + edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
142.1138 +
142.1139 + checkGraphNodeList(adaptor, 4);
142.1140 + checkGraphArcList(adaptor, 8);
142.1141 + checkGraphEdgeList(adaptor, 4);
142.1142 + checkGraphConArcList(adaptor, 8);
142.1143 + checkGraphConEdgeList(adaptor, 4);
142.1144 +
142.1145 + checkGraphIncEdgeArcLists(adaptor, n1, 2);
142.1146 + checkGraphIncEdgeArcLists(adaptor, n2, 2);
142.1147 + checkGraphIncEdgeArcLists(adaptor, n3, 3);
142.1148 + checkGraphIncEdgeArcLists(adaptor, n4, 1);
142.1149 +
142.1150 + checkNodeIds(adaptor);
142.1151 + checkArcIds(adaptor);
142.1152 + checkEdgeIds(adaptor);
142.1153 +
142.1154 + checkGraphNodeMap(adaptor);
142.1155 + checkGraphArcMap(adaptor);
142.1156 + checkGraphEdgeMap(adaptor);
142.1157 +
142.1158 + // Hide an edge
142.1159 + adaptor.status(e2, false);
142.1160 + adaptor.disable(e3);
142.1161 + if (!adaptor.status(e3)) adaptor.enable(e3);
142.1162 +
142.1163 + checkGraphNodeList(adaptor, 4);
142.1164 + checkGraphArcList(adaptor, 6);
142.1165 + checkGraphEdgeList(adaptor, 3);
142.1166 + checkGraphConArcList(adaptor, 6);
142.1167 + checkGraphConEdgeList(adaptor, 3);
142.1168 +
142.1169 + checkGraphIncEdgeArcLists(adaptor, n1, 1);
142.1170 + checkGraphIncEdgeArcLists(adaptor, n2, 2);
142.1171 + checkGraphIncEdgeArcLists(adaptor, n3, 2);
142.1172 + checkGraphIncEdgeArcLists(adaptor, n4, 1);
142.1173 +
142.1174 + checkNodeIds(adaptor);
142.1175 + checkArcIds(adaptor);
142.1176 + checkEdgeIds(adaptor);
142.1177 +
142.1178 + checkGraphNodeMap(adaptor);
142.1179 + checkGraphArcMap(adaptor);
142.1180 + checkGraphEdgeMap(adaptor);
142.1181 +
142.1182 + // Hide all edges
142.1183 + edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
142.1184 +
142.1185 + checkGraphNodeList(adaptor, 4);
142.1186 + checkGraphArcList(adaptor, 0);
142.1187 + checkGraphEdgeList(adaptor, 0);
142.1188 + checkGraphConArcList(adaptor, 0);
142.1189 + checkGraphConEdgeList(adaptor, 0);
142.1190 +
142.1191 + checkNodeIds(adaptor);
142.1192 + checkArcIds(adaptor);
142.1193 + checkEdgeIds(adaptor);
142.1194 +
142.1195 + checkGraphNodeMap(adaptor);
142.1196 + checkGraphArcMap(adaptor);
142.1197 + checkGraphEdgeMap(adaptor);
142.1198 +
142.1199 + // Check the conversion of nodes and edges
142.1200 + Graph::Node ng = n3;
142.1201 + ng = n4;
142.1202 + Adaptor::Node na = n1;
142.1203 + na = n2;
142.1204 + Graph::Edge eg = e3;
142.1205 + eg = e4;
142.1206 + Adaptor::Edge ea = e1;
142.1207 + ea = e2;
142.1208 +}
142.1209 +
142.1210 +void checkOrienter() {
142.1211 + // Check concepts
142.1212 + checkConcept<concepts::Digraph, Orienter<concepts::Graph> >();
142.1213 + checkConcept<concepts::Digraph, Orienter<ListGraph> >();
142.1214 + checkConcept<concepts::AlterableDigraphComponent<>,
142.1215 + Orienter<ListGraph> >();
142.1216 + checkConcept<concepts::ExtendableDigraphComponent<>,
142.1217 + Orienter<ListGraph> >();
142.1218 + checkConcept<concepts::ErasableDigraphComponent<>,
142.1219 + Orienter<ListGraph> >();
142.1220 + checkConcept<concepts::ClearableDigraphComponent<>,
142.1221 + Orienter<ListGraph> >();
142.1222 +
142.1223 + // Create a graph and an adaptor
142.1224 + typedef ListGraph Graph;
142.1225 + typedef ListGraph::EdgeMap<bool> DirMap;
142.1226 + typedef Orienter<Graph> Adaptor;
142.1227 +
142.1228 + Graph graph;
142.1229 + DirMap dir(graph);
142.1230 + Adaptor adaptor(graph, dir);
142.1231 +
142.1232 + // Add nodes and edges to the original graph and the adaptor
142.1233 + Graph::Node n1 = graph.addNode();
142.1234 + Graph::Node n2 = graph.addNode();
142.1235 + Adaptor::Node n3 = adaptor.addNode();
142.1236 +
142.1237 + Graph::Edge e1 = graph.addEdge(n1, n2);
142.1238 + Graph::Edge e2 = graph.addEdge(n1, n3);
142.1239 + Adaptor::Arc e3 = adaptor.addArc(n2, n3);
142.1240 +
142.1241 + dir[e1] = dir[e2] = dir[e3] = true;
142.1242 +
142.1243 + // Check the original graph
142.1244 + checkGraphNodeList(graph, 3);
142.1245 + checkGraphArcList(graph, 6);
142.1246 + checkGraphConArcList(graph, 6);
142.1247 + checkGraphEdgeList(graph, 3);
142.1248 + checkGraphConEdgeList(graph, 3);
142.1249 +
142.1250 + checkGraphIncEdgeArcLists(graph, n1, 2);
142.1251 + checkGraphIncEdgeArcLists(graph, n2, 2);
142.1252 + checkGraphIncEdgeArcLists(graph, n3, 2);
142.1253 +
142.1254 + checkNodeIds(graph);
142.1255 + checkArcIds(graph);
142.1256 + checkEdgeIds(graph);
142.1257 +
142.1258 + checkGraphNodeMap(graph);
142.1259 + checkGraphArcMap(graph);
142.1260 + checkGraphEdgeMap(graph);
142.1261 +
142.1262 + // Check the adaptor
142.1263 + checkGraphNodeList(adaptor, 3);
142.1264 + checkGraphArcList(adaptor, 3);
142.1265 + checkGraphConArcList(adaptor, 3);
142.1266 +
142.1267 + checkGraphOutArcList(adaptor, n1, 2);
142.1268 + checkGraphOutArcList(adaptor, n2, 1);
142.1269 + checkGraphOutArcList(adaptor, n3, 0);
142.1270 +
142.1271 + checkGraphInArcList(adaptor, n1, 0);
142.1272 + checkGraphInArcList(adaptor, n2, 1);
142.1273 + checkGraphInArcList(adaptor, n3, 2);
142.1274 +
142.1275 + checkNodeIds(adaptor);
142.1276 + checkArcIds(adaptor);
142.1277 +
142.1278 + checkGraphNodeMap(adaptor);
142.1279 + checkGraphArcMap(adaptor);
142.1280 +
142.1281 + // Check direction changing
142.1282 + {
142.1283 + dir[e1] = true;
142.1284 + Adaptor::Node u = adaptor.source(e1);
142.1285 + Adaptor::Node v = adaptor.target(e1);
142.1286 +
142.1287 + dir[e1] = false;
142.1288 + check (u == adaptor.target(e1), "Wrong dir");
142.1289 + check (v == adaptor.source(e1), "Wrong dir");
142.1290 +
142.1291 + check ((u == n1 && v == n2) || (u == n2 && v == n1), "Wrong dir");
142.1292 + dir[e1] = n1 == u;
142.1293 + }
142.1294 +
142.1295 + {
142.1296 + dir[e2] = true;
142.1297 + Adaptor::Node u = adaptor.source(e2);
142.1298 + Adaptor::Node v = adaptor.target(e2);
142.1299 +
142.1300 + dir[e2] = false;
142.1301 + check (u == adaptor.target(e2), "Wrong dir");
142.1302 + check (v == adaptor.source(e2), "Wrong dir");
142.1303 +
142.1304 + check ((u == n1 && v == n3) || (u == n3 && v == n1), "Wrong dir");
142.1305 + dir[e2] = n3 == u;
142.1306 + }
142.1307 +
142.1308 + {
142.1309 + dir[e3] = true;
142.1310 + Adaptor::Node u = adaptor.source(e3);
142.1311 + Adaptor::Node v = adaptor.target(e3);
142.1312 +
142.1313 + dir[e3] = false;
142.1314 + check (u == adaptor.target(e3), "Wrong dir");
142.1315 + check (v == adaptor.source(e3), "Wrong dir");
142.1316 +
142.1317 + check ((u == n2 && v == n3) || (u == n3 && v == n2), "Wrong dir");
142.1318 + dir[e3] = n2 == u;
142.1319 + }
142.1320 +
142.1321 + // Check the adaptor again
142.1322 + checkGraphNodeList(adaptor, 3);
142.1323 + checkGraphArcList(adaptor, 3);
142.1324 + checkGraphConArcList(adaptor, 3);
142.1325 +
142.1326 + checkGraphOutArcList(adaptor, n1, 1);
142.1327 + checkGraphOutArcList(adaptor, n2, 1);
142.1328 + checkGraphOutArcList(adaptor, n3, 1);
142.1329 +
142.1330 + checkGraphInArcList(adaptor, n1, 1);
142.1331 + checkGraphInArcList(adaptor, n2, 1);
142.1332 + checkGraphInArcList(adaptor, n3, 1);
142.1333 +
142.1334 + checkNodeIds(adaptor);
142.1335 + checkArcIds(adaptor);
142.1336 +
142.1337 + checkGraphNodeMap(adaptor);
142.1338 + checkGraphArcMap(adaptor);
142.1339 +
142.1340 + // Check reverseArc()
142.1341 + adaptor.reverseArc(e2);
142.1342 + adaptor.reverseArc(e3);
142.1343 + adaptor.reverseArc(e2);
142.1344 +
142.1345 + checkGraphNodeList(adaptor, 3);
142.1346 + checkGraphArcList(adaptor, 3);
142.1347 + checkGraphConArcList(adaptor, 3);
142.1348 +
142.1349 + checkGraphOutArcList(adaptor, n1, 1);
142.1350 + checkGraphOutArcList(adaptor, n2, 0);
142.1351 + checkGraphOutArcList(adaptor, n3, 2);
142.1352 +
142.1353 + checkGraphInArcList(adaptor, n1, 1);
142.1354 + checkGraphInArcList(adaptor, n2, 2);
142.1355 + checkGraphInArcList(adaptor, n3, 0);
142.1356 +
142.1357 + // Check the conversion of nodes and arcs/edges
142.1358 + Graph::Node ng = n3;
142.1359 + ng = n3;
142.1360 + Adaptor::Node na = n1;
142.1361 + na = n2;
142.1362 + Graph::Edge eg = e3;
142.1363 + eg = e3;
142.1364 + Adaptor::Arc aa = e1;
142.1365 + aa = e2;
142.1366 +}
142.1367 +
142.1368 +void checkCombiningAdaptors() {
142.1369 + // Create a grid graph
142.1370 + GridGraph graph(2,2);
142.1371 + GridGraph::Node n1 = graph(0,0);
142.1372 + GridGraph::Node n2 = graph(0,1);
142.1373 + GridGraph::Node n3 = graph(1,0);
142.1374 + GridGraph::Node n4 = graph(1,1);
142.1375 +
142.1376 + GridGraph::EdgeMap<bool> dir_map(graph);
142.1377 + dir_map[graph.right(n1)] = graph.u(graph.right(n1)) == n1;
142.1378 + dir_map[graph.up(n1)] = graph.u(graph.up(n1)) != n1;
142.1379 + dir_map[graph.left(n4)] = graph.u(graph.left(n4)) != n4;
142.1380 + dir_map[graph.down(n4)] = graph.u(graph.down(n4)) != n4;
142.1381 +
142.1382 + // Apply several adaptors on the grid graph
142.1383 + typedef SplitNodes< ReverseDigraph< const Orienter<
142.1384 + const GridGraph, GridGraph::EdgeMap<bool> > > >
142.1385 + RevSplitGridGraph;
142.1386 + typedef ReverseDigraph<const RevSplitGridGraph> SplitGridGraph;
142.1387 + typedef Undirector<const SplitGridGraph> USplitGridGraph;
142.1388 + typedef Undirector<const USplitGridGraph> UUSplitGridGraph;
142.1389 + checkConcept<concepts::Digraph, RevSplitGridGraph>();
142.1390 + checkConcept<concepts::Digraph, SplitGridGraph>();
142.1391 + checkConcept<concepts::Graph, USplitGridGraph>();
142.1392 + checkConcept<concepts::Graph, UUSplitGridGraph>();
142.1393 +
142.1394 + RevSplitGridGraph rev_adaptor =
142.1395 + splitNodes(reverseDigraph(orienter(graph, dir_map)));
142.1396 + SplitGridGraph adaptor = reverseDigraph(rev_adaptor);
142.1397 + USplitGridGraph uadaptor = undirector(adaptor);
142.1398 + UUSplitGridGraph uuadaptor = undirector(uadaptor);
142.1399 +
142.1400 + // Check adaptor
142.1401 + checkGraphNodeList(adaptor, 8);
142.1402 + checkGraphArcList(adaptor, 8);
142.1403 + checkGraphConArcList(adaptor, 8);
142.1404 +
142.1405 + checkGraphOutArcList(adaptor, rev_adaptor.inNode(n1), 1);
142.1406 + checkGraphOutArcList(adaptor, rev_adaptor.outNode(n1), 1);
142.1407 + checkGraphOutArcList(adaptor, rev_adaptor.inNode(n2), 2);
142.1408 + checkGraphOutArcList(adaptor, rev_adaptor.outNode(n2), 1);
142.1409 + checkGraphOutArcList(adaptor, rev_adaptor.inNode(n3), 1);
142.1410 + checkGraphOutArcList(adaptor, rev_adaptor.outNode(n3), 1);
142.1411 + checkGraphOutArcList(adaptor, rev_adaptor.inNode(n4), 0);
142.1412 + checkGraphOutArcList(adaptor, rev_adaptor.outNode(n4), 1);
142.1413 +
142.1414 + checkGraphInArcList(adaptor, rev_adaptor.inNode(n1), 1);
142.1415 + checkGraphInArcList(adaptor, rev_adaptor.outNode(n1), 1);
142.1416 + checkGraphInArcList(adaptor, rev_adaptor.inNode(n2), 1);
142.1417 + checkGraphInArcList(adaptor, rev_adaptor.outNode(n2), 0);
142.1418 + checkGraphInArcList(adaptor, rev_adaptor.inNode(n3), 1);
142.1419 + checkGraphInArcList(adaptor, rev_adaptor.outNode(n3), 1);
142.1420 + checkGraphInArcList(adaptor, rev_adaptor.inNode(n4), 1);
142.1421 + checkGraphInArcList(adaptor, rev_adaptor.outNode(n4), 2);
142.1422 +
142.1423 + checkNodeIds(adaptor);
142.1424 + checkArcIds(adaptor);
142.1425 +
142.1426 + checkGraphNodeMap(adaptor);
142.1427 + checkGraphArcMap(adaptor);
142.1428 +
142.1429 + // Check uadaptor
142.1430 + checkGraphNodeList(uadaptor, 8);
142.1431 + checkGraphEdgeList(uadaptor, 8);
142.1432 + checkGraphArcList(uadaptor, 16);
142.1433 + checkGraphConEdgeList(uadaptor, 8);
142.1434 + checkGraphConArcList(uadaptor, 16);
142.1435 +
142.1436 + checkNodeIds(uadaptor);
142.1437 + checkEdgeIds(uadaptor);
142.1438 + checkArcIds(uadaptor);
142.1439 +
142.1440 + checkGraphNodeMap(uadaptor);
142.1441 + checkGraphEdgeMap(uadaptor);
142.1442 + checkGraphArcMap(uadaptor);
142.1443 +
142.1444 + checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n1), 2);
142.1445 + checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n1), 2);
142.1446 + checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n2), 3);
142.1447 + checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n2), 1);
142.1448 + checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n3), 2);
142.1449 + checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n3), 2);
142.1450 + checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n4), 1);
142.1451 + checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n4), 3);
142.1452 +
142.1453 + // Check uuadaptor
142.1454 + checkGraphNodeList(uuadaptor, 8);
142.1455 + checkGraphEdgeList(uuadaptor, 16);
142.1456 + checkGraphArcList(uuadaptor, 32);
142.1457 + checkGraphConEdgeList(uuadaptor, 16);
142.1458 + checkGraphConArcList(uuadaptor, 32);
142.1459 +
142.1460 + checkNodeIds(uuadaptor);
142.1461 + checkEdgeIds(uuadaptor);
142.1462 + checkArcIds(uuadaptor);
142.1463 +
142.1464 + checkGraphNodeMap(uuadaptor);
142.1465 + checkGraphEdgeMap(uuadaptor);
142.1466 + checkGraphArcMap(uuadaptor);
142.1467 +}
142.1468 +
142.1469 +int main(int, const char **) {
142.1470 + // Check the digraph adaptors (using ListDigraph)
142.1471 + checkReverseDigraph();
142.1472 + checkSubDigraph();
142.1473 + checkFilterNodes1();
142.1474 + checkFilterArcs();
142.1475 + checkUndirector();
142.1476 + checkResidualDigraph();
142.1477 + checkSplitNodes();
142.1478 +
142.1479 + // Check the graph adaptors (using ListGraph)
142.1480 + checkSubGraph();
142.1481 + checkFilterNodes2();
142.1482 + checkFilterEdges();
142.1483 + checkOrienter();
142.1484 +
142.1485 + // Combine adaptors (using GridGraph)
142.1486 + checkCombiningAdaptors();
142.1487 +
142.1488 + return 0;
142.1489 +}
143.1 --- a/test/bfs_test.cc Fri Nov 13 12:33:33 2009 +0100
143.2 +++ b/test/bfs_test.cc Thu Dec 10 17:05:35 2009 +0100
143.3 @@ -2,7 +2,7 @@
143.4 *
143.5 * This file is a part of LEMON, a generic C++ optimization library.
143.6 *
143.7 - * Copyright (C) 2003-2008
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 @@ -58,41 +58,80 @@
143.13 typedef Digraph::Arc Arc;
143.14
143.15 Digraph G;
143.16 - Node s, t;
143.17 + Node s, t, n;
143.18 Arc e;
143.19 - int l;
143.20 + int l, i;
143.21 bool b;
143.22 BType::DistMap d(G);
143.23 BType::PredMap p(G);
143.24 Path<Digraph> pp;
143.25 + concepts::ReadMap<Node,bool> nm;
143.26
143.27 {
143.28 BType bfs_test(G);
143.29 + const BType& const_bfs_test = bfs_test;
143.30
143.31 bfs_test.run(s);
143.32 bfs_test.run(s,t);
143.33 bfs_test.run();
143.34
143.35 - l = bfs_test.dist(t);
143.36 - e = bfs_test.predArc(t);
143.37 - s = bfs_test.predNode(t);
143.38 - b = bfs_test.reached(t);
143.39 - d = bfs_test.distMap();
143.40 - p = bfs_test.predMap();
143.41 - pp = bfs_test.path(t);
143.42 + bfs_test.init();
143.43 + bfs_test.addSource(s);
143.44 + n = bfs_test.processNextNode();
143.45 + n = bfs_test.processNextNode(t, b);
143.46 + n = bfs_test.processNextNode(nm, n);
143.47 + n = const_bfs_test.nextNode();
143.48 + b = const_bfs_test.emptyQueue();
143.49 + i = const_bfs_test.queueSize();
143.50 +
143.51 + bfs_test.start();
143.52 + bfs_test.start(t);
143.53 + bfs_test.start(nm);
143.54 +
143.55 + l = const_bfs_test.dist(t);
143.56 + e = const_bfs_test.predArc(t);
143.57 + s = const_bfs_test.predNode(t);
143.58 + b = const_bfs_test.reached(t);
143.59 + d = const_bfs_test.distMap();
143.60 + p = const_bfs_test.predMap();
143.61 + pp = const_bfs_test.path(t);
143.62 }
143.63 {
143.64 BType
143.65 ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
143.66 ::SetDistMap<concepts::ReadWriteMap<Node,int> >
143.67 ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
143.68 + ::SetStandardProcessedMap
143.69 ::SetProcessedMap<concepts::WriteMap<Node,bool> >
143.70 - ::SetStandardProcessedMap
143.71 ::Create bfs_test(G);
143.72 +
143.73 + concepts::ReadWriteMap<Node,Arc> pred_map;
143.74 + concepts::ReadWriteMap<Node,int> dist_map;
143.75 + concepts::ReadWriteMap<Node,bool> reached_map;
143.76 + concepts::WriteMap<Node,bool> processed_map;
143.77 +
143.78 + bfs_test
143.79 + .predMap(pred_map)
143.80 + .distMap(dist_map)
143.81 + .reachedMap(reached_map)
143.82 + .processedMap(processed_map);
143.83
143.84 bfs_test.run(s);
143.85 bfs_test.run(s,t);
143.86 bfs_test.run();
143.87 +
143.88 + bfs_test.init();
143.89 + bfs_test.addSource(s);
143.90 + n = bfs_test.processNextNode();
143.91 + n = bfs_test.processNextNode(t, b);
143.92 + n = bfs_test.processNextNode(nm, n);
143.93 + n = bfs_test.nextNode();
143.94 + b = bfs_test.emptyQueue();
143.95 + i = bfs_test.queueSize();
143.96 +
143.97 + bfs_test.start();
143.98 + bfs_test.start(t);
143.99 + bfs_test.start(nm);
143.100
143.101 l = bfs_test.dist(t);
143.102 e = bfs_test.predArc(t);
144.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
144.2 +++ b/test/circulation_test.cc Thu Dec 10 17:05:35 2009 +0100
144.3 @@ -0,0 +1,163 @@
144.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
144.5 + *
144.6 + * This file is a part of LEMON, a generic C++ optimization library.
144.7 + *
144.8 + * Copyright (C) 2003-2009
144.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
144.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
144.11 + *
144.12 + * Permission to use, modify and distribute this software is granted
144.13 + * provided that this copyright notice appears in all copies. For
144.14 + * precise terms see the accompanying LICENSE file.
144.15 + *
144.16 + * This software is provided "AS IS" with no warranty of any kind,
144.17 + * express or implied, and with no claim as to its suitability for any
144.18 + * purpose.
144.19 + *
144.20 + */
144.21 +
144.22 +#include <iostream>
144.23 +
144.24 +#include "test_tools.h"
144.25 +#include <lemon/list_graph.h>
144.26 +#include <lemon/circulation.h>
144.27 +#include <lemon/lgf_reader.h>
144.28 +#include <lemon/concepts/digraph.h>
144.29 +#include <lemon/concepts/maps.h>
144.30 +
144.31 +using namespace lemon;
144.32 +
144.33 +char test_lgf[] =
144.34 + "@nodes\n"
144.35 + "label\n"
144.36 + "0\n"
144.37 + "1\n"
144.38 + "2\n"
144.39 + "3\n"
144.40 + "4\n"
144.41 + "5\n"
144.42 + "@arcs\n"
144.43 + " lcap ucap\n"
144.44 + "0 1 2 10\n"
144.45 + "0 2 2 6\n"
144.46 + "1 3 4 7\n"
144.47 + "1 4 0 5\n"
144.48 + "2 4 1 3\n"
144.49 + "3 5 3 8\n"
144.50 + "4 5 3 7\n"
144.51 + "@attributes\n"
144.52 + "source 0\n"
144.53 + "sink 5\n";
144.54 +
144.55 +void checkCirculationCompile()
144.56 +{
144.57 + typedef int VType;
144.58 + typedef concepts::Digraph Digraph;
144.59 +
144.60 + typedef Digraph::Node Node;
144.61 + typedef Digraph::Arc Arc;
144.62 + typedef concepts::ReadMap<Arc,VType> CapMap;
144.63 + typedef concepts::ReadMap<Node,VType> SupplyMap;
144.64 + typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
144.65 + typedef concepts::WriteMap<Node,bool> BarrierMap;
144.66 +
144.67 + typedef Elevator<Digraph, Digraph::Node> Elev;
144.68 + typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
144.69 +
144.70 + Digraph g;
144.71 + Node n;
144.72 + Arc a;
144.73 + CapMap lcap, ucap;
144.74 + SupplyMap supply;
144.75 + FlowMap flow;
144.76 + BarrierMap bar;
144.77 + VType v;
144.78 + bool b;
144.79 +
144.80 + typedef Circulation<Digraph, CapMap, CapMap, SupplyMap>
144.81 + ::SetFlowMap<FlowMap>
144.82 + ::SetElevator<Elev>
144.83 + ::SetStandardElevator<LinkedElev>
144.84 + ::Create CirculationType;
144.85 + CirculationType circ_test(g, lcap, ucap, supply);
144.86 + const CirculationType& const_circ_test = circ_test;
144.87 +
144.88 + circ_test
144.89 + .lowerMap(lcap)
144.90 + .upperMap(ucap)
144.91 + .supplyMap(supply)
144.92 + .flowMap(flow);
144.93 +
144.94 + circ_test.init();
144.95 + circ_test.greedyInit();
144.96 + circ_test.start();
144.97 + circ_test.run();
144.98 +
144.99 + v = const_circ_test.flow(a);
144.100 + const FlowMap& fm = const_circ_test.flowMap();
144.101 + b = const_circ_test.barrier(n);
144.102 + const_circ_test.barrierMap(bar);
144.103 +
144.104 + ignore_unused_variable_warning(fm);
144.105 +}
144.106 +
144.107 +template <class G, class LM, class UM, class DM>
144.108 +void checkCirculation(const G& g, const LM& lm, const UM& um,
144.109 + const DM& dm, bool find)
144.110 +{
144.111 + Circulation<G, LM, UM, DM> circ(g, lm, um, dm);
144.112 + bool ret = circ.run();
144.113 + if (find) {
144.114 + check(ret, "A feasible solution should have been found.");
144.115 + check(circ.checkFlow(), "The found flow is corrupt.");
144.116 + check(!circ.checkBarrier(), "A barrier should not have been found.");
144.117 + } else {
144.118 + check(!ret, "A feasible solution should not have been found.");
144.119 + check(circ.checkBarrier(), "The found barrier is corrupt.");
144.120 + }
144.121 +}
144.122 +
144.123 +int main (int, char*[])
144.124 +{
144.125 + typedef ListDigraph Digraph;
144.126 + DIGRAPH_TYPEDEFS(Digraph);
144.127 +
144.128 + Digraph g;
144.129 + IntArcMap lo(g), up(g);
144.130 + IntNodeMap delta(g, 0);
144.131 + Node s, t;
144.132 +
144.133 + std::istringstream input(test_lgf);
144.134 + DigraphReader<Digraph>(g,input).
144.135 + arcMap("lcap", lo).
144.136 + arcMap("ucap", up).
144.137 + node("source",s).
144.138 + node("sink",t).
144.139 + run();
144.140 +
144.141 + delta[s] = 7; delta[t] = -7;
144.142 + checkCirculation(g, lo, up, delta, true);
144.143 +
144.144 + delta[s] = 13; delta[t] = -13;
144.145 + checkCirculation(g, lo, up, delta, true);
144.146 +
144.147 + delta[s] = 6; delta[t] = -6;
144.148 + checkCirculation(g, lo, up, delta, false);
144.149 +
144.150 + delta[s] = 14; delta[t] = -14;
144.151 + checkCirculation(g, lo, up, delta, false);
144.152 +
144.153 + delta[s] = 7; delta[t] = -13;
144.154 + checkCirculation(g, lo, up, delta, true);
144.155 +
144.156 + delta[s] = 5; delta[t] = -15;
144.157 + checkCirculation(g, lo, up, delta, true);
144.158 +
144.159 + delta[s] = 10; delta[t] = -11;
144.160 + checkCirculation(g, lo, up, delta, true);
144.161 +
144.162 + delta[s] = 11; delta[t] = -10;
144.163 + checkCirculation(g, lo, up, delta, false);
144.164 +
144.165 + return 0;
144.166 +}
145.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
145.2 +++ b/test/connectivity_test.cc Thu Dec 10 17:05:35 2009 +0100
145.3 @@ -0,0 +1,297 @@
145.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
145.5 + *
145.6 + * This file is a part of LEMON, a generic C++ optimization library.
145.7 + *
145.8 + * Copyright (C) 2003-2009
145.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
145.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
145.11 + *
145.12 + * Permission to use, modify and distribute this software is granted
145.13 + * provided that this copyright notice appears in all copies. For
145.14 + * precise terms see the accompanying LICENSE file.
145.15 + *
145.16 + * This software is provided "AS IS" with no warranty of any kind,
145.17 + * express or implied, and with no claim as to its suitability for any
145.18 + * purpose.
145.19 + *
145.20 + */
145.21 +
145.22 +#include <lemon/connectivity.h>
145.23 +#include <lemon/list_graph.h>
145.24 +#include <lemon/adaptors.h>
145.25 +
145.26 +#include "test_tools.h"
145.27 +
145.28 +using namespace lemon;
145.29 +
145.30 +
145.31 +int main()
145.32 +{
145.33 + typedef ListDigraph Digraph;
145.34 + typedef Undirector<Digraph> Graph;
145.35 +
145.36 + {
145.37 + Digraph d;
145.38 + Digraph::NodeMap<int> order(d);
145.39 + Graph g(d);
145.40 +
145.41 + check(stronglyConnected(d), "The empty digraph is strongly connected");
145.42 + check(countStronglyConnectedComponents(d) == 0,
145.43 + "The empty digraph has 0 strongly connected component");
145.44 + check(connected(g), "The empty graph is connected");
145.45 + check(countConnectedComponents(g) == 0,
145.46 + "The empty graph has 0 connected component");
145.47 +
145.48 + check(biNodeConnected(g), "The empty graph is bi-node-connected");
145.49 + check(countBiNodeConnectedComponents(g) == 0,
145.50 + "The empty graph has 0 bi-node-connected component");
145.51 + check(biEdgeConnected(g), "The empty graph is bi-edge-connected");
145.52 + check(countBiEdgeConnectedComponents(g) == 0,
145.53 + "The empty graph has 0 bi-edge-connected component");
145.54 +
145.55 + check(dag(d), "The empty digraph is DAG.");
145.56 + check(checkedTopologicalSort(d, order), "The empty digraph is DAG.");
145.57 + check(loopFree(d), "The empty digraph is loop-free.");
145.58 + check(parallelFree(d), "The empty digraph is parallel-free.");
145.59 + check(simpleGraph(d), "The empty digraph is simple.");
145.60 +
145.61 + check(acyclic(g), "The empty graph is acyclic.");
145.62 + check(tree(g), "The empty graph is tree.");
145.63 + check(bipartite(g), "The empty graph is bipartite.");
145.64 + check(loopFree(g), "The empty graph is loop-free.");
145.65 + check(parallelFree(g), "The empty graph is parallel-free.");
145.66 + check(simpleGraph(g), "The empty graph is simple.");
145.67 + }
145.68 +
145.69 + {
145.70 + Digraph d;
145.71 + Digraph::NodeMap<int> order(d);
145.72 + Graph g(d);
145.73 + Digraph::Node n = d.addNode();
145.74 +
145.75 + check(stronglyConnected(d), "This digraph is strongly connected");
145.76 + check(countStronglyConnectedComponents(d) == 1,
145.77 + "This digraph has 1 strongly connected component");
145.78 + check(connected(g), "This graph is connected");
145.79 + check(countConnectedComponents(g) == 1,
145.80 + "This graph has 1 connected component");
145.81 +
145.82 + check(biNodeConnected(g), "This graph is bi-node-connected");
145.83 + check(countBiNodeConnectedComponents(g) == 0,
145.84 + "This graph has 0 bi-node-connected component");
145.85 + check(biEdgeConnected(g), "This graph is bi-edge-connected");
145.86 + check(countBiEdgeConnectedComponents(g) == 1,
145.87 + "This graph has 1 bi-edge-connected component");
145.88 +
145.89 + check(dag(d), "This digraph is DAG.");
145.90 + check(checkedTopologicalSort(d, order), "This digraph is DAG.");
145.91 + check(loopFree(d), "This digraph is loop-free.");
145.92 + check(parallelFree(d), "This digraph is parallel-free.");
145.93 + check(simpleGraph(d), "This digraph is simple.");
145.94 +
145.95 + check(acyclic(g), "This graph is acyclic.");
145.96 + check(tree(g), "This graph is tree.");
145.97 + check(bipartite(g), "This graph is bipartite.");
145.98 + check(loopFree(g), "This graph is loop-free.");
145.99 + check(parallelFree(g), "This graph is parallel-free.");
145.100 + check(simpleGraph(g), "This graph is simple.");
145.101 + }
145.102 +
145.103 + {
145.104 + Digraph d;
145.105 + Digraph::NodeMap<int> order(d);
145.106 + Graph g(d);
145.107 +
145.108 + Digraph::Node n1 = d.addNode();
145.109 + Digraph::Node n2 = d.addNode();
145.110 + Digraph::Node n3 = d.addNode();
145.111 + Digraph::Node n4 = d.addNode();
145.112 + Digraph::Node n5 = d.addNode();
145.113 + Digraph::Node n6 = d.addNode();
145.114 +
145.115 + d.addArc(n1, n3);
145.116 + d.addArc(n3, n2);
145.117 + d.addArc(n2, n1);
145.118 + d.addArc(n4, n2);
145.119 + d.addArc(n4, n3);
145.120 + d.addArc(n5, n6);
145.121 + d.addArc(n6, n5);
145.122 +
145.123 + check(!stronglyConnected(d), "This digraph is not strongly connected");
145.124 + check(countStronglyConnectedComponents(d) == 3,
145.125 + "This digraph has 3 strongly connected components");
145.126 + check(!connected(g), "This graph is not connected");
145.127 + check(countConnectedComponents(g) == 2,
145.128 + "This graph has 2 connected components");
145.129 +
145.130 + check(!dag(d), "This digraph is not DAG.");
145.131 + check(!checkedTopologicalSort(d, order), "This digraph is not DAG.");
145.132 + check(loopFree(d), "This digraph is loop-free.");
145.133 + check(parallelFree(d), "This digraph is parallel-free.");
145.134 + check(simpleGraph(d), "This digraph is simple.");
145.135 +
145.136 + check(!acyclic(g), "This graph is not acyclic.");
145.137 + check(!tree(g), "This graph is not tree.");
145.138 + check(!bipartite(g), "This graph is not bipartite.");
145.139 + check(loopFree(g), "This graph is loop-free.");
145.140 + check(!parallelFree(g), "This graph is not parallel-free.");
145.141 + check(!simpleGraph(g), "This graph is not simple.");
145.142 +
145.143 + d.addArc(n3, n3);
145.144 +
145.145 + check(!loopFree(d), "This digraph is not loop-free.");
145.146 + check(!loopFree(g), "This graph is not loop-free.");
145.147 + check(!simpleGraph(d), "This digraph is not simple.");
145.148 +
145.149 + d.addArc(n3, n2);
145.150 +
145.151 + check(!parallelFree(d), "This digraph is not parallel-free.");
145.152 + }
145.153 +
145.154 + {
145.155 + Digraph d;
145.156 + Digraph::ArcMap<bool> cutarcs(d, false);
145.157 + Graph g(d);
145.158 +
145.159 + Digraph::Node n1 = d.addNode();
145.160 + Digraph::Node n2 = d.addNode();
145.161 + Digraph::Node n3 = d.addNode();
145.162 + Digraph::Node n4 = d.addNode();
145.163 + Digraph::Node n5 = d.addNode();
145.164 + Digraph::Node n6 = d.addNode();
145.165 + Digraph::Node n7 = d.addNode();
145.166 + Digraph::Node n8 = d.addNode();
145.167 +
145.168 + d.addArc(n1, n2);
145.169 + d.addArc(n5, n1);
145.170 + d.addArc(n2, n8);
145.171 + d.addArc(n8, n5);
145.172 + d.addArc(n6, n4);
145.173 + d.addArc(n4, n6);
145.174 + d.addArc(n2, n5);
145.175 + d.addArc(n1, n8);
145.176 + d.addArc(n6, n7);
145.177 + d.addArc(n7, n6);
145.178 +
145.179 + check(!stronglyConnected(d), "This digraph is not strongly connected");
145.180 + check(countStronglyConnectedComponents(d) == 3,
145.181 + "This digraph has 3 strongly connected components");
145.182 + Digraph::NodeMap<int> scomp1(d);
145.183 + check(stronglyConnectedComponents(d, scomp1) == 3,
145.184 + "This digraph has 3 strongly connected components");
145.185 + check(scomp1[n1] != scomp1[n3] && scomp1[n1] != scomp1[n4] &&
145.186 + scomp1[n3] != scomp1[n4], "Wrong stronglyConnectedComponents()");
145.187 + check(scomp1[n1] == scomp1[n2] && scomp1[n1] == scomp1[n5] &&
145.188 + scomp1[n1] == scomp1[n8], "Wrong stronglyConnectedComponents()");
145.189 + check(scomp1[n4] == scomp1[n6] && scomp1[n4] == scomp1[n7],
145.190 + "Wrong stronglyConnectedComponents()");
145.191 + Digraph::ArcMap<bool> scut1(d, false);
145.192 + check(stronglyConnectedCutArcs(d, scut1) == 0,
145.193 + "This digraph has 0 strongly connected cut arc.");
145.194 + for (Digraph::ArcIt a(d); a != INVALID; ++a) {
145.195 + check(!scut1[a], "Wrong stronglyConnectedCutArcs()");
145.196 + }
145.197 +
145.198 + check(!connected(g), "This graph is not connected");
145.199 + check(countConnectedComponents(g) == 3,
145.200 + "This graph has 3 connected components");
145.201 + Graph::NodeMap<int> comp(g);
145.202 + check(connectedComponents(g, comp) == 3,
145.203 + "This graph has 3 connected components");
145.204 + check(comp[n1] != comp[n3] && comp[n1] != comp[n4] &&
145.205 + comp[n3] != comp[n4], "Wrong connectedComponents()");
145.206 + check(comp[n1] == comp[n2] && comp[n1] == comp[n5] &&
145.207 + comp[n1] == comp[n8], "Wrong connectedComponents()");
145.208 + check(comp[n4] == comp[n6] && comp[n4] == comp[n7],
145.209 + "Wrong connectedComponents()");
145.210 +
145.211 + cutarcs[d.addArc(n3, n1)] = true;
145.212 + cutarcs[d.addArc(n3, n5)] = true;
145.213 + cutarcs[d.addArc(n3, n8)] = true;
145.214 + cutarcs[d.addArc(n8, n6)] = true;
145.215 + cutarcs[d.addArc(n8, n7)] = true;
145.216 +
145.217 + check(!stronglyConnected(d), "This digraph is not strongly connected");
145.218 + check(countStronglyConnectedComponents(d) == 3,
145.219 + "This digraph has 3 strongly connected components");
145.220 + Digraph::NodeMap<int> scomp2(d);
145.221 + check(stronglyConnectedComponents(d, scomp2) == 3,
145.222 + "This digraph has 3 strongly connected components");
145.223 + check(scomp2[n3] == 0, "Wrong stronglyConnectedComponents()");
145.224 + check(scomp2[n1] == 1 && scomp2[n2] == 1 && scomp2[n5] == 1 &&
145.225 + scomp2[n8] == 1, "Wrong stronglyConnectedComponents()");
145.226 + check(scomp2[n4] == 2 && scomp2[n6] == 2 && scomp2[n7] == 2,
145.227 + "Wrong stronglyConnectedComponents()");
145.228 + Digraph::ArcMap<bool> scut2(d, false);
145.229 + check(stronglyConnectedCutArcs(d, scut2) == 5,
145.230 + "This digraph has 5 strongly connected cut arcs.");
145.231 + for (Digraph::ArcIt a(d); a != INVALID; ++a) {
145.232 + check(scut2[a] == cutarcs[a], "Wrong stronglyConnectedCutArcs()");
145.233 + }
145.234 + }
145.235 +
145.236 + {
145.237 + // DAG example for topological sort from the book New Algorithms
145.238 + // (T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein)
145.239 + Digraph d;
145.240 + Digraph::NodeMap<int> order(d);
145.241 +
145.242 + Digraph::Node belt = d.addNode();
145.243 + Digraph::Node trousers = d.addNode();
145.244 + Digraph::Node necktie = d.addNode();
145.245 + Digraph::Node coat = d.addNode();
145.246 + Digraph::Node socks = d.addNode();
145.247 + Digraph::Node shirt = d.addNode();
145.248 + Digraph::Node shoe = d.addNode();
145.249 + Digraph::Node watch = d.addNode();
145.250 + Digraph::Node pants = d.addNode();
145.251 +
145.252 + d.addArc(socks, shoe);
145.253 + d.addArc(pants, shoe);
145.254 + d.addArc(pants, trousers);
145.255 + d.addArc(trousers, shoe);
145.256 + d.addArc(trousers, belt);
145.257 + d.addArc(belt, coat);
145.258 + d.addArc(shirt, belt);
145.259 + d.addArc(shirt, necktie);
145.260 + d.addArc(necktie, coat);
145.261 +
145.262 + check(dag(d), "This digraph is DAG.");
145.263 + topologicalSort(d, order);
145.264 + for (Digraph::ArcIt a(d); a != INVALID; ++a) {
145.265 + check(order[d.source(a)] < order[d.target(a)],
145.266 + "Wrong topologicalSort()");
145.267 + }
145.268 + }
145.269 +
145.270 + {
145.271 + ListGraph g;
145.272 + ListGraph::NodeMap<bool> map(g);
145.273 +
145.274 + ListGraph::Node n1 = g.addNode();
145.275 + ListGraph::Node n2 = g.addNode();
145.276 + ListGraph::Node n3 = g.addNode();
145.277 + ListGraph::Node n4 = g.addNode();
145.278 + ListGraph::Node n5 = g.addNode();
145.279 + ListGraph::Node n6 = g.addNode();
145.280 + ListGraph::Node n7 = g.addNode();
145.281 +
145.282 + g.addEdge(n1, n3);
145.283 + g.addEdge(n1, n4);
145.284 + g.addEdge(n2, n5);
145.285 + g.addEdge(n3, n6);
145.286 + g.addEdge(n4, n6);
145.287 + g.addEdge(n4, n7);
145.288 + g.addEdge(n5, n7);
145.289 +
145.290 + check(bipartite(g), "This graph is bipartite");
145.291 + check(bipartitePartitions(g, map), "This graph is bipartite");
145.292 +
145.293 + check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7],
145.294 + "Wrong bipartitePartitions()");
145.295 + check(map[n3] == map[n4] && map[n3] == map[n5],
145.296 + "Wrong bipartitePartitions()");
145.297 + }
145.298 +
145.299 + return 0;
145.300 +}
146.1 --- a/test/counter_test.cc Fri Nov 13 12:33:33 2009 +0100
146.2 +++ b/test/counter_test.cc Thu Dec 10 17:05:35 2009 +0100
146.3 @@ -2,7 +2,7 @@
146.4 *
146.5 * This file is a part of LEMON, a generic C++ optimization library.
146.6 *
146.7 - * Copyright (C) 2003-2008
146.8 + * Copyright (C) 2003-2009
146.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
146.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
146.11 *
146.12 @@ -18,59 +18,86 @@
146.13
146.14 #include <lemon/counter.h>
146.15 #include <vector>
146.16 +#include <sstream>
146.17 +
146.18 +#include "test/test_tools.h"
146.19
146.20 using namespace lemon;
146.21
146.22 template <typename T>
146.23 void bubbleSort(std::vector<T>& v) {
146.24 - Counter op("Bubble Sort - Operations: ");
146.25 - Counter::NoSubCounter as(op, "Assignments: ");
146.26 - Counter::NoSubCounter co(op, "Comparisons: ");
146.27 - for (int i = v.size()-1; i > 0; --i) {
146.28 - for (int j = 0; j < i; ++j) {
146.29 - if (v[j] > v[j+1]) {
146.30 - T tmp = v[j];
146.31 - v[j] = v[j+1];
146.32 - v[j+1] = tmp;
146.33 - as += 3;
146.34 + std::stringstream s1, s2, s3;
146.35 + {
146.36 + Counter op("Bubble Sort - Operations: ", s1);
146.37 + Counter::SubCounter as(op, "Assignments: ", s2);
146.38 + Counter::SubCounter co(op, "Comparisons: ", s3);
146.39 + for (int i = v.size()-1; i > 0; --i) {
146.40 + for (int j = 0; j < i; ++j) {
146.41 + if (v[j] > v[j+1]) {
146.42 + T tmp = v[j];
146.43 + v[j] = v[j+1];
146.44 + v[j+1] = tmp;
146.45 + as += 3;
146.46 + }
146.47 + ++co;
146.48 }
146.49 - ++co;
146.50 }
146.51 }
146.52 + check(s1.str() == "Bubble Sort - Operations: 102\n", "Wrong counter");
146.53 + check(s2.str() == "Assignments: 57\n", "Wrong subcounter");
146.54 + check(s3.str() == "Comparisons: 45\n", "Wrong subcounter");
146.55 }
146.56
146.57 template <typename T>
146.58 void insertionSort(std::vector<T>& v) {
146.59 - Counter op("Insertion Sort - Operations: ");
146.60 - Counter::NoSubCounter as(op, "Assignments: ");
146.61 - Counter::NoSubCounter co(op, "Comparisons: ");
146.62 - for (int i = 1; i < int(v.size()); ++i) {
146.63 - T value = v[i];
146.64 - ++as;
146.65 - int j = i;
146.66 - while (j > 0 && v[j-1] > value) {
146.67 - v[j] = v[j-1];
146.68 - --j;
146.69 - ++co; ++as;
146.70 + std::stringstream s1, s2, s3;
146.71 + {
146.72 + Counter op("Insertion Sort - Operations: ", s1);
146.73 + Counter::SubCounter as(op, "Assignments: ", s2);
146.74 + Counter::SubCounter co(op, "Comparisons: ", s3);
146.75 + for (int i = 1; i < int(v.size()); ++i) {
146.76 + T value = v[i];
146.77 + ++as;
146.78 + int j = i;
146.79 + while (j > 0 && v[j-1] > value) {
146.80 + v[j] = v[j-1];
146.81 + --j;
146.82 + ++co; ++as;
146.83 + }
146.84 + v[j] = value;
146.85 + ++as;
146.86 }
146.87 - v[j] = value;
146.88 - ++as;
146.89 }
146.90 + check(s1.str() == "Insertion Sort - Operations: 56\n", "Wrong counter");
146.91 + check(s2.str() == "Assignments: 37\n", "Wrong subcounter");
146.92 + check(s3.str() == "Comparisons: 19\n", "Wrong subcounter");
146.93 }
146.94
146.95 template <typename MyCounter>
146.96 -void counterTest() {
146.97 - MyCounter c("Main Counter: ");
146.98 - c++;
146.99 - typename MyCounter::SubCounter d(c, "SubCounter: ");
146.100 - d++;
146.101 - typename MyCounter::SubCounter::NoSubCounter e(d, "SubSubCounter: ");
146.102 - e++;
146.103 - d+=3;
146.104 - c-=4;
146.105 - e-=2;
146.106 - c.reset(2);
146.107 - c.reset();
146.108 +void counterTest(bool output) {
146.109 + std::stringstream s1, s2, s3;
146.110 + {
146.111 + MyCounter c("Main Counter: ", s1);
146.112 + c++;
146.113 + typename MyCounter::SubCounter d(c, "SubCounter: ", s2);
146.114 + d++;
146.115 + typename MyCounter::SubCounter::NoSubCounter e(d, "SubSubCounter: ", s3);
146.116 + e++;
146.117 + d+=3;
146.118 + c-=4;
146.119 + e-=2;
146.120 + c.reset(2);
146.121 + c.reset();
146.122 + }
146.123 + if (output) {
146.124 + check(s1.str() == "Main Counter: 3\n", "Wrong Counter");
146.125 + check(s2.str() == "SubCounter: 3\n", "Wrong SubCounter");
146.126 + check(s3.str() == "", "Wrong NoSubCounter");
146.127 + } else {
146.128 + check(s1.str() == "", "Wrong NoCounter");
146.129 + check(s2.str() == "", "Wrong SubCounter");
146.130 + check(s3.str() == "", "Wrong NoSubCounter");
146.131 + }
146.132 }
146.133
146.134 void init(std::vector<int>& v) {
146.135 @@ -80,8 +107,8 @@
146.136
146.137 int main()
146.138 {
146.139 - counterTest<Counter>();
146.140 - counterTest<NoCounter>();
146.141 + counterTest<Counter>(true);
146.142 + counterTest<NoCounter>(false);
146.143
146.144 std::vector<int> x(10);
146.145 init(x); bubbleSort(x);
147.1 --- a/test/dfs_test.cc Fri Nov 13 12:33:33 2009 +0100
147.2 +++ b/test/dfs_test.cc Thu Dec 10 17:05:35 2009 +0100
147.3 @@ -2,7 +2,7 @@
147.4 *
147.5 * This file is a part of LEMON, a generic C++ optimization library.
147.6 *
147.7 - * Copyright (C) 2003-2008
147.8 + * Copyright (C) 2003-2009
147.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
147.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
147.11 *
147.12 @@ -62,39 +62,74 @@
147.13 Digraph G;
147.14 Node s, t;
147.15 Arc e;
147.16 - int l;
147.17 + int l, i;
147.18 bool b;
147.19 DType::DistMap d(G);
147.20 DType::PredMap p(G);
147.21 Path<Digraph> pp;
147.22 + concepts::ReadMap<Arc,bool> am;
147.23
147.24 {
147.25 DType dfs_test(G);
147.26 + const DType& const_dfs_test = dfs_test;
147.27
147.28 dfs_test.run(s);
147.29 dfs_test.run(s,t);
147.30 dfs_test.run();
147.31
147.32 - l = dfs_test.dist(t);
147.33 - e = dfs_test.predArc(t);
147.34 - s = dfs_test.predNode(t);
147.35 - b = dfs_test.reached(t);
147.36 - d = dfs_test.distMap();
147.37 - p = dfs_test.predMap();
147.38 - pp = dfs_test.path(t);
147.39 + dfs_test.init();
147.40 + dfs_test.addSource(s);
147.41 + e = dfs_test.processNextArc();
147.42 + e = const_dfs_test.nextArc();
147.43 + b = const_dfs_test.emptyQueue();
147.44 + i = const_dfs_test.queueSize();
147.45 +
147.46 + dfs_test.start();
147.47 + dfs_test.start(t);
147.48 + dfs_test.start(am);
147.49 +
147.50 + l = const_dfs_test.dist(t);
147.51 + e = const_dfs_test.predArc(t);
147.52 + s = const_dfs_test.predNode(t);
147.53 + b = const_dfs_test.reached(t);
147.54 + d = const_dfs_test.distMap();
147.55 + p = const_dfs_test.predMap();
147.56 + pp = const_dfs_test.path(t);
147.57 }
147.58 {
147.59 DType
147.60 ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
147.61 ::SetDistMap<concepts::ReadWriteMap<Node,int> >
147.62 ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
147.63 + ::SetStandardProcessedMap
147.64 ::SetProcessedMap<concepts::WriteMap<Node,bool> >
147.65 - ::SetStandardProcessedMap
147.66 ::Create dfs_test(G);
147.67
147.68 + concepts::ReadWriteMap<Node,Arc> pred_map;
147.69 + concepts::ReadWriteMap<Node,int> dist_map;
147.70 + concepts::ReadWriteMap<Node,bool> reached_map;
147.71 + concepts::WriteMap<Node,bool> processed_map;
147.72 +
147.73 + dfs_test
147.74 + .predMap(pred_map)
147.75 + .distMap(dist_map)
147.76 + .reachedMap(reached_map)
147.77 + .processedMap(processed_map);
147.78 +
147.79 dfs_test.run(s);
147.80 dfs_test.run(s,t);
147.81 dfs_test.run();
147.82 + dfs_test.init();
147.83 +
147.84 + dfs_test.addSource(s);
147.85 + e = dfs_test.processNextArc();
147.86 + e = dfs_test.nextArc();
147.87 + b = dfs_test.emptyQueue();
147.88 + i = dfs_test.queueSize();
147.89 +
147.90 + dfs_test.start();
147.91 + dfs_test.start(t);
147.92 + dfs_test.start(am);
147.93
147.94 l = dfs_test.dist(t);
147.95 e = dfs_test.predArc(t);
148.1 --- a/test/digraph_test.cc Fri Nov 13 12:33:33 2009 +0100
148.2 +++ b/test/digraph_test.cc Thu Dec 10 17:05:35 2009 +0100
148.3 @@ -2,7 +2,7 @@
148.4 *
148.5 * This file is a part of LEMON, a generic C++ optimization library.
148.6 *
148.7 - * Copyright (C) 2003-2008
148.8 + * Copyright (C) 2003-2009
148.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
148.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
148.11 *
148.12 @@ -19,8 +19,7 @@
148.13 #include <lemon/concepts/digraph.h>
148.14 #include <lemon/list_graph.h>
148.15 #include <lemon/smart_graph.h>
148.16 -//#include <lemon/full_graph.h>
148.17 -//#include <lemon/hypercube_graph.h>
148.18 +#include <lemon/full_graph.h>
148.19
148.20 #include "test_tools.h"
148.21 #include "graph_test.h"
148.22 @@ -29,7 +28,7 @@
148.23 using namespace lemon::concepts;
148.24
148.25 template <class Digraph>
148.26 -void checkDigraph() {
148.27 +void checkDigraphBuild() {
148.28 TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
148.29 Digraph G;
148.30
148.31 @@ -58,7 +57,208 @@
148.32
148.33 checkGraphConArcList(G, 1);
148.34
148.35 - Arc a2 = G.addArc(n2, n1), a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
148.36 + Arc a2 = G.addArc(n2, n1),
148.37 + a3 = G.addArc(n2, n3),
148.38 + a4 = G.addArc(n2, n3);
148.39 +
148.40 + checkGraphNodeList(G, 3);
148.41 + checkGraphArcList(G, 4);
148.42 +
148.43 + checkGraphOutArcList(G, n1, 1);
148.44 + checkGraphOutArcList(G, n2, 3);
148.45 + checkGraphOutArcList(G, n3, 0);
148.46 +
148.47 + checkGraphInArcList(G, n1, 1);
148.48 + checkGraphInArcList(G, n2, 1);
148.49 + checkGraphInArcList(G, n3, 2);
148.50 +
148.51 + checkGraphConArcList(G, 4);
148.52 +
148.53 + checkNodeIds(G);
148.54 + checkArcIds(G);
148.55 + checkGraphNodeMap(G);
148.56 + checkGraphArcMap(G);
148.57 +}
148.58 +
148.59 +template <class Digraph>
148.60 +void checkDigraphSplit() {
148.61 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
148.62 +
148.63 + Digraph G;
148.64 + Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
148.65 + Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
148.66 + a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
148.67 +
148.68 + Node n4 = G.split(n2);
148.69 +
148.70 + check(G.target(OutArcIt(G, n2)) == n4 &&
148.71 + G.source(InArcIt(G, n4)) == n2,
148.72 + "Wrong split.");
148.73 +
148.74 + checkGraphNodeList(G, 4);
148.75 + checkGraphArcList(G, 5);
148.76 +
148.77 + checkGraphOutArcList(G, n1, 1);
148.78 + checkGraphOutArcList(G, n2, 1);
148.79 + checkGraphOutArcList(G, n3, 0);
148.80 + checkGraphOutArcList(G, n4, 3);
148.81 +
148.82 + checkGraphInArcList(G, n1, 1);
148.83 + checkGraphInArcList(G, n2, 1);
148.84 + checkGraphInArcList(G, n3, 2);
148.85 + checkGraphInArcList(G, n4, 1);
148.86 +
148.87 + checkGraphConArcList(G, 5);
148.88 +}
148.89 +
148.90 +template <class Digraph>
148.91 +void checkDigraphAlter() {
148.92 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
148.93 +
148.94 + Digraph G;
148.95 + Node n1 = G.addNode(), n2 = G.addNode(),
148.96 + n3 = G.addNode(), n4 = G.addNode();
148.97 + Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
148.98 + a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3),
148.99 + a5 = G.addArc(n2, n4);
148.100 +
148.101 + checkGraphNodeList(G, 4);
148.102 + checkGraphArcList(G, 5);
148.103 +
148.104 + // Check changeSource() and changeTarget()
148.105 + G.changeTarget(a4, n1);
148.106 +
148.107 + checkGraphNodeList(G, 4);
148.108 + checkGraphArcList(G, 5);
148.109 +
148.110 + checkGraphOutArcList(G, n1, 1);
148.111 + checkGraphOutArcList(G, n2, 1);
148.112 + checkGraphOutArcList(G, n3, 0);
148.113 + checkGraphOutArcList(G, n4, 3);
148.114 +
148.115 + checkGraphInArcList(G, n1, 2);
148.116 + checkGraphInArcList(G, n2, 1);
148.117 + checkGraphInArcList(G, n3, 1);
148.118 + checkGraphInArcList(G, n4, 1);
148.119 +
148.120 + checkGraphConArcList(G, 5);
148.121 +
148.122 + G.changeSource(a4, n3);
148.123 +
148.124 + checkGraphNodeList(G, 4);
148.125 + checkGraphArcList(G, 5);
148.126 +
148.127 + checkGraphOutArcList(G, n1, 1);
148.128 + checkGraphOutArcList(G, n2, 1);
148.129 + checkGraphOutArcList(G, n3, 1);
148.130 + checkGraphOutArcList(G, n4, 2);
148.131 +
148.132 + checkGraphInArcList(G, n1, 2);
148.133 + checkGraphInArcList(G, n2, 1);
148.134 + checkGraphInArcList(G, n3, 1);
148.135 + checkGraphInArcList(G, n4, 1);
148.136 +
148.137 + checkGraphConArcList(G, 5);
148.138 +
148.139 + // Check contract()
148.140 + G.contract(n2, n4, false);
148.141 +
148.142 + checkGraphNodeList(G, 3);
148.143 + checkGraphArcList(G, 5);
148.144 +
148.145 + checkGraphOutArcList(G, n1, 1);
148.146 + checkGraphOutArcList(G, n2, 3);
148.147 + checkGraphOutArcList(G, n3, 1);
148.148 +
148.149 + checkGraphInArcList(G, n1, 2);
148.150 + checkGraphInArcList(G, n2, 2);
148.151 + checkGraphInArcList(G, n3, 1);
148.152 +
148.153 + checkGraphConArcList(G, 5);
148.154 +
148.155 + G.contract(n2, n1);
148.156 +
148.157 + checkGraphNodeList(G, 2);
148.158 + checkGraphArcList(G, 3);
148.159 +
148.160 + checkGraphOutArcList(G, n2, 2);
148.161 + checkGraphOutArcList(G, n3, 1);
148.162 +
148.163 + checkGraphInArcList(G, n2, 2);
148.164 + checkGraphInArcList(G, n3, 1);
148.165 +
148.166 + checkGraphConArcList(G, 3);
148.167 +}
148.168 +
148.169 +template <class Digraph>
148.170 +void checkDigraphErase() {
148.171 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
148.172 +
148.173 + Digraph G;
148.174 + Node n1 = G.addNode(), n2 = G.addNode(),
148.175 + n3 = G.addNode(), n4 = G.addNode();
148.176 + Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
148.177 + a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1),
148.178 + a5 = G.addArc(n2, n4);
148.179 +
148.180 + // Check arc deletion
148.181 + G.erase(a1);
148.182 +
148.183 + checkGraphNodeList(G, 4);
148.184 + checkGraphArcList(G, 4);
148.185 +
148.186 + checkGraphOutArcList(G, n1, 0);
148.187 + checkGraphOutArcList(G, n2, 1);
148.188 + checkGraphOutArcList(G, n3, 1);
148.189 + checkGraphOutArcList(G, n4, 2);
148.190 +
148.191 + checkGraphInArcList(G, n1, 2);
148.192 + checkGraphInArcList(G, n2, 0);
148.193 + checkGraphInArcList(G, n3, 1);
148.194 + checkGraphInArcList(G, n4, 1);
148.195 +
148.196 + checkGraphConArcList(G, 4);
148.197 +
148.198 + // Check node deletion
148.199 + G.erase(n4);
148.200 +
148.201 + checkGraphNodeList(G, 3);
148.202 + checkGraphArcList(G, 1);
148.203 +
148.204 + checkGraphOutArcList(G, n1, 0);
148.205 + checkGraphOutArcList(G, n2, 0);
148.206 + checkGraphOutArcList(G, n3, 1);
148.207 + checkGraphOutArcList(G, n4, 0);
148.208 +
148.209 + checkGraphInArcList(G, n1, 1);
148.210 + checkGraphInArcList(G, n2, 0);
148.211 + checkGraphInArcList(G, n3, 0);
148.212 + checkGraphInArcList(G, n4, 0);
148.213 +
148.214 + checkGraphConArcList(G, 1);
148.215 +}
148.216 +
148.217 +
148.218 +template <class Digraph>
148.219 +void checkDigraphSnapshot() {
148.220 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
148.221 +
148.222 + Digraph G;
148.223 + Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
148.224 + Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
148.225 + a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
148.226 +
148.227 + typename Digraph::Snapshot snapshot(G);
148.228 +
148.229 + Node n = G.addNode();
148.230 + G.addArc(n3, n);
148.231 + G.addArc(n, n3);
148.232 +
148.233 + checkGraphNodeList(G, 4);
148.234 + checkGraphArcList(G, 6);
148.235 +
148.236 + snapshot.restore();
148.237 +
148.238 checkGraphNodeList(G, 3);
148.239 checkGraphArcList(G, 4);
148.240
148.241 @@ -77,9 +277,17 @@
148.242 checkGraphNodeMap(G);
148.243 checkGraphArcMap(G);
148.244
148.245 + G.addNode();
148.246 + snapshot.save(G);
148.247 +
148.248 + G.addArc(G.addNode(), G.addNode());
148.249 +
148.250 + snapshot.restore();
148.251 +
148.252 + checkGraphNodeList(G, 4);
148.253 + checkGraphArcList(G, 4);
148.254 }
148.255
148.256 -
148.257 void checkConcepts() {
148.258 { // Checking digraph components
148.259 checkConcept<BaseDigraphComponent, BaseDigraphComponent >();
148.260 @@ -109,12 +317,9 @@
148.261 checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
148.262 checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
148.263 }
148.264 -// { // Checking FullDigraph
148.265 -// checkConcept<Digraph, FullDigraph>();
148.266 -// }
148.267 -// { // Checking HyperCubeDigraph
148.268 -// checkConcept<Digraph, HyperCubeDigraph>();
148.269 -// }
148.270 + { // Checking FullDigraph
148.271 + checkConcept<Digraph, FullDigraph>();
148.272 + }
148.273 }
148.274
148.275 template <typename Digraph>
148.276 @@ -167,15 +372,56 @@
148.277 check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
148.278 }
148.279
148.280 +void checkFullDigraph(int num) {
148.281 + typedef FullDigraph Digraph;
148.282 + DIGRAPH_TYPEDEFS(Digraph);
148.283 + Digraph G(num);
148.284 +
148.285 + checkGraphNodeList(G, num);
148.286 + checkGraphArcList(G, num * num);
148.287 +
148.288 + for (NodeIt n(G); n != INVALID; ++n) {
148.289 + checkGraphOutArcList(G, n, num);
148.290 + checkGraphInArcList(G, n, num);
148.291 + }
148.292 +
148.293 + checkGraphConArcList(G, num * num);
148.294 +
148.295 + checkNodeIds(G);
148.296 + checkArcIds(G);
148.297 + checkGraphNodeMap(G);
148.298 + checkGraphArcMap(G);
148.299 +
148.300 + for (int i = 0; i < G.nodeNum(); ++i) {
148.301 + check(G.index(G(i)) == i, "Wrong index");
148.302 + }
148.303 +
148.304 + for (NodeIt s(G); s != INVALID; ++s) {
148.305 + for (NodeIt t(G); t != INVALID; ++t) {
148.306 + Arc a = G.arc(s, t);
148.307 + check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
148.308 + }
148.309 + }
148.310 +}
148.311 +
148.312 void checkDigraphs() {
148.313 { // Checking ListDigraph
148.314 - checkDigraph<ListDigraph>();
148.315 + checkDigraphBuild<ListDigraph>();
148.316 + checkDigraphSplit<ListDigraph>();
148.317 + checkDigraphAlter<ListDigraph>();
148.318 + checkDigraphErase<ListDigraph>();
148.319 + checkDigraphSnapshot<ListDigraph>();
148.320 checkDigraphValidityErase<ListDigraph>();
148.321 }
148.322 { // Checking SmartDigraph
148.323 - checkDigraph<SmartDigraph>();
148.324 + checkDigraphBuild<SmartDigraph>();
148.325 + checkDigraphSplit<SmartDigraph>();
148.326 + checkDigraphSnapshot<SmartDigraph>();
148.327 checkDigraphValidity<SmartDigraph>();
148.328 }
148.329 + { // Checking FullDigraph
148.330 + checkFullDigraph(8);
148.331 + }
148.332 }
148.333
148.334 int main() {
149.1 --- a/test/dijkstra_test.cc Fri Nov 13 12:33:33 2009 +0100
149.2 +++ b/test/dijkstra_test.cc Thu Dec 10 17:05:35 2009 +0100
149.3 @@ -2,7 +2,7 @@
149.4 *
149.5 * This file is a part of LEMON, a generic C++ optimization library.
149.6 *
149.7 - * Copyright (C) 2003-2008
149.8 + * Copyright (C) 2003-2009
149.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
149.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
149.11 *
149.12 @@ -60,48 +60,94 @@
149.13 typedef Digraph::Arc Arc;
149.14
149.15 Digraph G;
149.16 - Node s, t;
149.17 + Node s, t, n;
149.18 Arc e;
149.19 VType l;
149.20 + int i;
149.21 bool b;
149.22 DType::DistMap d(G);
149.23 DType::PredMap p(G);
149.24 LengthMap length;
149.25 Path<Digraph> pp;
149.26 + concepts::ReadMap<Node,bool> nm;
149.27
149.28 {
149.29 DType dijkstra_test(G,length);
149.30 + const DType& const_dijkstra_test = dijkstra_test;
149.31
149.32 dijkstra_test.run(s);
149.33 dijkstra_test.run(s,t);
149.34
149.35 + dijkstra_test.init();
149.36 + dijkstra_test.addSource(s);
149.37 + dijkstra_test.addSource(s, 1);
149.38 + n = dijkstra_test.processNextNode();
149.39 + n = const_dijkstra_test.nextNode();
149.40 + b = const_dijkstra_test.emptyQueue();
149.41 + i = const_dijkstra_test.queueSize();
149.42 +
149.43 + dijkstra_test.start();
149.44 + dijkstra_test.start(t);
149.45 + dijkstra_test.start(nm);
149.46 +
149.47 + l = const_dijkstra_test.dist(t);
149.48 + e = const_dijkstra_test.predArc(t);
149.49 + s = const_dijkstra_test.predNode(t);
149.50 + b = const_dijkstra_test.reached(t);
149.51 + b = const_dijkstra_test.processed(t);
149.52 + d = const_dijkstra_test.distMap();
149.53 + p = const_dijkstra_test.predMap();
149.54 + pp = const_dijkstra_test.path(t);
149.55 + l = const_dijkstra_test.currentDist(t);
149.56 + }
149.57 + {
149.58 + DType
149.59 + ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
149.60 + ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
149.61 + ::SetStandardProcessedMap
149.62 + ::SetProcessedMap<concepts::WriteMap<Node,bool> >
149.63 + ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
149.64 + ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
149.65 + ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
149.66 + ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >,
149.67 + concepts::ReadWriteMap<Node,int> >
149.68 + ::Create dijkstra_test(G,length);
149.69 +
149.70 + LengthMap length_map;
149.71 + concepts::ReadWriteMap<Node,Arc> pred_map;
149.72 + concepts::ReadWriteMap<Node,VType> dist_map;
149.73 + concepts::WriteMap<Node,bool> processed_map;
149.74 + concepts::ReadWriteMap<Node,int> heap_cross_ref;
149.75 + BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
149.76 +
149.77 + dijkstra_test
149.78 + .lengthMap(length_map)
149.79 + .predMap(pred_map)
149.80 + .distMap(dist_map)
149.81 + .processedMap(processed_map)
149.82 + .heap(heap, heap_cross_ref);
149.83 +
149.84 + dijkstra_test.run(s);
149.85 + dijkstra_test.run(s,t);
149.86 +
149.87 + dijkstra_test.addSource(s);
149.88 + dijkstra_test.addSource(s, 1);
149.89 + n = dijkstra_test.processNextNode();
149.90 + n = dijkstra_test.nextNode();
149.91 + b = dijkstra_test.emptyQueue();
149.92 + i = dijkstra_test.queueSize();
149.93 +
149.94 + dijkstra_test.start();
149.95 + dijkstra_test.start(t);
149.96 + dijkstra_test.start(nm);
149.97 +
149.98 l = dijkstra_test.dist(t);
149.99 e = dijkstra_test.predArc(t);
149.100 s = dijkstra_test.predNode(t);
149.101 b = dijkstra_test.reached(t);
149.102 - d = dijkstra_test.distMap();
149.103 - p = dijkstra_test.predMap();
149.104 + b = dijkstra_test.processed(t);
149.105 pp = dijkstra_test.path(t);
149.106 - }
149.107 - {
149.108 - DType
149.109 - ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
149.110 - ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
149.111 - ::SetProcessedMap<concepts::WriteMap<Node,bool> >
149.112 - ::SetStandardProcessedMap
149.113 - ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
149.114 - ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
149.115 - ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
149.116 - ::Create dijkstra_test(G,length);
149.117 -
149.118 - dijkstra_test.run(s);
149.119 - dijkstra_test.run(s,t);
149.120 -
149.121 - l = dijkstra_test.dist(t);
149.122 - e = dijkstra_test.predArc(t);
149.123 - s = dijkstra_test.predNode(t);
149.124 - b = dijkstra_test.reached(t);
149.125 - pp = dijkstra_test.path(t);
149.126 + l = dijkstra_test.currentDist(t);
149.127 }
149.128
149.129 }
150.1 --- a/test/dim_test.cc Fri Nov 13 12:33:33 2009 +0100
150.2 +++ b/test/dim_test.cc Thu Dec 10 17:05:35 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 *
151.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
151.2 +++ b/test/edge_set_test.cc Thu Dec 10 17:05:35 2009 +0100
151.3 @@ -0,0 +1,380 @@
151.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
151.5 + *
151.6 + * This file is a part of LEMON, a generic C++ optimization library.
151.7 + *
151.8 + * Copyright (C) 2003-2008
151.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
151.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
151.11 + *
151.12 + * Permission to use, modify and distribute this software is granted
151.13 + * provided that this copyright notice appears in all copies. For
151.14 + * precise terms see the accompanying LICENSE file.
151.15 + *
151.16 + * This software is provided "AS IS" with no warranty of any kind,
151.17 + * express or implied, and with no claim as to its suitability for any
151.18 + * purpose.
151.19 + *
151.20 + */
151.21 +
151.22 +#include <iostream>
151.23 +#include <vector>
151.24 +
151.25 +#include <lemon/concepts/digraph.h>
151.26 +#include <lemon/concepts/graph.h>
151.27 +#include <lemon/concept_check.h>
151.28 +
151.29 +#include <lemon/list_graph.h>
151.30 +
151.31 +#include <lemon/edge_set.h>
151.32 +
151.33 +#include "graph_test.h"
151.34 +#include "test_tools.h"
151.35 +
151.36 +using namespace lemon;
151.37 +
151.38 +void checkSmartArcSet() {
151.39 + checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
151.40 +
151.41 + typedef ListDigraph Digraph;
151.42 + typedef SmartArcSet<Digraph> ArcSet;
151.43 +
151.44 + Digraph digraph;
151.45 + Digraph::Node
151.46 + n1 = digraph.addNode(),
151.47 + n2 = digraph.addNode();
151.48 +
151.49 + Digraph::Arc ga1 = digraph.addArc(n1, n2);
151.50 +
151.51 + ArcSet arc_set(digraph);
151.52 +
151.53 + Digraph::Arc ga2 = digraph.addArc(n2, n1);
151.54 +
151.55 + checkGraphNodeList(arc_set, 2);
151.56 + checkGraphArcList(arc_set, 0);
151.57 +
151.58 + Digraph::Node
151.59 + n3 = digraph.addNode();
151.60 + checkGraphNodeList(arc_set, 3);
151.61 + checkGraphArcList(arc_set, 0);
151.62 +
151.63 + ArcSet::Arc a1 = arc_set.addArc(n1, n2);
151.64 + check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
151.65 + checkGraphNodeList(arc_set, 3);
151.66 + checkGraphArcList(arc_set, 1);
151.67 +
151.68 + checkGraphOutArcList(arc_set, n1, 1);
151.69 + checkGraphOutArcList(arc_set, n2, 0);
151.70 + checkGraphOutArcList(arc_set, n3, 0);
151.71 +
151.72 + checkGraphInArcList(arc_set, n1, 0);
151.73 + checkGraphInArcList(arc_set, n2, 1);
151.74 + checkGraphInArcList(arc_set, n3, 0);
151.75 +
151.76 + checkGraphConArcList(arc_set, 1);
151.77 +
151.78 + ArcSet::Arc a2 = arc_set.addArc(n2, n1),
151.79 + a3 = arc_set.addArc(n2, n3),
151.80 + a4 = arc_set.addArc(n2, n3);
151.81 + checkGraphNodeList(arc_set, 3);
151.82 + checkGraphArcList(arc_set, 4);
151.83 +
151.84 + checkGraphOutArcList(arc_set, n1, 1);
151.85 + checkGraphOutArcList(arc_set, n2, 3);
151.86 + checkGraphOutArcList(arc_set, n3, 0);
151.87 +
151.88 + checkGraphInArcList(arc_set, n1, 1);
151.89 + checkGraphInArcList(arc_set, n2, 1);
151.90 + checkGraphInArcList(arc_set, n3, 2);
151.91 +
151.92 + checkGraphConArcList(arc_set, 4);
151.93 +
151.94 + checkNodeIds(arc_set);
151.95 + checkArcIds(arc_set);
151.96 + checkGraphNodeMap(arc_set);
151.97 + checkGraphArcMap(arc_set);
151.98 +
151.99 + check(arc_set.valid(), "Wrong validity");
151.100 + digraph.erase(n1);
151.101 + check(!arc_set.valid(), "Wrong validity");
151.102 +}
151.103 +
151.104 +void checkListArcSet() {
151.105 + checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
151.106 +
151.107 + typedef ListDigraph Digraph;
151.108 + typedef ListArcSet<Digraph> ArcSet;
151.109 +
151.110 + Digraph digraph;
151.111 + Digraph::Node
151.112 + n1 = digraph.addNode(),
151.113 + n2 = digraph.addNode();
151.114 +
151.115 + Digraph::Arc ga1 = digraph.addArc(n1, n2);
151.116 +
151.117 + ArcSet arc_set(digraph);
151.118 +
151.119 + Digraph::Arc ga2 = digraph.addArc(n2, n1);
151.120 +
151.121 + checkGraphNodeList(arc_set, 2);
151.122 + checkGraphArcList(arc_set, 0);
151.123 +
151.124 + Digraph::Node
151.125 + n3 = digraph.addNode();
151.126 + checkGraphNodeList(arc_set, 3);
151.127 + checkGraphArcList(arc_set, 0);
151.128 +
151.129 + ArcSet::Arc a1 = arc_set.addArc(n1, n2);
151.130 + check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
151.131 + checkGraphNodeList(arc_set, 3);
151.132 + checkGraphArcList(arc_set, 1);
151.133 +
151.134 + checkGraphOutArcList(arc_set, n1, 1);
151.135 + checkGraphOutArcList(arc_set, n2, 0);
151.136 + checkGraphOutArcList(arc_set, n3, 0);
151.137 +
151.138 + checkGraphInArcList(arc_set, n1, 0);
151.139 + checkGraphInArcList(arc_set, n2, 1);
151.140 + checkGraphInArcList(arc_set, n3, 0);
151.141 +
151.142 + checkGraphConArcList(arc_set, 1);
151.143 +
151.144 + ArcSet::Arc a2 = arc_set.addArc(n2, n1),
151.145 + a3 = arc_set.addArc(n2, n3),
151.146 + a4 = arc_set.addArc(n2, n3);
151.147 + checkGraphNodeList(arc_set, 3);
151.148 + checkGraphArcList(arc_set, 4);
151.149 +
151.150 + checkGraphOutArcList(arc_set, n1, 1);
151.151 + checkGraphOutArcList(arc_set, n2, 3);
151.152 + checkGraphOutArcList(arc_set, n3, 0);
151.153 +
151.154 + checkGraphInArcList(arc_set, n1, 1);
151.155 + checkGraphInArcList(arc_set, n2, 1);
151.156 + checkGraphInArcList(arc_set, n3, 2);
151.157 +
151.158 + checkGraphConArcList(arc_set, 4);
151.159 +
151.160 + checkNodeIds(arc_set);
151.161 + checkArcIds(arc_set);
151.162 + checkGraphNodeMap(arc_set);
151.163 + checkGraphArcMap(arc_set);
151.164 +
151.165 + digraph.erase(n1);
151.166 +
151.167 + checkGraphNodeList(arc_set, 2);
151.168 + checkGraphArcList(arc_set, 2);
151.169 +
151.170 + checkGraphOutArcList(arc_set, n2, 2);
151.171 + checkGraphOutArcList(arc_set, n3, 0);
151.172 +
151.173 + checkGraphInArcList(arc_set, n2, 0);
151.174 + checkGraphInArcList(arc_set, n3, 2);
151.175 +
151.176 + checkNodeIds(arc_set);
151.177 + checkArcIds(arc_set);
151.178 + checkGraphNodeMap(arc_set);
151.179 + checkGraphArcMap(arc_set);
151.180 +
151.181 + checkGraphConArcList(arc_set, 2);
151.182 +}
151.183 +
151.184 +void checkSmartEdgeSet() {
151.185 + checkConcept<concepts::Digraph, SmartEdgeSet<ListDigraph> >();
151.186 +
151.187 + typedef ListDigraph Digraph;
151.188 + typedef SmartEdgeSet<Digraph> EdgeSet;
151.189 +
151.190 + Digraph digraph;
151.191 + Digraph::Node
151.192 + n1 = digraph.addNode(),
151.193 + n2 = digraph.addNode();
151.194 +
151.195 + Digraph::Arc ga1 = digraph.addArc(n1, n2);
151.196 +
151.197 + EdgeSet edge_set(digraph);
151.198 +
151.199 + Digraph::Arc ga2 = digraph.addArc(n2, n1);
151.200 +
151.201 + checkGraphNodeList(edge_set, 2);
151.202 + checkGraphArcList(edge_set, 0);
151.203 + checkGraphEdgeList(edge_set, 0);
151.204 +
151.205 + Digraph::Node
151.206 + n3 = digraph.addNode();
151.207 + checkGraphNodeList(edge_set, 3);
151.208 + checkGraphArcList(edge_set, 0);
151.209 + checkGraphEdgeList(edge_set, 0);
151.210 +
151.211 + EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
151.212 + check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
151.213 + (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
151.214 + checkGraphNodeList(edge_set, 3);
151.215 + checkGraphArcList(edge_set, 2);
151.216 + checkGraphEdgeList(edge_set, 1);
151.217 +
151.218 + checkGraphOutArcList(edge_set, n1, 1);
151.219 + checkGraphOutArcList(edge_set, n2, 1);
151.220 + checkGraphOutArcList(edge_set, n3, 0);
151.221 +
151.222 + checkGraphInArcList(edge_set, n1, 1);
151.223 + checkGraphInArcList(edge_set, n2, 1);
151.224 + checkGraphInArcList(edge_set, n3, 0);
151.225 +
151.226 + checkGraphIncEdgeList(edge_set, n1, 1);
151.227 + checkGraphIncEdgeList(edge_set, n2, 1);
151.228 + checkGraphIncEdgeList(edge_set, n3, 0);
151.229 +
151.230 + checkGraphConEdgeList(edge_set, 1);
151.231 + checkGraphConArcList(edge_set, 2);
151.232 +
151.233 + EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
151.234 + e3 = edge_set.addEdge(n2, n3),
151.235 + e4 = edge_set.addEdge(n2, n3);
151.236 + checkGraphNodeList(edge_set, 3);
151.237 + checkGraphEdgeList(edge_set, 4);
151.238 +
151.239 + checkGraphOutArcList(edge_set, n1, 2);
151.240 + checkGraphOutArcList(edge_set, n2, 4);
151.241 + checkGraphOutArcList(edge_set, n3, 2);
151.242 +
151.243 + checkGraphInArcList(edge_set, n1, 2);
151.244 + checkGraphInArcList(edge_set, n2, 4);
151.245 + checkGraphInArcList(edge_set, n3, 2);
151.246 +
151.247 + checkGraphIncEdgeList(edge_set, n1, 2);
151.248 + checkGraphIncEdgeList(edge_set, n2, 4);
151.249 + checkGraphIncEdgeList(edge_set, n3, 2);
151.250 +
151.251 + checkGraphConEdgeList(edge_set, 4);
151.252 + checkGraphConArcList(edge_set, 8);
151.253 +
151.254 + checkArcDirections(edge_set);
151.255 +
151.256 + checkNodeIds(edge_set);
151.257 + checkArcIds(edge_set);
151.258 + checkEdgeIds(edge_set);
151.259 + checkGraphNodeMap(edge_set);
151.260 + checkGraphArcMap(edge_set);
151.261 + checkGraphEdgeMap(edge_set);
151.262 +
151.263 + check(edge_set.valid(), "Wrong validity");
151.264 + digraph.erase(n1);
151.265 + check(!edge_set.valid(), "Wrong validity");
151.266 +}
151.267 +
151.268 +void checkListEdgeSet() {
151.269 + checkConcept<concepts::Digraph, ListEdgeSet<ListDigraph> >();
151.270 +
151.271 + typedef ListDigraph Digraph;
151.272 + typedef ListEdgeSet<Digraph> EdgeSet;
151.273 +
151.274 + Digraph digraph;
151.275 + Digraph::Node
151.276 + n1 = digraph.addNode(),
151.277 + n2 = digraph.addNode();
151.278 +
151.279 + Digraph::Arc ga1 = digraph.addArc(n1, n2);
151.280 +
151.281 + EdgeSet edge_set(digraph);
151.282 +
151.283 + Digraph::Arc ga2 = digraph.addArc(n2, n1);
151.284 +
151.285 + checkGraphNodeList(edge_set, 2);
151.286 + checkGraphArcList(edge_set, 0);
151.287 + checkGraphEdgeList(edge_set, 0);
151.288 +
151.289 + Digraph::Node
151.290 + n3 = digraph.addNode();
151.291 + checkGraphNodeList(edge_set, 3);
151.292 + checkGraphArcList(edge_set, 0);
151.293 + checkGraphEdgeList(edge_set, 0);
151.294 +
151.295 + EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
151.296 + check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
151.297 + (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
151.298 + checkGraphNodeList(edge_set, 3);
151.299 + checkGraphArcList(edge_set, 2);
151.300 + checkGraphEdgeList(edge_set, 1);
151.301 +
151.302 + checkGraphOutArcList(edge_set, n1, 1);
151.303 + checkGraphOutArcList(edge_set, n2, 1);
151.304 + checkGraphOutArcList(edge_set, n3, 0);
151.305 +
151.306 + checkGraphInArcList(edge_set, n1, 1);
151.307 + checkGraphInArcList(edge_set, n2, 1);
151.308 + checkGraphInArcList(edge_set, n3, 0);
151.309 +
151.310 + checkGraphIncEdgeList(edge_set, n1, 1);
151.311 + checkGraphIncEdgeList(edge_set, n2, 1);
151.312 + checkGraphIncEdgeList(edge_set, n3, 0);
151.313 +
151.314 + checkGraphConEdgeList(edge_set, 1);
151.315 + checkGraphConArcList(edge_set, 2);
151.316 +
151.317 + EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
151.318 + e3 = edge_set.addEdge(n2, n3),
151.319 + e4 = edge_set.addEdge(n2, n3);
151.320 + checkGraphNodeList(edge_set, 3);
151.321 + checkGraphEdgeList(edge_set, 4);
151.322 +
151.323 + checkGraphOutArcList(edge_set, n1, 2);
151.324 + checkGraphOutArcList(edge_set, n2, 4);
151.325 + checkGraphOutArcList(edge_set, n3, 2);
151.326 +
151.327 + checkGraphInArcList(edge_set, n1, 2);
151.328 + checkGraphInArcList(edge_set, n2, 4);
151.329 + checkGraphInArcList(edge_set, n3, 2);
151.330 +
151.331 + checkGraphIncEdgeList(edge_set, n1, 2);
151.332 + checkGraphIncEdgeList(edge_set, n2, 4);
151.333 + checkGraphIncEdgeList(edge_set, n3, 2);
151.334 +
151.335 + checkGraphConEdgeList(edge_set, 4);
151.336 + checkGraphConArcList(edge_set, 8);
151.337 +
151.338 + checkArcDirections(edge_set);
151.339 +
151.340 + checkNodeIds(edge_set);
151.341 + checkArcIds(edge_set);
151.342 + checkEdgeIds(edge_set);
151.343 + checkGraphNodeMap(edge_set);
151.344 + checkGraphArcMap(edge_set);
151.345 + checkGraphEdgeMap(edge_set);
151.346 +
151.347 + digraph.erase(n1);
151.348 +
151.349 + checkGraphNodeList(edge_set, 2);
151.350 + checkGraphArcList(edge_set, 4);
151.351 + checkGraphEdgeList(edge_set, 2);
151.352 +
151.353 + checkGraphOutArcList(edge_set, n2, 2);
151.354 + checkGraphOutArcList(edge_set, n3, 2);
151.355 +
151.356 + checkGraphInArcList(edge_set, n2, 2);
151.357 + checkGraphInArcList(edge_set, n3, 2);
151.358 +
151.359 + checkGraphIncEdgeList(edge_set, n2, 2);
151.360 + checkGraphIncEdgeList(edge_set, n3, 2);
151.361 +
151.362 + checkNodeIds(edge_set);
151.363 + checkArcIds(edge_set);
151.364 + checkEdgeIds(edge_set);
151.365 + checkGraphNodeMap(edge_set);
151.366 + checkGraphArcMap(edge_set);
151.367 + checkGraphEdgeMap(edge_set);
151.368 +
151.369 + checkGraphConEdgeList(edge_set, 2);
151.370 + checkGraphConArcList(edge_set, 4);
151.371 +
151.372 +}
151.373 +
151.374 +
151.375 +int main() {
151.376 +
151.377 + checkSmartArcSet();
151.378 + checkListArcSet();
151.379 + checkSmartEdgeSet();
151.380 + checkListEdgeSet();
151.381 +
151.382 + return 0;
151.383 +}
152.1 --- a/test/error_test.cc Fri Nov 13 12:33:33 2009 +0100
152.2 +++ b/test/error_test.cc Thu Dec 10 17:05:35 2009 +0100
152.3 @@ -2,7 +2,7 @@
152.4 *
152.5 * This file is a part of LEMON, a generic C++ optimization library.
152.6 *
152.7 - * Copyright (C) 2003-2008
152.8 + * Copyright (C) 2003-2009
152.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
152.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
152.11 *
153.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
153.2 +++ b/test/euler_test.cc Thu Dec 10 17:05:35 2009 +0100
153.3 @@ -0,0 +1,223 @@
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 <lemon/euler.h>
153.23 +#include <lemon/list_graph.h>
153.24 +#include <lemon/adaptors.h>
153.25 +#include "test_tools.h"
153.26 +
153.27 +using namespace lemon;
153.28 +
153.29 +template <typename Digraph>
153.30 +void checkDiEulerIt(const Digraph& g,
153.31 + const typename Digraph::Node& start = INVALID)
153.32 +{
153.33 + typename Digraph::template ArcMap<int> visitationNumber(g, 0);
153.34 +
153.35 + DiEulerIt<Digraph> e(g, start);
153.36 + if (e == INVALID) return;
153.37 + typename Digraph::Node firstNode = g.source(e);
153.38 + typename Digraph::Node lastNode = g.target(e);
153.39 + if (start != INVALID) {
153.40 + check(firstNode == start, "checkDiEulerIt: Wrong first node");
153.41 + }
153.42 +
153.43 + for (; e != INVALID; ++e) {
153.44 + if (e != INVALID) lastNode = g.target(e);
153.45 + ++visitationNumber[e];
153.46 + }
153.47 +
153.48 + check(firstNode == lastNode,
153.49 + "checkDiEulerIt: First and last nodes are not the same");
153.50 +
153.51 + for (typename Digraph::ArcIt a(g); a != INVALID; ++a)
153.52 + {
153.53 + check(visitationNumber[a] == 1,
153.54 + "checkDiEulerIt: Not visited or multiple times visited arc found");
153.55 + }
153.56 +}
153.57 +
153.58 +template <typename Graph>
153.59 +void checkEulerIt(const Graph& g,
153.60 + const typename Graph::Node& start = INVALID)
153.61 +{
153.62 + typename Graph::template EdgeMap<int> visitationNumber(g, 0);
153.63 +
153.64 + EulerIt<Graph> e(g, start);
153.65 + if (e == INVALID) return;
153.66 + typename Graph::Node firstNode = g.source(typename Graph::Arc(e));
153.67 + typename Graph::Node lastNode = g.target(typename Graph::Arc(e));
153.68 + if (start != INVALID) {
153.69 + check(firstNode == start, "checkEulerIt: Wrong first node");
153.70 + }
153.71 +
153.72 + for (; e != INVALID; ++e) {
153.73 + if (e != INVALID) lastNode = g.target(typename Graph::Arc(e));
153.74 + ++visitationNumber[e];
153.75 + }
153.76 +
153.77 + check(firstNode == lastNode,
153.78 + "checkEulerIt: First and last nodes are not the same");
153.79 +
153.80 + for (typename Graph::EdgeIt e(g); e != INVALID; ++e)
153.81 + {
153.82 + check(visitationNumber[e] == 1,
153.83 + "checkEulerIt: Not visited or multiple times visited edge found");
153.84 + }
153.85 +}
153.86 +
153.87 +int main()
153.88 +{
153.89 + typedef ListDigraph Digraph;
153.90 + typedef Undirector<Digraph> Graph;
153.91 +
153.92 + {
153.93 + Digraph d;
153.94 + Graph g(d);
153.95 +
153.96 + checkDiEulerIt(d);
153.97 + checkDiEulerIt(g);
153.98 + checkEulerIt(g);
153.99 +
153.100 + check(eulerian(d), "This graph is Eulerian");
153.101 + check(eulerian(g), "This graph is Eulerian");
153.102 + }
153.103 + {
153.104 + Digraph d;
153.105 + Graph g(d);
153.106 + Digraph::Node n = d.addNode();
153.107 +
153.108 + checkDiEulerIt(d);
153.109 + checkDiEulerIt(g);
153.110 + checkEulerIt(g);
153.111 +
153.112 + check(eulerian(d), "This graph is Eulerian");
153.113 + check(eulerian(g), "This graph is Eulerian");
153.114 + }
153.115 + {
153.116 + Digraph d;
153.117 + Graph g(d);
153.118 + Digraph::Node n = d.addNode();
153.119 + d.addArc(n, n);
153.120 +
153.121 + checkDiEulerIt(d);
153.122 + checkDiEulerIt(g);
153.123 + checkEulerIt(g);
153.124 +
153.125 + check(eulerian(d), "This graph is Eulerian");
153.126 + check(eulerian(g), "This graph is Eulerian");
153.127 + }
153.128 + {
153.129 + Digraph d;
153.130 + Graph g(d);
153.131 + Digraph::Node n1 = d.addNode();
153.132 + Digraph::Node n2 = d.addNode();
153.133 + Digraph::Node n3 = d.addNode();
153.134 +
153.135 + d.addArc(n1, n2);
153.136 + d.addArc(n2, n1);
153.137 + d.addArc(n2, n3);
153.138 + d.addArc(n3, n2);
153.139 +
153.140 + checkDiEulerIt(d);
153.141 + checkDiEulerIt(d, n2);
153.142 + checkDiEulerIt(g);
153.143 + checkDiEulerIt(g, n2);
153.144 + checkEulerIt(g);
153.145 + checkEulerIt(g, n2);
153.146 +
153.147 + check(eulerian(d), "This graph is Eulerian");
153.148 + check(eulerian(g), "This graph is Eulerian");
153.149 + }
153.150 + {
153.151 + Digraph d;
153.152 + Graph g(d);
153.153 + Digraph::Node n1 = d.addNode();
153.154 + Digraph::Node n2 = d.addNode();
153.155 + Digraph::Node n3 = d.addNode();
153.156 + Digraph::Node n4 = d.addNode();
153.157 + Digraph::Node n5 = d.addNode();
153.158 + Digraph::Node n6 = d.addNode();
153.159 +
153.160 + d.addArc(n1, n2);
153.161 + d.addArc(n2, n4);
153.162 + d.addArc(n1, n3);
153.163 + d.addArc(n3, n4);
153.164 + d.addArc(n4, n1);
153.165 + d.addArc(n3, n5);
153.166 + d.addArc(n5, n2);
153.167 + d.addArc(n4, n6);
153.168 + d.addArc(n2, n6);
153.169 + d.addArc(n6, n1);
153.170 + d.addArc(n6, n3);
153.171 +
153.172 + checkDiEulerIt(d);
153.173 + checkDiEulerIt(d, n1);
153.174 + checkDiEulerIt(d, n5);
153.175 +
153.176 + checkDiEulerIt(g);
153.177 + checkDiEulerIt(g, n1);
153.178 + checkDiEulerIt(g, n5);
153.179 + checkEulerIt(g);
153.180 + checkEulerIt(g, n1);
153.181 + checkEulerIt(g, n5);
153.182 +
153.183 + check(eulerian(d), "This graph is Eulerian");
153.184 + check(eulerian(g), "This graph is Eulerian");
153.185 + }
153.186 + {
153.187 + Digraph d;
153.188 + Graph g(d);
153.189 + Digraph::Node n0 = d.addNode();
153.190 + Digraph::Node n1 = d.addNode();
153.191 + Digraph::Node n2 = d.addNode();
153.192 + Digraph::Node n3 = d.addNode();
153.193 + Digraph::Node n4 = d.addNode();
153.194 + Digraph::Node n5 = d.addNode();
153.195 +
153.196 + d.addArc(n1, n2);
153.197 + d.addArc(n2, n3);
153.198 + d.addArc(n3, n1);
153.199 +
153.200 + checkDiEulerIt(d);
153.201 + checkDiEulerIt(d, n2);
153.202 +
153.203 + checkDiEulerIt(g);
153.204 + checkDiEulerIt(g, n2);
153.205 + checkEulerIt(g);
153.206 + checkEulerIt(g, n2);
153.207 +
153.208 + check(!eulerian(d), "This graph is not Eulerian");
153.209 + check(!eulerian(g), "This graph is not Eulerian");
153.210 + }
153.211 + {
153.212 + Digraph d;
153.213 + Graph g(d);
153.214 + Digraph::Node n1 = d.addNode();
153.215 + Digraph::Node n2 = d.addNode();
153.216 + Digraph::Node n3 = d.addNode();
153.217 +
153.218 + d.addArc(n1, n2);
153.219 + d.addArc(n2, n3);
153.220 +
153.221 + check(!eulerian(d), "This graph is not Eulerian");
153.222 + check(!eulerian(g), "This graph is not Eulerian");
153.223 + }
153.224 +
153.225 + return 0;
153.226 +}
154.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
154.2 +++ b/test/gomory_hu_test.cc Thu Dec 10 17:05:35 2009 +0100
154.3 @@ -0,0 +1,123 @@
154.4 +#include <iostream>
154.5 +
154.6 +#include "test_tools.h"
154.7 +#include <lemon/smart_graph.h>
154.8 +#include <lemon/concepts/graph.h>
154.9 +#include <lemon/concepts/maps.h>
154.10 +#include <lemon/lgf_reader.h>
154.11 +#include <lemon/gomory_hu.h>
154.12 +#include <cstdlib>
154.13 +
154.14 +using namespace std;
154.15 +using namespace lemon;
154.16 +
154.17 +typedef SmartGraph Graph;
154.18 +
154.19 +char test_lgf[] =
154.20 + "@nodes\n"
154.21 + "label\n"
154.22 + "0\n"
154.23 + "1\n"
154.24 + "2\n"
154.25 + "3\n"
154.26 + "4\n"
154.27 + "@arcs\n"
154.28 + " label capacity\n"
154.29 + "0 1 0 1\n"
154.30 + "1 2 1 1\n"
154.31 + "2 3 2 1\n"
154.32 + "0 3 4 5\n"
154.33 + "0 3 5 10\n"
154.34 + "0 3 6 7\n"
154.35 + "4 2 7 1\n"
154.36 + "@attributes\n"
154.37 + "source 0\n"
154.38 + "target 3\n";
154.39 +
154.40 +void checkGomoryHuCompile()
154.41 +{
154.42 + typedef int Value;
154.43 + typedef concepts::Graph Graph;
154.44 +
154.45 + typedef Graph::Node Node;
154.46 + typedef Graph::Edge Edge;
154.47 + typedef concepts::ReadMap<Edge, Value> CapMap;
154.48 + typedef concepts::ReadWriteMap<Node, bool> CutMap;
154.49 +
154.50 + Graph g;
154.51 + Node n;
154.52 + CapMap cap;
154.53 + CutMap cut;
154.54 + Value v;
154.55 + int d;
154.56 +
154.57 + GomoryHu<Graph, CapMap> gh_test(g, cap);
154.58 + const GomoryHu<Graph, CapMap>&
154.59 + const_gh_test = gh_test;
154.60 +
154.61 + gh_test.run();
154.62 +
154.63 + n = const_gh_test.predNode(n);
154.64 + v = const_gh_test.predValue(n);
154.65 + d = const_gh_test.rootDist(n);
154.66 + v = const_gh_test.minCutValue(n, n);
154.67 + v = const_gh_test.minCutMap(n, n, cut);
154.68 +}
154.69 +
154.70 +GRAPH_TYPEDEFS(Graph);
154.71 +typedef Graph::EdgeMap<int> IntEdgeMap;
154.72 +typedef Graph::NodeMap<bool> BoolNodeMap;
154.73 +
154.74 +int cutValue(const Graph& graph, const BoolNodeMap& cut,
154.75 + const IntEdgeMap& capacity) {
154.76 +
154.77 + int sum = 0;
154.78 + for (EdgeIt e(graph); e != INVALID; ++e) {
154.79 + Node s = graph.u(e);
154.80 + Node t = graph.v(e);
154.81 +
154.82 + if (cut[s] != cut[t]) {
154.83 + sum += capacity[e];
154.84 + }
154.85 + }
154.86 + return sum;
154.87 +}
154.88 +
154.89 +
154.90 +int main() {
154.91 + Graph graph;
154.92 + IntEdgeMap capacity(graph);
154.93 +
154.94 + std::istringstream input(test_lgf);
154.95 + GraphReader<Graph>(graph, input).
154.96 + edgeMap("capacity", capacity).run();
154.97 +
154.98 + GomoryHu<Graph> ght(graph, capacity);
154.99 + ght.run();
154.100 +
154.101 + for (NodeIt u(graph); u != INVALID; ++u) {
154.102 + for (NodeIt v(graph); v != u; ++v) {
154.103 + Preflow<Graph, IntEdgeMap> pf(graph, capacity, u, v);
154.104 + pf.runMinCut();
154.105 + BoolNodeMap cm(graph);
154.106 + ght.minCutMap(u, v, cm);
154.107 + check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1");
154.108 + check(cm[u] != cm[v], "Wrong cut 2");
154.109 + check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 3");
154.110 +
154.111 + int sum=0;
154.112 + for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
154.113 + sum+=capacity[a];
154.114 + check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
154.115 +
154.116 + sum=0;
154.117 + for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,true);n!=INVALID;++n)
154.118 + sum++;
154.119 + for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,false);n!=INVALID;++n)
154.120 + sum++;
154.121 + check(sum == countNodes(graph), "Problem with MinCutNodeIt");
154.122 + }
154.123 + }
154.124 +
154.125 + return 0;
154.126 +}
155.1 --- a/test/graph_copy_test.cc Fri Nov 13 12:33:33 2009 +0100
155.2 +++ b/test/graph_copy_test.cc Thu Dec 10 17:05:35 2009 +0100
155.3 @@ -2,7 +2,7 @@
155.4 *
155.5 * This file is a part of LEMON, a generic C++ optimization library.
155.6 *
155.7 - * Copyright (C) 2003-2008
155.8 + * Copyright (C) 2003-2009
155.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
155.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
155.11 *
156.1 --- a/test/graph_test.cc Fri Nov 13 12:33:33 2009 +0100
156.2 +++ b/test/graph_test.cc Thu Dec 10 17:05:35 2009 +0100
156.3 @@ -2,7 +2,7 @@
156.4 *
156.5 * This file is a part of LEMON, a generic C++ optimization library.
156.6 *
156.7 - * Copyright (C) 2003-2008
156.8 + * Copyright (C) 2003-2009
156.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
156.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
156.11 *
156.12 @@ -19,8 +19,9 @@
156.13 #include <lemon/concepts/graph.h>
156.14 #include <lemon/list_graph.h>
156.15 #include <lemon/smart_graph.h>
156.16 -// #include <lemon/full_graph.h>
156.17 -// #include <lemon/grid_graph.h>
156.18 +#include <lemon/full_graph.h>
156.19 +#include <lemon/grid_graph.h>
156.20 +#include <lemon/hypercube_graph.h>
156.21
156.22 #include "test_tools.h"
156.23 #include "graph_test.h"
156.24 @@ -29,12 +30,13 @@
156.25 using namespace lemon::concepts;
156.26
156.27 template <class Graph>
156.28 -void checkGraph() {
156.29 +void checkGraphBuild() {
156.30 TEMPLATE_GRAPH_TYPEDEFS(Graph);
156.31
156.32 Graph G;
156.33 checkGraphNodeList(G, 0);
156.34 checkGraphEdgeList(G, 0);
156.35 + checkGraphArcList(G, 0);
156.36
156.37 Node
156.38 n1 = G.addNode(),
156.39 @@ -42,48 +44,36 @@
156.40 n3 = G.addNode();
156.41 checkGraphNodeList(G, 3);
156.42 checkGraphEdgeList(G, 0);
156.43 + checkGraphArcList(G, 0);
156.44
156.45 Edge e1 = G.addEdge(n1, n2);
156.46 check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
156.47 "Wrong edge");
156.48 +
156.49 checkGraphNodeList(G, 3);
156.50 + checkGraphEdgeList(G, 1);
156.51 checkGraphArcList(G, 2);
156.52 - checkGraphEdgeList(G, 1);
156.53
156.54 - checkGraphOutArcList(G, n1, 1);
156.55 - checkGraphOutArcList(G, n2, 1);
156.56 - checkGraphOutArcList(G, n3, 0);
156.57 + checkGraphIncEdgeArcLists(G, n1, 1);
156.58 + checkGraphIncEdgeArcLists(G, n2, 1);
156.59 + checkGraphIncEdgeArcLists(G, n3, 0);
156.60
156.61 - checkGraphInArcList(G, n1, 1);
156.62 - checkGraphInArcList(G, n2, 1);
156.63 - checkGraphInArcList(G, n3, 0);
156.64 + checkGraphConEdgeList(G, 1);
156.65 + checkGraphConArcList(G, 2);
156.66
156.67 - checkGraphIncEdgeList(G, n1, 1);
156.68 - checkGraphIncEdgeList(G, n2, 1);
156.69 - checkGraphIncEdgeList(G, n3, 0);
156.70 + Edge e2 = G.addEdge(n2, n1),
156.71 + e3 = G.addEdge(n2, n3);
156.72
156.73 - checkGraphConArcList(G, 2);
156.74 - checkGraphConEdgeList(G, 1);
156.75 + checkGraphNodeList(G, 3);
156.76 + checkGraphEdgeList(G, 3);
156.77 + checkGraphArcList(G, 6);
156.78
156.79 - Edge e2 = G.addEdge(n2, n1), e3 = G.addEdge(n2, n3);
156.80 - checkGraphNodeList(G, 3);
156.81 - checkGraphArcList(G, 6);
156.82 - checkGraphEdgeList(G, 3);
156.83 + checkGraphIncEdgeArcLists(G, n1, 2);
156.84 + checkGraphIncEdgeArcLists(G, n2, 3);
156.85 + checkGraphIncEdgeArcLists(G, n3, 1);
156.86
156.87 - checkGraphOutArcList(G, n1, 2);
156.88 - checkGraphOutArcList(G, n2, 3);
156.89 - checkGraphOutArcList(G, n3, 1);
156.90 -
156.91 - checkGraphInArcList(G, n1, 2);
156.92 - checkGraphInArcList(G, n2, 3);
156.93 - checkGraphInArcList(G, n3, 1);
156.94 -
156.95 - checkGraphIncEdgeList(G, n1, 2);
156.96 - checkGraphIncEdgeList(G, n2, 3);
156.97 - checkGraphIncEdgeList(G, n3, 1);
156.98 -
156.99 + checkGraphConEdgeList(G, 3);
156.100 checkGraphConArcList(G, 6);
156.101 - checkGraphConEdgeList(G, 3);
156.102
156.103 checkArcDirections(G);
156.104
156.105 @@ -95,6 +85,230 @@
156.106 checkGraphEdgeMap(G);
156.107 }
156.108
156.109 +template <class Graph>
156.110 +void checkGraphAlter() {
156.111 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
156.112 +
156.113 + Graph G;
156.114 + Node n1 = G.addNode(), n2 = G.addNode(),
156.115 + n3 = G.addNode(), n4 = G.addNode();
156.116 + Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
156.117 + e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
156.118 + e5 = G.addEdge(n4, n3);
156.119 +
156.120 + checkGraphNodeList(G, 4);
156.121 + checkGraphEdgeList(G, 5);
156.122 + checkGraphArcList(G, 10);
156.123 +
156.124 + // Check changeU() and changeV()
156.125 + if (G.u(e2) == n2) {
156.126 + G.changeU(e2, n3);
156.127 + } else {
156.128 + G.changeV(e2, n3);
156.129 + }
156.130 +
156.131 + checkGraphNodeList(G, 4);
156.132 + checkGraphEdgeList(G, 5);
156.133 + checkGraphArcList(G, 10);
156.134 +
156.135 + checkGraphIncEdgeArcLists(G, n1, 3);
156.136 + checkGraphIncEdgeArcLists(G, n2, 2);
156.137 + checkGraphIncEdgeArcLists(G, n3, 3);
156.138 + checkGraphIncEdgeArcLists(G, n4, 2);
156.139 +
156.140 + checkGraphConEdgeList(G, 5);
156.141 + checkGraphConArcList(G, 10);
156.142 +
156.143 + if (G.u(e2) == n1) {
156.144 + G.changeU(e2, n2);
156.145 + } else {
156.146 + G.changeV(e2, n2);
156.147 + }
156.148 +
156.149 + checkGraphNodeList(G, 4);
156.150 + checkGraphEdgeList(G, 5);
156.151 + checkGraphArcList(G, 10);
156.152 +
156.153 + checkGraphIncEdgeArcLists(G, n1, 2);
156.154 + checkGraphIncEdgeArcLists(G, n2, 3);
156.155 + checkGraphIncEdgeArcLists(G, n3, 3);
156.156 + checkGraphIncEdgeArcLists(G, n4, 2);
156.157 +
156.158 + checkGraphConEdgeList(G, 5);
156.159 + checkGraphConArcList(G, 10);
156.160 +
156.161 + // Check contract()
156.162 + G.contract(n1, n4, false);
156.163 +
156.164 + checkGraphNodeList(G, 3);
156.165 + checkGraphEdgeList(G, 5);
156.166 + checkGraphArcList(G, 10);
156.167 +
156.168 + checkGraphIncEdgeArcLists(G, n1, 4);
156.169 + checkGraphIncEdgeArcLists(G, n2, 3);
156.170 + checkGraphIncEdgeArcLists(G, n3, 3);
156.171 +
156.172 + checkGraphConEdgeList(G, 5);
156.173 + checkGraphConArcList(G, 10);
156.174 +
156.175 + G.contract(n2, n3);
156.176 +
156.177 + checkGraphNodeList(G, 2);
156.178 + checkGraphEdgeList(G, 3);
156.179 + checkGraphArcList(G, 6);
156.180 +
156.181 + checkGraphIncEdgeArcLists(G, n1, 4);
156.182 + checkGraphIncEdgeArcLists(G, n2, 2);
156.183 +
156.184 + checkGraphConEdgeList(G, 3);
156.185 + checkGraphConArcList(G, 6);
156.186 +}
156.187 +
156.188 +template <class Graph>
156.189 +void checkGraphErase() {
156.190 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
156.191 +
156.192 + Graph G;
156.193 + Node n1 = G.addNode(), n2 = G.addNode(),
156.194 + n3 = G.addNode(), n4 = G.addNode();
156.195 + Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
156.196 + e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
156.197 + e5 = G.addEdge(n4, n3);
156.198 +
156.199 + // Check edge deletion
156.200 + G.erase(e2);
156.201 +
156.202 + checkGraphNodeList(G, 4);
156.203 + checkGraphEdgeList(G, 4);
156.204 + checkGraphArcList(G, 8);
156.205 +
156.206 + checkGraphIncEdgeArcLists(G, n1, 2);
156.207 + checkGraphIncEdgeArcLists(G, n2, 2);
156.208 + checkGraphIncEdgeArcLists(G, n3, 2);
156.209 + checkGraphIncEdgeArcLists(G, n4, 2);
156.210 +
156.211 + checkGraphConEdgeList(G, 4);
156.212 + checkGraphConArcList(G, 8);
156.213 +
156.214 + // Check node deletion
156.215 + G.erase(n3);
156.216 +
156.217 + checkGraphNodeList(G, 3);
156.218 + checkGraphEdgeList(G, 2);
156.219 + checkGraphArcList(G, 4);
156.220 +
156.221 + checkGraphIncEdgeArcLists(G, n1, 2);
156.222 + checkGraphIncEdgeArcLists(G, n2, 1);
156.223 + checkGraphIncEdgeArcLists(G, n4, 1);
156.224 +
156.225 + checkGraphConEdgeList(G, 2);
156.226 + checkGraphConArcList(G, 4);
156.227 +}
156.228 +
156.229 +
156.230 +template <class Graph>
156.231 +void checkGraphSnapshot() {
156.232 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
156.233 +
156.234 + Graph G;
156.235 + Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
156.236 + Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
156.237 + e3 = G.addEdge(n2, n3);
156.238 +
156.239 + checkGraphNodeList(G, 3);
156.240 + checkGraphEdgeList(G, 3);
156.241 + checkGraphArcList(G, 6);
156.242 +
156.243 + typename Graph::Snapshot snapshot(G);
156.244 +
156.245 + Node n = G.addNode();
156.246 + G.addEdge(n3, n);
156.247 + G.addEdge(n, n3);
156.248 + G.addEdge(n3, n2);
156.249 +
156.250 + checkGraphNodeList(G, 4);
156.251 + checkGraphEdgeList(G, 6);
156.252 + checkGraphArcList(G, 12);
156.253 +
156.254 + snapshot.restore();
156.255 +
156.256 + checkGraphNodeList(G, 3);
156.257 + checkGraphEdgeList(G, 3);
156.258 + checkGraphArcList(G, 6);
156.259 +
156.260 + checkGraphIncEdgeArcLists(G, n1, 2);
156.261 + checkGraphIncEdgeArcLists(G, n2, 3);
156.262 + checkGraphIncEdgeArcLists(G, n3, 1);
156.263 +
156.264 + checkGraphConEdgeList(G, 3);
156.265 + checkGraphConArcList(G, 6);
156.266 +
156.267 + checkNodeIds(G);
156.268 + checkEdgeIds(G);
156.269 + checkArcIds(G);
156.270 + checkGraphNodeMap(G);
156.271 + checkGraphEdgeMap(G);
156.272 + checkGraphArcMap(G);
156.273 +
156.274 + G.addNode();
156.275 + snapshot.save(G);
156.276 +
156.277 + G.addEdge(G.addNode(), G.addNode());
156.278 +
156.279 + snapshot.restore();
156.280 +
156.281 + checkGraphNodeList(G, 4);
156.282 + checkGraphEdgeList(G, 3);
156.283 + checkGraphArcList(G, 6);
156.284 +}
156.285 +
156.286 +void checkFullGraph(int num) {
156.287 + typedef FullGraph Graph;
156.288 + GRAPH_TYPEDEFS(Graph);
156.289 +
156.290 + Graph G(num);
156.291 + checkGraphNodeList(G, num);
156.292 + checkGraphEdgeList(G, num * (num - 1) / 2);
156.293 +
156.294 + for (NodeIt n(G); n != INVALID; ++n) {
156.295 + checkGraphOutArcList(G, n, num - 1);
156.296 + checkGraphInArcList(G, n, num - 1);
156.297 + checkGraphIncEdgeList(G, n, num - 1);
156.298 + }
156.299 +
156.300 + checkGraphConArcList(G, num * (num - 1));
156.301 + checkGraphConEdgeList(G, num * (num - 1) / 2);
156.302 +
156.303 + checkArcDirections(G);
156.304 +
156.305 + checkNodeIds(G);
156.306 + checkArcIds(G);
156.307 + checkEdgeIds(G);
156.308 + checkGraphNodeMap(G);
156.309 + checkGraphArcMap(G);
156.310 + checkGraphEdgeMap(G);
156.311 +
156.312 +
156.313 + for (int i = 0; i < G.nodeNum(); ++i) {
156.314 + check(G.index(G(i)) == i, "Wrong index");
156.315 + }
156.316 +
156.317 + for (NodeIt u(G); u != INVALID; ++u) {
156.318 + for (NodeIt v(G); v != INVALID; ++v) {
156.319 + Edge e = G.edge(u, v);
156.320 + Arc a = G.arc(u, v);
156.321 + if (u == v) {
156.322 + check(e == INVALID, "Wrong edge lookup");
156.323 + check(a == INVALID, "Wrong arc lookup");
156.324 + } else {
156.325 + check((G.u(e) == u && G.v(e) == v) ||
156.326 + (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
156.327 + check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
156.328 + }
156.329 + }
156.330 + }
156.331 +}
156.332 +
156.333 void checkConcepts() {
156.334 { // Checking graph components
156.335 checkConcept<BaseGraphComponent, BaseGraphComponent >();
156.336 @@ -124,14 +338,15 @@
156.337 checkConcept<ExtendableGraphComponent<>, SmartGraph>();
156.338 checkConcept<ClearableGraphComponent<>, SmartGraph>();
156.339 }
156.340 -// { // Checking FullGraph
156.341 -// checkConcept<Graph, FullGraph>();
156.342 -// checkGraphIterators<FullGraph>();
156.343 -// }
156.344 -// { // Checking GridGraph
156.345 -// checkConcept<Graph, GridGraph>();
156.346 -// checkGraphIterators<GridGraph>();
156.347 -// }
156.348 + { // Checking FullGraph
156.349 + checkConcept<Graph, FullGraph>();
156.350 + }
156.351 + { // Checking GridGraph
156.352 + checkConcept<Graph, GridGraph>();
156.353 + }
156.354 + { // Checking HypercubeGraph
156.355 + checkConcept<Graph, HypercubeGraph>();
156.356 + }
156.357 }
156.358
156.359 template <typename Graph>
156.360 @@ -188,70 +403,163 @@
156.361 check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
156.362 }
156.363
156.364 -// void checkGridGraph(const GridGraph& g, int w, int h) {
156.365 -// check(g.width() == w, "Wrong width");
156.366 -// check(g.height() == h, "Wrong height");
156.367 +void checkGridGraph(int width, int height) {
156.368 + typedef GridGraph Graph;
156.369 + GRAPH_TYPEDEFS(Graph);
156.370 + Graph G(width, height);
156.371
156.372 -// for (int i = 0; i < w; ++i) {
156.373 -// for (int j = 0; j < h; ++j) {
156.374 -// check(g.col(g(i, j)) == i, "Wrong col");
156.375 -// check(g.row(g(i, j)) == j, "Wrong row");
156.376 -// }
156.377 -// }
156.378 + check(G.width() == width, "Wrong column number");
156.379 + check(G.height() == height, "Wrong row number");
156.380
156.381 -// for (int i = 0; i < w; ++i) {
156.382 -// for (int j = 0; j < h - 1; ++j) {
156.383 -// check(g.source(g.down(g(i, j))) == g(i, j), "Wrong down");
156.384 -// check(g.target(g.down(g(i, j))) == g(i, j + 1), "Wrong down");
156.385 -// }
156.386 -// check(g.down(g(i, h - 1)) == INVALID, "Wrong down");
156.387 -// }
156.388 + for (int i = 0; i < width; ++i) {
156.389 + for (int j = 0; j < height; ++j) {
156.390 + check(G.col(G(i, j)) == i, "Wrong column");
156.391 + check(G.row(G(i, j)) == j, "Wrong row");
156.392 + check(G.pos(G(i, j)).x == i, "Wrong column");
156.393 + check(G.pos(G(i, j)).y == j, "Wrong row");
156.394 + }
156.395 + }
156.396
156.397 -// for (int i = 0; i < w; ++i) {
156.398 -// for (int j = 1; j < h; ++j) {
156.399 -// check(g.source(g.up(g(i, j))) == g(i, j), "Wrong up");
156.400 -// check(g.target(g.up(g(i, j))) == g(i, j - 1), "Wrong up");
156.401 -// }
156.402 -// check(g.up(g(i, 0)) == INVALID, "Wrong up");
156.403 -// }
156.404 + for (int j = 0; j < height; ++j) {
156.405 + for (int i = 0; i < width - 1; ++i) {
156.406 + check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
156.407 + check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
156.408 + }
156.409 + check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
156.410 + }
156.411
156.412 -// for (int j = 0; j < h; ++j) {
156.413 -// for (int i = 0; i < w - 1; ++i) {
156.414 -// check(g.source(g.right(g(i, j))) == g(i, j), "Wrong right");
156.415 -// check(g.target(g.right(g(i, j))) == g(i + 1, j), "Wrong right");
156.416 -// }
156.417 -// check(g.right(g(w - 1, j)) == INVALID, "Wrong right");
156.418 -// }
156.419 + for (int j = 0; j < height; ++j) {
156.420 + for (int i = 1; i < width; ++i) {
156.421 + check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
156.422 + check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
156.423 + }
156.424 + check(G.left(G(0, j)) == INVALID, "Wrong left");
156.425 + }
156.426
156.427 -// for (int j = 0; j < h; ++j) {
156.428 -// for (int i = 1; i < w; ++i) {
156.429 -// check(g.source(g.left(g(i, j))) == g(i, j), "Wrong left");
156.430 -// check(g.target(g.left(g(i, j))) == g(i - 1, j), "Wrong left");
156.431 -// }
156.432 -// check(g.left(g(0, j)) == INVALID, "Wrong left");
156.433 -// }
156.434 -// }
156.435 + for (int i = 0; i < width; ++i) {
156.436 + for (int j = 0; j < height - 1; ++j) {
156.437 + check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
156.438 + check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
156.439 + }
156.440 + check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
156.441 + }
156.442 +
156.443 + for (int i = 0; i < width; ++i) {
156.444 + for (int j = 1; j < height; ++j) {
156.445 + check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
156.446 + check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
156.447 + }
156.448 + check(G.down(G(i, 0)) == INVALID, "Wrong down");
156.449 + }
156.450 +
156.451 + checkGraphNodeList(G, width * height);
156.452 + checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
156.453 + checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
156.454 +
156.455 + for (NodeIt n(G); n != INVALID; ++n) {
156.456 + int nb = 4;
156.457 + if (G.col(n) == 0) --nb;
156.458 + if (G.col(n) == width - 1) --nb;
156.459 + if (G.row(n) == 0) --nb;
156.460 + if (G.row(n) == height - 1) --nb;
156.461 +
156.462 + checkGraphOutArcList(G, n, nb);
156.463 + checkGraphInArcList(G, n, nb);
156.464 + checkGraphIncEdgeList(G, n, nb);
156.465 + }
156.466 +
156.467 + checkArcDirections(G);
156.468 +
156.469 + checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
156.470 + checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
156.471 +
156.472 + checkNodeIds(G);
156.473 + checkArcIds(G);
156.474 + checkEdgeIds(G);
156.475 + checkGraphNodeMap(G);
156.476 + checkGraphArcMap(G);
156.477 + checkGraphEdgeMap(G);
156.478 +
156.479 +}
156.480 +
156.481 +void checkHypercubeGraph(int dim) {
156.482 + GRAPH_TYPEDEFS(HypercubeGraph);
156.483 +
156.484 + HypercubeGraph G(dim);
156.485 + checkGraphNodeList(G, 1 << dim);
156.486 + checkGraphEdgeList(G, dim * (1 << (dim-1)));
156.487 + checkGraphArcList(G, dim * (1 << dim));
156.488 +
156.489 + Node n = G.nodeFromId(dim);
156.490 +
156.491 + for (NodeIt n(G); n != INVALID; ++n) {
156.492 + checkGraphIncEdgeList(G, n, dim);
156.493 + for (IncEdgeIt e(G, n); e != INVALID; ++e) {
156.494 + check( (G.u(e) == n &&
156.495 + G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
156.496 + (G.v(e) == n &&
156.497 + G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
156.498 + "Wrong edge or wrong dimension");
156.499 + }
156.500 +
156.501 + checkGraphOutArcList(G, n, dim);
156.502 + for (OutArcIt a(G, n); a != INVALID; ++a) {
156.503 + check(G.source(a) == n &&
156.504 + G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
156.505 + "Wrong arc or wrong dimension");
156.506 + }
156.507 +
156.508 + checkGraphInArcList(G, n, dim);
156.509 + for (InArcIt a(G, n); a != INVALID; ++a) {
156.510 + check(G.target(a) == n &&
156.511 + G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
156.512 + "Wrong arc or wrong dimension");
156.513 + }
156.514 + }
156.515 +
156.516 + checkGraphConArcList(G, (1 << dim) * dim);
156.517 + checkGraphConEdgeList(G, dim * (1 << (dim-1)));
156.518 +
156.519 + checkArcDirections(G);
156.520 +
156.521 + checkNodeIds(G);
156.522 + checkArcIds(G);
156.523 + checkEdgeIds(G);
156.524 + checkGraphNodeMap(G);
156.525 + checkGraphArcMap(G);
156.526 + checkGraphEdgeMap(G);
156.527 +}
156.528
156.529 void checkGraphs() {
156.530 { // Checking ListGraph
156.531 - checkGraph<ListGraph>();
156.532 + checkGraphBuild<ListGraph>();
156.533 + checkGraphAlter<ListGraph>();
156.534 + checkGraphErase<ListGraph>();
156.535 + checkGraphSnapshot<ListGraph>();
156.536 checkGraphValidityErase<ListGraph>();
156.537 }
156.538 { // Checking SmartGraph
156.539 - checkGraph<SmartGraph>();
156.540 + checkGraphBuild<SmartGraph>();
156.541 + checkGraphSnapshot<SmartGraph>();
156.542 checkGraphValidity<SmartGraph>();
156.543 }
156.544 -// { // Checking FullGraph
156.545 -// FullGraph g(5);
156.546 -// checkGraphNodeList(g, 5);
156.547 -// checkGraphEdgeList(g, 10);
156.548 -// }
156.549 -// { // Checking GridGraph
156.550 -// GridGraph g(5, 6);
156.551 -// checkGraphNodeList(g, 30);
156.552 -// checkGraphEdgeList(g, 49);
156.553 -// checkGridGraph(g, 5, 6);
156.554 -// }
156.555 + { // Checking FullGraph
156.556 + checkFullGraph(7);
156.557 + checkFullGraph(8);
156.558 + }
156.559 + { // Checking GridGraph
156.560 + checkGridGraph(5, 8);
156.561 + checkGridGraph(8, 5);
156.562 + checkGridGraph(5, 5);
156.563 + checkGridGraph(0, 0);
156.564 + checkGridGraph(1, 1);
156.565 + }
156.566 + { // Checking HypercubeGraph
156.567 + checkHypercubeGraph(1);
156.568 + checkHypercubeGraph(2);
156.569 + checkHypercubeGraph(3);
156.570 + checkHypercubeGraph(4);
156.571 + }
156.572 }
156.573
156.574 int main() {
157.1 --- a/test/graph_test.h Fri Nov 13 12:33:33 2009 +0100
157.2 +++ b/test/graph_test.h Thu Dec 10 17:05:35 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 @@ -117,6 +117,15 @@
157.13 }
157.14
157.15 template <class Graph>
157.16 + void checkGraphIncEdgeArcLists(const Graph &G, typename Graph::Node n,
157.17 + int cnt)
157.18 + {
157.19 + checkGraphIncEdgeList(G, n, cnt);
157.20 + checkGraphOutArcList(G, n, cnt);
157.21 + checkGraphInArcList(G, n, cnt);
157.22 + }
157.23 +
157.24 + template <class Graph>
157.25 void checkGraphConArcList(const Graph &G, int cnt) {
157.26 int i = 0;
157.27 for (typename Graph::NodeIt u(G); u != INVALID; ++u) {
158.1 --- a/test/graph_utils_test.cc Fri Nov 13 12:33:33 2009 +0100
158.2 +++ b/test/graph_utils_test.cc Thu Dec 10 17:05:35 2009 +0100
158.3 @@ -2,7 +2,7 @@
158.4 *
158.5 * This file is a part of LEMON, a generic C++ optimization library.
158.6 *
158.7 - * Copyright (C) 2003-2008
158.8 + * Copyright (C) 2003-2009
158.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
158.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
158.11 *
158.12 @@ -38,15 +38,15 @@
158.13 for (int i = 0; i < 10; ++i) {
158.14 digraph.addNode();
158.15 }
158.16 - DescriptorMap<Digraph, Node> nodes(digraph);
158.17 - typename DescriptorMap<Digraph, Node>::InverseMap invNodes(nodes);
158.18 + RangeIdMap<Digraph, Node> nodes(digraph);
158.19 + typename RangeIdMap<Digraph, Node>::InverseMap invNodes(nodes);
158.20 for (int i = 0; i < 100; ++i) {
158.21 int src = rnd[invNodes.size()];
158.22 int trg = rnd[invNodes.size()];
158.23 digraph.addArc(invNodes[src], invNodes[trg]);
158.24 }
158.25 typename Digraph::template ArcMap<bool> found(digraph, false);
158.26 - DescriptorMap<Digraph, Arc> arcs(digraph);
158.27 + RangeIdMap<Digraph, Arc> arcs(digraph);
158.28 for (NodeIt src(digraph); src != INVALID; ++src) {
158.29 for (NodeIt trg(digraph); trg != INVALID; ++trg) {
158.30 for (ConArcIt<Digraph> con(digraph, src, trg); con != INVALID; ++con) {
158.31 @@ -113,15 +113,15 @@
158.32 for (int i = 0; i < 10; ++i) {
158.33 graph.addNode();
158.34 }
158.35 - DescriptorMap<Graph, Node> nodes(graph);
158.36 - typename DescriptorMap<Graph, Node>::InverseMap invNodes(nodes);
158.37 + RangeIdMap<Graph, Node> nodes(graph);
158.38 + typename RangeIdMap<Graph, Node>::InverseMap invNodes(nodes);
158.39 for (int i = 0; i < 100; ++i) {
158.40 int src = rnd[invNodes.size()];
158.41 int trg = rnd[invNodes.size()];
158.42 graph.addEdge(invNodes[src], invNodes[trg]);
158.43 }
158.44 typename Graph::template EdgeMap<int> found(graph, 0);
158.45 - DescriptorMap<Graph, Edge> edges(graph);
158.46 + RangeIdMap<Graph, Edge> edges(graph);
158.47 for (NodeIt src(graph); src != INVALID; ++src) {
158.48 for (NodeIt trg(graph); trg != INVALID; ++trg) {
158.49 for (ConEdgeIt<Graph> con(graph, src, trg); con != INVALID; ++con) {
159.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
159.2 +++ b/test/hao_orlin_test.cc Thu Dec 10 17:05:35 2009 +0100
159.3 @@ -0,0 +1,163 @@
159.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
159.5 + *
159.6 + * This file is a part of LEMON, a generic C++ optimization library.
159.7 + *
159.8 + * Copyright (C) 2003-2009
159.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
159.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
159.11 + *
159.12 + * Permission to use, modify and distribute this software is granted
159.13 + * provided that this copyright notice appears in all copies. For
159.14 + * precise terms see the accompanying LICENSE file.
159.15 + *
159.16 + * This software is provided "AS IS" with no warranty of any kind,
159.17 + * express or implied, and with no claim as to its suitability for any
159.18 + * purpose.
159.19 + *
159.20 + */
159.21 +
159.22 +#include <sstream>
159.23 +
159.24 +#include <lemon/smart_graph.h>
159.25 +#include <lemon/adaptors.h>
159.26 +#include <lemon/concepts/digraph.h>
159.27 +#include <lemon/concepts/maps.h>
159.28 +#include <lemon/lgf_reader.h>
159.29 +#include <lemon/hao_orlin.h>
159.30 +
159.31 +#include "test_tools.h"
159.32 +
159.33 +using namespace lemon;
159.34 +using namespace std;
159.35 +
159.36 +const std::string lgf =
159.37 + "@nodes\n"
159.38 + "label\n"
159.39 + "0\n"
159.40 + "1\n"
159.41 + "2\n"
159.42 + "3\n"
159.43 + "4\n"
159.44 + "5\n"
159.45 + "@edges\n"
159.46 + " cap1 cap2 cap3\n"
159.47 + "0 1 1 1 1 \n"
159.48 + "0 2 2 2 4 \n"
159.49 + "1 2 4 4 4 \n"
159.50 + "3 4 1 1 1 \n"
159.51 + "3 5 2 2 4 \n"
159.52 + "4 5 4 4 4 \n"
159.53 + "5 4 4 4 4 \n"
159.54 + "2 3 1 6 6 \n"
159.55 + "4 0 1 6 6 \n";
159.56 +
159.57 +void checkHaoOrlinCompile()
159.58 +{
159.59 + typedef int Value;
159.60 + typedef concepts::Digraph Digraph;
159.61 +
159.62 + typedef Digraph::Node Node;
159.63 + typedef Digraph::Arc Arc;
159.64 + typedef concepts::ReadMap<Arc, Value> CapMap;
159.65 + typedef concepts::WriteMap<Node, bool> CutMap;
159.66 +
159.67 + Digraph g;
159.68 + Node n;
159.69 + CapMap cap;
159.70 + CutMap cut;
159.71 + Value v;
159.72 +
159.73 + HaoOrlin<Digraph, CapMap> ho_test(g, cap);
159.74 + const HaoOrlin<Digraph, CapMap>&
159.75 + const_ho_test = ho_test;
159.76 +
159.77 + ho_test.init();
159.78 + ho_test.init(n);
159.79 + ho_test.calculateOut();
159.80 + ho_test.calculateIn();
159.81 + ho_test.run();
159.82 + ho_test.run(n);
159.83 +
159.84 + v = const_ho_test.minCutValue();
159.85 + v = const_ho_test.minCutMap(cut);
159.86 +}
159.87 +
159.88 +template <typename Graph, typename CapMap, typename CutMap>
159.89 +typename CapMap::Value
159.90 + cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
159.91 +{
159.92 + typename CapMap::Value sum = 0;
159.93 + for (typename Graph::ArcIt a(graph); a != INVALID; ++a) {
159.94 + if (cut[graph.source(a)] && !cut[graph.target(a)])
159.95 + sum += cap[a];
159.96 + }
159.97 + return sum;
159.98 +}
159.99 +
159.100 +int main() {
159.101 + SmartDigraph graph;
159.102 + SmartDigraph::ArcMap<int> cap1(graph), cap2(graph), cap3(graph);
159.103 + SmartDigraph::NodeMap<bool> cut(graph);
159.104 +
159.105 + istringstream input(lgf);
159.106 + digraphReader(graph, input)
159.107 + .arcMap("cap1", cap1)
159.108 + .arcMap("cap2", cap2)
159.109 + .arcMap("cap3", cap3)
159.110 + .run();
159.111 +
159.112 + {
159.113 + HaoOrlin<SmartDigraph> ho(graph, cap1);
159.114 + ho.run();
159.115 + ho.minCutMap(cut);
159.116 +
159.117 + check(ho.minCutValue() == 1, "Wrong cut value");
159.118 + check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
159.119 + }
159.120 + {
159.121 + HaoOrlin<SmartDigraph> ho(graph, cap2);
159.122 + ho.run();
159.123 + ho.minCutMap(cut);
159.124 +
159.125 + check(ho.minCutValue() == 1, "Wrong cut value");
159.126 + check(ho.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
159.127 + }
159.128 + {
159.129 + HaoOrlin<SmartDigraph> ho(graph, cap3);
159.130 + ho.run();
159.131 + ho.minCutMap(cut);
159.132 +
159.133 + check(ho.minCutValue() == 1, "Wrong cut value");
159.134 + check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
159.135 + }
159.136 +
159.137 + typedef Undirector<SmartDigraph> UGraph;
159.138 + UGraph ugraph(graph);
159.139 +
159.140 + {
159.141 + HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1);
159.142 + ho.run();
159.143 + ho.minCutMap(cut);
159.144 +
159.145 + check(ho.minCutValue() == 2, "Wrong cut value");
159.146 + check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value");
159.147 + }
159.148 + {
159.149 + HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap2);
159.150 + ho.run();
159.151 + ho.minCutMap(cut);
159.152 +
159.153 + check(ho.minCutValue() == 5, "Wrong cut value");
159.154 + check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value");
159.155 + }
159.156 + {
159.157 + HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap3);
159.158 + ho.run();
159.159 + ho.minCutMap(cut);
159.160 +
159.161 + check(ho.minCutValue() == 5, "Wrong cut value");
159.162 + check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value");
159.163 + }
159.164 +
159.165 + return 0;
159.166 +}
160.1 --- a/test/heap_test.cc Fri Nov 13 12:33:33 2009 +0100
160.2 +++ b/test/heap_test.cc Thu Dec 10 17:05:35 2009 +0100
160.3 @@ -2,7 +2,7 @@
160.4 *
160.5 * This file is a part of LEMON, a generic C++ optimization library.
160.6 *
160.7 - * Copyright (C) 2003-2008
160.8 + * Copyright (C) 2003-2009
160.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
160.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
160.11 *
160.12 @@ -31,6 +31,9 @@
160.13 #include <lemon/maps.h>
160.14
160.15 #include <lemon/bin_heap.h>
160.16 +#include <lemon/fib_heap.h>
160.17 +#include <lemon/radix_heap.h>
160.18 +#include <lemon/bucket_heap.h>
160.19
160.20 #include "test_tools.h"
160.21
160.22 @@ -183,5 +186,39 @@
160.23 dijkstraHeapTest<NodeHeap>(digraph, length, source);
160.24 }
160.25
160.26 + {
160.27 + typedef FibHeap<Prio, ItemIntMap> IntHeap;
160.28 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
160.29 + heapSortTest<IntHeap>();
160.30 + heapIncreaseTest<IntHeap>();
160.31 +
160.32 + typedef FibHeap<Prio, IntNodeMap > NodeHeap;
160.33 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
160.34 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
160.35 + }
160.36 +
160.37 + {
160.38 + typedef RadixHeap<ItemIntMap> IntHeap;
160.39 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
160.40 + heapSortTest<IntHeap>();
160.41 + heapIncreaseTest<IntHeap>();
160.42 +
160.43 + typedef RadixHeap<IntNodeMap > NodeHeap;
160.44 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
160.45 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
160.46 + }
160.47 +
160.48 + {
160.49 + typedef BucketHeap<ItemIntMap> IntHeap;
160.50 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
160.51 + heapSortTest<IntHeap>();
160.52 + heapIncreaseTest<IntHeap>();
160.53 +
160.54 + typedef BucketHeap<IntNodeMap > NodeHeap;
160.55 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
160.56 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
160.57 + }
160.58 +
160.59 +
160.60 return 0;
160.61 }
161.1 --- a/test/kruskal_test.cc Fri Nov 13 12:33:33 2009 +0100
161.2 +++ b/test/kruskal_test.cc Thu Dec 10 17:05:35 2009 +0100
161.3 @@ -2,7 +2,7 @@
161.4 *
161.5 * This file is a part of LEMON, a generic C++ optimization library.
161.6 *
161.7 - * Copyright (C) 2003-2008
161.8 + * Copyright (C) 2003-2009
161.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
161.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
161.11 *
161.12 @@ -99,16 +99,16 @@
161.13 check(kruskal(G, edge_cost_map, tree_map)==10,
161.14 "Total cost should be 10");
161.15
161.16 - edge_cost_map.set(e1, -10);
161.17 - edge_cost_map.set(e2, -9);
161.18 - edge_cost_map.set(e3, -8);
161.19 - edge_cost_map.set(e4, -7);
161.20 - edge_cost_map.set(e5, -6);
161.21 - edge_cost_map.set(e6, -5);
161.22 - edge_cost_map.set(e7, -4);
161.23 - edge_cost_map.set(e8, -3);
161.24 - edge_cost_map.set(e9, -2);
161.25 - edge_cost_map.set(e10, -1);
161.26 + edge_cost_map[e1] = -10;
161.27 + edge_cost_map[e2] = -9;
161.28 + edge_cost_map[e3] = -8;
161.29 + edge_cost_map[e4] = -7;
161.30 + edge_cost_map[e5] = -6;
161.31 + edge_cost_map[e6] = -5;
161.32 + edge_cost_map[e7] = -4;
161.33 + edge_cost_map[e8] = -3;
161.34 + edge_cost_map[e9] = -2;
161.35 + edge_cost_map[e10] = -1;
161.36
161.37 vector<Edge> tree_edge_vec(5);
161.38
162.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
162.2 +++ b/test/lp_test.cc Thu Dec 10 17:05:35 2009 +0100
162.3 @@ -0,0 +1,419 @@
162.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
162.5 + *
162.6 + * This file is a part of LEMON, a generic C++ optimization library.
162.7 + *
162.8 + * Copyright (C) 2003-2009
162.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
162.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
162.11 + *
162.12 + * Permission to use, modify and distribute this software is granted
162.13 + * provided that this copyright notice appears in all copies. For
162.14 + * precise terms see the accompanying LICENSE file.
162.15 + *
162.16 + * This software is provided "AS IS" with no warranty of any kind,
162.17 + * express or implied, and with no claim as to its suitability for any
162.18 + * purpose.
162.19 + *
162.20 + */
162.21 +
162.22 +#include <sstream>
162.23 +#include <lemon/lp_skeleton.h>
162.24 +#include "test_tools.h"
162.25 +#include <lemon/tolerance.h>
162.26 +
162.27 +#include <lemon/config.h>
162.28 +
162.29 +#ifdef LEMON_HAVE_GLPK
162.30 +#include <lemon/glpk.h>
162.31 +#endif
162.32 +
162.33 +#ifdef LEMON_HAVE_CPLEX
162.34 +#include <lemon/cplex.h>
162.35 +#endif
162.36 +
162.37 +#ifdef LEMON_HAVE_SOPLEX
162.38 +#include <lemon/soplex.h>
162.39 +#endif
162.40 +
162.41 +#ifdef LEMON_HAVE_CLP
162.42 +#include <lemon/clp.h>
162.43 +#endif
162.44 +
162.45 +using namespace lemon;
162.46 +
162.47 +void lpTest(LpSolver& lp)
162.48 +{
162.49 +
162.50 + typedef LpSolver LP;
162.51 +
162.52 + std::vector<LP::Col> x(10);
162.53 + // for(int i=0;i<10;i++) x.push_back(lp.addCol());
162.54 + lp.addColSet(x);
162.55 + lp.colLowerBound(x,1);
162.56 + lp.colUpperBound(x,1);
162.57 + lp.colBounds(x,1,2);
162.58 +
162.59 + std::vector<LP::Col> y(10);
162.60 + lp.addColSet(y);
162.61 +
162.62 + lp.colLowerBound(y,1);
162.63 + lp.colUpperBound(y,1);
162.64 + lp.colBounds(y,1,2);
162.65 +
162.66 + std::map<int,LP::Col> z;
162.67 +
162.68 + z.insert(std::make_pair(12,INVALID));
162.69 + z.insert(std::make_pair(2,INVALID));
162.70 + z.insert(std::make_pair(7,INVALID));
162.71 + z.insert(std::make_pair(5,INVALID));
162.72 +
162.73 + lp.addColSet(z);
162.74 +
162.75 + lp.colLowerBound(z,1);
162.76 + lp.colUpperBound(z,1);
162.77 + lp.colBounds(z,1,2);
162.78 +
162.79 + {
162.80 + LP::Expr e,f,g;
162.81 + LP::Col p1,p2,p3,p4,p5;
162.82 + LP::Constr c;
162.83 +
162.84 + p1=lp.addCol();
162.85 + p2=lp.addCol();
162.86 + p3=lp.addCol();
162.87 + p4=lp.addCol();
162.88 + p5=lp.addCol();
162.89 +
162.90 + e[p1]=2;
162.91 + *e=12;
162.92 + e[p1]+=2;
162.93 + *e+=12;
162.94 + e[p1]-=2;
162.95 + *e-=12;
162.96 +
162.97 + e=2;
162.98 + e=2.2;
162.99 + e=p1;
162.100 + e=f;
162.101 +
162.102 + e+=2;
162.103 + e+=2.2;
162.104 + e+=p1;
162.105 + e+=f;
162.106 +
162.107 + e-=2;
162.108 + e-=2.2;
162.109 + e-=p1;
162.110 + e-=f;
162.111 +
162.112 + e*=2;
162.113 + e*=2.2;
162.114 + e/=2;
162.115 + e/=2.2;
162.116 +
162.117 + e=((p1+p2)+(p1-p2)+(p1+12)+(12+p1)+(p1-12)+(12-p1)+
162.118 + (f+12)+(12+f)+(p1+f)+(f+p1)+(f+g)+
162.119 + (f-12)+(12-f)+(p1-f)+(f-p1)+(f-g)+
162.120 + 2.2*f+f*2.2+f/2.2+
162.121 + 2*f+f*2+f/2+
162.122 + 2.2*p1+p1*2.2+p1/2.2+
162.123 + 2*p1+p1*2+p1/2
162.124 + );
162.125 +
162.126 +
162.127 + c = (e <= f );
162.128 + c = (e <= 2.2);
162.129 + c = (e <= 2 );
162.130 + c = (e <= p1 );
162.131 + c = (2.2<= f );
162.132 + c = (2 <= f );
162.133 + c = (p1 <= f );
162.134 + c = (p1 <= p2 );
162.135 + c = (p1 <= 2.2);
162.136 + c = (p1 <= 2 );
162.137 + c = (2.2<= p2 );
162.138 + c = (2 <= p2 );
162.139 +
162.140 + c = (e >= f );
162.141 + c = (e >= 2.2);
162.142 + c = (e >= 2 );
162.143 + c = (e >= p1 );
162.144 + c = (2.2>= f );
162.145 + c = (2 >= f );
162.146 + c = (p1 >= f );
162.147 + c = (p1 >= p2 );
162.148 + c = (p1 >= 2.2);
162.149 + c = (p1 >= 2 );
162.150 + c = (2.2>= p2 );
162.151 + c = (2 >= p2 );
162.152 +
162.153 + c = (e == f );
162.154 + c = (e == 2.2);
162.155 + c = (e == 2 );
162.156 + c = (e == p1 );
162.157 + c = (2.2== f );
162.158 + c = (2 == f );
162.159 + c = (p1 == f );
162.160 + //c = (p1 == p2 );
162.161 + c = (p1 == 2.2);
162.162 + c = (p1 == 2 );
162.163 + c = (2.2== p2 );
162.164 + c = (2 == p2 );
162.165 +
162.166 + c = ((2 <= e) <= 3);
162.167 + c = ((2 <= p1) <= 3);
162.168 +
162.169 + c = ((2 >= e) >= 3);
162.170 + c = ((2 >= p1) >= 3);
162.171 +
162.172 + e[x[3]]=2;
162.173 + e[x[3]]=4;
162.174 + e[x[3]]=1;
162.175 + *e=12;
162.176 +
162.177 + lp.addRow(-LP::INF,e,23);
162.178 + lp.addRow(-LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
162.179 + lp.addRow(-LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
162.180 +
162.181 + lp.addRow(x[1]+x[3]<=x[5]-3);
162.182 + lp.addRow((-7<=x[1]+x[3]-12)<=3);
162.183 + lp.addRow(x[1]<=x[5]);
162.184 +
162.185 + std::ostringstream buf;
162.186 +
162.187 +
162.188 + e=((p1+p2)+(p1-0.99*p2));
162.189 + //e.prettyPrint(std::cout);
162.190 + //(e<=2).prettyPrint(std::cout);
162.191 + double tolerance=0.001;
162.192 + e.simplify(tolerance);
162.193 + buf << "Coeff. of p2 should be 0.01";
162.194 + check(e[p2]>0, buf.str());
162.195 +
162.196 + tolerance=0.02;
162.197 + e.simplify(tolerance);
162.198 + buf << "Coeff. of p2 should be 0";
162.199 + check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
162.200 +
162.201 + //Test for clone/new
162.202 + LP* lpnew = lp.newSolver();
162.203 + LP* lpclone = lp.cloneSolver();
162.204 + delete lpnew;
162.205 + delete lpclone;
162.206 +
162.207 + }
162.208 +
162.209 + {
162.210 + LP::DualExpr e,f,g;
162.211 + LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID,
162.212 + p4 = INVALID, p5 = INVALID;
162.213 +
162.214 + e[p1]=2;
162.215 + e[p1]+=2;
162.216 + e[p1]-=2;
162.217 +
162.218 + e=p1;
162.219 + e=f;
162.220 +
162.221 + e+=p1;
162.222 + e+=f;
162.223 +
162.224 + e-=p1;
162.225 + e-=f;
162.226 +
162.227 + e*=2;
162.228 + e*=2.2;
162.229 + e/=2;
162.230 + e/=2.2;
162.231 +
162.232 + e=((p1+p2)+(p1-p2)+
162.233 + (p1+f)+(f+p1)+(f+g)+
162.234 + (p1-f)+(f-p1)+(f-g)+
162.235 + 2.2*f+f*2.2+f/2.2+
162.236 + 2*f+f*2+f/2+
162.237 + 2.2*p1+p1*2.2+p1/2.2+
162.238 + 2*p1+p1*2+p1/2
162.239 + );
162.240 + }
162.241 +
162.242 +}
162.243 +
162.244 +void solveAndCheck(LpSolver& lp, LpSolver::ProblemType stat,
162.245 + double exp_opt) {
162.246 + using std::string;
162.247 + lp.solve();
162.248 +
162.249 + std::ostringstream buf;
162.250 + buf << "PrimalType should be: " << int(stat) << int(lp.primalType());
162.251 +
162.252 + check(lp.primalType()==stat, buf.str());
162.253 +
162.254 + if (stat == LpSolver::OPTIMAL) {
162.255 + std::ostringstream sbuf;
162.256 + sbuf << "Wrong optimal value (" << lp.primal() <<") with "
162.257 + << lp.solverName() <<"\n the right optimum is " << exp_opt;
162.258 + check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
162.259 + }
162.260 +}
162.261 +
162.262 +void aTest(LpSolver & lp)
162.263 +{
162.264 + typedef LpSolver LP;
162.265 +
162.266 + //The following example is very simple
162.267 +
162.268 + typedef LpSolver::Row Row;
162.269 + typedef LpSolver::Col Col;
162.270 +
162.271 +
162.272 + Col x1 = lp.addCol();
162.273 + Col x2 = lp.addCol();
162.274 +
162.275 +
162.276 + //Constraints
162.277 + Row upright=lp.addRow(x1+2*x2 <=1);
162.278 + lp.addRow(x1+x2 >=-1);
162.279 + lp.addRow(x1-x2 <=1);
162.280 + lp.addRow(x1-x2 >=-1);
162.281 + //Nonnegativity of the variables
162.282 + lp.colLowerBound(x1, 0);
162.283 + lp.colLowerBound(x2, 0);
162.284 + //Objective function
162.285 + lp.obj(x1+x2);
162.286 +
162.287 + lp.sense(lp.MAX);
162.288 +
162.289 + //Testing the problem retrieving routines
162.290 + check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
162.291 + check(lp.sense() == lp.MAX,"This is a maximization!");
162.292 + check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
162.293 + check(lp.colLowerBound(x1)==0,
162.294 + "The lower bound for variable x1 should be 0.");
162.295 + check(lp.colUpperBound(x1)==LpSolver::INF,
162.296 + "The upper bound for variable x1 should be infty.");
162.297 + check(lp.rowLowerBound(upright) == -LpSolver::INF,
162.298 + "The lower bound for the first row should be -infty.");
162.299 + check(lp.rowUpperBound(upright)==1,
162.300 + "The upper bound for the first row should be 1.");
162.301 + LpSolver::Expr e = lp.row(upright);
162.302 + check(e[x1] == 1, "The first coefficient should 1.");
162.303 + check(e[x2] == 2, "The second coefficient should 1.");
162.304 +
162.305 + lp.row(upright, x1+x2 <=1);
162.306 + e = lp.row(upright);
162.307 + check(e[x1] == 1, "The first coefficient should 1.");
162.308 + check(e[x2] == 1, "The second coefficient should 1.");
162.309 +
162.310 + LpSolver::DualExpr de = lp.col(x1);
162.311 + check( de[upright] == 1, "The first coefficient should 1.");
162.312 +
162.313 + LpSolver* clp = lp.cloneSolver();
162.314 +
162.315 + //Testing the problem retrieving routines
162.316 + check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!");
162.317 + check(clp->sense() == clp->MAX,"This is a maximization!");
162.318 + check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!");
162.319 + // std::cout<<lp.colLowerBound(x1)<<std::endl;
162.320 + check(clp->colLowerBound(x1)==0,
162.321 + "The lower bound for variable x1 should be 0.");
162.322 + check(clp->colUpperBound(x1)==LpSolver::INF,
162.323 + "The upper bound for variable x1 should be infty.");
162.324 +
162.325 + check(lp.rowLowerBound(upright)==-LpSolver::INF,
162.326 + "The lower bound for the first row should be -infty.");
162.327 + check(lp.rowUpperBound(upright)==1,
162.328 + "The upper bound for the first row should be 1.");
162.329 + e = clp->row(upright);
162.330 + check(e[x1] == 1, "The first coefficient should 1.");
162.331 + check(e[x2] == 1, "The second coefficient should 1.");
162.332 +
162.333 + de = clp->col(x1);
162.334 + check(de[upright] == 1, "The first coefficient should 1.");
162.335 +
162.336 + delete clp;
162.337 +
162.338 + //Maximization of x1+x2
162.339 + //over the triangle with vertices (0,0) (0,1) (1,0)
162.340 + double expected_opt=1;
162.341 + solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
162.342 +
162.343 + //Minimization
162.344 + lp.sense(lp.MIN);
162.345 + expected_opt=0;
162.346 + solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
162.347 +
162.348 + //Vertex (-1,0) instead of (0,0)
162.349 + lp.colLowerBound(x1, -LpSolver::INF);
162.350 + expected_opt=-1;
162.351 + solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
162.352 +
162.353 + //Erase one constraint and return to maximization
162.354 + lp.erase(upright);
162.355 + lp.sense(lp.MAX);
162.356 + expected_opt=LpSolver::INF;
162.357 + solveAndCheck(lp, LpSolver::UNBOUNDED, expected_opt);
162.358 +
162.359 + //Infeasibilty
162.360 + lp.addRow(x1+x2 <=-2);
162.361 + solveAndCheck(lp, LpSolver::INFEASIBLE, expected_opt);
162.362 +
162.363 +}
162.364 +
162.365 +template<class LP>
162.366 +void cloneTest()
162.367 +{
162.368 + //Test for clone/new
162.369 +
162.370 + LP* lp = new LP();
162.371 + LP* lpnew = lp->newSolver();
162.372 + LP* lpclone = lp->cloneSolver();
162.373 + delete lp;
162.374 + delete lpnew;
162.375 + delete lpclone;
162.376 +}
162.377 +
162.378 +int main()
162.379 +{
162.380 + LpSkeleton lp_skel;
162.381 + lpTest(lp_skel);
162.382 +
162.383 +#ifdef LEMON_HAVE_GLPK
162.384 + {
162.385 + GlpkLp lp_glpk1,lp_glpk2;
162.386 + lpTest(lp_glpk1);
162.387 + aTest(lp_glpk2);
162.388 + cloneTest<GlpkLp>();
162.389 + }
162.390 +#endif
162.391 +
162.392 +#ifdef LEMON_HAVE_CPLEX
162.393 + try {
162.394 + CplexLp lp_cplex1,lp_cplex2;
162.395 + lpTest(lp_cplex1);
162.396 + aTest(lp_cplex2);
162.397 + cloneTest<CplexLp>();
162.398 + } catch (CplexEnv::LicenseError& error) {
162.399 + check(false, error.what());
162.400 + }
162.401 +#endif
162.402 +
162.403 +#ifdef LEMON_HAVE_SOPLEX
162.404 + {
162.405 + SoplexLp lp_soplex1,lp_soplex2;
162.406 + lpTest(lp_soplex1);
162.407 + aTest(lp_soplex2);
162.408 + cloneTest<SoplexLp>();
162.409 + }
162.410 +#endif
162.411 +
162.412 +#ifdef LEMON_HAVE_CLP
162.413 + {
162.414 + ClpLp lp_clp1,lp_clp2;
162.415 + lpTest(lp_clp1);
162.416 + aTest(lp_clp2);
162.417 + cloneTest<ClpLp>();
162.418 + }
162.419 +#endif
162.420 +
162.421 + return 0;
162.422 +}
163.1 --- a/test/maps_test.cc Fri Nov 13 12:33:33 2009 +0100
163.2 +++ b/test/maps_test.cc Thu Dec 10 17:05:35 2009 +0100
163.3 @@ -2,7 +2,7 @@
163.4 *
163.5 * This file is a part of LEMON, a generic C++ optimization library.
163.6 *
163.7 - * Copyright (C) 2003-2008
163.8 + * Copyright (C) 2003-2009
163.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
163.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
163.11 *
163.12 @@ -170,7 +170,7 @@
163.13 {
163.14 typedef ComposeMap<DoubleMap, ReadMap<B,A> > CompMap;
163.15 checkConcept<ReadMap<B,double>, CompMap>();
163.16 - CompMap map1(DoubleMap(),ReadMap<B,A>());
163.17 + CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
163.18 CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
163.19
163.20 SparseMap<double, bool> m1(false); m1[3.14] = true;
163.21 @@ -183,7 +183,7 @@
163.22 {
163.23 typedef CombineMap<DoubleMap, DoubleMap, std::plus<double> > CombMap;
163.24 checkConcept<ReadMap<A,double>, CombMap>();
163.25 - CombMap map1(DoubleMap(), DoubleMap());
163.26 + CombMap map1 = CombMap(DoubleMap(), DoubleMap());
163.27 CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
163.28
163.29 check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3,
163.30 @@ -195,11 +195,11 @@
163.31 checkConcept<ReadMap<A,B>, FunctorToMap<F,A,B> >();
163.32 checkConcept<ReadMap<A,B>, FunctorToMap<F> >();
163.33 FunctorToMap<F> map1;
163.34 - FunctorToMap<F> map2(F());
163.35 + FunctorToMap<F> map2 = FunctorToMap<F>(F());
163.36 B b = functorToMap(F())[A()];
163.37
163.38 checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
163.39 - MapToFunctor<ReadMap<A,B> > map(ReadMap<A,B>());
163.40 + MapToFunctor<ReadMap<A,B> > map = MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
163.41
163.42 check(functorToMap(&func)[A()] == 3,
163.43 "Something is wrong with FunctorToMap");
164.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
164.2 +++ b/test/matching_test.cc Thu Dec 10 17:05:35 2009 +0100
164.3 @@ -0,0 +1,424 @@
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 +#include <iostream>
164.23 +#include <sstream>
164.24 +#include <vector>
164.25 +#include <queue>
164.26 +#include <cstdlib>
164.27 +
164.28 +#include <lemon/matching.h>
164.29 +#include <lemon/smart_graph.h>
164.30 +#include <lemon/concepts/graph.h>
164.31 +#include <lemon/concepts/maps.h>
164.32 +#include <lemon/lgf_reader.h>
164.33 +#include <lemon/math.h>
164.34 +
164.35 +#include "test_tools.h"
164.36 +
164.37 +using namespace std;
164.38 +using namespace lemon;
164.39 +
164.40 +GRAPH_TYPEDEFS(SmartGraph);
164.41 +
164.42 +
164.43 +const int lgfn = 3;
164.44 +const std::string lgf[lgfn] = {
164.45 + "@nodes\n"
164.46 + "label\n"
164.47 + "0\n"
164.48 + "1\n"
164.49 + "2\n"
164.50 + "3\n"
164.51 + "4\n"
164.52 + "5\n"
164.53 + "6\n"
164.54 + "7\n"
164.55 + "@edges\n"
164.56 + " label weight\n"
164.57 + "7 4 0 984\n"
164.58 + "0 7 1 73\n"
164.59 + "7 1 2 204\n"
164.60 + "2 3 3 583\n"
164.61 + "2 7 4 565\n"
164.62 + "2 1 5 582\n"
164.63 + "0 4 6 551\n"
164.64 + "2 5 7 385\n"
164.65 + "1 5 8 561\n"
164.66 + "5 3 9 484\n"
164.67 + "7 5 10 904\n"
164.68 + "3 6 11 47\n"
164.69 + "7 6 12 888\n"
164.70 + "3 0 13 747\n"
164.71 + "6 1 14 310\n",
164.72 +
164.73 + "@nodes\n"
164.74 + "label\n"
164.75 + "0\n"
164.76 + "1\n"
164.77 + "2\n"
164.78 + "3\n"
164.79 + "4\n"
164.80 + "5\n"
164.81 + "6\n"
164.82 + "7\n"
164.83 + "@edges\n"
164.84 + " label weight\n"
164.85 + "2 5 0 710\n"
164.86 + "0 5 1 241\n"
164.87 + "2 4 2 856\n"
164.88 + "2 6 3 762\n"
164.89 + "4 1 4 747\n"
164.90 + "6 1 5 962\n"
164.91 + "4 7 6 723\n"
164.92 + "1 7 7 661\n"
164.93 + "2 3 8 376\n"
164.94 + "1 0 9 416\n"
164.95 + "6 7 10 391\n",
164.96 +
164.97 + "@nodes\n"
164.98 + "label\n"
164.99 + "0\n"
164.100 + "1\n"
164.101 + "2\n"
164.102 + "3\n"
164.103 + "4\n"
164.104 + "5\n"
164.105 + "6\n"
164.106 + "7\n"
164.107 + "@edges\n"
164.108 + " label weight\n"
164.109 + "6 2 0 553\n"
164.110 + "0 7 1 653\n"
164.111 + "6 3 2 22\n"
164.112 + "4 7 3 846\n"
164.113 + "7 2 4 981\n"
164.114 + "7 6 5 250\n"
164.115 + "5 2 6 539\n",
164.116 +};
164.117 +
164.118 +void checkMaxMatchingCompile()
164.119 +{
164.120 + typedef concepts::Graph Graph;
164.121 + typedef Graph::Node Node;
164.122 + typedef Graph::Edge Edge;
164.123 + typedef Graph::EdgeMap<bool> MatMap;
164.124 +
164.125 + Graph g;
164.126 + Node n;
164.127 + Edge e;
164.128 + MatMap mat(g);
164.129 +
164.130 + MaxMatching<Graph> mat_test(g);
164.131 + const MaxMatching<Graph>&
164.132 + const_mat_test = mat_test;
164.133 +
164.134 + mat_test.init();
164.135 + mat_test.greedyInit();
164.136 + mat_test.matchingInit(mat);
164.137 + mat_test.startSparse();
164.138 + mat_test.startDense();
164.139 + mat_test.run();
164.140 +
164.141 + const_mat_test.matchingSize();
164.142 + const_mat_test.matching(e);
164.143 + const_mat_test.matching(n);
164.144 + const MaxMatching<Graph>::MatchingMap& mmap =
164.145 + const_mat_test.matchingMap();
164.146 + e = mmap[n];
164.147 + const_mat_test.mate(n);
164.148 +
164.149 + MaxMatching<Graph>::Status stat =
164.150 + const_mat_test.status(n);
164.151 + const MaxMatching<Graph>::StatusMap& smap =
164.152 + const_mat_test.statusMap();
164.153 + stat = smap[n];
164.154 + const_mat_test.barrier(n);
164.155 +}
164.156 +
164.157 +void checkMaxWeightedMatchingCompile()
164.158 +{
164.159 + typedef concepts::Graph Graph;
164.160 + typedef Graph::Node Node;
164.161 + typedef Graph::Edge Edge;
164.162 + typedef Graph::EdgeMap<int> WeightMap;
164.163 +
164.164 + Graph g;
164.165 + Node n;
164.166 + Edge e;
164.167 + WeightMap w(g);
164.168 +
164.169 + MaxWeightedMatching<Graph> mat_test(g, w);
164.170 + const MaxWeightedMatching<Graph>&
164.171 + const_mat_test = mat_test;
164.172 +
164.173 + mat_test.init();
164.174 + mat_test.start();
164.175 + mat_test.run();
164.176 +
164.177 + const_mat_test.matchingWeight();
164.178 + const_mat_test.matchingSize();
164.179 + const_mat_test.matching(e);
164.180 + const_mat_test.matching(n);
164.181 + const MaxWeightedMatching<Graph>::MatchingMap& mmap =
164.182 + const_mat_test.matchingMap();
164.183 + e = mmap[n];
164.184 + const_mat_test.mate(n);
164.185 +
164.186 + int k = 0;
164.187 + const_mat_test.dualValue();
164.188 + const_mat_test.nodeValue(n);
164.189 + const_mat_test.blossomNum();
164.190 + const_mat_test.blossomSize(k);
164.191 + const_mat_test.blossomValue(k);
164.192 +}
164.193 +
164.194 +void checkMaxWeightedPerfectMatchingCompile()
164.195 +{
164.196 + typedef concepts::Graph Graph;
164.197 + typedef Graph::Node Node;
164.198 + typedef Graph::Edge Edge;
164.199 + typedef Graph::EdgeMap<int> WeightMap;
164.200 +
164.201 + Graph g;
164.202 + Node n;
164.203 + Edge e;
164.204 + WeightMap w(g);
164.205 +
164.206 + MaxWeightedPerfectMatching<Graph> mat_test(g, w);
164.207 + const MaxWeightedPerfectMatching<Graph>&
164.208 + const_mat_test = mat_test;
164.209 +
164.210 + mat_test.init();
164.211 + mat_test.start();
164.212 + mat_test.run();
164.213 +
164.214 + const_mat_test.matchingWeight();
164.215 + const_mat_test.matching(e);
164.216 + const_mat_test.matching(n);
164.217 + const MaxWeightedPerfectMatching<Graph>::MatchingMap& mmap =
164.218 + const_mat_test.matchingMap();
164.219 + e = mmap[n];
164.220 + const_mat_test.mate(n);
164.221 +
164.222 + int k = 0;
164.223 + const_mat_test.dualValue();
164.224 + const_mat_test.nodeValue(n);
164.225 + const_mat_test.blossomNum();
164.226 + const_mat_test.blossomSize(k);
164.227 + const_mat_test.blossomValue(k);
164.228 +}
164.229 +
164.230 +void checkMatching(const SmartGraph& graph,
164.231 + const MaxMatching<SmartGraph>& mm) {
164.232 + int num = 0;
164.233 +
164.234 + IntNodeMap comp_index(graph);
164.235 + UnionFind<IntNodeMap> comp(comp_index);
164.236 +
164.237 + int barrier_num = 0;
164.238 +
164.239 + for (NodeIt n(graph); n != INVALID; ++n) {
164.240 + check(mm.status(n) == MaxMatching<SmartGraph>::EVEN ||
164.241 + mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
164.242 + if (mm.status(n) == MaxMatching<SmartGraph>::ODD) {
164.243 + ++barrier_num;
164.244 + } else {
164.245 + comp.insert(n);
164.246 + }
164.247 + }
164.248 +
164.249 + for (EdgeIt e(graph); e != INVALID; ++e) {
164.250 + if (mm.matching(e)) {
164.251 + check(e == mm.matching(graph.u(e)), "Wrong matching");
164.252 + check(e == mm.matching(graph.v(e)), "Wrong matching");
164.253 + ++num;
164.254 + }
164.255 + check(mm.status(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
164.256 + mm.status(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
164.257 + "Wrong Gallai-Edmonds decomposition");
164.258 +
164.259 + check(mm.status(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
164.260 + mm.status(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
164.261 + "Wrong Gallai-Edmonds decomposition");
164.262 +
164.263 + if (mm.status(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
164.264 + mm.status(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
164.265 + comp.join(graph.u(e), graph.v(e));
164.266 + }
164.267 + }
164.268 +
164.269 + std::set<int> comp_root;
164.270 + int odd_comp_num = 0;
164.271 + for (NodeIt n(graph); n != INVALID; ++n) {
164.272 + if (mm.status(n) != MaxMatching<SmartGraph>::ODD) {
164.273 + int root = comp.find(n);
164.274 + if (comp_root.find(root) == comp_root.end()) {
164.275 + comp_root.insert(root);
164.276 + if (comp.size(n) % 2 == 1) {
164.277 + ++odd_comp_num;
164.278 + }
164.279 + }
164.280 + }
164.281 + }
164.282 +
164.283 + check(mm.matchingSize() == num, "Wrong matching");
164.284 + check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num),
164.285 + "Wrong matching");
164.286 + return;
164.287 +}
164.288 +
164.289 +void checkWeightedMatching(const SmartGraph& graph,
164.290 + const SmartGraph::EdgeMap<int>& weight,
164.291 + const MaxWeightedMatching<SmartGraph>& mwm) {
164.292 + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
164.293 + if (graph.u(e) == graph.v(e)) continue;
164.294 + int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e));
164.295 +
164.296 + for (int i = 0; i < mwm.blossomNum(); ++i) {
164.297 + bool s = false, t = false;
164.298 + for (MaxWeightedMatching<SmartGraph>::BlossomIt n(mwm, i);
164.299 + n != INVALID; ++n) {
164.300 + if (graph.u(e) == n) s = true;
164.301 + if (graph.v(e) == n) t = true;
164.302 + }
164.303 + if (s == true && t == true) {
164.304 + rw += mwm.blossomValue(i);
164.305 + }
164.306 + }
164.307 + rw -= weight[e] * mwm.dualScale;
164.308 +
164.309 + check(rw >= 0, "Negative reduced weight");
164.310 + check(rw == 0 || !mwm.matching(e),
164.311 + "Non-zero reduced weight on matching edge");
164.312 + }
164.313 +
164.314 + int pv = 0;
164.315 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
164.316 + if (mwm.matching(n) != INVALID) {
164.317 + check(mwm.nodeValue(n) >= 0, "Invalid node value");
164.318 + pv += weight[mwm.matching(n)];
164.319 + SmartGraph::Node o = graph.target(mwm.matching(n));
164.320 + check(mwm.mate(n) == o, "Invalid matching");
164.321 + check(mwm.matching(n) == graph.oppositeArc(mwm.matching(o)),
164.322 + "Invalid matching");
164.323 + } else {
164.324 + check(mwm.mate(n) == INVALID, "Invalid matching");
164.325 + check(mwm.nodeValue(n) == 0, "Invalid matching");
164.326 + }
164.327 + }
164.328 +
164.329 + int dv = 0;
164.330 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
164.331 + dv += mwm.nodeValue(n);
164.332 + }
164.333 +
164.334 + for (int i = 0; i < mwm.blossomNum(); ++i) {
164.335 + check(mwm.blossomValue(i) >= 0, "Invalid blossom value");
164.336 + check(mwm.blossomSize(i) % 2 == 1, "Even blossom size");
164.337 + dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2);
164.338 + }
164.339 +
164.340 + check(pv * mwm.dualScale == dv * 2, "Wrong duality");
164.341 +
164.342 + return;
164.343 +}
164.344 +
164.345 +void checkWeightedPerfectMatching(const SmartGraph& graph,
164.346 + const SmartGraph::EdgeMap<int>& weight,
164.347 + const MaxWeightedPerfectMatching<SmartGraph>& mwpm) {
164.348 + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
164.349 + if (graph.u(e) == graph.v(e)) continue;
164.350 + int rw = mwpm.nodeValue(graph.u(e)) + mwpm.nodeValue(graph.v(e));
164.351 +
164.352 + for (int i = 0; i < mwpm.blossomNum(); ++i) {
164.353 + bool s = false, t = false;
164.354 + for (MaxWeightedPerfectMatching<SmartGraph>::BlossomIt n(mwpm, i);
164.355 + n != INVALID; ++n) {
164.356 + if (graph.u(e) == n) s = true;
164.357 + if (graph.v(e) == n) t = true;
164.358 + }
164.359 + if (s == true && t == true) {
164.360 + rw += mwpm.blossomValue(i);
164.361 + }
164.362 + }
164.363 + rw -= weight[e] * mwpm.dualScale;
164.364 +
164.365 + check(rw >= 0, "Negative reduced weight");
164.366 + check(rw == 0 || !mwpm.matching(e),
164.367 + "Non-zero reduced weight on matching edge");
164.368 + }
164.369 +
164.370 + int pv = 0;
164.371 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
164.372 + check(mwpm.matching(n) != INVALID, "Non perfect");
164.373 + pv += weight[mwpm.matching(n)];
164.374 + SmartGraph::Node o = graph.target(mwpm.matching(n));
164.375 + check(mwpm.mate(n) == o, "Invalid matching");
164.376 + check(mwpm.matching(n) == graph.oppositeArc(mwpm.matching(o)),
164.377 + "Invalid matching");
164.378 + }
164.379 +
164.380 + int dv = 0;
164.381 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
164.382 + dv += mwpm.nodeValue(n);
164.383 + }
164.384 +
164.385 + for (int i = 0; i < mwpm.blossomNum(); ++i) {
164.386 + check(mwpm.blossomValue(i) >= 0, "Invalid blossom value");
164.387 + check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size");
164.388 + dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2);
164.389 + }
164.390 +
164.391 + check(pv * mwpm.dualScale == dv * 2, "Wrong duality");
164.392 +
164.393 + return;
164.394 +}
164.395 +
164.396 +
164.397 +int main() {
164.398 +
164.399 + for (int i = 0; i < lgfn; ++i) {
164.400 + SmartGraph graph;
164.401 + SmartGraph::EdgeMap<int> weight(graph);
164.402 +
164.403 + istringstream lgfs(lgf[i]);
164.404 + graphReader(graph, lgfs).
164.405 + edgeMap("weight", weight).run();
164.406 +
164.407 + MaxMatching<SmartGraph> mm(graph);
164.408 + mm.run();
164.409 + checkMatching(graph, mm);
164.410 +
164.411 + MaxWeightedMatching<SmartGraph> mwm(graph, weight);
164.412 + mwm.run();
164.413 + checkWeightedMatching(graph, weight, mwm);
164.414 +
164.415 + MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
164.416 + bool perfect = mwpm.run();
164.417 +
164.418 + check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
164.419 + "Perfect matching found");
164.420 +
164.421 + if (perfect) {
164.422 + checkWeightedPerfectMatching(graph, weight, mwpm);
164.423 + }
164.424 + }
164.425 +
164.426 + return 0;
164.427 +}
165.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
165.2 +++ b/test/min_cost_arborescence_test.cc Thu Dec 10 17:05:35 2009 +0100
165.3 @@ -0,0 +1,206 @@
165.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
165.5 + *
165.6 + * This file is a part of LEMON, a generic C++ optimization library.
165.7 + *
165.8 + * Copyright (C) 2003-2008
165.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
165.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
165.11 + *
165.12 + * Permission to use, modify and distribute this software is granted
165.13 + * provided that this copyright notice appears in all copies. For
165.14 + * precise terms see the accompanying LICENSE file.
165.15 + *
165.16 + * This software is provided "AS IS" with no warranty of any kind,
165.17 + * express or implied, and with no claim as to its suitability for any
165.18 + * purpose.
165.19 + *
165.20 + */
165.21 +
165.22 +#include <iostream>
165.23 +#include <set>
165.24 +#include <vector>
165.25 +#include <iterator>
165.26 +
165.27 +#include <lemon/smart_graph.h>
165.28 +#include <lemon/min_cost_arborescence.h>
165.29 +#include <lemon/lgf_reader.h>
165.30 +#include <lemon/concepts/digraph.h>
165.31 +
165.32 +#include "test_tools.h"
165.33 +
165.34 +using namespace lemon;
165.35 +using namespace std;
165.36 +
165.37 +const char test_lgf[] =
165.38 + "@nodes\n"
165.39 + "label\n"
165.40 + "0\n"
165.41 + "1\n"
165.42 + "2\n"
165.43 + "3\n"
165.44 + "4\n"
165.45 + "5\n"
165.46 + "6\n"
165.47 + "7\n"
165.48 + "8\n"
165.49 + "9\n"
165.50 + "@arcs\n"
165.51 + " label cost\n"
165.52 + "1 8 0 107\n"
165.53 + "0 3 1 70\n"
165.54 + "2 1 2 46\n"
165.55 + "4 1 3 28\n"
165.56 + "4 4 4 91\n"
165.57 + "3 9 5 76\n"
165.58 + "9 8 6 61\n"
165.59 + "8 1 7 39\n"
165.60 + "9 8 8 74\n"
165.61 + "8 0 9 39\n"
165.62 + "4 3 10 45\n"
165.63 + "2 2 11 34\n"
165.64 + "0 1 12 100\n"
165.65 + "6 3 13 95\n"
165.66 + "4 1 14 22\n"
165.67 + "1 1 15 31\n"
165.68 + "7 2 16 51\n"
165.69 + "2 6 17 29\n"
165.70 + "8 3 18 115\n"
165.71 + "6 9 19 32\n"
165.72 + "1 1 20 60\n"
165.73 + "0 3 21 40\n"
165.74 + "@attributes\n"
165.75 + "source 0\n";
165.76 +
165.77 +
165.78 +void checkMinCostArborescenceCompile()
165.79 +{
165.80 + typedef double VType;
165.81 + typedef concepts::Digraph Digraph;
165.82 + typedef concepts::ReadMap<Digraph::Arc, VType> CostMap;
165.83 + typedef Digraph::Node Node;
165.84 + typedef Digraph::Arc Arc;
165.85 + typedef concepts::WriteMap<Digraph::Arc, bool> ArbMap;
165.86 + typedef concepts::ReadWriteMap<Digraph::Node, Digraph::Arc> PredMap;
165.87 +
165.88 + typedef MinCostArborescence<Digraph, CostMap>::
165.89 + SetArborescenceMap<ArbMap>::
165.90 + SetPredMap<PredMap>::Create MinCostArbType;
165.91 +
165.92 + Digraph g;
165.93 + Node s, n;
165.94 + Arc e;
165.95 + VType c;
165.96 + bool b;
165.97 + int i;
165.98 + CostMap cost;
165.99 + ArbMap arb;
165.100 + PredMap pred;
165.101 +
165.102 + MinCostArbType mcarb_test(g, cost);
165.103 + const MinCostArbType& const_mcarb_test = mcarb_test;
165.104 +
165.105 + mcarb_test
165.106 + .arborescenceMap(arb)
165.107 + .predMap(pred)
165.108 + .run(s);
165.109 +
165.110 + mcarb_test.init();
165.111 + mcarb_test.addSource(s);
165.112 + mcarb_test.start();
165.113 + n = mcarb_test.processNextNode();
165.114 + b = const_mcarb_test.emptyQueue();
165.115 + i = const_mcarb_test.queueSize();
165.116 +
165.117 + c = const_mcarb_test.arborescenceCost();
165.118 + b = const_mcarb_test.arborescence(e);
165.119 + e = const_mcarb_test.pred(n);
165.120 + const MinCostArbType::ArborescenceMap &am =
165.121 + const_mcarb_test.arborescenceMap();
165.122 + const MinCostArbType::PredMap &pm =
165.123 + const_mcarb_test.predMap();
165.124 + b = const_mcarb_test.reached(n);
165.125 + b = const_mcarb_test.processed(n);
165.126 +
165.127 + i = const_mcarb_test.dualNum();
165.128 + c = const_mcarb_test.dualValue();
165.129 + i = const_mcarb_test.dualSize(i);
165.130 + c = const_mcarb_test.dualValue(i);
165.131 +
165.132 + ignore_unused_variable_warning(am);
165.133 + ignore_unused_variable_warning(pm);
165.134 +}
165.135 +
165.136 +int main() {
165.137 + typedef SmartDigraph Digraph;
165.138 + DIGRAPH_TYPEDEFS(Digraph);
165.139 +
165.140 + typedef Digraph::ArcMap<double> CostMap;
165.141 +
165.142 + Digraph digraph;
165.143 + CostMap cost(digraph);
165.144 + Node source;
165.145 +
165.146 + std::istringstream is(test_lgf);
165.147 + digraphReader(digraph, is).
165.148 + arcMap("cost", cost).
165.149 + node("source", source).run();
165.150 +
165.151 + MinCostArborescence<Digraph, CostMap> mca(digraph, cost);
165.152 + mca.run(source);
165.153 +
165.154 + vector<pair<double, set<Node> > > dualSolution(mca.dualNum());
165.155 +
165.156 + for (int i = 0; i < mca.dualNum(); ++i) {
165.157 + dualSolution[i].first = mca.dualValue(i);
165.158 + for (MinCostArborescence<Digraph, CostMap>::DualIt it(mca, i);
165.159 + it != INVALID; ++it) {
165.160 + dualSolution[i].second.insert(it);
165.161 + }
165.162 + }
165.163 +
165.164 + for (ArcIt it(digraph); it != INVALID; ++it) {
165.165 + if (mca.reached(digraph.source(it))) {
165.166 + double sum = 0.0;
165.167 + for (int i = 0; i < int(dualSolution.size()); ++i) {
165.168 + if (dualSolution[i].second.find(digraph.target(it))
165.169 + != dualSolution[i].second.end() &&
165.170 + dualSolution[i].second.find(digraph.source(it))
165.171 + == dualSolution[i].second.end()) {
165.172 + sum += dualSolution[i].first;
165.173 + }
165.174 + }
165.175 + if (mca.arborescence(it)) {
165.176 + check(sum == cost[it], "Invalid dual solution");
165.177 + }
165.178 + check(sum <= cost[it], "Invalid dual solution");
165.179 + }
165.180 + }
165.181 +
165.182 +
165.183 + check(mca.dualValue() == mca.arborescenceCost(), "Invalid dual solution");
165.184 +
165.185 + check(mca.reached(source), "Invalid arborescence");
165.186 + for (ArcIt a(digraph); a != INVALID; ++a) {
165.187 + check(!mca.reached(digraph.source(a)) ||
165.188 + mca.reached(digraph.target(a)), "Invalid arborescence");
165.189 + }
165.190 +
165.191 + for (NodeIt n(digraph); n != INVALID; ++n) {
165.192 + if (!mca.reached(n)) continue;
165.193 + int cnt = 0;
165.194 + for (InArcIt a(digraph, n); a != INVALID; ++a) {
165.195 + if (mca.arborescence(a)) {
165.196 + check(mca.pred(n) == a, "Invalid arborescence");
165.197 + ++cnt;
165.198 + }
165.199 + }
165.200 + check((n == source ? cnt == 0 : cnt == 1), "Invalid arborescence");
165.201 + }
165.202 +
165.203 + Digraph::ArcMap<bool> arborescence(digraph);
165.204 + check(mca.arborescenceCost() ==
165.205 + minCostArborescence(digraph, cost, source, arborescence),
165.206 + "Wrong result of the function interface");
165.207 +
165.208 + return 0;
165.209 +}
166.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
166.2 +++ b/test/min_cost_flow_test.cc Thu Dec 10 17:05:35 2009 +0100
166.3 @@ -0,0 +1,450 @@
166.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
166.5 + *
166.6 + * This file is a part of LEMON, a generic C++ optimization library.
166.7 + *
166.8 + * Copyright (C) 2003-2009
166.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
166.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
166.11 + *
166.12 + * Permission to use, modify and distribute this software is granted
166.13 + * provided that this copyright notice appears in all copies. For
166.14 + * precise terms see the accompanying LICENSE file.
166.15 + *
166.16 + * This software is provided "AS IS" with no warranty of any kind,
166.17 + * express or implied, and with no claim as to its suitability for any
166.18 + * purpose.
166.19 + *
166.20 + */
166.21 +
166.22 +#include <iostream>
166.23 +#include <fstream>
166.24 +#include <limits>
166.25 +
166.26 +#include <lemon/list_graph.h>
166.27 +#include <lemon/lgf_reader.h>
166.28 +
166.29 +#include <lemon/network_simplex.h>
166.30 +
166.31 +#include <lemon/concepts/digraph.h>
166.32 +#include <lemon/concept_check.h>
166.33 +
166.34 +#include "test_tools.h"
166.35 +
166.36 +using namespace lemon;
166.37 +
166.38 +char test_lgf[] =
166.39 + "@nodes\n"
166.40 + "label sup1 sup2 sup3 sup4 sup5 sup6\n"
166.41 + " 1 20 27 0 30 20 30\n"
166.42 + " 2 -4 0 0 0 -8 -3\n"
166.43 + " 3 0 0 0 0 0 0\n"
166.44 + " 4 0 0 0 0 0 0\n"
166.45 + " 5 9 0 0 0 6 11\n"
166.46 + " 6 -6 0 0 0 -5 -6\n"
166.47 + " 7 0 0 0 0 0 0\n"
166.48 + " 8 0 0 0 0 0 3\n"
166.49 + " 9 3 0 0 0 0 0\n"
166.50 + " 10 -2 0 0 0 -7 -2\n"
166.51 + " 11 0 0 0 0 -10 0\n"
166.52 + " 12 -20 -27 0 -30 -30 -20\n"
166.53 + "\n"
166.54 + "@arcs\n"
166.55 + " cost cap low1 low2 low3\n"
166.56 + " 1 2 70 11 0 8 8\n"
166.57 + " 1 3 150 3 0 1 0\n"
166.58 + " 1 4 80 15 0 2 2\n"
166.59 + " 2 8 80 12 0 0 0\n"
166.60 + " 3 5 140 5 0 3 1\n"
166.61 + " 4 6 60 10 0 1 0\n"
166.62 + " 4 7 80 2 0 0 0\n"
166.63 + " 4 8 110 3 0 0 0\n"
166.64 + " 5 7 60 14 0 0 0\n"
166.65 + " 5 11 120 12 0 0 0\n"
166.66 + " 6 3 0 3 0 0 0\n"
166.67 + " 6 9 140 4 0 0 0\n"
166.68 + " 6 10 90 8 0 0 0\n"
166.69 + " 7 1 30 5 0 0 -5\n"
166.70 + " 8 12 60 16 0 4 3\n"
166.71 + " 9 12 50 6 0 0 0\n"
166.72 + "10 12 70 13 0 5 2\n"
166.73 + "10 2 100 7 0 0 0\n"
166.74 + "10 7 60 10 0 0 -3\n"
166.75 + "11 10 20 14 0 6 -20\n"
166.76 + "12 11 30 10 0 0 -10\n"
166.77 + "\n"
166.78 + "@attributes\n"
166.79 + "source 1\n"
166.80 + "target 12\n";
166.81 +
166.82 +
166.83 +enum SupplyType {
166.84 + EQ,
166.85 + GEQ,
166.86 + LEQ
166.87 +};
166.88 +
166.89 +// Check the interface of an MCF algorithm
166.90 +template <typename GR, typename Value, typename Cost>
166.91 +class McfClassConcept
166.92 +{
166.93 +public:
166.94 +
166.95 + template <typename MCF>
166.96 + struct Constraints {
166.97 + void constraints() {
166.98 + checkConcept<concepts::Digraph, GR>();
166.99 +
166.100 + const Constraints& me = *this;
166.101 +
166.102 + MCF mcf(me.g);
166.103 + const MCF& const_mcf = mcf;
166.104 +
166.105 + b = mcf.reset()
166.106 + .lowerMap(me.lower)
166.107 + .upperMap(me.upper)
166.108 + .costMap(me.cost)
166.109 + .supplyMap(me.sup)
166.110 + .stSupply(me.n, me.n, me.k)
166.111 + .run();
166.112 +
166.113 + c = const_mcf.totalCost();
166.114 + x = const_mcf.template totalCost<double>();
166.115 + v = const_mcf.flow(me.a);
166.116 + c = const_mcf.potential(me.n);
166.117 + const_mcf.flowMap(fm);
166.118 + const_mcf.potentialMap(pm);
166.119 + }
166.120 +
166.121 + typedef typename GR::Node Node;
166.122 + typedef typename GR::Arc Arc;
166.123 + typedef concepts::ReadMap<Node, Value> NM;
166.124 + typedef concepts::ReadMap<Arc, Value> VAM;
166.125 + typedef concepts::ReadMap<Arc, Cost> CAM;
166.126 + typedef concepts::WriteMap<Arc, Value> FlowMap;
166.127 + typedef concepts::WriteMap<Node, Cost> PotMap;
166.128 +
166.129 + GR g;
166.130 + VAM lower;
166.131 + VAM upper;
166.132 + CAM cost;
166.133 + NM sup;
166.134 + Node n;
166.135 + Arc a;
166.136 + Value k;
166.137 +
166.138 + FlowMap fm;
166.139 + PotMap pm;
166.140 + bool b;
166.141 + double x;
166.142 + typename MCF::Value v;
166.143 + typename MCF::Cost c;
166.144 + };
166.145 +
166.146 +};
166.147 +
166.148 +
166.149 +// Check the feasibility of the given flow (primal soluiton)
166.150 +template < typename GR, typename LM, typename UM,
166.151 + typename SM, typename FM >
166.152 +bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
166.153 + const SM& supply, const FM& flow,
166.154 + SupplyType type = EQ )
166.155 +{
166.156 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
166.157 +
166.158 + for (ArcIt e(gr); e != INVALID; ++e) {
166.159 + if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
166.160 + }
166.161 +
166.162 + for (NodeIt n(gr); n != INVALID; ++n) {
166.163 + typename SM::Value sum = 0;
166.164 + for (OutArcIt e(gr, n); e != INVALID; ++e)
166.165 + sum += flow[e];
166.166 + for (InArcIt e(gr, n); e != INVALID; ++e)
166.167 + sum -= flow[e];
166.168 + bool b = (type == EQ && sum == supply[n]) ||
166.169 + (type == GEQ && sum >= supply[n]) ||
166.170 + (type == LEQ && sum <= supply[n]);
166.171 + if (!b) return false;
166.172 + }
166.173 +
166.174 + return true;
166.175 +}
166.176 +
166.177 +// Check the feasibility of the given potentials (dual soluiton)
166.178 +// using the "Complementary Slackness" optimality condition
166.179 +template < typename GR, typename LM, typename UM,
166.180 + typename CM, typename SM, typename FM, typename PM >
166.181 +bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
166.182 + const CM& cost, const SM& supply, const FM& flow,
166.183 + const PM& pi, SupplyType type )
166.184 +{
166.185 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
166.186 +
166.187 + bool opt = true;
166.188 + for (ArcIt e(gr); opt && e != INVALID; ++e) {
166.189 + typename CM::Value red_cost =
166.190 + cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
166.191 + opt = red_cost == 0 ||
166.192 + (red_cost > 0 && flow[e] == lower[e]) ||
166.193 + (red_cost < 0 && flow[e] == upper[e]);
166.194 + }
166.195 +
166.196 + for (NodeIt n(gr); opt && n != INVALID; ++n) {
166.197 + typename SM::Value sum = 0;
166.198 + for (OutArcIt e(gr, n); e != INVALID; ++e)
166.199 + sum += flow[e];
166.200 + for (InArcIt e(gr, n); e != INVALID; ++e)
166.201 + sum -= flow[e];
166.202 + if (type != LEQ) {
166.203 + opt = (pi[n] <= 0) && (sum == supply[n] || pi[n] == 0);
166.204 + } else {
166.205 + opt = (pi[n] >= 0) && (sum == supply[n] || pi[n] == 0);
166.206 + }
166.207 + }
166.208 +
166.209 + return opt;
166.210 +}
166.211 +
166.212 +// Check whether the dual cost is equal to the primal cost
166.213 +template < typename GR, typename LM, typename UM,
166.214 + typename CM, typename SM, typename PM >
166.215 +bool checkDualCost( const GR& gr, const LM& lower, const UM& upper,
166.216 + const CM& cost, const SM& supply, const PM& pi,
166.217 + typename CM::Value total )
166.218 +{
166.219 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
166.220 +
166.221 + typename CM::Value dual_cost = 0;
166.222 + SM red_supply(gr);
166.223 + for (NodeIt n(gr); n != INVALID; ++n) {
166.224 + red_supply[n] = supply[n];
166.225 + }
166.226 + for (ArcIt a(gr); a != INVALID; ++a) {
166.227 + if (lower[a] != 0) {
166.228 + dual_cost += lower[a] * cost[a];
166.229 + red_supply[gr.source(a)] -= lower[a];
166.230 + red_supply[gr.target(a)] += lower[a];
166.231 + }
166.232 + }
166.233 +
166.234 + for (NodeIt n(gr); n != INVALID; ++n) {
166.235 + dual_cost -= red_supply[n] * pi[n];
166.236 + }
166.237 + for (ArcIt a(gr); a != INVALID; ++a) {
166.238 + typename CM::Value red_cost =
166.239 + cost[a] + pi[gr.source(a)] - pi[gr.target(a)];
166.240 + dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0);
166.241 + }
166.242 +
166.243 + return dual_cost == total;
166.244 +}
166.245 +
166.246 +// Run a minimum cost flow algorithm and check the results
166.247 +template < typename MCF, typename GR,
166.248 + typename LM, typename UM,
166.249 + typename CM, typename SM,
166.250 + typename PT >
166.251 +void checkMcf( const MCF& mcf, PT mcf_result,
166.252 + const GR& gr, const LM& lower, const UM& upper,
166.253 + const CM& cost, const SM& supply,
166.254 + PT result, bool optimal, typename CM::Value total,
166.255 + const std::string &test_id = "",
166.256 + SupplyType type = EQ )
166.257 +{
166.258 + check(mcf_result == result, "Wrong result " + test_id);
166.259 + if (optimal) {
166.260 + typename GR::template ArcMap<typename SM::Value> flow(gr);
166.261 + typename GR::template NodeMap<typename CM::Value> pi(gr);
166.262 + mcf.flowMap(flow);
166.263 + mcf.potentialMap(pi);
166.264 + check(checkFlow(gr, lower, upper, supply, flow, type),
166.265 + "The flow is not feasible " + test_id);
166.266 + check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
166.267 + check(checkPotential(gr, lower, upper, cost, supply, flow, pi, type),
166.268 + "Wrong potentials " + test_id);
166.269 + check(checkDualCost(gr, lower, upper, cost, supply, pi, total),
166.270 + "Wrong dual cost " + test_id);
166.271 + }
166.272 +}
166.273 +
166.274 +int main()
166.275 +{
166.276 + // Check the interfaces
166.277 + {
166.278 + typedef concepts::Digraph GR;
166.279 + checkConcept< McfClassConcept<GR, int, int>,
166.280 + NetworkSimplex<GR> >();
166.281 + checkConcept< McfClassConcept<GR, double, double>,
166.282 + NetworkSimplex<GR, double> >();
166.283 + checkConcept< McfClassConcept<GR, int, double>,
166.284 + NetworkSimplex<GR, int, double> >();
166.285 + }
166.286 +
166.287 + // Run various MCF tests
166.288 + typedef ListDigraph Digraph;
166.289 + DIGRAPH_TYPEDEFS(ListDigraph);
166.290 +
166.291 + // Read the test digraph
166.292 + Digraph gr;
166.293 + Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
166.294 + Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
166.295 + ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
166.296 + Node v, w;
166.297 +
166.298 + std::istringstream input(test_lgf);
166.299 + DigraphReader<Digraph>(gr, input)
166.300 + .arcMap("cost", c)
166.301 + .arcMap("cap", u)
166.302 + .arcMap("low1", l1)
166.303 + .arcMap("low2", l2)
166.304 + .arcMap("low3", l3)
166.305 + .nodeMap("sup1", s1)
166.306 + .nodeMap("sup2", s2)
166.307 + .nodeMap("sup3", s3)
166.308 + .nodeMap("sup4", s4)
166.309 + .nodeMap("sup5", s5)
166.310 + .nodeMap("sup6", s6)
166.311 + .node("source", v)
166.312 + .node("target", w)
166.313 + .run();
166.314 +
166.315 + // Build test digraphs with negative costs
166.316 + Digraph neg_gr;
166.317 + Node n1 = neg_gr.addNode();
166.318 + Node n2 = neg_gr.addNode();
166.319 + Node n3 = neg_gr.addNode();
166.320 + Node n4 = neg_gr.addNode();
166.321 + Node n5 = neg_gr.addNode();
166.322 + Node n6 = neg_gr.addNode();
166.323 + Node n7 = neg_gr.addNode();
166.324 +
166.325 + Arc a1 = neg_gr.addArc(n1, n2);
166.326 + Arc a2 = neg_gr.addArc(n1, n3);
166.327 + Arc a3 = neg_gr.addArc(n2, n4);
166.328 + Arc a4 = neg_gr.addArc(n3, n4);
166.329 + Arc a5 = neg_gr.addArc(n3, n2);
166.330 + Arc a6 = neg_gr.addArc(n5, n3);
166.331 + Arc a7 = neg_gr.addArc(n5, n6);
166.332 + Arc a8 = neg_gr.addArc(n6, n7);
166.333 + Arc a9 = neg_gr.addArc(n7, n5);
166.334 +
166.335 + Digraph::ArcMap<int> neg_c(neg_gr), neg_l1(neg_gr, 0), neg_l2(neg_gr, 0);
166.336 + ConstMap<Arc, int> neg_u1(std::numeric_limits<int>::max()), neg_u2(5000);
166.337 + Digraph::NodeMap<int> neg_s(neg_gr, 0);
166.338 +
166.339 + neg_l2[a7] = 1000;
166.340 + neg_l2[a8] = -1000;
166.341 +
166.342 + neg_s[n1] = 100;
166.343 + neg_s[n4] = -100;
166.344 +
166.345 + neg_c[a1] = 100;
166.346 + neg_c[a2] = 30;
166.347 + neg_c[a3] = 20;
166.348 + neg_c[a4] = 80;
166.349 + neg_c[a5] = 50;
166.350 + neg_c[a6] = 10;
166.351 + neg_c[a7] = 80;
166.352 + neg_c[a8] = 30;
166.353 + neg_c[a9] = -120;
166.354 +
166.355 + Digraph negs_gr;
166.356 + Digraph::NodeMap<int> negs_s(negs_gr);
166.357 + Digraph::ArcMap<int> negs_c(negs_gr);
166.358 + ConstMap<Arc, int> negs_l(0), negs_u(1000);
166.359 + n1 = negs_gr.addNode();
166.360 + n2 = negs_gr.addNode();
166.361 + negs_s[n1] = 100;
166.362 + negs_s[n2] = -300;
166.363 + negs_c[negs_gr.addArc(n1, n2)] = -1;
166.364 +
166.365 +
166.366 + // A. Test NetworkSimplex with the default pivot rule
166.367 + {
166.368 + NetworkSimplex<Digraph> mcf(gr);
166.369 +
166.370 + // Check the equality form
166.371 + mcf.upperMap(u).costMap(c);
166.372 + checkMcf(mcf, mcf.supplyMap(s1).run(),
166.373 + gr, l1, u, c, s1, mcf.OPTIMAL, true, 5240, "#A1");
166.374 + checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
166.375 + gr, l1, u, c, s2, mcf.OPTIMAL, true, 7620, "#A2");
166.376 + mcf.lowerMap(l2);
166.377 + checkMcf(mcf, mcf.supplyMap(s1).run(),
166.378 + gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#A3");
166.379 + checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
166.380 + gr, l2, u, c, s2, mcf.OPTIMAL, true, 8010, "#A4");
166.381 + mcf.reset();
166.382 + checkMcf(mcf, mcf.supplyMap(s1).run(),
166.383 + gr, l1, cu, cc, s1, mcf.OPTIMAL, true, 74, "#A5");
166.384 + checkMcf(mcf, mcf.lowerMap(l2).stSupply(v, w, 27).run(),
166.385 + gr, l2, cu, cc, s2, mcf.OPTIMAL, true, 94, "#A6");
166.386 + mcf.reset();
166.387 + checkMcf(mcf, mcf.run(),
166.388 + gr, l1, cu, cc, s3, mcf.OPTIMAL, true, 0, "#A7");
166.389 + checkMcf(mcf, mcf.lowerMap(l2).upperMap(u).run(),
166.390 + gr, l2, u, cc, s3, mcf.INFEASIBLE, false, 0, "#A8");
166.391 + mcf.reset().lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
166.392 + checkMcf(mcf, mcf.run(),
166.393 + gr, l3, u, c, s4, mcf.OPTIMAL, true, 6360, "#A9");
166.394 +
166.395 + // Check the GEQ form
166.396 + mcf.reset().upperMap(u).costMap(c).supplyMap(s5);
166.397 + checkMcf(mcf, mcf.run(),
166.398 + gr, l1, u, c, s5, mcf.OPTIMAL, true, 3530, "#A10", GEQ);
166.399 + mcf.supplyType(mcf.GEQ);
166.400 + checkMcf(mcf, mcf.lowerMap(l2).run(),
166.401 + gr, l2, u, c, s5, mcf.OPTIMAL, true, 4540, "#A11", GEQ);
166.402 + mcf.supplyMap(s6);
166.403 + checkMcf(mcf, mcf.run(),
166.404 + gr, l2, u, c, s6, mcf.INFEASIBLE, false, 0, "#A12", GEQ);
166.405 +
166.406 + // Check the LEQ form
166.407 + mcf.reset().supplyType(mcf.LEQ);
166.408 + mcf.upperMap(u).costMap(c).supplyMap(s6);
166.409 + checkMcf(mcf, mcf.run(),
166.410 + gr, l1, u, c, s6, mcf.OPTIMAL, true, 5080, "#A13", LEQ);
166.411 + checkMcf(mcf, mcf.lowerMap(l2).run(),
166.412 + gr, l2, u, c, s6, mcf.OPTIMAL, true, 5930, "#A14", LEQ);
166.413 + mcf.supplyMap(s5);
166.414 + checkMcf(mcf, mcf.run(),
166.415 + gr, l2, u, c, s5, mcf.INFEASIBLE, false, 0, "#A15", LEQ);
166.416 +
166.417 + // Check negative costs
166.418 + NetworkSimplex<Digraph> neg_mcf(neg_gr);
166.419 + neg_mcf.lowerMap(neg_l1).costMap(neg_c).supplyMap(neg_s);
166.420 + checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u1,
166.421 + neg_c, neg_s, neg_mcf.UNBOUNDED, false, 0, "#A16");
166.422 + neg_mcf.upperMap(neg_u2);
166.423 + checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u2,
166.424 + neg_c, neg_s, neg_mcf.OPTIMAL, true, -40000, "#A17");
166.425 + neg_mcf.reset().lowerMap(neg_l2).costMap(neg_c).supplyMap(neg_s);
166.426 + checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l2, neg_u1,
166.427 + neg_c, neg_s, neg_mcf.UNBOUNDED, false, 0, "#A18");
166.428 +
166.429 + NetworkSimplex<Digraph> negs_mcf(negs_gr);
166.430 + negs_mcf.costMap(negs_c).supplyMap(negs_s);
166.431 + checkMcf(negs_mcf, negs_mcf.run(), negs_gr, negs_l, negs_u,
166.432 + negs_c, negs_s, negs_mcf.OPTIMAL, true, -300, "#A19", GEQ);
166.433 + }
166.434 +
166.435 + // B. Test NetworkSimplex with each pivot rule
166.436 + {
166.437 + NetworkSimplex<Digraph> mcf(gr);
166.438 + mcf.supplyMap(s1).costMap(c).upperMap(u).lowerMap(l2);
166.439 +
166.440 + checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::FIRST_ELIGIBLE),
166.441 + gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B1");
166.442 + checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BEST_ELIGIBLE),
166.443 + gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B2");
166.444 + checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BLOCK_SEARCH),
166.445 + gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B3");
166.446 + checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::CANDIDATE_LIST),
166.447 + gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B4");
166.448 + checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::ALTERING_LIST),
166.449 + gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B5");
166.450 + }
166.451 +
166.452 + return 0;
166.453 +}
167.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
167.2 +++ b/test/mip_test.cc Thu Dec 10 17:05:35 2009 +0100
167.3 @@ -0,0 +1,158 @@
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 +#include "test_tools.h"
167.23 +
167.24 +#include <lemon/config.h>
167.25 +
167.26 +#ifdef LEMON_HAVE_CPLEX
167.27 +#include <lemon/cplex.h>
167.28 +#endif
167.29 +
167.30 +#ifdef LEMON_HAVE_GLPK
167.31 +#include <lemon/glpk.h>
167.32 +#endif
167.33 +
167.34 +#ifdef LEMON_HAVE_CBC
167.35 +#include <lemon/cbc.h>
167.36 +#endif
167.37 +
167.38 +
167.39 +using namespace lemon;
167.40 +
167.41 +void solveAndCheck(MipSolver& mip, MipSolver::ProblemType stat,
167.42 + double exp_opt) {
167.43 + using std::string;
167.44 +
167.45 + mip.solve();
167.46 + //int decimal,sign;
167.47 + std::ostringstream buf;
167.48 + buf << "Type should be: " << int(stat)<<" and it is "<<int(mip.type());
167.49 +
167.50 +
167.51 + // itoa(stat,buf1, 10);
167.52 + check(mip.type()==stat, buf.str());
167.53 +
167.54 + if (stat == MipSolver::OPTIMAL) {
167.55 + std::ostringstream sbuf;
167.56 + buf << "Wrong optimal value: the right optimum is " << exp_opt;
167.57 + check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
167.58 + //+ecvt(exp_opt,2)
167.59 + }
167.60 +}
167.61 +
167.62 +void aTest(MipSolver& mip)
167.63 +{
167.64 + //The following example is very simple
167.65 +
167.66 +
167.67 + typedef MipSolver::Row Row;
167.68 + typedef MipSolver::Col Col;
167.69 +
167.70 +
167.71 + Col x1 = mip.addCol();
167.72 + Col x2 = mip.addCol();
167.73 +
167.74 +
167.75 + //Objective function
167.76 + mip.obj(x1);
167.77 +
167.78 + mip.max();
167.79 +
167.80 + //Unconstrained optimization
167.81 + mip.solve();
167.82 + //Check it out!
167.83 +
167.84 + //Constraints
167.85 + mip.addRow(2 * x1 + x2 <= 2);
167.86 + Row y2 = mip.addRow(x1 - 2 * x2 <= 0);
167.87 +
167.88 + //Nonnegativity of the variable x1
167.89 + mip.colLowerBound(x1, 0);
167.90 +
167.91 +
167.92 + //Maximization of x1
167.93 + //over the triangle with vertices (0,0),(4/5,2/5),(0,2)
167.94 + double expected_opt=4.0/5.0;
167.95 + solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
167.96 +
167.97 +
167.98 + //Restrict x2 to integer
167.99 + mip.colType(x2,MipSolver::INTEGER);
167.100 + expected_opt=1.0/2.0;
167.101 + solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
167.102 +
167.103 +
167.104 + //Restrict both to integer
167.105 + mip.colType(x1,MipSolver::INTEGER);
167.106 + expected_opt=0;
167.107 + solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
167.108 +
167.109 + //Erase a variable
167.110 + mip.erase(x2);
167.111 + mip.rowUpperBound(y2, 8);
167.112 + expected_opt=1;
167.113 + solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
167.114 +
167.115 +}
167.116 +
167.117 +
167.118 +template<class MIP>
167.119 +void cloneTest()
167.120 +{
167.121 +
167.122 + MIP* mip = new MIP();
167.123 + MIP* mipnew = mip->newSolver();
167.124 + MIP* mipclone = mip->cloneSolver();
167.125 + delete mip;
167.126 + delete mipnew;
167.127 + delete mipclone;
167.128 +}
167.129 +
167.130 +int main()
167.131 +{
167.132 +
167.133 +#ifdef LEMON_HAVE_GLPK
167.134 + {
167.135 + GlpkMip mip1;
167.136 + aTest(mip1);
167.137 + cloneTest<GlpkMip>();
167.138 + }
167.139 +#endif
167.140 +
167.141 +#ifdef LEMON_HAVE_CPLEX
167.142 + try {
167.143 + CplexMip mip2;
167.144 + aTest(mip2);
167.145 + cloneTest<CplexMip>();
167.146 + } catch (CplexEnv::LicenseError& error) {
167.147 + check(false, error.what());
167.148 + }
167.149 +#endif
167.150 +
167.151 +#ifdef LEMON_HAVE_CBC
167.152 + {
167.153 + CbcMip mip1;
167.154 + aTest(mip1);
167.155 + cloneTest<CbcMip>();
167.156 + }
167.157 +#endif
167.158 +
167.159 + return 0;
167.160 +
167.161 +}
168.1 --- a/test/path_test.cc Fri Nov 13 12:33:33 2009 +0100
168.2 +++ b/test/path_test.cc Thu Dec 10 17:05:35 2009 +0100
168.3 @@ -2,7 +2,7 @@
168.4 *
168.5 * This file is a part of LEMON, a generic C++ optimization library.
168.6 *
168.7 - * Copyright (C) 2003-2008
168.8 + * Copyright (C) 2003-2009
168.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
168.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
168.11 *
169.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
169.2 +++ b/test/preflow_test.cc Thu Dec 10 17:05:35 2009 +0100
169.3 @@ -0,0 +1,245 @@
169.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
169.5 + *
169.6 + * This file is a part of LEMON, a generic C++ optimization library.
169.7 + *
169.8 + * Copyright (C) 2003-2009
169.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
169.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
169.11 + *
169.12 + * Permission to use, modify and distribute this software is granted
169.13 + * provided that this copyright notice appears in all copies. For
169.14 + * precise terms see the accompanying LICENSE file.
169.15 + *
169.16 + * This software is provided "AS IS" with no warranty of any kind,
169.17 + * express or implied, and with no claim as to its suitability for any
169.18 + * purpose.
169.19 + *
169.20 + */
169.21 +
169.22 +#include <iostream>
169.23 +
169.24 +#include "test_tools.h"
169.25 +#include <lemon/smart_graph.h>
169.26 +#include <lemon/preflow.h>
169.27 +#include <lemon/concepts/digraph.h>
169.28 +#include <lemon/concepts/maps.h>
169.29 +#include <lemon/lgf_reader.h>
169.30 +#include <lemon/elevator.h>
169.31 +
169.32 +using namespace lemon;
169.33 +
169.34 +char test_lgf[] =
169.35 + "@nodes\n"
169.36 + "label\n"
169.37 + "0\n"
169.38 + "1\n"
169.39 + "2\n"
169.40 + "3\n"
169.41 + "4\n"
169.42 + "5\n"
169.43 + "6\n"
169.44 + "7\n"
169.45 + "8\n"
169.46 + "9\n"
169.47 + "@arcs\n"
169.48 + " label capacity\n"
169.49 + "0 1 0 20\n"
169.50 + "0 2 1 0\n"
169.51 + "1 1 2 3\n"
169.52 + "1 2 3 8\n"
169.53 + "1 3 4 8\n"
169.54 + "2 5 5 5\n"
169.55 + "3 2 6 5\n"
169.56 + "3 5 7 5\n"
169.57 + "3 6 8 5\n"
169.58 + "4 3 9 3\n"
169.59 + "5 7 10 3\n"
169.60 + "5 6 11 10\n"
169.61 + "5 8 12 10\n"
169.62 + "6 8 13 8\n"
169.63 + "8 9 14 20\n"
169.64 + "8 1 15 5\n"
169.65 + "9 5 16 5\n"
169.66 + "@attributes\n"
169.67 + "source 1\n"
169.68 + "target 8\n";
169.69 +
169.70 +void checkPreflowCompile()
169.71 +{
169.72 + typedef int VType;
169.73 + typedef concepts::Digraph Digraph;
169.74 +
169.75 + typedef Digraph::Node Node;
169.76 + typedef Digraph::Arc Arc;
169.77 + typedef concepts::ReadMap<Arc,VType> CapMap;
169.78 + typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
169.79 + typedef concepts::WriteMap<Node,bool> CutMap;
169.80 +
169.81 + typedef Elevator<Digraph, Digraph::Node> Elev;
169.82 + typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
169.83 +
169.84 + Digraph g;
169.85 + Node n;
169.86 + Arc e;
169.87 + CapMap cap;
169.88 + FlowMap flow;
169.89 + CutMap cut;
169.90 + VType v;
169.91 + bool b;
169.92 +
169.93 + typedef Preflow<Digraph, CapMap>
169.94 + ::SetFlowMap<FlowMap>
169.95 + ::SetElevator<Elev>
169.96 + ::SetStandardElevator<LinkedElev>
169.97 + ::Create PreflowType;
169.98 + PreflowType preflow_test(g, cap, n, n);
169.99 + const PreflowType& const_preflow_test = preflow_test;
169.100 +
169.101 + preflow_test
169.102 + .capacityMap(cap)
169.103 + .flowMap(flow)
169.104 + .source(n)
169.105 + .target(n);
169.106 +
169.107 + preflow_test.init();
169.108 + preflow_test.init(cap);
169.109 + preflow_test.startFirstPhase();
169.110 + preflow_test.startSecondPhase();
169.111 + preflow_test.run();
169.112 + preflow_test.runMinCut();
169.113 +
169.114 + v = const_preflow_test.flowValue();
169.115 + v = const_preflow_test.flow(e);
169.116 + const FlowMap& fm = const_preflow_test.flowMap();
169.117 + b = const_preflow_test.minCut(n);
169.118 + const_preflow_test.minCutMap(cut);
169.119 +
169.120 + ignore_unused_variable_warning(fm);
169.121 +}
169.122 +
169.123 +int cutValue (const SmartDigraph& g,
169.124 + const SmartDigraph::NodeMap<bool>& cut,
169.125 + const SmartDigraph::ArcMap<int>& cap) {
169.126 +
169.127 + int c=0;
169.128 + for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
169.129 + if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
169.130 + }
169.131 + return c;
169.132 +}
169.133 +
169.134 +bool checkFlow(const SmartDigraph& g,
169.135 + const SmartDigraph::ArcMap<int>& flow,
169.136 + const SmartDigraph::ArcMap<int>& cap,
169.137 + SmartDigraph::Node s, SmartDigraph::Node t) {
169.138 +
169.139 + for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
169.140 + if (flow[e] < 0 || flow[e] > cap[e]) return false;
169.141 + }
169.142 +
169.143 + for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
169.144 + if (n == s || n == t) continue;
169.145 + int sum = 0;
169.146 + for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
169.147 + sum += flow[e];
169.148 + }
169.149 + for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
169.150 + sum -= flow[e];
169.151 + }
169.152 + if (sum != 0) return false;
169.153 + }
169.154 + return true;
169.155 +}
169.156 +
169.157 +int main() {
169.158 +
169.159 + typedef SmartDigraph Digraph;
169.160 +
169.161 + typedef Digraph::Node Node;
169.162 + typedef Digraph::NodeIt NodeIt;
169.163 + typedef Digraph::ArcIt ArcIt;
169.164 + typedef Digraph::ArcMap<int> CapMap;
169.165 + typedef Digraph::ArcMap<int> FlowMap;
169.166 + typedef Digraph::NodeMap<bool> CutMap;
169.167 +
169.168 + typedef Preflow<Digraph, CapMap> PType;
169.169 +
169.170 + Digraph g;
169.171 + Node s, t;
169.172 + CapMap cap(g);
169.173 + std::istringstream input(test_lgf);
169.174 + DigraphReader<Digraph>(g,input).
169.175 + arcMap("capacity", cap).
169.176 + node("source",s).
169.177 + node("target",t).
169.178 + run();
169.179 +
169.180 + PType preflow_test(g, cap, s, t);
169.181 + preflow_test.run();
169.182 +
169.183 + check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
169.184 + "The flow is not feasible.");
169.185 +
169.186 + CutMap min_cut(g);
169.187 + preflow_test.minCutMap(min_cut);
169.188 + int min_cut_value=cutValue(g,min_cut,cap);
169.189 +
169.190 + check(preflow_test.flowValue() == min_cut_value,
169.191 + "The max flow value is not equal to the three min cut values.");
169.192 +
169.193 + FlowMap flow(g);
169.194 + for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
169.195 +
169.196 + int flow_value=preflow_test.flowValue();
169.197 +
169.198 + for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
169.199 + preflow_test.init(flow);
169.200 + preflow_test.startFirstPhase();
169.201 +
169.202 + CutMap min_cut1(g);
169.203 + preflow_test.minCutMap(min_cut1);
169.204 + min_cut_value=cutValue(g,min_cut1,cap);
169.205 +
169.206 + check(preflow_test.flowValue() == min_cut_value &&
169.207 + min_cut_value == 2*flow_value,
169.208 + "The max flow value or the min cut value is wrong.");
169.209 +
169.210 + preflow_test.startSecondPhase();
169.211 +
169.212 + check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
169.213 + "The flow is not feasible.");
169.214 +
169.215 + CutMap min_cut2(g);
169.216 + preflow_test.minCutMap(min_cut2);
169.217 + min_cut_value=cutValue(g,min_cut2,cap);
169.218 +
169.219 + check(preflow_test.flowValue() == min_cut_value &&
169.220 + min_cut_value == 2*flow_value,
169.221 + "The max flow value or the three min cut values were not doubled");
169.222 +
169.223 +
169.224 + preflow_test.flowMap(flow);
169.225 +
169.226 + NodeIt tmp1(g,s);
169.227 + ++tmp1;
169.228 + if ( tmp1 != INVALID ) s=tmp1;
169.229 +
169.230 + NodeIt tmp2(g,t);
169.231 + ++tmp2;
169.232 + if ( tmp2 != INVALID ) t=tmp2;
169.233 +
169.234 + preflow_test.source(s);
169.235 + preflow_test.target(t);
169.236 +
169.237 + preflow_test.run();
169.238 +
169.239 + CutMap min_cut3(g);
169.240 + preflow_test.minCutMap(min_cut3);
169.241 + min_cut_value=cutValue(g,min_cut3,cap);
169.242 +
169.243 +
169.244 + check(preflow_test.flowValue() == min_cut_value,
169.245 + "The max flow value or the three min cut values are incorrect.");
169.246 +
169.247 + return 0;
169.248 +}
170.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
170.2 +++ b/test/radix_sort_test.cc Thu Dec 10 17:05:35 2009 +0100
170.3 @@ -0,0 +1,147 @@
170.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
170.5 + *
170.6 + * This file is a part of LEMON, a generic C++ optimization library.
170.7 + *
170.8 + * Copyright (C) 2003-2009
170.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
170.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
170.11 + *
170.12 + * Permission to use, modify and distribute this software is granted
170.13 + * provided that this copyright notice appears in all copies. For
170.14 + * precise terms see the accompanying LICENSE file.
170.15 + *
170.16 + * This software is provided "AS IS" with no warranty of any kind,
170.17 + * express or implied, and with no claim as to its suitability for any
170.18 + * purpose.
170.19 + *
170.20 + */
170.21 +
170.22 +#include <lemon/time_measure.h>
170.23 +#include <lemon/smart_graph.h>
170.24 +#include <lemon/maps.h>
170.25 +#include <lemon/radix_sort.h>
170.26 +#include <lemon/math.h>
170.27 +
170.28 +#include "test_tools.h"
170.29 +
170.30 +#include <vector>
170.31 +#include <algorithm>
170.32 +
170.33 +using namespace lemon;
170.34 +
170.35 +static const int n = 10000;
170.36 +
170.37 +struct Negate {
170.38 + typedef int argument_type;
170.39 + typedef int result_type;
170.40 + int operator()(int a) { return - a; }
170.41 +};
170.42 +
170.43 +int negate(int a) { return - a; }
170.44 +
170.45 +
170.46 +void generateIntSequence(int n, std::vector<int>& data) {
170.47 + int prime = 9973;
170.48 + int root = 136, value = 1;
170.49 + for (int i = 0; i < n; ++i) {
170.50 + data.push_back(value - prime / 2);
170.51 + value = (value * root) % prime;
170.52 + }
170.53 +}
170.54 +
170.55 +void generateCharSequence(int n, std::vector<unsigned char>& data) {
170.56 + int prime = 251;
170.57 + int root = 3, value = root;
170.58 + for (int i = 0; i < n; ++i) {
170.59 + data.push_back(static_cast<unsigned char>(value));
170.60 + value = (value * root) % prime;
170.61 + }
170.62 +}
170.63 +
170.64 +void checkRadixSort() {
170.65 + {
170.66 + std::vector<int> data1;
170.67 + generateIntSequence(n, data1);
170.68 +
170.69 + std::vector<int> data2(data1);
170.70 + std::sort(data1.begin(), data1.end());
170.71 +
170.72 + radixSort(data2.begin(), data2.end());
170.73 + for (int i = 0; i < n; ++i) {
170.74 + check(data1[i] == data2[i], "Test failed");
170.75 + }
170.76 +
170.77 + radixSort(data2.begin(), data2.end(), Negate());
170.78 + for (int i = 0; i < n; ++i) {
170.79 + check(data1[i] == data2[n - 1 - i], "Test failed");
170.80 + }
170.81 +
170.82 + radixSort(data2.begin(), data2.end(), negate);
170.83 + for (int i = 0; i < n; ++i) {
170.84 + check(data1[i] == data2[n - 1 - i], "Test failed");
170.85 + }
170.86 +
170.87 + }
170.88 +
170.89 + {
170.90 + std::vector<unsigned char> data1(n);
170.91 + generateCharSequence(n, data1);
170.92 +
170.93 + std::vector<unsigned char> data2(data1);
170.94 + std::sort(data1.begin(), data1.end());
170.95 +
170.96 + radixSort(data2.begin(), data2.end());
170.97 + for (int i = 0; i < n; ++i) {
170.98 + check(data1[i] == data2[i], "Test failed");
170.99 + }
170.100 +
170.101 + }
170.102 +}
170.103 +
170.104 +
170.105 +void checkStableRadixSort() {
170.106 + {
170.107 + std::vector<int> data1;
170.108 + generateIntSequence(n, data1);
170.109 +
170.110 + std::vector<int> data2(data1);
170.111 + std::sort(data1.begin(), data1.end());
170.112 +
170.113 + stableRadixSort(data2.begin(), data2.end());
170.114 + for (int i = 0; i < n; ++i) {
170.115 + check(data1[i] == data2[i], "Test failed");
170.116 + }
170.117 +
170.118 + stableRadixSort(data2.begin(), data2.end(), Negate());
170.119 + for (int i = 0; i < n; ++i) {
170.120 + check(data1[i] == data2[n - 1 - i], "Test failed");
170.121 + }
170.122 +
170.123 + stableRadixSort(data2.begin(), data2.end(), negate);
170.124 + for (int i = 0; i < n; ++i) {
170.125 + check(data1[i] == data2[n - 1 - i], "Test failed");
170.126 + }
170.127 + }
170.128 +
170.129 + {
170.130 + std::vector<unsigned char> data1(n);
170.131 + generateCharSequence(n, data1);
170.132 +
170.133 + std::vector<unsigned char> data2(data1);
170.134 + std::sort(data1.begin(), data1.end());
170.135 +
170.136 + radixSort(data2.begin(), data2.end());
170.137 + for (int i = 0; i < n; ++i) {
170.138 + check(data1[i] == data2[i], "Test failed");
170.139 + }
170.140 +
170.141 + }
170.142 +}
170.143 +
170.144 +int main() {
170.145 +
170.146 + checkRadixSort();
170.147 + checkStableRadixSort();
170.148 +
170.149 + return 0;
170.150 +}
171.1 --- a/test/random_test.cc Fri Nov 13 12:33:33 2009 +0100
171.2 +++ b/test/random_test.cc Thu Dec 10 17:05:35 2009 +0100
171.3 @@ -2,7 +2,7 @@
171.4 *
171.5 * This file is a part of LEMON, a generic C++ optimization library.
171.6 *
171.7 - * Copyright (C) 2003-2008
171.8 + * Copyright (C) 2003-2009
171.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
171.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
171.11 *
172.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
172.2 +++ b/test/suurballe_test.cc Thu Dec 10 17:05:35 2009 +0100
172.3 @@ -0,0 +1,241 @@
172.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
172.5 + *
172.6 + * This file is a part of LEMON, a generic C++ optimization library.
172.7 + *
172.8 + * Copyright (C) 2003-2009
172.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
172.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
172.11 + *
172.12 + * Permission to use, modify and distribute this software is granted
172.13 + * provided that this copyright notice appears in all copies. For
172.14 + * precise terms see the accompanying LICENSE file.
172.15 + *
172.16 + * This software is provided "AS IS" with no warranty of any kind,
172.17 + * express or implied, and with no claim as to its suitability for any
172.18 + * purpose.
172.19 + *
172.20 + */
172.21 +
172.22 +#include <iostream>
172.23 +
172.24 +#include <lemon/list_graph.h>
172.25 +#include <lemon/lgf_reader.h>
172.26 +#include <lemon/path.h>
172.27 +#include <lemon/suurballe.h>
172.28 +#include <lemon/concepts/digraph.h>
172.29 +
172.30 +#include "test_tools.h"
172.31 +
172.32 +using namespace lemon;
172.33 +
172.34 +char test_lgf[] =
172.35 + "@nodes\n"
172.36 + "label\n"
172.37 + "1\n"
172.38 + "2\n"
172.39 + "3\n"
172.40 + "4\n"
172.41 + "5\n"
172.42 + "6\n"
172.43 + "7\n"
172.44 + "8\n"
172.45 + "9\n"
172.46 + "10\n"
172.47 + "11\n"
172.48 + "12\n"
172.49 + "@arcs\n"
172.50 + " length\n"
172.51 + " 1 2 70\n"
172.52 + " 1 3 150\n"
172.53 + " 1 4 80\n"
172.54 + " 2 8 80\n"
172.55 + " 3 5 140\n"
172.56 + " 4 6 60\n"
172.57 + " 4 7 80\n"
172.58 + " 4 8 110\n"
172.59 + " 5 7 60\n"
172.60 + " 5 11 120\n"
172.61 + " 6 3 0\n"
172.62 + " 6 9 140\n"
172.63 + " 6 10 90\n"
172.64 + " 7 1 30\n"
172.65 + " 8 12 60\n"
172.66 + " 9 12 50\n"
172.67 + "10 12 70\n"
172.68 + "10 2 100\n"
172.69 + "10 7 60\n"
172.70 + "11 10 20\n"
172.71 + "12 11 30\n"
172.72 + "@attributes\n"
172.73 + "source 1\n"
172.74 + "target 12\n"
172.75 + "@end\n";
172.76 +
172.77 +// Check the interface of Suurballe
172.78 +void checkSuurballeCompile()
172.79 +{
172.80 + typedef int VType;
172.81 + typedef concepts::Digraph Digraph;
172.82 +
172.83 + typedef Digraph::Node Node;
172.84 + typedef Digraph::Arc Arc;
172.85 + typedef concepts::ReadMap<Arc, VType> LengthMap;
172.86 +
172.87 + typedef Suurballe<Digraph, LengthMap> SuurballeType;
172.88 +
172.89 + Digraph g;
172.90 + Node n;
172.91 + Arc e;
172.92 + LengthMap len;
172.93 + SuurballeType::FlowMap flow(g);
172.94 + SuurballeType::PotentialMap pi(g);
172.95 +
172.96 + SuurballeType suurb_test(g, len);
172.97 + const SuurballeType& const_suurb_test = suurb_test;
172.98 +
172.99 + suurb_test
172.100 + .flowMap(flow)
172.101 + .potentialMap(pi);
172.102 +
172.103 + int k;
172.104 + k = suurb_test.run(n, n);
172.105 + k = suurb_test.run(n, n, k);
172.106 + suurb_test.init(n);
172.107 + k = suurb_test.findFlow(n);
172.108 + k = suurb_test.findFlow(n, k);
172.109 + suurb_test.findPaths();
172.110 +
172.111 + int f;
172.112 + VType c;
172.113 + c = const_suurb_test.totalLength();
172.114 + f = const_suurb_test.flow(e);
172.115 + const SuurballeType::FlowMap& fm =
172.116 + const_suurb_test.flowMap();
172.117 + c = const_suurb_test.potential(n);
172.118 + const SuurballeType::PotentialMap& pm =
172.119 + const_suurb_test.potentialMap();
172.120 + k = const_suurb_test.pathNum();
172.121 + Path<Digraph> p = const_suurb_test.path(k);
172.122 +
172.123 + ignore_unused_variable_warning(fm);
172.124 + ignore_unused_variable_warning(pm);
172.125 +}
172.126 +
172.127 +// Check the feasibility of the flow
172.128 +template <typename Digraph, typename FlowMap>
172.129 +bool checkFlow( const Digraph& gr, const FlowMap& flow,
172.130 + typename Digraph::Node s, typename Digraph::Node t,
172.131 + int value )
172.132 +{
172.133 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
172.134 + for (ArcIt e(gr); e != INVALID; ++e)
172.135 + if (!(flow[e] == 0 || flow[e] == 1)) return false;
172.136 +
172.137 + for (NodeIt n(gr); n != INVALID; ++n) {
172.138 + int sum = 0;
172.139 + for (OutArcIt e(gr, n); e != INVALID; ++e)
172.140 + sum += flow[e];
172.141 + for (InArcIt e(gr, n); e != INVALID; ++e)
172.142 + sum -= flow[e];
172.143 + if (n == s && sum != value) return false;
172.144 + if (n == t && sum != -value) return false;
172.145 + if (n != s && n != t && sum != 0) return false;
172.146 + }
172.147 +
172.148 + return true;
172.149 +}
172.150 +
172.151 +// Check the optimalitiy of the flow
172.152 +template < typename Digraph, typename CostMap,
172.153 + typename FlowMap, typename PotentialMap >
172.154 +bool checkOptimality( const Digraph& gr, const CostMap& cost,
172.155 + const FlowMap& flow, const PotentialMap& pi )
172.156 +{
172.157 + // Check the "Complementary Slackness" optimality condition
172.158 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
172.159 + bool opt = true;
172.160 + for (ArcIt e(gr); e != INVALID; ++e) {
172.161 + typename CostMap::Value red_cost =
172.162 + cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
172.163 + opt = (flow[e] == 0 && red_cost >= 0) ||
172.164 + (flow[e] == 1 && red_cost <= 0);
172.165 + if (!opt) break;
172.166 + }
172.167 + return opt;
172.168 +}
172.169 +
172.170 +// Check a path
172.171 +template <typename Digraph, typename Path>
172.172 +bool checkPath( const Digraph& gr, const Path& path,
172.173 + typename Digraph::Node s, typename Digraph::Node t)
172.174 +{
172.175 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
172.176 + Node n = s;
172.177 + for (int i = 0; i < path.length(); ++i) {
172.178 + if (gr.source(path.nth(i)) != n) return false;
172.179 + n = gr.target(path.nth(i));
172.180 + }
172.181 + return n == t;
172.182 +}
172.183 +
172.184 +
172.185 +int main()
172.186 +{
172.187 + DIGRAPH_TYPEDEFS(ListDigraph);
172.188 +
172.189 + // Read the test digraph
172.190 + ListDigraph digraph;
172.191 + ListDigraph::ArcMap<int> length(digraph);
172.192 + Node s, t;
172.193 +
172.194 + std::istringstream input(test_lgf);
172.195 + DigraphReader<ListDigraph>(digraph, input).
172.196 + arcMap("length", length).
172.197 + node("source", s).
172.198 + node("target", t).
172.199 + run();
172.200 +
172.201 + // Find 2 paths
172.202 + {
172.203 + Suurballe<ListDigraph> suurballe(digraph, length);
172.204 + check(suurballe.run(s, t) == 2, "Wrong number of paths");
172.205 + check(checkFlow(digraph, suurballe.flowMap(), s, t, 2),
172.206 + "The flow is not feasible");
172.207 + check(suurballe.totalLength() == 510, "The flow is not optimal");
172.208 + check(checkOptimality(digraph, length, suurballe.flowMap(),
172.209 + suurballe.potentialMap()),
172.210 + "Wrong potentials");
172.211 + for (int i = 0; i < suurballe.pathNum(); ++i)
172.212 + check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
172.213 + }
172.214 +
172.215 + // Find 3 paths
172.216 + {
172.217 + Suurballe<ListDigraph> suurballe(digraph, length);
172.218 + check(suurballe.run(s, t, 3) == 3, "Wrong number of paths");
172.219 + check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
172.220 + "The flow is not feasible");
172.221 + check(suurballe.totalLength() == 1040, "The flow is not optimal");
172.222 + check(checkOptimality(digraph, length, suurballe.flowMap(),
172.223 + suurballe.potentialMap()),
172.224 + "Wrong potentials");
172.225 + for (int i = 0; i < suurballe.pathNum(); ++i)
172.226 + check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
172.227 + }
172.228 +
172.229 + // Find 5 paths (only 3 can be found)
172.230 + {
172.231 + Suurballe<ListDigraph> suurballe(digraph, length);
172.232 + check(suurballe.run(s, t, 5) == 3, "Wrong number of paths");
172.233 + check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
172.234 + "The flow is not feasible");
172.235 + check(suurballe.totalLength() == 1040, "The flow is not optimal");
172.236 + check(checkOptimality(digraph, length, suurballe.flowMap(),
172.237 + suurballe.potentialMap()),
172.238 + "Wrong potentials");
172.239 + for (int i = 0; i < suurballe.pathNum(); ++i)
172.240 + check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
172.241 + }
172.242 +
172.243 + return 0;
172.244 +}
173.1 --- a/test/test_tools.h Fri Nov 13 12:33:33 2009 +0100
173.2 +++ b/test/test_tools.h Thu Dec 10 17:05:35 2009 +0100
173.3 @@ -2,7 +2,7 @@
173.4 *
173.5 * This file is a part of LEMON, a generic C++ optimization library.
173.6 *
173.7 - * Copyright (C) 2003-2008
173.8 + * Copyright (C) 2003-2009
173.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
173.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
173.11 *
174.1 --- a/test/test_tools_fail.cc Fri Nov 13 12:33:33 2009 +0100
174.2 +++ b/test/test_tools_fail.cc Thu Dec 10 17:05:35 2009 +0100
174.3 @@ -2,7 +2,7 @@
174.4 *
174.5 * This file is a part of LEMON, a generic C++ optimization library.
174.6 *
174.7 - * Copyright (C) 2003-2008
174.8 + * Copyright (C) 2003-2009
174.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
174.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
174.11 *
175.1 --- a/test/test_tools_pass.cc Fri Nov 13 12:33:33 2009 +0100
175.2 +++ b/test/test_tools_pass.cc Thu Dec 10 17:05:35 2009 +0100
175.3 @@ -2,7 +2,7 @@
175.4 *
175.5 * This file is a part of LEMON, a generic C++ optimization library.
175.6 *
175.7 - * Copyright (C) 2003-2008
175.8 + * Copyright (C) 2003-2009
175.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
175.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
175.11 *
176.1 --- a/test/time_measure_test.cc Fri Nov 13 12:33:33 2009 +0100
176.2 +++ b/test/time_measure_test.cc Thu Dec 10 17:05:35 2009 +0100
176.3 @@ -2,7 +2,7 @@
176.4 *
176.5 * This file is a part of LEMON, a generic C++ optimization library.
176.6 *
176.7 - * Copyright (C) 2003-2008
176.8 + * Copyright (C) 2003-2009
176.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
176.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
176.11 *
176.12 @@ -39,18 +39,16 @@
176.13 {
176.14 Timer T;
176.15 unsigned int n;
176.16 - for(n=0;T.realTime()<1.0;n++) ;
176.17 + for(n=0;T.realTime()<0.1;n++) ;
176.18 std::cout << T << " (" << n << " time queries)\n";
176.19 - T.restart();
176.20 - while(T.realTime()<2.0) ;
176.21 - std::cout << T << '\n';
176.22 +
176.23 TimeStamp full;
176.24 TimeStamp t;
176.25 - t=runningTimeTest(f,1,&n,&full);
176.26 + t=runningTimeTest(f,0.1,&n,&full);
176.27 std::cout << t << " (" << n << " tests)\n";
176.28 std::cout << "Total: " << full << "\n";
176.29
176.30 - t=runningTimeTest(g,1,&n,&full);
176.31 + t=runningTimeTest(g,0.1,&n,&full);
176.32 std::cout << t << " (" << n << " tests)\n";
176.33 std::cout << "Total: " << full << "\n";
176.34
177.1 --- a/test/unionfind_test.cc Fri Nov 13 12:33:33 2009 +0100
177.2 +++ b/test/unionfind_test.cc Thu Dec 10 17:05:35 2009 +0100
177.3 @@ -2,7 +2,7 @@
177.4 *
177.5 * This file is a part of LEMON, a generic C++ optimization library.
177.6 *
177.7 - * Copyright (C) 2003-2008
177.8 + * Copyright (C) 2003-2009
177.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
177.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
177.11 *
178.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
178.2 +++ b/tools/CMakeLists.txt Thu Dec 10 17:05:35 2009 +0100
178.3 @@ -0,0 +1,31 @@
178.4 +INCLUDE_DIRECTORIES(
178.5 + ${PROJECT_SOURCE_DIR}
178.6 + ${PROJECT_BINARY_DIR}
178.7 +)
178.8 +
178.9 +LINK_DIRECTORIES(
178.10 + ${PROJECT_BINARY_DIR}/lemon
178.11 +)
178.12 +
178.13 +ADD_EXECUTABLE(lgf-gen lgf-gen.cc)
178.14 +TARGET_LINK_LIBRARIES(lgf-gen lemon)
178.15 +
178.16 +ADD_EXECUTABLE(dimacs-to-lgf dimacs-to-lgf.cc)
178.17 +TARGET_LINK_LIBRARIES(dimacs-to-lgf lemon)
178.18 +
178.19 +ADD_EXECUTABLE(dimacs-solver dimacs-solver.cc)
178.20 +TARGET_LINK_LIBRARIES(dimacs-solver lemon)
178.21 +
178.22 +INSTALL(
178.23 + TARGETS lgf-gen dimacs-to-lgf dimacs-solver
178.24 + RUNTIME DESTINATION bin
178.25 + COMPONENT bin
178.26 +)
178.27 +
178.28 +IF(NOT WIN32)
178.29 + INSTALL(
178.30 + PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/lemon-0.x-to-1.x.sh
178.31 + DESTINATION bin
178.32 + COMPONENT bin
178.33 + )
178.34 +ENDIF()
179.1 --- a/tools/Makefile.am Fri Nov 13 12:33:33 2009 +0100
179.2 +++ b/tools/Makefile.am Thu Dec 10 17:05:35 2009 +0100
179.3 @@ -1,6 +1,17 @@
179.4 +EXTRA_DIST += \
179.5 + tools/CMakeLists.txt
179.6 +
179.7 if WANT_TOOLS
179.8
179.9 -bin_PROGRAMS +=
179.10 +bin_PROGRAMS += \
179.11 + tools/dimacs-solver \
179.12 + tools/dimacs-to-lgf \
179.13 + tools/lgf-gen
179.14 +
179.15 dist_bin_SCRIPTS += tools/lemon-0.x-to-1.x.sh
179.16
179.17 endif WANT_TOOLS
179.18 +
179.19 +tools_dimacs_solver_SOURCES = tools/dimacs-solver.cc
179.20 +tools_dimacs_to_lgf_SOURCES = tools/dimacs-to-lgf.cc
179.21 +tools_lgf_gen_SOURCES = tools/lgf-gen.cc
180.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
180.2 +++ b/tools/dimacs-solver.cc Thu Dec 10 17:05:35 2009 +0100
180.3 @@ -0,0 +1,277 @@
180.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
180.5 + *
180.6 + * This file is a part of LEMON, a generic C++ optimization library.
180.7 + *
180.8 + * Copyright (C) 2003-2009
180.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
180.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
180.11 + *
180.12 + * Permission to use, modify and distribute this software is granted
180.13 + * provided that this copyright notice appears in all copies. For
180.14 + * precise terms see the accompanying LICENSE file.
180.15 + *
180.16 + * This software is provided "AS IS" with no warranty of any kind,
180.17 + * express or implied, and with no claim as to its suitability for any
180.18 + * purpose.
180.19 + *
180.20 + */
180.21 +
180.22 +///\ingroup tools
180.23 +///\file
180.24 +///\brief DIMACS problem solver.
180.25 +///
180.26 +/// This program solves various problems given in DIMACS format.
180.27 +///
180.28 +/// See
180.29 +/// \code
180.30 +/// dimacs-solver --help
180.31 +/// \endcode
180.32 +/// for more info on usage.
180.33 +
180.34 +#include <iostream>
180.35 +#include <fstream>
180.36 +#include <cstring>
180.37 +
180.38 +#include <lemon/smart_graph.h>
180.39 +#include <lemon/dimacs.h>
180.40 +#include <lemon/lgf_writer.h>
180.41 +#include <lemon/time_measure.h>
180.42 +
180.43 +#include <lemon/arg_parser.h>
180.44 +#include <lemon/error.h>
180.45 +
180.46 +#include <lemon/dijkstra.h>
180.47 +#include <lemon/preflow.h>
180.48 +#include <lemon/matching.h>
180.49 +#include <lemon/network_simplex.h>
180.50 +
180.51 +using namespace lemon;
180.52 +typedef SmartDigraph Digraph;
180.53 +DIGRAPH_TYPEDEFS(Digraph);
180.54 +typedef SmartGraph Graph;
180.55 +
180.56 +template<class Value>
180.57 +void solve_sp(ArgParser &ap, std::istream &is, std::ostream &,
180.58 + DimacsDescriptor &desc)
180.59 +{
180.60 + bool report = !ap.given("q");
180.61 + Digraph g;
180.62 + Node s;
180.63 + Digraph::ArcMap<Value> len(g);
180.64 + Timer t;
180.65 + t.restart();
180.66 + readDimacsSp(is, g, len, s, desc);
180.67 + if(report) std::cerr << "Read the file: " << t << '\n';
180.68 + t.restart();
180.69 + Dijkstra<Digraph, Digraph::ArcMap<Value> > dij(g,len);
180.70 + if(report) std::cerr << "Setup Dijkstra class: " << t << '\n';
180.71 + t.restart();
180.72 + dij.run(s);
180.73 + if(report) std::cerr << "Run Dijkstra: " << t << '\n';
180.74 +}
180.75 +
180.76 +template<class Value>
180.77 +void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
180.78 + Value infty, DimacsDescriptor &desc)
180.79 +{
180.80 + bool report = !ap.given("q");
180.81 + Digraph g;
180.82 + Node s,t;
180.83 + Digraph::ArcMap<Value> cap(g);
180.84 + Timer ti;
180.85 + ti.restart();
180.86 + readDimacsMax(is, g, cap, s, t, infty, desc);
180.87 + if(report) std::cerr << "Read the file: " << ti << '\n';
180.88 + ti.restart();
180.89 + Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
180.90 + if(report) std::cerr << "Setup Preflow class: " << ti << '\n';
180.91 + ti.restart();
180.92 + pre.run();
180.93 + if(report) std::cerr << "Run Preflow: " << ti << '\n';
180.94 + if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';
180.95 +}
180.96 +
180.97 +template<class Value>
180.98 +void solve_min(ArgParser &ap, std::istream &is, std::ostream &,
180.99 + Value infty, DimacsDescriptor &desc)
180.100 +{
180.101 + bool report = !ap.given("q");
180.102 + Digraph g;
180.103 + Digraph::ArcMap<Value> lower(g), cap(g), cost(g);
180.104 + Digraph::NodeMap<Value> sup(g);
180.105 + Timer ti;
180.106 +
180.107 + ti.restart();
180.108 + readDimacsMin(is, g, lower, cap, cost, sup, infty, desc);
180.109 + ti.stop();
180.110 + Value sum_sup = 0;
180.111 + for (Digraph::NodeIt n(g); n != INVALID; ++n) {
180.112 + sum_sup += sup[n];
180.113 + }
180.114 + if (report) {
180.115 + std::cerr << "Sum of supply values: " << sum_sup << "\n";
180.116 + if (sum_sup <= 0)
180.117 + std::cerr << "GEQ supply contraints are used for NetworkSimplex\n\n";
180.118 + else
180.119 + std::cerr << "LEQ supply contraints are used for NetworkSimplex\n\n";
180.120 + }
180.121 + if (report) std::cerr << "Read the file: " << ti << '\n';
180.122 +
180.123 + ti.restart();
180.124 + NetworkSimplex<Digraph, Value> ns(g);
180.125 + ns.lowerMap(lower).upperMap(cap).costMap(cost).supplyMap(sup);
180.126 + if (sum_sup > 0) ns.supplyType(ns.LEQ);
180.127 + if (report) std::cerr << "Setup NetworkSimplex class: " << ti << '\n';
180.128 + ti.restart();
180.129 + bool res = ns.run();
180.130 + if (report) {
180.131 + std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
180.132 + std::cerr << "Feasible flow: " << (res ? "found" : "not found") << '\n';
180.133 + if (res) std::cerr << "Min flow cost: " << ns.totalCost() << '\n';
180.134 + }
180.135 +}
180.136 +
180.137 +void solve_mat(ArgParser &ap, std::istream &is, std::ostream &,
180.138 + DimacsDescriptor &desc)
180.139 +{
180.140 + bool report = !ap.given("q");
180.141 + Graph g;
180.142 + Timer ti;
180.143 + ti.restart();
180.144 + readDimacsMat(is, g, desc);
180.145 + if(report) std::cerr << "Read the file: " << ti << '\n';
180.146 + ti.restart();
180.147 + MaxMatching<Graph> mat(g);
180.148 + if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n';
180.149 + ti.restart();
180.150 + mat.run();
180.151 + if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
180.152 + if(report) std::cerr << "\nCardinality of max matching: "
180.153 + << mat.matchingSize() << '\n';
180.154 +}
180.155 +
180.156 +
180.157 +template<class Value>
180.158 +void solve(ArgParser &ap, std::istream &is, std::ostream &os,
180.159 + DimacsDescriptor &desc)
180.160 +{
180.161 + std::stringstream iss(static_cast<std::string>(ap["infcap"]));
180.162 + Value infty;
180.163 + iss >> infty;
180.164 + if(iss.fail())
180.165 + {
180.166 + std::cerr << "Cannot interpret '"
180.167 + << static_cast<std::string>(ap["infcap"]) << "' as infinite"
180.168 + << std::endl;
180.169 + exit(1);
180.170 + }
180.171 +
180.172 + switch(desc.type)
180.173 + {
180.174 + case DimacsDescriptor::MIN:
180.175 + solve_min<Value>(ap,is,os,infty,desc);
180.176 + break;
180.177 + case DimacsDescriptor::MAX:
180.178 + solve_max<Value>(ap,is,os,infty,desc);
180.179 + break;
180.180 + case DimacsDescriptor::SP:
180.181 + solve_sp<Value>(ap,is,os,desc);
180.182 + break;
180.183 + case DimacsDescriptor::MAT:
180.184 + solve_mat(ap,is,os,desc);
180.185 + break;
180.186 + default:
180.187 + break;
180.188 + }
180.189 +}
180.190 +
180.191 +int main(int argc, const char *argv[]) {
180.192 + typedef SmartDigraph Digraph;
180.193 +
180.194 + typedef Digraph::Arc Arc;
180.195 +
180.196 + std::string inputName;
180.197 + std::string outputName;
180.198 +
180.199 + ArgParser ap(argc, argv);
180.200 + ap.other("[INFILE [OUTFILE]]",
180.201 + "If either the INFILE or OUTFILE file is missing the standard\n"
180.202 + " input/output will be used instead.")
180.203 + .boolOption("q", "Do not print any report")
180.204 + .boolOption("int","Use 'int' for capacities, costs etc. (default)")
180.205 + .optionGroup("datatype","int")
180.206 +#ifdef LEMON_HAVE_LONG_LONG
180.207 + .boolOption("long","Use 'long long' for capacities, costs etc.")
180.208 + .optionGroup("datatype","long")
180.209 +#endif
180.210 + .boolOption("double","Use 'double' for capacities, costs etc.")
180.211 + .optionGroup("datatype","double")
180.212 + .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
180.213 + .optionGroup("datatype","ldouble")
180.214 + .onlyOneGroup("datatype")
180.215 + .stringOption("infcap","Value used for 'very high' capacities","0")
180.216 + .run();
180.217 +
180.218 + std::ifstream input;
180.219 + std::ofstream output;
180.220 +
180.221 + switch(ap.files().size())
180.222 + {
180.223 + case 2:
180.224 + output.open(ap.files()[1].c_str());
180.225 + if (!output) {
180.226 + throw IoError("Cannot open the file for writing", ap.files()[1]);
180.227 + }
180.228 + case 1:
180.229 + input.open(ap.files()[0].c_str());
180.230 + if (!input) {
180.231 + throw IoError("File cannot be found", ap.files()[0]);
180.232 + }
180.233 + case 0:
180.234 + break;
180.235 + default:
180.236 + std::cerr << ap.commandName() << ": too many arguments\n";
180.237 + return 1;
180.238 + }
180.239 + std::istream& is = (ap.files().size()<1 ? std::cin : input);
180.240 + std::ostream& os = (ap.files().size()<2 ? std::cout : output);
180.241 +
180.242 + DimacsDescriptor desc = dimacsType(is);
180.243 +
180.244 + if(!ap.given("q"))
180.245 + {
180.246 + std::cout << "Problem type: ";
180.247 + switch(desc.type)
180.248 + {
180.249 + case DimacsDescriptor::MIN:
180.250 + std::cout << "min";
180.251 + break;
180.252 + case DimacsDescriptor::MAX:
180.253 + std::cout << "max";
180.254 + break;
180.255 + case DimacsDescriptor::SP:
180.256 + std::cout << "sp";
180.257 + case DimacsDescriptor::MAT:
180.258 + std::cout << "mat";
180.259 + break;
180.260 + default:
180.261 + exit(1);
180.262 + break;
180.263 + }
180.264 + std::cout << "\nNum of nodes: " << desc.nodeNum;
180.265 + std::cout << "\nNum of arcs: " << desc.edgeNum;
180.266 + std::cout << "\n\n";
180.267 + }
180.268 +
180.269 + if(ap.given("double"))
180.270 + solve<double>(ap,is,os,desc);
180.271 + else if(ap.given("ldouble"))
180.272 + solve<long double>(ap,is,os,desc);
180.273 +#ifdef LEMON_HAVE_LONG_LONG
180.274 + else if(ap.given("long"))
180.275 + solve<long long>(ap,is,os,desc);
180.276 +#endif
180.277 + else solve<int>(ap,is,os,desc);
180.278 +
180.279 + return 0;
180.280 +}
181.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
181.2 +++ b/tools/dimacs-to-lgf.cc Thu Dec 10 17:05:35 2009 +0100
181.3 @@ -0,0 +1,148 @@
181.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
181.5 + *
181.6 + * This file is a part of LEMON, a generic C++ optimization library.
181.7 + *
181.8 + * Copyright (C) 2003-2009
181.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
181.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
181.11 + *
181.12 + * Permission to use, modify and distribute this software is granted
181.13 + * provided that this copyright notice appears in all copies. For
181.14 + * precise terms see the accompanying LICENSE file.
181.15 + *
181.16 + * This software is provided "AS IS" with no warranty of any kind,
181.17 + * express or implied, and with no claim as to its suitability for any
181.18 + * purpose.
181.19 + *
181.20 + */
181.21 +
181.22 +///\ingroup tools
181.23 +///\file
181.24 +///\brief DIMACS to LGF converter.
181.25 +///
181.26 +/// This program converts various DIMACS formats to the LEMON Digraph Format
181.27 +/// (LGF).
181.28 +///
181.29 +/// See
181.30 +/// \code
181.31 +/// dimacs-to-lgf --help
181.32 +/// \endcode
181.33 +/// for more info on the usage.
181.34 +
181.35 +#include <iostream>
181.36 +#include <fstream>
181.37 +#include <cstring>
181.38 +
181.39 +#include <lemon/smart_graph.h>
181.40 +#include <lemon/dimacs.h>
181.41 +#include <lemon/lgf_writer.h>
181.42 +
181.43 +#include <lemon/arg_parser.h>
181.44 +#include <lemon/error.h>
181.45 +
181.46 +using namespace std;
181.47 +using namespace lemon;
181.48 +
181.49 +
181.50 +int main(int argc, const char *argv[]) {
181.51 + typedef SmartDigraph Digraph;
181.52 +
181.53 + typedef Digraph::Arc Arc;
181.54 + typedef Digraph::Node Node;
181.55 + typedef Digraph::ArcIt ArcIt;
181.56 + typedef Digraph::NodeIt NodeIt;
181.57 + typedef Digraph::ArcMap<double> DoubleArcMap;
181.58 + typedef Digraph::NodeMap<double> DoubleNodeMap;
181.59 +
181.60 + std::string inputName;
181.61 + std::string outputName;
181.62 +
181.63 + ArgParser ap(argc, argv);
181.64 + ap.other("[INFILE [OUTFILE]]",
181.65 + "If either the INFILE or OUTFILE file is missing the standard\n"
181.66 + " input/output will be used instead.")
181.67 + .run();
181.68 +
181.69 + ifstream input;
181.70 + ofstream output;
181.71 +
181.72 + switch(ap.files().size())
181.73 + {
181.74 + case 2:
181.75 + output.open(ap.files()[1].c_str());
181.76 + if (!output) {
181.77 + throw IoError("Cannot open the file for writing", ap.files()[1]);
181.78 + }
181.79 + case 1:
181.80 + input.open(ap.files()[0].c_str());
181.81 + if (!input) {
181.82 + throw IoError("File cannot be found", ap.files()[0]);
181.83 + }
181.84 + case 0:
181.85 + break;
181.86 + default:
181.87 + cerr << ap.commandName() << ": too many arguments\n";
181.88 + return 1;
181.89 + }
181.90 + istream& is = (ap.files().size()<1 ? cin : input);
181.91 + ostream& os = (ap.files().size()<2 ? cout : output);
181.92 +
181.93 + DimacsDescriptor desc = dimacsType(is);
181.94 + switch(desc.type)
181.95 + {
181.96 + case DimacsDescriptor::MIN:
181.97 + {
181.98 + Digraph digraph;
181.99 + DoubleArcMap lower(digraph), capacity(digraph), cost(digraph);
181.100 + DoubleNodeMap supply(digraph);
181.101 + readDimacsMin(is, digraph, lower, capacity, cost, supply, 0, desc);
181.102 + DigraphWriter<Digraph>(digraph, os).
181.103 + nodeMap("supply", supply).
181.104 + arcMap("lower", lower).
181.105 + arcMap("capacity", capacity).
181.106 + arcMap("cost", cost).
181.107 + attribute("problem","min").
181.108 + run();
181.109 + }
181.110 + break;
181.111 + case DimacsDescriptor::MAX:
181.112 + {
181.113 + Digraph digraph;
181.114 + Node s, t;
181.115 + DoubleArcMap capacity(digraph);
181.116 + readDimacsMax(is, digraph, capacity, s, t, 0, desc);
181.117 + DigraphWriter<Digraph>(digraph, os).
181.118 + arcMap("capacity", capacity).
181.119 + node("source", s).
181.120 + node("target", t).
181.121 + attribute("problem","max").
181.122 + run();
181.123 + }
181.124 + break;
181.125 + case DimacsDescriptor::SP:
181.126 + {
181.127 + Digraph digraph;
181.128 + Node s;
181.129 + DoubleArcMap capacity(digraph);
181.130 + readDimacsSp(is, digraph, capacity, s, desc);
181.131 + DigraphWriter<Digraph>(digraph, os).
181.132 + arcMap("capacity", capacity).
181.133 + node("source", s).
181.134 + attribute("problem","sp").
181.135 + run();
181.136 + }
181.137 + break;
181.138 + case DimacsDescriptor::MAT:
181.139 + {
181.140 + Digraph digraph;
181.141 + readDimacsMat(is, digraph,desc);
181.142 + DigraphWriter<Digraph>(digraph, os).
181.143 + attribute("problem","mat").
181.144 + run();
181.145 + }
181.146 + break;
181.147 + default:
181.148 + break;
181.149 + }
181.150 + return 0;
181.151 +}
182.1 --- a/tools/lemon-0.x-to-1.x.sh Fri Nov 13 12:33:33 2009 +0100
182.2 +++ b/tools/lemon-0.x-to-1.x.sh Thu Dec 10 17:05:35 2009 +0100
182.3 @@ -3,125 +3,127 @@
182.4 set -e
182.5
182.6 if [ $# -eq 0 -o x$1 = "x-h" -o x$1 = "x-help" -o x$1 = "x--help" ]; then
182.7 - echo "Usage:"
182.8 - echo " $0 source-file"
182.9 - exit
182.10 + echo "Usage:"
182.11 + echo " $0 source-file(s)"
182.12 + exit
182.13 fi
182.14
182.15 -TMP=`mktemp`
182.16 -
182.17 -sed -e "s/undirected graph/_gr_aph_label_/g"\
182.18 - -e "s/undirected edge/_ed_ge_label_/g"\
182.19 - -e "s/graph_/_gr_aph_label__/g"\
182.20 - -e "s/_graph/__gr_aph_label_/g"\
182.21 - -e "s/UGraph/_Gr_aph_label_/g"\
182.22 - -e "s/uGraph/_gr_aph_label_/g"\
182.23 - -e "s/ugraph/_gr_aph_label_/g"\
182.24 - -e "s/Graph/_Digr_aph_label_/g"\
182.25 - -e "s/graph/_digr_aph_label_/g"\
182.26 - -e "s/UEdge/_Ed_ge_label_/g"\
182.27 - -e "s/uEdge/_ed_ge_label_/g"\
182.28 - -e "s/uedge/_ed_ge_label_/g"\
182.29 - -e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
182.30 - -e "s/Edge/_Ar_c_label_/g"\
182.31 - -e "s/edge/_ar_c_label_/g"\
182.32 - -e "s/ANode/_Re_d_label_/g"\
182.33 - -e "s/BNode/_Blu_e_label_/g"\
182.34 - -e "s/A-Node/_Re_d_label_/g"\
182.35 - -e "s/B-Node/_Blu_e_label_/g"\
182.36 - -e "s/anode/_re_d_label_/g"\
182.37 - -e "s/bnode/_blu_e_label_/g"\
182.38 - -e "s/aNode/_re_d_label_/g"\
182.39 - -e "s/bNode/_blu_e_label_/g"\
182.40 - -e "s/_Digr_aph_label_/Digraph/g"\
182.41 - -e "s/_digr_aph_label_/digraph/g"\
182.42 - -e "s/_Gr_aph_label_/Graph/g"\
182.43 - -e "s/_gr_aph_label_/graph/g"\
182.44 - -e "s/_Ar_c_label_/Arc/g"\
182.45 - -e "s/_ar_c_label_/arc/g"\
182.46 - -e "s/_Ed_ge_label_/Edge/g"\
182.47 - -e "s/_ed_ge_label_/edge/g"\
182.48 - -e "s/_In_cEd_geIt_label_/IncEdgeIt/g"\
182.49 - -e "s/_Re_d_label_/Red/g"\
182.50 - -e "s/_Blu_e_label_/Blue/g"\
182.51 - -e "s/_re_d_label_/red/g"\
182.52 - -e "s/_blu_e_label_/blue/g"\
182.53 - -e "s/\(\W\)DefPredMap\(\W\)/\1SetPredMap\2/g"\
182.54 - -e "s/\(\W\)DefPredMap$/\1SetPredMap/g"\
182.55 - -e "s/^DefPredMap\(\W\)/SetPredMap\1/g"\
182.56 - -e "s/^DefPredMap$/SetPredMap/g"\
182.57 - -e "s/\(\W\)DefDistMap\(\W\)/\1SetDistMap\2/g"\
182.58 - -e "s/\(\W\)DefDistMap$/\1SetDistMap/g"\
182.59 - -e "s/^DefDistMap\(\W\)/SetDistMap\1/g"\
182.60 - -e "s/^DefDistMap$/SetDistMap/g"\
182.61 - -e "s/\(\W\)DefReachedMap\(\W\)/\1SetReachedMap\2/g"\
182.62 - -e "s/\(\W\)DefReachedMap$/\1SetReachedMap/g"\
182.63 - -e "s/^DefReachedMap\(\W\)/SetReachedMap\1/g"\
182.64 - -e "s/^DefReachedMap$/SetReachedMap/g"\
182.65 - -e "s/\(\W\)DefProcessedMap\(\W\)/\1SetProcessedMap\2/g"\
182.66 - -e "s/\(\W\)DefProcessedMap$/\1SetProcessedMap/g"\
182.67 - -e "s/^DefProcessedMap\(\W\)/SetProcessedMap\1/g"\
182.68 - -e "s/^DefProcessedMap$/SetProcessedMap/g"\
182.69 - -e "s/\(\W\)DefHeap\(\W\)/\1SetHeap\2/g"\
182.70 - -e "s/\(\W\)DefHeap$/\1SetHeap/g"\
182.71 - -e "s/^DefHeap\(\W\)/SetHeap\1/g"\
182.72 - -e "s/^DefHeap$/SetHeap/g"\
182.73 - -e "s/\(\W\)DefStandardHeap\(\W\)/\1SetStandradHeap\2/g"\
182.74 - -e "s/\(\W\)DefStandardHeap$/\1SetStandradHeap/g"\
182.75 - -e "s/^DefStandardHeap\(\W\)/SetStandradHeap\1/g"\
182.76 - -e "s/^DefStandardHeap$/SetStandradHeap/g"\
182.77 - -e "s/\(\W\)DefOperationTraits\(\W\)/\1SetOperationTraits\2/g"\
182.78 - -e "s/\(\W\)DefOperationTraits$/\1SetOperationTraits/g"\
182.79 - -e "s/^DefOperationTraits\(\W\)/SetOperationTraits\1/g"\
182.80 - -e "s/^DefOperationTraits$/SetOperationTraits/g"\
182.81 - -e "s/\(\W\)DefProcessedMapToBeDefaultMap\(\W\)/\1SetStandardProcessedMap\2/g"\
182.82 - -e "s/\(\W\)DefProcessedMapToBeDefaultMap$/\1SetStandardProcessedMap/g"\
182.83 - -e "s/^DefProcessedMapToBeDefaultMap\(\W\)/SetStandardProcessedMap\1/g"\
182.84 - -e "s/^DefProcessedMapToBeDefaultMap$/SetStandardProcessedMap/g"\
182.85 - -e "s/\(\W\)IntegerMap\(\W\)/\1RangeMap\2/g"\
182.86 - -e "s/\(\W\)IntegerMap$/\1RangeMap/g"\
182.87 - -e "s/^IntegerMap\(\W\)/RangeMap\1/g"\
182.88 - -e "s/^IntegerMap$/RangeMap/g"\
182.89 - -e "s/\(\W\)integerMap\(\W\)/\1rangeMap\2/g"\
182.90 - -e "s/\(\W\)integerMap$/\1rangeMap/g"\
182.91 - -e "s/^integerMap\(\W\)/rangeMap\1/g"\
182.92 - -e "s/^integerMap$/rangeMap/g"\
182.93 - -e "s/\(\W\)copyGraph\(\W\)/\1graphCopy\2/g"\
182.94 - -e "s/\(\W\)copyGraph$/\1graphCopy/g"\
182.95 - -e "s/^copyGraph\(\W\)/graphCopy\1/g"\
182.96 - -e "s/^copyGraph$/graphCopy/g"\
182.97 - -e "s/\(\W\)copyDigraph\(\W\)/\1digraphCopy\2/g"\
182.98 - -e "s/\(\W\)copyDigraph$/\1digraphCopy/g"\
182.99 - -e "s/^copyDigraph\(\W\)/digraphCopy\1/g"\
182.100 - -e "s/^copyDigraph$/digraphCopy/g"\
182.101 - -e "s/\(\W\)\([sS]\)tdMap\(\W\)/\1\2parseMap\3/g"\
182.102 - -e "s/\(\W\)\([sS]\)tdMap$/\1\2parseMap/g"\
182.103 - -e "s/^\([sS]\)tdMap\(\W\)/\1parseMap\2/g"\
182.104 - -e "s/^\([sS]\)tdMap$/\1parseMap/g"\
182.105 - -e "s/\(\W\)\([Ff]\)unctorMap\(\W\)/\1\2unctorToMap\3/g"\
182.106 - -e "s/\(\W\)\([Ff]\)unctorMap$/\1\2unctorToMap/g"\
182.107 - -e "s/^\([Ff]\)unctorMap\(\W\)/\1unctorToMap\2/g"\
182.108 - -e "s/^\([Ff]\)unctorMap$/\1unctorToMap/g"\
182.109 - -e "s/\(\W\)\([Mm]\)apFunctor\(\W\)/\1\2apToFunctor\3/g"\
182.110 - -e "s/\(\W\)\([Mm]\)apFunctor$/\1\2apToFunctor/g"\
182.111 - -e "s/^\([Mm]\)apFunctor\(\W\)/\1apToFunctor\2/g"\
182.112 - -e "s/^\([Mm]\)apFunctor$/\1apToFunctor/g"\
182.113 - -e "s/\(\W\)\([Ff]\)orkWriteMap\(\W\)/\1\2orkMap\3/g"\
182.114 - -e "s/\(\W\)\([Ff]\)orkWriteMap$/\1\2orkMap/g"\
182.115 - -e "s/^\([Ff]\)orkWriteMap\(\W\)/\1orkMap\2/g"\
182.116 - -e "s/^\([Ff]\)orkWriteMap$/\1orkMap/g"\
182.117 - -e "s/\(\W\)StoreBoolMap\(\W\)/\1LoggerBoolMap\2/g"\
182.118 - -e "s/\(\W\)StoreBoolMap$/\1LoggerBoolMap/g"\
182.119 - -e "s/^StoreBoolMap\(\W\)/LoggerBoolMap\1/g"\
182.120 - -e "s/^StoreBoolMap$/LoggerBoolMap/g"\
182.121 - -e "s/\(\W\)storeBoolMap\(\W\)/\1loggerBoolMap\2/g"\
182.122 - -e "s/\(\W\)storeBoolMap$/\1loggerBoolMap/g"\
182.123 - -e "s/^storeBoolMap\(\W\)/loggerBoolMap\1/g"\
182.124 - -e "s/^storeBoolMap$/loggerBoolMap/g"\
182.125 - -e "s/\(\W\)BoundingBox\(\W\)/\1Box\2/g"\
182.126 - -e "s/\(\W\)BoundingBox$/\1Box/g"\
182.127 - -e "s/^BoundingBox\(\W\)/Box\1/g"\
182.128 - -e "s/^BoundingBox$/Box/g"\
182.129 -<$1 > $TMP
182.130 -
182.131 -mv $TMP $1
182.132 \ No newline at end of file
182.133 +for i in $@
182.134 +do
182.135 + echo Update $i...
182.136 + TMP=`mktemp`
182.137 + sed -e "s/\<undirected graph\>/_gr_aph_label_/g"\
182.138 + -e "s/\<undirected graphs\>/_gr_aph_label_s/g"\
182.139 + -e "s/\<undirected edge\>/_ed_ge_label_/g"\
182.140 + -e "s/\<undirected edges\>/_ed_ge_label_s/g"\
182.141 + -e "s/\<directed graph\>/_digr_aph_label_/g"\
182.142 + -e "s/\<directed graphs\>/_digr_aph_label_s/g"\
182.143 + -e "s/\<directed edge\>/_ar_c_label_/g"\
182.144 + -e "s/\<directed edges\>/_ar_c_label_s/g"\
182.145 + -e "s/UGraph/_Gr_aph_label_/g"\
182.146 + -e "s/u[Gg]raph/_gr_aph_label_/g"\
182.147 + -e "s/Graph\>/_Digr_aph_label_/g"\
182.148 + -e "s/\<graph\>/_digr_aph_label_/g"\
182.149 + -e "s/Graphs\>/_Digr_aph_label_s/g"\
182.150 + -e "s/\<graphs\>/_digr_aph_label_s/g"\
182.151 + -e "s/\([Gg]\)raph\([a-z]\)/_\1r_aph_label_\2/g"\
182.152 + -e "s/\([a-z_]\)graph/\1_gr_aph_label_/g"\
182.153 + -e "s/Graph/_Digr_aph_label_/g"\
182.154 + -e "s/graph/_digr_aph_label_/g"\
182.155 + -e "s/UEdge/_Ed_ge_label_/g"\
182.156 + -e "s/u[Ee]dge/_ed_ge_label_/g"\
182.157 + -e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
182.158 + -e "s/Edge\>/_Ar_c_label_/g"\
182.159 + -e "s/\<edge\>/_ar_c_label_/g"\
182.160 + -e "s/_edge\>/_ar_c_label_/g"\
182.161 + -e "s/Edges\>/_Ar_c_label_s/g"\
182.162 + -e "s/\<edges\>/_ar_c_label_s/g"\
182.163 + -e "s/_edges\>/_ar_c_label_s/g"\
182.164 + -e "s/\([Ee]\)dge\([a-z]\)/_\1d_ge_label_\2/g"\
182.165 + -e "s/\([a-z]\)edge/\1_ed_ge_label_/g"\
182.166 + -e "s/Edge/_Ar_c_label_/g"\
182.167 + -e "s/edge/_ar_c_label_/g"\
182.168 + -e "s/A[Nn]ode/_Re_d_label_/g"\
182.169 + -e "s/B[Nn]ode/_Blu_e_label_/g"\
182.170 + -e "s/A-[Nn]ode/_Re_d_label_/g"\
182.171 + -e "s/B-[Nn]ode/_Blu_e_label_/g"\
182.172 + -e "s/a[Nn]ode/_re_d_label_/g"\
182.173 + -e "s/b[Nn]ode/_blu_e_label_/g"\
182.174 + -e "s/\<UGRAPH_TYPEDEFS\([ \t]*([ \t]*\)typename[ \t]/TEMPLATE__GR_APH_TY_PEDE_FS_label_\1/g"\
182.175 + -e "s/\<GRAPH_TYPEDEFS\([ \t]*([ \t]*\)typename[ \t]/TEMPLATE__DIGR_APH_TY_PEDE_FS_label_\1/g"\
182.176 + -e "s/\<UGRAPH_TYPEDEFS\>/_GR_APH_TY_PEDE_FS_label_/g"\
182.177 + -e "s/\<GRAPH_TYPEDEFS\>/_DIGR_APH_TY_PEDE_FS_label_/g"\
182.178 + -e "s/_Digr_aph_label_/Digraph/g"\
182.179 + -e "s/_digr_aph_label_/digraph/g"\
182.180 + -e "s/_Gr_aph_label_/Graph/g"\
182.181 + -e "s/_gr_aph_label_/graph/g"\
182.182 + -e "s/_Ar_c_label_/Arc/g"\
182.183 + -e "s/_ar_c_label_/arc/g"\
182.184 + -e "s/_Ed_ge_label_/Edge/g"\
182.185 + -e "s/_ed_ge_label_/edge/g"\
182.186 + -e "s/_In_cEd_geIt_label_/IncEdgeIt/g"\
182.187 + -e "s/_Re_d_label_/Red/g"\
182.188 + -e "s/_Blu_e_label_/Blue/g"\
182.189 + -e "s/_re_d_label_/red/g"\
182.190 + -e "s/_blu_e_label_/blue/g"\
182.191 + -e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\
182.192 + -e "s/_DIGR_APH_TY_PEDE_FS_label_/DIGRAPH_TYPEDEFS/g"\
182.193 + -e "s/DigraphToEps/GraphToEps/g"\
182.194 + -e "s/digraphToEps/graphToEps/g"\
182.195 + -e "s/\<DefPredMap\>/SetPredMap/g"\
182.196 + -e "s/\<DefDistMap\>/SetDistMap/g"\
182.197 + -e "s/\<DefReachedMap\>/SetReachedMap/g"\
182.198 + -e "s/\<DefProcessedMap\>/SetProcessedMap/g"\
182.199 + -e "s/\<DefHeap\>/SetHeap/g"\
182.200 + -e "s/\<DefStandardHeap\>/SetStandradHeap/g"\
182.201 + -e "s/\<DefOperationTraits\>/SetOperationTraits/g"\
182.202 + -e "s/\<DefProcessedMapToBeDefaultMap\>/SetStandardProcessedMap/g"\
182.203 + -e "s/\<copyGraph\>/graphCopy/g"\
182.204 + -e "s/\<copyDigraph\>/digraphCopy/g"\
182.205 + -e "s/\<HyperCubeDigraph\>/HypercubeGraph/g"\
182.206 + -e "s/\<IntegerMap\>/RangeMap/g"\
182.207 + -e "s/\<integerMap\>/rangeMap/g"\
182.208 + -e "s/\<\([sS]\)tdMap\>/\1parseMap/g"\
182.209 + -e "s/\<\([Ff]\)unctorMap\>/\1unctorToMap/g"\
182.210 + -e "s/\<\([Mm]\)apFunctor\>/\1apToFunctor/g"\
182.211 + -e "s/\<\([Ff]\)orkWriteMap\>/\1orkMap/g"\
182.212 + -e "s/\<StoreBoolMap\>/LoggerBoolMap/g"\
182.213 + -e "s/\<storeBoolMap\>/loggerBoolMap/g"\
182.214 + -e "s/\<InvertableMap\>/CrossRefMap/g"\
182.215 + -e "s/\<invertableMap\>/crossRefMap/g"\
182.216 + -e "s/\<DescriptorMap\>/RangeIdMap/g"\
182.217 + -e "s/\<descriptorMap\>/rangeIdMap/g"\
182.218 + -e "s/\<BoundingBox\>/Box/g"\
182.219 + -e "s/\<readNauty\>/readNautyGraph/g"\
182.220 + -e "s/\<RevDigraphAdaptor\>/ReverseDigraph/g"\
182.221 + -e "s/\<revDigraphAdaptor\>/reverseDigraph/g"\
182.222 + -e "s/\<SubDigraphAdaptor\>/SubDigraph/g"\
182.223 + -e "s/\<subDigraphAdaptor\>/subDigraph/g"\
182.224 + -e "s/\<SubGraphAdaptor\>/SubGraph/g"\
182.225 + -e "s/\<subGraphAdaptor\>/subGraph/g"\
182.226 + -e "s/\<NodeSubDigraphAdaptor\>/FilterNodes/g"\
182.227 + -e "s/\<nodeSubDigraphAdaptor\>/filterNodes/g"\
182.228 + -e "s/\<ArcSubDigraphAdaptor\>/FilterArcs/g"\
182.229 + -e "s/\<arcSubDigraphAdaptor\>/filterArcs/g"\
182.230 + -e "s/\<UndirDigraphAdaptor\>/Undirector/g"\
182.231 + -e "s/\<undirDigraphAdaptor\>/undirector/g"\
182.232 + -e "s/\<ResDigraphAdaptor\>/ResidualDigraph/g"\
182.233 + -e "s/\<resDigraphAdaptor\>/residualDigraph/g"\
182.234 + -e "s/\<SplitDigraphAdaptor\>/SplitNodes/g"\
182.235 + -e "s/\<splitDigraphAdaptor\>/splitNodes/g"\
182.236 + -e "s/\<SubGraphAdaptor\>/SubGraph/g"\
182.237 + -e "s/\<subGraphAdaptor\>/subGraph/g"\
182.238 + -e "s/\<NodeSubGraphAdaptor\>/FilterNodes/g"\
182.239 + -e "s/\<nodeSubGraphAdaptor\>/filterNodes/g"\
182.240 + -e "s/\<ArcSubGraphAdaptor\>/FilterEdges/g"\
182.241 + -e "s/\<arcSubGraphAdaptor\>/filterEdges/g"\
182.242 + -e "s/\<DirGraphAdaptor\>/Orienter/g"\
182.243 + -e "s/\<dirGraphAdaptor\>/orienter/g"\
182.244 + -e "s/\<LpCplex\>/CplexLp/g"\
182.245 + -e "s/\<MipCplex\>/CplexMip/g"\
182.246 + -e "s/\<LpGlpk\>/GlpkLp/g"\
182.247 + -e "s/\<MipGlpk\>/GlpkMip/g"\
182.248 + -e "s/\<LpSoplex\>/SoplexLp/g"\
182.249 + <$i > $TMP
182.250 + mv $TMP $i
182.251 +done
183.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
183.2 +++ b/tools/lgf-gen.cc Thu Dec 10 17:05:35 2009 +0100
183.3 @@ -0,0 +1,834 @@
183.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
183.5 + *
183.6 + * This file is a part of LEMON, a generic C++ optimization library.
183.7 + *
183.8 + * Copyright (C) 2003-2009
183.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
183.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
183.11 + *
183.12 + * Permission to use, modify and distribute this software is granted
183.13 + * provided that this copyright notice appears in all copies. For
183.14 + * precise terms see the accompanying LICENSE file.
183.15 + *
183.16 + * This software is provided "AS IS" with no warranty of any kind,
183.17 + * express or implied, and with no claim as to its suitability for any
183.18 + * purpose.
183.19 + *
183.20 + */
183.21 +
183.22 +/// \ingroup tools
183.23 +/// \file
183.24 +/// \brief Special plane graph generator.
183.25 +///
183.26 +/// Graph generator application for various types of plane graphs.
183.27 +///
183.28 +/// See
183.29 +/// \code
183.30 +/// lgf-gen --help
183.31 +/// \endcode
183.32 +/// for more information on the usage.
183.33 +
183.34 +#include <algorithm>
183.35 +#include <set>
183.36 +#include <ctime>
183.37 +#include <lemon/list_graph.h>
183.38 +#include <lemon/random.h>
183.39 +#include <lemon/dim2.h>
183.40 +#include <lemon/bfs.h>
183.41 +#include <lemon/counter.h>
183.42 +#include <lemon/suurballe.h>
183.43 +#include <lemon/graph_to_eps.h>
183.44 +#include <lemon/lgf_writer.h>
183.45 +#include <lemon/arg_parser.h>
183.46 +#include <lemon/euler.h>
183.47 +#include <lemon/math.h>
183.48 +#include <lemon/kruskal.h>
183.49 +#include <lemon/time_measure.h>
183.50 +
183.51 +using namespace lemon;
183.52 +
183.53 +typedef dim2::Point<double> Point;
183.54 +
183.55 +GRAPH_TYPEDEFS(ListGraph);
183.56 +
183.57 +bool progress=true;
183.58 +
183.59 +int N;
183.60 +// int girth;
183.61 +
183.62 +ListGraph g;
183.63 +
183.64 +std::vector<Node> nodes;
183.65 +ListGraph::NodeMap<Point> coords(g);
183.66 +
183.67 +
183.68 +double totalLen(){
183.69 + double tlen=0;
183.70 + for(EdgeIt e(g);e!=INVALID;++e)
183.71 + tlen+=std::sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
183.72 + return tlen;
183.73 +}
183.74 +
183.75 +int tsp_impr_num=0;
183.76 +
183.77 +const double EPSILON=1e-8;
183.78 +bool tsp_improve(Node u, Node v)
183.79 +{
183.80 + double luv=std::sqrt((coords[v]-coords[u]).normSquare());
183.81 + Node u2=u;
183.82 + Node v2=v;
183.83 + do {
183.84 + Node n;
183.85 + for(IncEdgeIt e(g,v2);(n=g.runningNode(e))==u2;++e) { }
183.86 + u2=v2;
183.87 + v2=n;
183.88 + if(luv+std::sqrt((coords[v2]-coords[u2]).normSquare())-EPSILON>
183.89 + std::sqrt((coords[u]-coords[u2]).normSquare())+
183.90 + std::sqrt((coords[v]-coords[v2]).normSquare()))
183.91 + {
183.92 + g.erase(findEdge(g,u,v));
183.93 + g.erase(findEdge(g,u2,v2));
183.94 + g.addEdge(u2,u);
183.95 + g.addEdge(v,v2);
183.96 + tsp_impr_num++;
183.97 + return true;
183.98 + }
183.99 + } while(v2!=u);
183.100 + return false;
183.101 +}
183.102 +
183.103 +bool tsp_improve(Node u)
183.104 +{
183.105 + for(IncEdgeIt e(g,u);e!=INVALID;++e)
183.106 + if(tsp_improve(u,g.runningNode(e))) return true;
183.107 + return false;
183.108 +}
183.109 +
183.110 +void tsp_improve()
183.111 +{
183.112 + bool b;
183.113 + do {
183.114 + b=false;
183.115 + for(NodeIt n(g);n!=INVALID;++n)
183.116 + if(tsp_improve(n)) b=true;
183.117 + } while(b);
183.118 +}
183.119 +
183.120 +void tsp()
183.121 +{
183.122 + for(int i=0;i<N;i++) g.addEdge(nodes[i],nodes[(i+1)%N]);
183.123 + tsp_improve();
183.124 +}
183.125 +
183.126 +class Line
183.127 +{
183.128 +public:
183.129 + Point a;
183.130 + Point b;
183.131 + Line(Point _a,Point _b) :a(_a),b(_b) {}
183.132 + Line(Node _a,Node _b) : a(coords[_a]),b(coords[_b]) {}
183.133 + Line(const Arc &e) : a(coords[g.source(e)]),b(coords[g.target(e)]) {}
183.134 + Line(const Edge &e) : a(coords[g.u(e)]),b(coords[g.v(e)]) {}
183.135 +};
183.136 +
183.137 +inline std::ostream& operator<<(std::ostream &os, const Line &l)
183.138 +{
183.139 + os << l.a << "->" << l.b;
183.140 + return os;
183.141 +}
183.142 +
183.143 +bool cross(Line a, Line b)
183.144 +{
183.145 + Point ao=rot90(a.b-a.a);
183.146 + Point bo=rot90(b.b-b.a);
183.147 + return (ao*(b.a-a.a))*(ao*(b.b-a.a))<0 &&
183.148 + (bo*(a.a-b.a))*(bo*(a.b-b.a))<0;
183.149 +}
183.150 +
183.151 +struct Parc
183.152 +{
183.153 + Node a;
183.154 + Node b;
183.155 + double len;
183.156 +};
183.157 +
183.158 +bool pedgeLess(Parc a,Parc b)
183.159 +{
183.160 + return a.len<b.len;
183.161 +}
183.162 +
183.163 +std::vector<Edge> arcs;
183.164 +
183.165 +namespace _delaunay_bits {
183.166 +
183.167 + struct Part {
183.168 + int prev, curr, next;
183.169 +
183.170 + Part(int p, int c, int n) : prev(p), curr(c), next(n) {}
183.171 + };
183.172 +
183.173 + inline std::ostream& operator<<(std::ostream& os, const Part& part) {
183.174 + os << '(' << part.prev << ',' << part.curr << ',' << part.next << ')';
183.175 + return os;
183.176 + }
183.177 +
183.178 + inline double circle_point(const Point& p, const Point& q, const Point& r) {
183.179 + double a = p.x * (q.y - r.y) + q.x * (r.y - p.y) + r.x * (p.y - q.y);
183.180 + if (a == 0) return std::numeric_limits<double>::quiet_NaN();
183.181 +
183.182 + double d = (p.x * p.x + p.y * p.y) * (q.y - r.y) +
183.183 + (q.x * q.x + q.y * q.y) * (r.y - p.y) +
183.184 + (r.x * r.x + r.y * r.y) * (p.y - q.y);
183.185 +
183.186 + double e = (p.x * p.x + p.y * p.y) * (q.x - r.x) +
183.187 + (q.x * q.x + q.y * q.y) * (r.x - p.x) +
183.188 + (r.x * r.x + r.y * r.y) * (p.x - q.x);
183.189 +
183.190 + double f = (p.x * p.x + p.y * p.y) * (q.x * r.y - r.x * q.y) +
183.191 + (q.x * q.x + q.y * q.y) * (r.x * p.y - p.x * r.y) +
183.192 + (r.x * r.x + r.y * r.y) * (p.x * q.y - q.x * p.y);
183.193 +
183.194 + return d / (2 * a) + std::sqrt((d * d + e * e) / (4 * a * a) + f / a);
183.195 + }
183.196 +
183.197 + inline bool circle_form(const Point& p, const Point& q, const Point& r) {
183.198 + return rot90(q - p) * (r - q) < 0.0;
183.199 + }
183.200 +
183.201 + inline double intersection(const Point& p, const Point& q, double sx) {
183.202 + const double epsilon = 1e-8;
183.203 +
183.204 + if (p.x == q.x) return (p.y + q.y) / 2.0;
183.205 +
183.206 + if (sx < p.x + epsilon) return p.y;
183.207 + if (sx < q.x + epsilon) return q.y;
183.208 +
183.209 + double a = q.x - p.x;
183.210 + double b = (q.x - sx) * p.y - (p.x - sx) * q.y;
183.211 + double d = (q.x - sx) * (p.x - sx) * (p - q).normSquare();
183.212 + return (b - std::sqrt(d)) / a;
183.213 + }
183.214 +
183.215 + struct YLess {
183.216 +
183.217 +
183.218 + YLess(const std::vector<Point>& points, double& sweep)
183.219 + : _points(points), _sweep(sweep) {}
183.220 +
183.221 + bool operator()(const Part& l, const Part& r) const {
183.222 + const double epsilon = 1e-8;
183.223 +
183.224 + // std::cerr << l << " vs " << r << std::endl;
183.225 + double lbx = l.prev != -1 ?
183.226 + intersection(_points[l.prev], _points[l.curr], _sweep) :
183.227 + - std::numeric_limits<double>::infinity();
183.228 + double rbx = r.prev != -1 ?
183.229 + intersection(_points[r.prev], _points[r.curr], _sweep) :
183.230 + - std::numeric_limits<double>::infinity();
183.231 + double lex = l.next != -1 ?
183.232 + intersection(_points[l.curr], _points[l.next], _sweep) :
183.233 + std::numeric_limits<double>::infinity();
183.234 + double rex = r.next != -1 ?
183.235 + intersection(_points[r.curr], _points[r.next], _sweep) :
183.236 + std::numeric_limits<double>::infinity();
183.237 +
183.238 + if (lbx > lex) std::swap(lbx, lex);
183.239 + if (rbx > rex) std::swap(rbx, rex);
183.240 +
183.241 + if (lex < epsilon + rex && lbx + epsilon < rex) return true;
183.242 + if (rex < epsilon + lex && rbx + epsilon < lex) return false;
183.243 + return lex < rex;
183.244 + }
183.245 +
183.246 + const std::vector<Point>& _points;
183.247 + double& _sweep;
183.248 + };
183.249 +
183.250 + struct BeachIt;
183.251 +
183.252 + typedef std::multimap<double, BeachIt> SpikeHeap;
183.253 +
183.254 + typedef std::multimap<Part, SpikeHeap::iterator, YLess> Beach;
183.255 +
183.256 + struct BeachIt {
183.257 + Beach::iterator it;
183.258 +
183.259 + BeachIt(Beach::iterator iter) : it(iter) {}
183.260 + };
183.261 +
183.262 +}
183.263 +
183.264 +inline void delaunay() {
183.265 + Counter cnt("Number of arcs added: ");
183.266 +
183.267 + using namespace _delaunay_bits;
183.268 +
183.269 + typedef _delaunay_bits::Part Part;
183.270 + typedef std::vector<std::pair<double, int> > SiteHeap;
183.271 +
183.272 +
183.273 + std::vector<Point> points;
183.274 + std::vector<Node> nodes;
183.275 +
183.276 + for (NodeIt it(g); it != INVALID; ++it) {
183.277 + nodes.push_back(it);
183.278 + points.push_back(coords[it]);
183.279 + }
183.280 +
183.281 + SiteHeap siteheap(points.size());
183.282 +
183.283 + double sweep;
183.284 +
183.285 +
183.286 + for (int i = 0; i < int(siteheap.size()); ++i) {
183.287 + siteheap[i] = std::make_pair(points[i].x, i);
183.288 + }
183.289 +
183.290 + std::sort(siteheap.begin(), siteheap.end());
183.291 + sweep = siteheap.front().first;
183.292 +
183.293 + YLess yless(points, sweep);
183.294 + Beach beach(yless);
183.295 +
183.296 + SpikeHeap spikeheap;
183.297 +
183.298 + std::set<std::pair<int, int> > arcs;
183.299 +
183.300 + int siteindex = 0;
183.301 + {
183.302 + SiteHeap front;
183.303 +
183.304 + while (siteindex < int(siteheap.size()) &&
183.305 + siteheap[0].first == siteheap[siteindex].first) {
183.306 + front.push_back(std::make_pair(points[siteheap[siteindex].second].y,
183.307 + siteheap[siteindex].second));
183.308 + ++siteindex;
183.309 + }
183.310 +
183.311 + std::sort(front.begin(), front.end());
183.312 +
183.313 + for (int i = 0; i < int(front.size()); ++i) {
183.314 + int prev = (i == 0 ? -1 : front[i - 1].second);
183.315 + int curr = front[i].second;
183.316 + int next = (i + 1 == int(front.size()) ? -1 : front[i + 1].second);
183.317 +
183.318 + beach.insert(std::make_pair(Part(prev, curr, next),
183.319 + spikeheap.end()));
183.320 + }
183.321 + }
183.322 +
183.323 + while (siteindex < int(points.size()) || !spikeheap.empty()) {
183.324 +
183.325 + SpikeHeap::iterator spit = spikeheap.begin();
183.326 +
183.327 + if (siteindex < int(points.size()) &&
183.328 + (spit == spikeheap.end() || siteheap[siteindex].first < spit->first)) {
183.329 + int site = siteheap[siteindex].second;
183.330 + sweep = siteheap[siteindex].first;
183.331 +
183.332 + Beach::iterator bit = beach.upper_bound(Part(site, site, site));
183.333 +
183.334 + if (bit->second != spikeheap.end()) {
183.335 + spikeheap.erase(bit->second);
183.336 + }
183.337 +
183.338 + int prev = bit->first.prev;
183.339 + int curr = bit->first.curr;
183.340 + int next = bit->first.next;
183.341 +
183.342 + beach.erase(bit);
183.343 +
183.344 + SpikeHeap::iterator pit = spikeheap.end();
183.345 + if (prev != -1 &&
183.346 + circle_form(points[prev], points[curr], points[site])) {
183.347 + double x = circle_point(points[prev], points[curr], points[site]);
183.348 + pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
183.349 + pit->second.it =
183.350 + beach.insert(std::make_pair(Part(prev, curr, site), pit));
183.351 + } else {
183.352 + beach.insert(std::make_pair(Part(prev, curr, site), pit));
183.353 + }
183.354 +
183.355 + beach.insert(std::make_pair(Part(curr, site, curr), spikeheap.end()));
183.356 +
183.357 + SpikeHeap::iterator nit = spikeheap.end();
183.358 + if (next != -1 &&
183.359 + circle_form(points[site], points[curr],points[next])) {
183.360 + double x = circle_point(points[site], points[curr], points[next]);
183.361 + nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
183.362 + nit->second.it =
183.363 + beach.insert(std::make_pair(Part(site, curr, next), nit));
183.364 + } else {
183.365 + beach.insert(std::make_pair(Part(site, curr, next), nit));
183.366 + }
183.367 +
183.368 + ++siteindex;
183.369 + } else {
183.370 + sweep = spit->first;
183.371 +
183.372 + Beach::iterator bit = spit->second.it;
183.373 +
183.374 + int prev = bit->first.prev;
183.375 + int curr = bit->first.curr;
183.376 + int next = bit->first.next;
183.377 +
183.378 + {
183.379 + std::pair<int, int> arc;
183.380 +
183.381 + arc = prev < curr ?
183.382 + std::make_pair(prev, curr) : std::make_pair(curr, prev);
183.383 +
183.384 + if (arcs.find(arc) == arcs.end()) {
183.385 + arcs.insert(arc);
183.386 + g.addEdge(nodes[prev], nodes[curr]);
183.387 + ++cnt;
183.388 + }
183.389 +
183.390 + arc = curr < next ?
183.391 + std::make_pair(curr, next) : std::make_pair(next, curr);
183.392 +
183.393 + if (arcs.find(arc) == arcs.end()) {
183.394 + arcs.insert(arc);
183.395 + g.addEdge(nodes[curr], nodes[next]);
183.396 + ++cnt;
183.397 + }
183.398 + }
183.399 +
183.400 + Beach::iterator pbit = bit; --pbit;
183.401 + int ppv = pbit->first.prev;
183.402 + Beach::iterator nbit = bit; ++nbit;
183.403 + int nnt = nbit->first.next;
183.404 +
183.405 + if (bit->second != spikeheap.end()) spikeheap.erase(bit->second);
183.406 + if (pbit->second != spikeheap.end()) spikeheap.erase(pbit->second);
183.407 + if (nbit->second != spikeheap.end()) spikeheap.erase(nbit->second);
183.408 +
183.409 + beach.erase(nbit);
183.410 + beach.erase(bit);
183.411 + beach.erase(pbit);
183.412 +
183.413 + SpikeHeap::iterator pit = spikeheap.end();
183.414 + if (ppv != -1 && ppv != next &&
183.415 + circle_form(points[ppv], points[prev], points[next])) {
183.416 + double x = circle_point(points[ppv], points[prev], points[next]);
183.417 + if (x < sweep) x = sweep;
183.418 + pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
183.419 + pit->second.it =
183.420 + beach.insert(std::make_pair(Part(ppv, prev, next), pit));
183.421 + } else {
183.422 + beach.insert(std::make_pair(Part(ppv, prev, next), pit));
183.423 + }
183.424 +
183.425 + SpikeHeap::iterator nit = spikeheap.end();
183.426 + if (nnt != -1 && prev != nnt &&
183.427 + circle_form(points[prev], points[next], points[nnt])) {
183.428 + double x = circle_point(points[prev], points[next], points[nnt]);
183.429 + if (x < sweep) x = sweep;
183.430 + nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
183.431 + nit->second.it =
183.432 + beach.insert(std::make_pair(Part(prev, next, nnt), nit));
183.433 + } else {
183.434 + beach.insert(std::make_pair(Part(prev, next, nnt), nit));
183.435 + }
183.436 +
183.437 + }
183.438 + }
183.439 +
183.440 + for (Beach::iterator it = beach.begin(); it != beach.end(); ++it) {
183.441 + int curr = it->first.curr;
183.442 + int next = it->first.next;
183.443 +
183.444 + if (next == -1) continue;
183.445 +
183.446 + std::pair<int, int> arc;
183.447 +
183.448 + arc = curr < next ?
183.449 + std::make_pair(curr, next) : std::make_pair(next, curr);
183.450 +
183.451 + if (arcs.find(arc) == arcs.end()) {
183.452 + arcs.insert(arc);
183.453 + g.addEdge(nodes[curr], nodes[next]);
183.454 + ++cnt;
183.455 + }
183.456 + }
183.457 +}
183.458 +
183.459 +void sparse(int d)
183.460 +{
183.461 + Counter cnt("Number of arcs removed: ");
183.462 + Bfs<ListGraph> bfs(g);
183.463 + for(std::vector<Edge>::reverse_iterator ei=arcs.rbegin();
183.464 + ei!=arcs.rend();++ei)
183.465 + {
183.466 + Node a=g.u(*ei);
183.467 + Node b=g.v(*ei);
183.468 + g.erase(*ei);
183.469 + bfs.run(a,b);
183.470 + if(bfs.predArc(b)==INVALID || bfs.dist(b)>d)
183.471 + g.addEdge(a,b);
183.472 + else cnt++;
183.473 + }
183.474 +}
183.475 +
183.476 +void sparse2(int d)
183.477 +{
183.478 + Counter cnt("Number of arcs removed: ");
183.479 + for(std::vector<Edge>::reverse_iterator ei=arcs.rbegin();
183.480 + ei!=arcs.rend();++ei)
183.481 + {
183.482 + Node a=g.u(*ei);
183.483 + Node b=g.v(*ei);
183.484 + g.erase(*ei);
183.485 + ConstMap<Arc,int> cegy(1);
183.486 + Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
183.487 + int k=sur.run(a,b,2);
183.488 + if(k<2 || sur.totalLength()>d)
183.489 + g.addEdge(a,b);
183.490 + else cnt++;
183.491 +// else std::cout << "Remove arc " << g.id(a) << "-" << g.id(b) << '\n';
183.492 + }
183.493 +}
183.494 +
183.495 +void sparseTriangle(int d)
183.496 +{
183.497 + Counter cnt("Number of arcs added: ");
183.498 + std::vector<Parc> pedges;
183.499 + for(NodeIt n(g);n!=INVALID;++n)
183.500 + for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
183.501 + {
183.502 + Parc p;
183.503 + p.a=n;
183.504 + p.b=m;
183.505 + p.len=(coords[m]-coords[n]).normSquare();
183.506 + pedges.push_back(p);
183.507 + }
183.508 + std::sort(pedges.begin(),pedges.end(),pedgeLess);
183.509 + for(std::vector<Parc>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
183.510 + {
183.511 + Line li(pi->a,pi->b);
183.512 + EdgeIt e(g);
183.513 + for(;e!=INVALID && !cross(e,li);++e) ;
183.514 + Edge ne;
183.515 + if(e==INVALID) {
183.516 + ConstMap<Arc,int> cegy(1);
183.517 + Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
183.518 + int k=sur.run(pi->a,pi->b,2);
183.519 + if(k<2 || sur.totalLength()>d)
183.520 + {
183.521 + ne=g.addEdge(pi->a,pi->b);
183.522 + arcs.push_back(ne);
183.523 + cnt++;
183.524 + }
183.525 + }
183.526 + }
183.527 +}
183.528 +
183.529 +template <typename Graph, typename CoordMap>
183.530 +class LengthSquareMap {
183.531 +public:
183.532 + typedef typename Graph::Edge Key;
183.533 + typedef typename CoordMap::Value::Value Value;
183.534 +
183.535 + LengthSquareMap(const Graph& graph, const CoordMap& coords)
183.536 + : _graph(graph), _coords(coords) {}
183.537 +
183.538 + Value operator[](const Key& key) const {
183.539 + return (_coords[_graph.v(key)] -
183.540 + _coords[_graph.u(key)]).normSquare();
183.541 + }
183.542 +
183.543 +private:
183.544 +
183.545 + const Graph& _graph;
183.546 + const CoordMap& _coords;
183.547 +};
183.548 +
183.549 +void minTree() {
183.550 + std::vector<Parc> pedges;
183.551 + Timer T;
183.552 + std::cout << T.realTime() << "s: Creating delaunay triangulation...\n";
183.553 + delaunay();
183.554 + std::cout << T.realTime() << "s: Calculating spanning tree...\n";
183.555 + LengthSquareMap<ListGraph, ListGraph::NodeMap<Point> > ls(g, coords);
183.556 + ListGraph::EdgeMap<bool> tree(g);
183.557 + kruskal(g, ls, tree);
183.558 + std::cout << T.realTime() << "s: Removing non tree arcs...\n";
183.559 + std::vector<Edge> remove;
183.560 + for (EdgeIt e(g); e != INVALID; ++e) {
183.561 + if (!tree[e]) remove.push_back(e);
183.562 + }
183.563 + for(int i = 0; i < int(remove.size()); ++i) {
183.564 + g.erase(remove[i]);
183.565 + }
183.566 + std::cout << T.realTime() << "s: Done\n";
183.567 +}
183.568 +
183.569 +void tsp2()
183.570 +{
183.571 + std::cout << "Find a tree..." << std::endl;
183.572 +
183.573 + minTree();
183.574 +
183.575 + std::cout << "Total arc length (tree) : " << totalLen() << std::endl;
183.576 +
183.577 + std::cout << "Make it Euler..." << std::endl;
183.578 +
183.579 + {
183.580 + std::vector<Node> leafs;
183.581 + for(NodeIt n(g);n!=INVALID;++n)
183.582 + if(countIncEdges(g,n)%2==1) leafs.push_back(n);
183.583 +
183.584 +// for(unsigned int i=0;i<leafs.size();i+=2)
183.585 +// g.addArc(leafs[i],leafs[i+1]);
183.586 +
183.587 + std::vector<Parc> pedges;
183.588 + for(unsigned int i=0;i<leafs.size()-1;i++)
183.589 + for(unsigned int j=i+1;j<leafs.size();j++)
183.590 + {
183.591 + Node n=leafs[i];
183.592 + Node m=leafs[j];
183.593 + Parc p;
183.594 + p.a=n;
183.595 + p.b=m;
183.596 + p.len=(coords[m]-coords[n]).normSquare();
183.597 + pedges.push_back(p);
183.598 + }
183.599 + std::sort(pedges.begin(),pedges.end(),pedgeLess);
183.600 + for(unsigned int i=0;i<pedges.size();i++)
183.601 + if(countIncEdges(g,pedges[i].a)%2 &&
183.602 + countIncEdges(g,pedges[i].b)%2)
183.603 + g.addEdge(pedges[i].a,pedges[i].b);
183.604 + }
183.605 +
183.606 + for(NodeIt n(g);n!=INVALID;++n)
183.607 + if(countIncEdges(g,n)%2 || countIncEdges(g,n)==0 )
183.608 + std::cout << "GEBASZ!!!" << std::endl;
183.609 +
183.610 + for(EdgeIt e(g);e!=INVALID;++e)
183.611 + if(g.u(e)==g.v(e))
183.612 + std::cout << "LOOP GEBASZ!!!" << std::endl;
183.613 +
183.614 + std::cout << "Number of arcs : " << countEdges(g) << std::endl;
183.615 +
183.616 + std::cout << "Total arc length (euler) : " << totalLen() << std::endl;
183.617 +
183.618 + ListGraph::EdgeMap<Arc> enext(g);
183.619 + {
183.620 + EulerIt<ListGraph> e(g);
183.621 + Arc eo=e;
183.622 + Arc ef=e;
183.623 +// std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl;
183.624 + for(++e;e!=INVALID;++e)
183.625 + {
183.626 +// std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl;
183.627 + enext[eo]=e;
183.628 + eo=e;
183.629 + }
183.630 + enext[eo]=ef;
183.631 + }
183.632 +
183.633 + std::cout << "Creating a tour from that..." << std::endl;
183.634 +
183.635 + int nnum = countNodes(g);
183.636 + int ednum = countEdges(g);
183.637 +
183.638 + for(Arc p=enext[EdgeIt(g)];ednum>nnum;p=enext[p])
183.639 + {
183.640 +// std::cout << "Checking arc " << g.id(p) << std::endl;
183.641 + Arc e=enext[p];
183.642 + Arc f=enext[e];
183.643 + Node n2=g.source(f);
183.644 + Node n1=g.oppositeNode(n2,e);
183.645 + Node n3=g.oppositeNode(n2,f);
183.646 + if(countIncEdges(g,n2)>2)
183.647 + {
183.648 +// std::cout << "Remove an Arc" << std::endl;
183.649 + Arc ff=enext[f];
183.650 + g.erase(e);
183.651 + g.erase(f);
183.652 + if(n1!=n3)
183.653 + {
183.654 + Arc ne=g.direct(g.addEdge(n1,n3),n1);
183.655 + enext[p]=ne;
183.656 + enext[ne]=ff;
183.657 + ednum--;
183.658 + }
183.659 + else {
183.660 + enext[p]=ff;
183.661 + ednum-=2;
183.662 + }
183.663 + }
183.664 + }
183.665 +
183.666 + std::cout << "Total arc length (tour) : " << totalLen() << std::endl;
183.667 +
183.668 + std::cout << "2-opt the tour..." << std::endl;
183.669 +
183.670 + tsp_improve();
183.671 +
183.672 + std::cout << "Total arc length (2-opt tour) : " << totalLen() << std::endl;
183.673 +}
183.674 +
183.675 +
183.676 +int main(int argc,const char **argv)
183.677 +{
183.678 + ArgParser ap(argc,argv);
183.679 +
183.680 +// bool eps;
183.681 + bool disc_d, square_d, gauss_d;
183.682 +// bool tsp_a,two_a,tree_a;
183.683 + int num_of_cities=1;
183.684 + double area=1;
183.685 + N=100;
183.686 +// girth=10;
183.687 + std::string ndist("disc");
183.688 + ap.refOption("n", "Number of nodes (default is 100)", N)
183.689 + .intOption("g", "Girth parameter (default is 10)", 10)
183.690 + .refOption("cities", "Number of cities (default is 1)", num_of_cities)
183.691 + .refOption("area", "Full relative area of the cities (default is 1)", area)
183.692 + .refOption("disc", "Nodes are evenly distributed on a unit disc (default)",
183.693 + disc_d)
183.694 + .optionGroup("dist", "disc")
183.695 + .refOption("square", "Nodes are evenly distributed on a unit square",
183.696 + square_d)
183.697 + .optionGroup("dist", "square")
183.698 + .refOption("gauss", "Nodes are located according to a two-dim Gauss "
183.699 + "distribution", gauss_d)
183.700 + .optionGroup("dist", "gauss")
183.701 + .onlyOneGroup("dist")
183.702 + .boolOption("eps", "Also generate .eps output (<prefix>.eps)")
183.703 + .boolOption("nonodes", "Draw only the edges in the generated .eps output")
183.704 + .boolOption("dir", "Directed graph is generated (each edge is replaced by "
183.705 + "two directed arcs)")
183.706 + .boolOption("2con", "Create a two connected planar graph")
183.707 + .optionGroup("alg","2con")
183.708 + .boolOption("tree", "Create a min. cost spanning tree")
183.709 + .optionGroup("alg","tree")
183.710 + .boolOption("tsp", "Create a TSP tour")
183.711 + .optionGroup("alg","tsp")
183.712 + .boolOption("tsp2", "Create a TSP tour (tree based)")
183.713 + .optionGroup("alg","tsp2")
183.714 + .boolOption("dela", "Delaunay triangulation graph")
183.715 + .optionGroup("alg","dela")
183.716 + .onlyOneGroup("alg")
183.717 + .boolOption("rand", "Use time seed for random number generator")
183.718 + .optionGroup("rand", "rand")
183.719 + .intOption("seed", "Random seed", -1)
183.720 + .optionGroup("rand", "seed")
183.721 + .onlyOneGroup("rand")
183.722 + .other("[prefix]","Prefix of the output files. Default is 'lgf-gen-out'")
183.723 + .run();
183.724 +
183.725 + if (ap["rand"]) {
183.726 + int seed = int(time(0));
183.727 + std::cout << "Random number seed: " << seed << std::endl;
183.728 + rnd = Random(seed);
183.729 + }
183.730 + if (ap.given("seed")) {
183.731 + int seed = ap["seed"];
183.732 + std::cout << "Random number seed: " << seed << std::endl;
183.733 + rnd = Random(seed);
183.734 + }
183.735 +
183.736 + std::string prefix;
183.737 + switch(ap.files().size())
183.738 + {
183.739 + case 0:
183.740 + prefix="lgf-gen-out";
183.741 + break;
183.742 + case 1:
183.743 + prefix=ap.files()[0];
183.744 + break;
183.745 + default:
183.746 + std::cerr << "\nAt most one prefix can be given\n\n";
183.747 + exit(1);
183.748 + }
183.749 +
183.750 + double sum_sizes=0;
183.751 + std::vector<double> sizes;
183.752 + std::vector<double> cum_sizes;
183.753 + for(int s=0;s<num_of_cities;s++)
183.754 + {
183.755 + // sum_sizes+=rnd.exponential();
183.756 + double d=rnd();
183.757 + sum_sizes+=d;
183.758 + sizes.push_back(d);
183.759 + cum_sizes.push_back(sum_sizes);
183.760 + }
183.761 + int i=0;
183.762 + for(int s=0;s<num_of_cities;s++)
183.763 + {
183.764 + Point center=(num_of_cities==1?Point(0,0):rnd.disc());
183.765 + if(gauss_d)
183.766 + for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
183.767 + Node n=g.addNode();
183.768 + nodes.push_back(n);
183.769 + coords[n]=center+rnd.gauss2()*area*
183.770 + std::sqrt(sizes[s]/sum_sizes);
183.771 + }
183.772 + else if(square_d)
183.773 + for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
183.774 + Node n=g.addNode();
183.775 + nodes.push_back(n);
183.776 + coords[n]=center+Point(rnd()*2-1,rnd()*2-1)*area*
183.777 + std::sqrt(sizes[s]/sum_sizes);
183.778 + }
183.779 + else if(disc_d || true)
183.780 + for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
183.781 + Node n=g.addNode();
183.782 + nodes.push_back(n);
183.783 + coords[n]=center+rnd.disc()*area*
183.784 + std::sqrt(sizes[s]/sum_sizes);
183.785 + }
183.786 + }
183.787 +
183.788 +// for (ListGraph::NodeIt n(g); n != INVALID; ++n) {
183.789 +// std::cerr << coords[n] << std::endl;
183.790 +// }
183.791 +
183.792 + if(ap["tsp"]) {
183.793 + tsp();
183.794 + std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
183.795 + }
183.796 + if(ap["tsp2"]) {
183.797 + tsp2();
183.798 + std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
183.799 + }
183.800 + else if(ap["2con"]) {
183.801 + std::cout << "Make triangles\n";
183.802 + // triangle();
183.803 + sparseTriangle(ap["g"]);
183.804 + std::cout << "Make it sparser\n";
183.805 + sparse2(ap["g"]);
183.806 + }
183.807 + else if(ap["tree"]) {
183.808 + minTree();
183.809 + }
183.810 + else if(ap["dela"]) {
183.811 + delaunay();
183.812 + }
183.813 +
183.814 +
183.815 + std::cout << "Number of nodes : " << countNodes(g) << std::endl;
183.816 + std::cout << "Number of arcs : " << countEdges(g) << std::endl;
183.817 + double tlen=0;
183.818 + for(EdgeIt e(g);e!=INVALID;++e)
183.819 + tlen+=std::sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
183.820 + std::cout << "Total arc length : " << tlen << std::endl;
183.821 +
183.822 + if(ap["eps"])
183.823 + graphToEps(g,prefix+".eps").scaleToA4().
183.824 + scale(600).nodeScale(.005).arcWidthScale(.001).preScale(false).
183.825 + coords(coords).hideNodes(ap.given("nonodes")).run();
183.826 +
183.827 + if(ap["dir"])
183.828 + DigraphWriter<ListGraph>(g,prefix+".lgf").
183.829 + nodeMap("coordinates_x",scaleMap(xMap(coords),600)).
183.830 + nodeMap("coordinates_y",scaleMap(yMap(coords),600)).
183.831 + run();
183.832 + else GraphWriter<ListGraph>(g,prefix+".lgf").
183.833 + nodeMap("coordinates_x",scaleMap(xMap(coords),600)).
183.834 + nodeMap("coordinates_y",scaleMap(yMap(coords),600)).
183.835 + run();
183.836 +}
183.837 +